PaStiX Handbook 6.4.0
Loading...
Searching...
No Matches
schur.c
Go to the documentation of this file.
1/**
2 *
3 * @file sopalin/schur.c
4 *
5 * PaStiX schur interface functions
6 *
7 * @copyright 2017-2025 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8 * Univ. Bordeaux. All rights reserved.
9 *
10 * @version 6.4.0
11 * @author Mathieu Faverge
12 * @author Pierre Ramet
13 * @author Xavier Lacoste
14 * @date 2024-07-05
15 *
16 * @addtogroup pastix_schur
17 * @{
18 *
19 **/
20#include "common.h"
21#include <spm.h>
22#include <lapacke.h>
23#include "blend/solver.h"
24#include "sopalin/coeftab_z.h"
25#include "sopalin/coeftab_c.h"
26#include "sopalin/coeftab_d.h"
27#include "sopalin/coeftab_s.h"
28
29/**
30 *******************************************************************************
31 *
32 * @brief Set a list of unknowns that needs to be isolated and pushed at the end
33 * of the ordering before the Schur unknowns if any.
34 *
35 * Remark: This is usually required when some unknowns are disconnected or
36 * zeroes appear on the diagonal.
37 *
38 *******************************************************************************
39 *
40 * @param[inout] pastix_data
41 * The pastix data structure of the solver to store the list of unknowns.
42 *
43 * @param[in] n
44 * The number of unknowns hat needs to be isolated.
45 *
46 * @param[in] list
47 * Array of integer of size n.
48 * The list of unknowns to isolate.
49 *
50 *******************************************************************************/
51void
54 const pastix_int_t *list )
55{
56 if ( n > 0 ) {
57 pastix_data->zeros_n = n;
58 pastix_data->zeros_list = (pastix_int_t*)malloc(n * sizeof(pastix_int_t));
59 memcpy( pastix_data->zeros_list, list, n * sizeof(pastix_int_t) );
60 }
61}
62
63/**
64 *******************************************************************************
65 *
66 * @brief Set the list of unknowns that belongs to the schur complement.
67 *
68 *******************************************************************************
69 *
70 * @param[inout] pastix_data
71 * The pastix data structure of the solver to store the list of Schur
72 * unknowns.
73 *
74 * @param[in] n
75 * The number of unknowns in the Schur complement.
76 *
77 * @param[in] list
78 * Array of integer of size n.
79 * The list of unknowns belonging to the Schur complement with the same
80 * baseval as the associated spm.
81 *
82 *******************************************************************************/
83void
86 const pastix_int_t *list )
87{
88 if ( n > 0 ) {
89 pastix_data->schur_n = n;
90 pastix_data->schur_list = (pastix_int_t*)malloc(n * sizeof(pastix_int_t));
91 memcpy( pastix_data->schur_list, list, n * sizeof(pastix_int_t) );
92 }
93}
94
95/**
96 *******************************************************************************
97 *
98 * @brief Return the Schur complement.
99 *
100 * The Schur complement is returned in the column major layout used by the
101 * classic linear algebra libraries such as Blas or Lapack.
102 *
103 *******************************************************************************
104 *
105 * @param[in] pastix_data
106 * The pastix data structure of the problem solved.
107 *
108 * @param[inout] S
109 * Array of size spm->n -by- lds of arithmetic spm->flttype, where spm
110 * is the spm of the original problem.
111 * On exit, the array contains the Schur complement of the factorized
112 * matrix. The full S is initialized for non symmetric problems, only
113 * the lower part is initialized and the upper part remains untouched
114 * for symmetric ones. (Enable PASTIX_NUMFACT_SYMMETRIZED_SCHUR to force
115 * upper part initialization in symmetric case)
116 *
117 * @param[in] lds
118 * The leading dimension of the S array.
119 *
120 ********************************************************************************
121 *
122 * @retval PASTIX_SUCCESS on successful exit,
123 * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
124 *
125 *******************************************************************************/
126int
127pastixGetSchur( const pastix_data_t *pastix_data,
128 void *S,
129 pastix_int_t lds )
130{
131 pastix_int_t *iparm;
132
133 /*
134 * Check parameters
135 */
136 if (pastix_data == NULL) {
137 pastix_print_error( "pastix_getSchur: wrong pastix_data parameter" );
139 }
140 if (S == NULL) {
141 pastix_print_error( "pastix_getSchur: S parameter" );
143 }
144 if (lds <= 0) {
145 pastix_print_error( "pastix_getSchur: lds parameter" );
147 }
148 if ( !(pastix_data->steps & STEP_NUMFACT) ) {
149 pastix_print_error( "pastix_getSchur: All steps from pastix_task_init() to pastix_task_numfact() have to be called before calling this function" );
151 }
152#if defined(PASTIX_WITH_MPI)
153 if (pastix_data->inter_node_procnbr > 1) {
154 if ( pastix_data->inter_node_procnum == 0 ) {
155 pastix_print_error( "pastix_getSchur: Schur complement is not available yet with multiple MPI processes\n" );
156 }
157 return -1;
158 }
159#endif
160
161 iparm = pastix_data->iparm;
162 switch(iparm[IPARM_FLOAT])
163 {
164 case PastixPattern:
165 break;
166 case PastixFloat:
167 coeftab_sgetschur( pastix_data->solvmatr, S, lds );
168 break;
169 case PastixComplex32:
170 coeftab_cgetschur( pastix_data->solvmatr, S, lds );
171 break;
172 case PastixComplex64:
173 coeftab_zgetschur( pastix_data->solvmatr, S, lds );
174 break;
175 case PastixDouble:
176 default:
177 coeftab_dgetschur( pastix_data->solvmatr, S, lds );
178 }
179 return PASTIX_SUCCESS;
180}
181
182/**
183 *******************************************************************************
184 *
185 * @ingroup pastix_solve
186 *
187 * @brief Get the vector in an RHS data structure.
188 *
189 *******************************************************************************
190 *
191 * @param[in] pastix_data
192 * TODO
193 *
194 * @param[in] m
195 * The number of rows of the vector b, must be equal to the number of
196 * unknowns in the Schur complement.
197 *
198 * @param[in] n
199 * The number of columns of the vector b.
200 *
201 * @param[in] rhsB
202 * The pastix_rhs_t data structure used to solve the system.
203 *
204 * @param[inout] B
205 * On entry, a vector of size ldb-by-n.
206 * On exit, the m-by-n leading part contains the right hand side
207 * related to the Schur part.
208 *
209 * @param[in] ldb
210 * The leading dimension of the vector b.
211 *
212 *******************************************************************************
213 *
214 * @retval PASTIX_SUCCESS on successful exit,
215 * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
216 *
217 *******************************************************************************/
218int
220 pastix_int_t m,
221 pastix_int_t n,
222 pastix_rhs_t rhsB,
223 void *B,
224 pastix_int_t ldb )
225{
226 const SolverMatrix *solvmtx;
227 const SolverCblk *cblk;
228 pastix_int_t mschur;
229 void *bptr;
230 int rc;
231
232 if ( pastix_data == NULL ) {
233 pastix_print_error( "pastixRhsSchurGet: wrong pastix_data parameter" );
235 }
236 if ( rhsB == NULL ) {
237 pastix_print_error( "pastixRhsSchurGet: wrong rhsB parameter" );
239 }
240 if ( B == NULL ) {
241 pastix_print_error( "pastixRhsSchurGet: wrong b parameter" );
243 }
244
245 solvmtx = pastix_data->solvmatr;
246 cblk = solvmtx->cblktab + solvmtx->cblkschur;
247 mschur = solvmtx->nodenbr - cblk->fcolnum;
248
249 if ( m != mschur ) {
250 pastix_print_error( "pastixRhsSchurGet: wrong m parameter expecting %ld but was %ld\n",
251 (long)mschur, (long)m );
253 }
254 if ( n != rhsB->n ) {
255 pastix_print_error( "pastixRhsSchurGet: wrong n parameter expecting %ld but was %ld\n",
256 (long)rhsB->n, (long)n );
258 }
259 if ( ldb < m ) {
260 pastix_print_error( "pastixRhsSchurGet: wrong ldb parameter\n" );
262 }
263
264 bptr = ((char *)rhsB->b) + cblk->lcolidx * pastix_size_of( rhsB->flttype );
265
266 switch( rhsB->flttype ) {
267 case SpmComplex64:
268 rc = LAPACKE_zlacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, (pastix_complex64_t *)bptr, rhsB->ld, B, ldb );
269 break;
270 case SpmComplex32:
271 rc = LAPACKE_clacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, (pastix_complex32_t *)bptr, rhsB->ld, B, ldb );
272 break;
273 case SpmDouble:
274 rc = LAPACKE_dlacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, (double *)bptr, rhsB->ld, B, ldb );
275 break;
276 case SpmFloat:
277 rc = LAPACKE_slacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, (float *)bptr, rhsB->ld, B, ldb );
278 break;
279 default:
280 pastix_print_error( "pastixRhsSchurGet: unknown flttype\n" );
282 }
283
284 return rc;
285}
286
287/**
288 *******************************************************************************
289 *
290 * @ingroup pastix_solve
291 *
292 * @brief Set the vector in an RHS data structure.
293 *
294 *******************************************************************************
295 *
296 * @param[in] pastix_data
297 * TODO
298 *
299 * @param[in] m
300 * The number of rows of the vector b.
301 *
302 * @param[in] n
303 * The number of columns of the vector b.
304 *
305 * @param[in] B
306 * The vector b.
307 *
308 * @param[in] ldb
309 * The leading dimension of the vector b.
310 *
311 * @param[out] rhsB
312 * The pastix_rhs_t data structure which contains the vector b.
313 *
314 *******************************************************************************
315 *
316 * @retval PASTIX_SUCCESS on successful exit,
317 * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
318 *
319 *******************************************************************************/
320int
322 pastix_int_t m,
323 pastix_int_t n,
324 void *B,
325 pastix_int_t ldb,
326 pastix_rhs_t rhsB )
327{
328 const SolverMatrix *solvmtx;
329 const SolverCblk *cblk;
330 pastix_int_t mschur;
331 void *bptr;
332 int rc;
333
334 if ( pastix_data == NULL ) {
335 pastix_print_error( "pastixRhsSchurSet: wrong pastix_data parameter" );
337 }
338 if ( rhsB == NULL ) {
339 pastix_print_error( "pastixRhsSchurSet: wrong rhsB parameter" );
341 }
342 if ( B == NULL ) {
343 pastix_print_error( "pastixRhsSchurSet: wrong b parameter" );
345 }
346
347 solvmtx = pastix_data->solvmatr;
348 cblk = solvmtx->cblktab + solvmtx->cblkschur;
349 mschur = solvmtx->nodenbr - cblk->fcolnum;
350
351 if ( m != mschur ) {
352 pastix_print_error( "pastixRhsSchurSet: wrong m parameter expecting %ld but was %ld\n",
353 (long)mschur, (long)m );
355 }
356 if ( n != rhsB->n ) {
357 pastix_print_error( "pastixRhsSchurSet: wrong n parameter expecting %ld but was %ld\n",
358 (long)rhsB->n, (long)n );
360 }
361 if ( ldb < m ) {
362 pastix_print_error( "pastixRhsSchurSet: wrong ldb parameter\n" );
364 }
365
366 bptr = ((char *)rhsB->b) + cblk->lcolidx * pastix_size_of( rhsB->flttype );
367
368 switch( rhsB->flttype ) {
369 case SpmComplex64:
370 rc = LAPACKE_zlacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, B, ldb, (pastix_complex64_t *)bptr, rhsB->ld );
371 break;
372 case SpmComplex32:
373 rc = LAPACKE_clacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, B, ldb, (pastix_complex32_t *)bptr, rhsB->ld );
374 break;
375 case SpmDouble:
376 rc = LAPACKE_dlacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, B, ldb, (double *)bptr, rhsB->ld );
377 break;
378 case SpmFloat:
379 rc = LAPACKE_slacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, B, ldb, (float *)bptr, rhsB->ld );
380 break;
381 default:
382 pastix_print_error( "pastixRhsSchurSet: unknown flttype\n" );
384 }
385
386 return rc;
387}
388
389/**
390 * @}
391 */
BEGIN_C_DECLS typedef int pastix_int_t
Definition datatypes.h:51
float _Complex pastix_complex32_t
Definition datatypes.h:76
void coeftab_sgetschur(const SolverMatrix *solvmtx, float *S, pastix_int_t lds)
Extract the Schur complement.
Definition coeftab_s.c:611
void coeftab_dgetschur(const SolverMatrix *solvmtx, double *S, pastix_int_t lds)
Extract the Schur complement.
Definition coeftab_d.c:611
void coeftab_zgetschur(const SolverMatrix *solvmtx, pastix_complex64_t *S, pastix_int_t lds)
Extract the Schur complement.
Definition coeftab_z.c:611
void coeftab_cgetschur(const SolverMatrix *solvmtx, pastix_complex32_t *S, pastix_int_t lds)
Extract the Schur complement.
Definition coeftab_c.c:611
@ IPARM_FLOAT
Definition api.h:149
@ PASTIX_SUCCESS
Definition api.h:367
@ PASTIX_ERR_BADPARAMETER
Definition api.h:374
void pastixSetSchurUnknownList(pastix_data_t *pastix_data, pastix_int_t n, const pastix_int_t *list)
Set the list of unknowns that belongs to the schur complement.
Definition schur.c:84
int pastixGetSchur(const pastix_data_t *pastix_data, void *S, pastix_int_t lds)
Return the Schur complement.
Definition schur.c:127
void pastixIsolateUnknowns(pastix_data_t *pastix_data, pastix_int_t n, const pastix_int_t *list)
Set a list of unknowns that needs to be isolated and pushed at the end of the ordering before the Sch...
Definition schur.c:52
int pastixRhsSchurSet(const pastix_data_t *pastix_data, pastix_int_t m, pastix_int_t n, void *B, pastix_int_t ldb, pastix_rhs_t rhsB)
Set the vector in an RHS data structure.
Definition schur.c:321
int pastixRhsSchurGet(const pastix_data_t *pastix_data, pastix_int_t m, pastix_int_t n, pastix_rhs_t rhsB, void *B, pastix_int_t ldb)
Get the vector in an RHS data structure.
Definition schur.c:219
int inter_node_procnum
Definition pastixdata.h:84
SolverMatrix * solvmatr
Definition pastixdata.h:103
int inter_node_procnbr
Definition pastixdata.h:83
pastix_int_t zeros_n
Definition pastixdata.h:96
pastix_int_t * iparm
Definition pastixdata.h:70
pastix_int_t ld
Definition pastixdata.h:160
pastix_coeftype_t flttype
Definition pastixdata.h:157
pastix_int_t schur_n
Definition pastixdata.h:94
pastix_int_t * schur_list
Definition pastixdata.h:95
pastix_int_t * zeros_list
Definition pastixdata.h:97
pastix_int_t steps
Definition pastixdata.h:73
pastix_int_t n
Definition pastixdata.h:159
Main PaStiX data structure.
Definition pastixdata.h:68
Main PaStiX RHS structure.
Definition pastixdata.h:155
pastix_int_t nodenbr
Definition solver.h:208
pastix_int_t lcolidx
Definition solver.h:170
SolverCblk *restrict cblktab
Definition solver.h:228
pastix_int_t cblkschur
Definition solver.h:221
pastix_int_t fcolnum
Definition solver.h:166
Solver column block structure.
Definition solver.h:161
Solver column block structure.
Definition solver.h:203