1 /*
2  *
3  *  This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011
4  *
5  *
6  *  This version of MUMPS is provided to you free of charge. It is public
7  *  domain, based on public domain software developed during the Esprit IV
8  *  European project PARASOL (1996-1999). Since this first public domain
9  *  version in 1999, research and developments have been supported by the
10  *  following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT,
11  *  INRIA, and University of Bordeaux.
12  *
13  *  The MUMPS team at the moment of releasing this version includes
14  *  Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche,
15  *  Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora
16  *  Ucar and Clement Weisbecker.
17  *
18  *  We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil
19  *  Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat,
20  *  Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire
21  *  Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who
22  *  have been contributing to this project.
23  *
24  *  Up-to-date copies of the MUMPS package can be obtained
25  *  from the Web pages:
26  *  http://mumps.enseeiht.fr/  or  http://graal.ens-lyon.fr/MUMPS
27  *
28  *
29  *   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
30  *   EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
31  *
32  *
33  *  User documentation of any code that uses this software can
34  *  include this complete notice. You can acknowledge (using
35  *  references [1] and [2]) the contribution of this package
36  *  in any scientific publication dependent upon the use of the
37  *  package. You shall use reasonable endeavours to notify
38  *  the authors of the package of this publication.
39  *
40  *   [1] P. R. Amestoy, I. S. Duff, J. Koster and  J.-Y. L'Excellent,
41  *   A fully asynchronous multifrontal solver using distributed dynamic
42  *   scheduling, SIAM Journal of Matrix Analysis and Applications,
43  *   Vol 23, No 1, pp 15-41 (2001).
44  *
45  *   [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and
46  *   S. Pralet, Hybrid scheduling for the parallel solution of linear
47  *   systems. Parallel Computing Vol 32 (2), pp 136-156 (2006).
48  *
49  */
50 /* Written by JYL, march 2002 */
51 /* This file groups so far all C functions and symbols that vary with the
52    arithmetic */
53 /* Header used for debug purpose only
54 #include <stdio.h>
55 */
56 #include <string.h>
57 #include "mumps_common.h"
58 #if MUMPS_ARITH == MUMPS_ARITH_s
59 # include "smumps_c.h"
60 # define MUMPS_REAL    SMUMPS_REAL
61 # define MUMPS_COMPLEX SMUMPS_COMPLEX
62 #elif MUMPS_ARITH == MUMPS_ARITH_d
63 # include "dmumps_c.h"
64 # define MUMPS_REAL    DMUMPS_REAL
65 # define MUMPS_COMPLEX DMUMPS_COMPLEX
66 #elif MUMPS_ARITH == MUMPS_ARITH_c
67 # include "cmumps_c.h"
68 # define MUMPS_REAL    CMUMPS_REAL
69 # define MUMPS_COMPLEX CMUMPS_COMPLEX
70 #elif MUMPS_ARITH == MUMPS_ARITH_z
71 # include "zmumps_c.h"
72 # define MUMPS_REAL    ZMUMPS_REAL
73 # define MUMPS_COMPLEX ZMUMPS_COMPLEX
74 #endif
75 /**
76  * F_SYM_ARITH is the same as F_SYMBOL (see mumps_commn.h) for the symbols
77  * that depend on the arithmetic.
78  * Example: For CMUMPS_XXX, first define
79  *   #define CMUMPS_XXX F_SYM_ARITH(xxx,XXX) and then use
80  *   CMUMPS_XXX in the code to get rid of any symbol convention annoyance.
81  */
82 #if MUMPS_ARITH == MUMPS_ARITH_s
83 # if defined(UPPER) || defined(MUMPS_WIN32)
84 #  define F_SYM_ARITH(lower_case,upper_case) SMUMPS_##upper_case
85 # elif defined(Add_)
86 #  define F_SYM_ARITH(lower_case,upper_case) smumps_##lower_case##_
87 # elif defined(Add__)
88 #  define F_SYM_ARITH(lower_case,upper_case) smumps_##lower_case##__
89 # else
90 #  define F_SYM_ARITH(lower_case,upper_case) smumps_##lower_case
91 # endif
92 #elif MUMPS_ARITH == MUMPS_ARITH_d
93 # if defined(UPPER) || defined(MUMPS_WIN32)
94 #  define F_SYM_ARITH(lower_case,upper_case) DMUMPS_##upper_case
95 # elif defined(Add_)
96 #  define F_SYM_ARITH(lower_case,upper_case) dmumps_##lower_case##_
97 # elif defined(Add__)
98 #  define F_SYM_ARITH(lower_case,upper_case) dmumps_##lower_case##__
99 # else
100 #  define F_SYM_ARITH(lower_case,upper_case) dmumps_##lower_case
101 # endif
102 #elif MUMPS_ARITH == MUMPS_ARITH_c
103 # if defined(UPPER) || defined(MUMPS_WIN32)
104 #  define F_SYM_ARITH(lower_case,upper_case) CMUMPS_##upper_case
105 # elif defined(Add_)
106 #  define F_SYM_ARITH(lower_case,upper_case) cmumps_##lower_case##_
107 # elif defined(Add__)
108 #  define F_SYM_ARITH(lower_case,upper_case) cmumps_##lower_case##__
109 # else
110 #  define F_SYM_ARITH(lower_case,upper_case) cmumps_##lower_case
111 # endif
112 #elif MUMPS_ARITH == MUMPS_ARITH_z
113 # if defined(UPPER) || defined(MUMPS_WIN32)
114 #  define F_SYM_ARITH(lower_case,upper_case) ZMUMPS_##upper_case
115 # elif defined(Add_)
116 #  define F_SYM_ARITH(lower_case,upper_case) zmumps_##lower_case##_
117 # elif defined(Add__)
118 #  define F_SYM_ARITH(lower_case,upper_case) zmumps_##lower_case##__
119 # else
120 #  define F_SYM_ARITH(lower_case,upper_case) zmumps_##lower_case
121 # endif
122 #endif
123 #define MUMPS_F77       \
124     F_SYM_ARITH(f77,F77)
125 void MUMPS_CALL
126 MUMPS_F77( MUMPS_INT      *job,
127            MUMPS_INT      *sym,
128            MUMPS_INT      *par,
129            MUMPS_INT      *comm_fortran,
130            MUMPS_INT      *n,
131            MUMPS_INT      *icntl,
132            MUMPS_REAL     *cntl,
133            MUMPS_INT      *nz,
134            MUMPS_INT      *irn,
135            MUMPS_INT      *irn_avail,
136            MUMPS_INT      *jcn,
137            MUMPS_INT      *jcn_avail,
138            MUMPS_COMPLEX  *a,
139            MUMPS_INT      *a_avail,
140            MUMPS_INT      *nz_loc,
141            MUMPS_INT      *irn_loc,
142            MUMPS_INT      *irn_loc_avail,
143            MUMPS_INT      *jcn_loc,
144            MUMPS_INT      *jcn_loc_avail,
145            MUMPS_COMPLEX  *a_loc,
146            MUMPS_INT      *a_loc_avail,
147            MUMPS_INT      *nelt,
148            MUMPS_INT      *eltptr,
149            MUMPS_INT      *eltptr_avail,
150            MUMPS_INT      *eltvar,
151            MUMPS_INT      *eltvar_avail,
152            MUMPS_COMPLEX  *a_elt,
153            MUMPS_INT      *a_elt_avail,
154            MUMPS_INT      *perm_in,
155            MUMPS_INT      *perm_in_avail,
156            MUMPS_COMPLEX  *rhs,
157            MUMPS_INT      *rhs_avail,
158            MUMPS_COMPLEX  *redrhs,
159            MUMPS_INT      *redrhs_avail,
160            MUMPS_INT      *info,
161            MUMPS_REAL     *rinfo,
162            MUMPS_INT      *infog,
163            MUMPS_REAL     *rinfog,
164            MUMPS_INT      *deficiency,
165            MUMPS_INT      *lwk_user,
166            MUMPS_INT      *size_schur,
167            MUMPS_INT      *listvar_schur,
168            MUMPS_INT      *listvar_schur_avail,
169            MUMPS_COMPLEX  *schur,
170            MUMPS_INT      *schur_avail,
171            MUMPS_COMPLEX  *wk_user,
172            MUMPS_INT      *wk_user_avail,
173            MUMPS_REAL     *colsca,
174            MUMPS_INT      *colsca_avail,
175            MUMPS_REAL     *rowsca,
176            MUMPS_INT      *rowsca_avail,
177            MUMPS_INT      *instance_number,
178            MUMPS_INT      *nrhs,
179            MUMPS_INT      *lrhs,
180            MUMPS_INT      *lredrhs,
181            MUMPS_COMPLEX  *rhs_sparse,
182            MUMPS_INT      *rhs_sparse_avail,
183            MUMPS_COMPLEX  *sol_loc,
184            MUMPS_INT      *sol_loc_avail,
185            MUMPS_INT      *irhs_sparse,
186            MUMPS_INT      *irhs_sparse_avail,
187            MUMPS_INT      *irhs_ptr,
188            MUMPS_INT      *irhs_ptr_avail,
189            MUMPS_INT      *isol_loc,
190            MUMPS_INT      *isol_loc_avail,
191            MUMPS_INT      *nz_rhs,
192            MUMPS_INT      *lsol_loc,
193            MUMPS_INT      *schur_mloc,
194            MUMPS_INT      *schur_nloc,
195            MUMPS_INT      *schur_lld,
196            MUMPS_INT      *schur_mblock,
197            MUMPS_INT      *schur_nblock,
198            MUMPS_INT      *schur_nprow,
199            MUMPS_INT      *schur_npcol,
200            MUMPS_INT      *ooc_tmpdir,
201            MUMPS_INT      *ooc_prefix,
202            MUMPS_INT      *write_problem,
203            MUMPS_INT      *ooc_tmpdirlen,
204            MUMPS_INT      *ooc_prefixlen,
205            MUMPS_INT      *write_problemlen
206            );
207 #ifdef return_scaling
208 /*
209  * Those two are static. They are passed inside cmumps_f77 but
210  * might also be changed on return by MUMPS_AFFECT_COLSCA/ROWSCA
211  * NB: They are put here because they use MUMPS_REAL and need thus
212  * one symbol per arithmetic.
213  */
214 #if MUMPS_ARITH == MUMPS_ARITH_s
215 # define MUMPS_COLSCA_STATIC SMUMPS_COLSCA_STATIC
216 # define MUMPS_ROWSCA_STATIC SMUMPS_ROWSCA_STATIC
217 #elif MUMPS_ARITH == MUMPS_ARITH_d
218 # define MUMPS_COLSCA_STATIC SMUMPS_COLSCA_STATIC
219 # define MUMPS_ROWSCA_STATIC SMUMPS_ROWSCA_STATIC
220 #elif MUMPS_ARITH == MUMPS_ARITH_c
221 # define MUMPS_COLSCA_STATIC CMUMPS_COLSCA_STATIC
222 # define MUMPS_ROWSCA_STATIC CMUMPS_ROWSCA_STATIC
223 #elif MUMPS_ARITH == MUMPS_ARITH_z
224 # define MUMPS_COLSCA_STATIC ZMUMPS_COLSCA_STATIC
225 # define MUMPS_ROWSCA_STATIC ZMUMPS_ROWSCA_STATIC
226 #endif
227 static MUMPS_REAL * MUMPS_COLSCA_STATIC;
228 static MUMPS_REAL * MUMPS_ROWSCA_STATIC;
229 #define MUMPS_AFFECT_COLSCA \
230     F_SYM_ARITH(affect_colsca,AFFECT_COLSCA)
231 void MUMPS_CALL
MUMPS_AFFECT_COLSCA(MUMPS_REAL * f77colsca)232 MUMPS_AFFECT_COLSCA(MUMPS_REAL * f77colsca)
233 {
234   MUMPS_COLSCA_STATIC = f77colsca;
235 }
236 #define MUMPS_NULLIFY_C_COLSCA \
237     F_SYM_ARITH(nullify_c_colsca,NULLIFY_C_COLSCA)
238 void MUMPS_CALL
MUMPS_NULLIFY_C_COLSCA()239 MUMPS_NULLIFY_C_COLSCA()
240 {
241   MUMPS_COLSCA_STATIC = 0;
242 }
243 #define MUMPS_AFFECT_ROWSCA \
244     F_SYM_ARITH(affect_rowsca,AFFECT_ROWSCA)
245 void MUMPS_CALL
MUMPS_AFFECT_ROWSCA(MUMPS_REAL * f77rowsca)246 MUMPS_AFFECT_ROWSCA(MUMPS_REAL * f77rowsca)
247 {
248   MUMPS_ROWSCA_STATIC = f77rowsca;
249 }
250 #define MUMPS_NULLIFY_C_ROWSCA \
251     F_SYM_ARITH(nullify_c_rowsca,NULLIFY_C_ROWSCA)
252 void MUMPS_CALL
MUMPS_NULLIFY_C_ROWSCA()253 MUMPS_NULLIFY_C_ROWSCA()
254 {
255   MUMPS_ROWSCA_STATIC = 0;
256 }
257 #endif /* return_scaling */
258 #if MUMPS_ARITH == MUMPS_ARITH_s
259 # define mumps_c       smumps_c
260 # define MUMPS_STRUC_C SMUMPS_STRUC_C
261 #elif MUMPS_ARITH == MUMPS_ARITH_d
262 # define mumps_c       dmumps_c
263 # define MUMPS_STRUC_C DMUMPS_STRUC_C
264 #elif MUMPS_ARITH == MUMPS_ARITH_c
265 # define mumps_c       cmumps_c
266 # define MUMPS_STRUC_C CMUMPS_STRUC_C
267 #elif MUMPS_ARITH == MUMPS_ARITH_z
268 # define mumps_c       zmumps_c
269 # define MUMPS_STRUC_C ZMUMPS_STRUC_C
270 #endif
271 void MUMPS_CALL
mumps_c(MUMPS_STRUC_C * mumps_par)272 mumps_c(MUMPS_STRUC_C * mumps_par)
273 {
274     /*
275      * The following local variables will
276      *  be passed to the F77 interface.
277      */
278     MUMPS_INT *icntl;
279     MUMPS_REAL *cntl;
280     MUMPS_INT *irn; MUMPS_INT *jcn; MUMPS_COMPLEX *a;
281     MUMPS_INT *irn_loc; MUMPS_INT *jcn_loc; MUMPS_COMPLEX *a_loc;
282     MUMPS_INT *eltptr, *eltvar; MUMPS_COMPLEX *a_elt;
283     MUMPS_INT *perm_in; MUMPS_INT perm_in_avail;
284     MUMPS_INT *listvar_schur; MUMPS_INT listvar_schur_avail;
285     MUMPS_COMPLEX *schur; MUMPS_INT schur_avail;
286     MUMPS_COMPLEX *rhs; MUMPS_COMPLEX *redrhs;
287     MUMPS_COMPLEX *wk_user; MUMPS_INT wk_user_avail;
288     MUMPS_REAL *colsca; MUMPS_REAL *rowsca;
289     MUMPS_COMPLEX *rhs_sparse, *sol_loc;
290     MUMPS_INT *irhs_sparse, *irhs_ptr, *isol_loc;
291     MUMPS_INT irn_avail, jcn_avail, a_avail, rhs_avail, redrhs_avail;
292     /* These are actually used
293      * as booleans, but we stick
294      * to simple types for the
295      * C-F77 interface */
296     MUMPS_INT irn_loc_avail, jcn_loc_avail, a_loc_avail;
297     MUMPS_INT eltptr_avail, eltvar_avail, a_elt_avail;
298     MUMPS_INT colsca_avail, rowsca_avail;
299     MUMPS_INT irhs_ptr_avail, rhs_sparse_avail, sol_loc_avail;
300     MUMPS_INT irhs_sparse_avail, isol_loc_avail;
301     MUMPS_INT *info; MUMPS_INT *infog;
302     MUMPS_REAL *rinfo; MUMPS_REAL *rinfog;
303     MUMPS_INT ooc_tmpdir[255]; MUMPS_INT ooc_prefix[63];
304     MUMPS_INT write_problem[255];
305     /* Other local variables */
306     MUMPS_INT idummy; MUMPS_INT *idummyp;
307     MUMPS_REAL rdummy; MUMPS_REAL *rdummyp;
308     MUMPS_COMPLEX cdummy; MUMPS_COMPLEX *cdummyp;
309     /* String lengths to be passed to Fortran by address */
310     int ooc_tmpdirlen;
311     int ooc_prefixlen;
312     int write_problemlen;
313     int i;
314     static const MUMPS_INT no = 0;
315     static const MUMPS_INT yes = 1;
316     idummyp = &idummy;
317     cdummyp = &cdummy;
318     rdummyp = &rdummy;
319 #ifdef return_scaling
320     /* Don't forget to initialize those two before
321      * each call to mumps as we may copy values from
322      * old instances otherwise ! */
323     MUMPS_COLSCA_STATIC=0;
324     MUMPS_ROWSCA_STATIC=0;
325 #endif
326     /* Initialize pointers to zero for job == -1 */
327     if ( mumps_par->job == -1 )
328       { /* job = -1: we just reset all pointers to 0 */
329         mumps_par->irn=0; mumps_par->jcn=0; mumps_par->a=0; mumps_par->rhs=0; mumps_par->wk_user=0;
330         mumps_par->redrhs=0;
331         mumps_par->eltptr=0; mumps_par->eltvar=0; mumps_par->a_elt=0; mumps_par->perm_in=0; mumps_par->sym_perm=0; mumps_par->uns_perm=0; mumps_par->irn_loc=0;mumps_par->jcn_loc=0;mumps_par->a_loc=0; mumps_par->listvar_schur=0;mumps_par->schur=0;mumps_par->mapping=0;mumps_par->pivnul_list=0;mumps_par->colsca=0;mumps_par->rowsca=0; mumps_par->rhs_sparse=0; mumps_par->irhs_sparse=0; mumps_par->sol_loc=0; mumps_par->irhs_ptr=0; mumps_par->isol_loc=0;
332         strcpy(mumps_par->ooc_tmpdir,"NAME_NOT_INITIALIZED");
333         strcpy(mumps_par->ooc_prefix,"NAME_NOT_INITIALIZED");
334         strcpy(mumps_par->write_problem,"NAME_NOT_INITIALIZED");
335         strncpy(mumps_par->version_number,MUMPS_VERSION,MUMPS_VERSION_MAX_LEN);
336         mumps_par->version_number[MUMPS_VERSION_MAX_LEN+1] = '\0';
337         /* Next line initializes scalars to arbitrary values.
338          * Some of those will anyway be overwritten during the
339          * call to Fortran routine [SDCZ]MUMPS_INIT_PHASE */
340         mumps_par->n=0; mumps_par->nz=0; mumps_par->nz_loc=0; mumps_par->nelt=0;mumps_par->instance_number=0;mumps_par->deficiency=0;mumps_par->lwk_user=0;mumps_par->size_schur=0;mumps_par->lrhs=0; mumps_par->lredrhs=0; mumps_par->nrhs=0; mumps_par->nz_rhs=0; mumps_par->lsol_loc=0;
341  mumps_par->schur_mloc=0; mumps_par->schur_nloc=0; mumps_par->schur_lld=0; mumps_par->mblock=0; mumps_par->nblock=0; mumps_par->nprow=0; mumps_par->npcol=0;
342       }
343      ooc_tmpdirlen=(int)strlen(mumps_par->ooc_tmpdir);
344      ooc_prefixlen=(int)strlen(mumps_par->ooc_prefix);
345      write_problemlen=(int)strlen(mumps_par->write_problem);
346     /* Avoid the use of strnlen which may not be
347      * available on all systems. Allow strings without
348      * \0 at the end, if the file is not found, the
349      * Fortran layer is responsible for raising an
350      * error.  */
351     if(ooc_tmpdirlen > 255){
352         ooc_tmpdirlen=255;
353       }
354     if(ooc_prefixlen > 63){
355         ooc_prefixlen=63;
356       }
357     if(write_problemlen > 255){
358         write_problemlen=255;
359       }
360     /*
361      * Extract info from the C structure to call the F77 interface. The
362      * following macro avoids repeating the same code with risks of errors.
363      */
364 #define EXTRACT_POINTERS(component,dummypointer) \
365     if ( mumps_par-> component == 0) \
366       { component = dummypointer; \
367         component ## _avail = no; }  \
368     else  \
369       { component = mumps_par-> component; \
370         component ## _avail = yes; }
371     /*
372      * For example, EXTRACT_POINTERS(irn,idummyp) produces the following line of code:
373        if (mumps_par->irn== 0) {irn= idummyp;irn_avail = no; } else {  irn  = mumps_par->irn;irn_avail = yes; } ;
374      * which says that irn is set to mumps_par->irn except if
375      * mumps_par->irn is 0, which means that it is not available.
376      */
377     EXTRACT_POINTERS(irn,idummyp);
378     EXTRACT_POINTERS(jcn,idummyp);
379     EXTRACT_POINTERS(rhs,cdummyp);
380     EXTRACT_POINTERS(wk_user,cdummyp);
381     EXTRACT_POINTERS(redrhs,cdummyp);
382     EXTRACT_POINTERS(irn_loc,idummyp);
383     EXTRACT_POINTERS(jcn_loc,idummyp);
384     EXTRACT_POINTERS(a_loc,cdummyp);
385     EXTRACT_POINTERS(a,cdummyp);
386     EXTRACT_POINTERS(eltptr,idummyp);
387     EXTRACT_POINTERS(eltvar,idummyp);
388     EXTRACT_POINTERS(a_elt,cdummyp);
389     EXTRACT_POINTERS(perm_in,idummyp);
390     EXTRACT_POINTERS(listvar_schur,idummyp);
391     EXTRACT_POINTERS(schur,cdummyp);
392     EXTRACT_POINTERS(colsca,rdummyp);
393     EXTRACT_POINTERS(rowsca,rdummyp);
394     EXTRACT_POINTERS(rhs_sparse,cdummyp);
395     EXTRACT_POINTERS(sol_loc,cdummyp);
396     EXTRACT_POINTERS(irhs_sparse,idummyp);
397     EXTRACT_POINTERS(isol_loc,idummyp);
398     EXTRACT_POINTERS(irhs_ptr,idummyp);
399     /* printf("irn_avail,jcn_avail, rhs_avail, a_avail, eltptr_avail, eltvar_avail,a_elt_avail,perm_in_avail= %d %d %d %d %d %d %d \n", irn_avail,jcn_avail, rhs_avail, a_avail, eltptr_avail, eltvar_avail, a_elt_avail, perm_in_avail);*/
400     /*
401      * Extract integers (input) or pointers that are
402      * always allocated (such as ICNTL, INFO, ...)
403      */
404     /* size_schur = mumps_par->size_schur; */
405     /* instance_number = mumps_par->instance_number; */
406     icntl = mumps_par->icntl;
407     cntl = mumps_par->cntl;
408     info = mumps_par->info;
409     infog = mumps_par->infog;
410     rinfo = mumps_par->rinfo;
411     rinfog = mumps_par->rinfog;
412     for(i=0;i<ooc_tmpdirlen;i++){
413       ooc_tmpdir[i]=(int)mumps_par->ooc_tmpdir[i];
414     }
415     for(i=0;i<ooc_prefixlen;i++){
416       ooc_prefix[i]=(int)mumps_par->ooc_prefix[i];
417     }
418     for(i=0;i<write_problemlen;i++){
419       write_problem[i]=(int)mumps_par->write_problem[i];
420     }
421     /* Call F77 interface */
422     MUMPS_F77(&(mumps_par->job), &(mumps_par->sym), &(mumps_par->par), &(mumps_par->comm_fortran),
423           &(mumps_par->n), icntl, cntl,
424           &(mumps_par->nz), irn, &irn_avail, jcn, &jcn_avail, a, &a_avail,
425           &(mumps_par->nz_loc), irn_loc, &irn_loc_avail, jcn_loc, &jcn_loc_avail,
426           a_loc, &a_loc_avail,
427           &(mumps_par->nelt), eltptr, &eltptr_avail, eltvar, &eltvar_avail, a_elt, &a_elt_avail,
428           perm_in, &perm_in_avail,
429           rhs, &rhs_avail, redrhs, &redrhs_avail, info, rinfo, infog, rinfog,
430           &(mumps_par->deficiency), &(mumps_par->lwk_user), &(mumps_par->size_schur), listvar_schur, &listvar_schur_avail, schur,
431           &schur_avail, wk_user, &wk_user_avail, colsca, &colsca_avail, rowsca, &rowsca_avail,
432           &(mumps_par->instance_number), &(mumps_par->nrhs), &(mumps_par->lrhs),
433           &(mumps_par->lredrhs),
434           rhs_sparse, &rhs_sparse_avail, sol_loc, &sol_loc_avail, irhs_sparse,
435           &irhs_sparse_avail, irhs_ptr, &irhs_ptr_avail, isol_loc,
436           &isol_loc_avail, &(mumps_par->nz_rhs), &(mumps_par->lsol_loc)
437           , &(mumps_par->schur_mloc)
438           , &(mumps_par->schur_nloc)
439           , &(mumps_par->schur_lld)
440           , &(mumps_par->mblock)
441           , &(mumps_par->nblock)
442           , &(mumps_par->nprow)
443           , &(mumps_par->npcol)
444           , ooc_tmpdir
445           , ooc_prefix
446           , write_problem
447           , &ooc_tmpdirlen
448           , &ooc_prefixlen
449           , &write_problemlen
450     );
451     /*
452      * mapping and pivnul_list are usually 0 except if
453      * MUMPS_AFFECT_MAPPING/MUMPS_AFFECT_PIVNUL_LIST was called.
454      */
455     mumps_par->mapping=mumps_get_mapping();
456     mumps_par->pivnul_list=mumps_get_pivnul_list();
457     /* to get permutations computed during analysis */
458     mumps_par->sym_perm=mumps_get_sym_perm();
459     mumps_par->uns_perm=mumps_get_uns_perm();
460 #ifdef return_scaling
461     /*
462      * colsca/rowsca can either be user data or have been
463      * modified within mumps by calls to MUMPS_AFFECT_COLSCA/ROWSCA.
464      */
465     if (colsca_avail == no) mumps_par->colsca = MUMPS_COLSCA_STATIC;
466     if (rowsca_avail == no) mumps_par->rowsca = MUMPS_ROWSCA_STATIC;
467 #endif
468 }
469