1 #define PETSCMAT_DLL 2 3 /* 4 Provides an interface to the MUMPS sparse solver 5 */ 6 #include "src/mat/impls/aij/seq/aij.h" 7 #include "src/mat/impls/aij/mpi/mpiaij.h" 8 #include "src/mat/impls/sbaij/seq/sbaij.h" 9 #include "src/mat/impls/sbaij/mpi/mpisbaij.h" 10 11 EXTERN_C_BEGIN 12 #if defined(PETSC_USE_COMPLEX) 13 #include "zmumps_c.h" 14 #else 15 #include "dmumps_c.h" 16 #endif 17 EXTERN_C_END 18 #define JOB_INIT -1 19 #define JOB_END -2 20 /* macros s.t. indices match MUMPS documentation */ 21 #define ICNTL(I) icntl[(I)-1] 22 #define CNTL(I) cntl[(I)-1] 23 #define INFOG(I) infog[(I)-1] 24 #define INFO(I) info[(I)-1] 25 #define RINFOG(I) rinfog[(I)-1] 26 #define RINFO(I) rinfo[(I)-1] 27 28 typedef struct { 29 #if defined(PETSC_USE_COMPLEX) 30 ZMUMPS_STRUC_C id; 31 #else 32 DMUMPS_STRUC_C id; 33 #endif 34 MatStructure matstruc; 35 PetscMPIInt myid,size; 36 PetscInt *irn,*jcn,sym,nSolve; 37 PetscScalar *val; 38 MPI_Comm comm_mumps; 39 VecScatter scat_rhs, scat_sol; 40 PetscTruth isAIJ,CleanUpMUMPS; 41 Vec b_seq,x_seq; 42 } Mat_MUMPS; 43 44 EXTERN PetscErrorCode MatDuplicate_MUMPS(Mat,MatDuplicateOption,Mat*); 45 46 /* convert Petsc mpiaij matrix to triples: row[nz], col[nz], val[nz] */ 47 /* 48 input: 49 A - matrix in mpiaij or mpisbaij (bs=1) format 50 shift - 0: C style output triple; 1: Fortran style output triple. 51 valOnly - FALSE: spaces are allocated and values are set for the triple 52 TRUE: only the values in v array are updated 53 output: 54 nnz - dim of r, c, and v (number of local nonzero entries of A) 55 r, c, v - row and col index, matrix values (matrix triples) 56 */ 57 PetscErrorCode MatConvertToTriples(Mat A,int shift,PetscTruth valOnly,int *nnz,int **r, int **c, PetscScalar **v) 58 { 59 PetscInt *ai, *aj, *bi, *bj, rstart,nz, *garray; 60 PetscErrorCode ierr; 61 PetscInt i,j,jj,jB,irow,m=A->rmap.n,*ajj,*bjj,countA,countB,colA_start,jcol; 62 PetscInt *row,*col; 63 PetscScalar *av, *bv,*val; 64 Mat_MUMPS *mumps=(Mat_MUMPS*)A->spptr; 65 66 PetscFunctionBegin; 67 if (mumps->isAIJ){ 68 Mat_MPIAIJ *mat = (Mat_MPIAIJ*)A->data; 69 Mat_SeqAIJ *aa=(Mat_SeqAIJ*)(mat->A)->data; 70 Mat_SeqAIJ *bb=(Mat_SeqAIJ*)(mat->B)->data; 71 nz = aa->nz + bb->nz; 72 ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap.rstart; 73 garray = mat->garray; 74 av=aa->a; bv=bb->a; 75 76 } else { 77 Mat_MPISBAIJ *mat = (Mat_MPISBAIJ*)A->data; 78 Mat_SeqSBAIJ *aa=(Mat_SeqSBAIJ*)(mat->A)->data; 79 Mat_SeqBAIJ *bb=(Mat_SeqBAIJ*)(mat->B)->data; 80 if (A->rmap.bs > 1) SETERRQ1(PETSC_ERR_SUP," bs=%d is not supported yet\n", A->rmap.bs); 81 nz = aa->nz + bb->nz; 82 ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap.rstart; 83 garray = mat->garray; 84 av=aa->a; bv=bb->a; 85 } 86 87 if (!valOnly){ 88 ierr = PetscMalloc(nz*sizeof(PetscInt) ,&row);CHKERRQ(ierr); 89 ierr = PetscMalloc(nz*sizeof(PetscInt),&col);CHKERRQ(ierr); 90 ierr = PetscMalloc(nz*sizeof(PetscScalar),&val);CHKERRQ(ierr); 91 *r = row; *c = col; *v = val; 92 } else { 93 row = *r; col = *c; val = *v; 94 } 95 *nnz = nz; 96 97 jj = 0; irow = rstart; 98 for ( i=0; i<m; i++ ) { 99 ajj = aj + ai[i]; /* ptr to the beginning of this row */ 100 countA = ai[i+1] - ai[i]; 101 countB = bi[i+1] - bi[i]; 102 bjj = bj + bi[i]; 103 104 /* get jB, the starting local col index for the 2nd B-part */ 105 colA_start = rstart + ajj[0]; /* the smallest col index for A */ 106 j=-1; 107 do { 108 j++; 109 if (j == countB) break; 110 jcol = garray[bjj[j]]; 111 } while (jcol < colA_start); 112 jB = j; 113 114 /* B-part, smaller col index */ 115 colA_start = rstart + ajj[0]; /* the smallest col index for A */ 116 for (j=0; j<jB; j++){ 117 jcol = garray[bjj[j]]; 118 if (!valOnly){ 119 row[jj] = irow + shift; col[jj] = jcol + shift; 120 121 } 122 val[jj++] = *bv++; 123 } 124 /* A-part */ 125 for (j=0; j<countA; j++){ 126 if (!valOnly){ 127 row[jj] = irow + shift; col[jj] = rstart + ajj[j] + shift; 128 } 129 val[jj++] = *av++; 130 } 131 /* B-part, larger col index */ 132 for (j=jB; j<countB; j++){ 133 if (!valOnly){ 134 row[jj] = irow + shift; col[jj] = garray[bjj[j]] + shift; 135 } 136 val[jj++] = *bv++; 137 } 138 irow++; 139 } 140 141 PetscFunctionReturn(0); 142 } 143 144 #undef __FUNCT__ 145 #define __FUNCT__ "MatDestroy_MUMPS" 146 PetscErrorCode MatDestroy_MUMPS(Mat A) 147 { 148 Mat_MUMPS *lu=(Mat_MUMPS*)A->spptr; 149 PetscErrorCode ierr; 150 PetscMPIInt size=lu->size; 151 PetscErrorCode (*specialdestroy)(Mat); 152 153 PetscFunctionBegin; 154 if (lu->CleanUpMUMPS) { 155 /* Terminate instance, deallocate memories */ 156 if (size > 1){ 157 ierr = PetscFree(lu->id.sol_loc);CHKERRQ(ierr); 158 ierr = VecScatterDestroy(lu->scat_rhs);CHKERRQ(ierr); 159 ierr = VecDestroy(lu->b_seq);CHKERRQ(ierr); 160 if (lu->nSolve && lu->scat_sol){ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr);} 161 if (lu->nSolve && lu->x_seq){ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr);} 162 ierr = PetscFree(lu->val);CHKERRQ(ierr); 163 } 164 lu->id.job=JOB_END; 165 #if defined(PETSC_USE_COMPLEX) 166 zmumps_c(&lu->id); 167 #else 168 dmumps_c(&lu->id); 169 #endif 170 ierr = PetscFree(lu->irn);CHKERRQ(ierr); 171 ierr = PetscFree(lu->jcn);CHKERRQ(ierr); 172 ierr = MPI_Comm_free(&(lu->comm_mumps));CHKERRQ(ierr); 173 } 174 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 175 PetscFunctionReturn(0); 176 } 177 178 #undef __FUNCT__ 179 #define __FUNCT__ "MatSolve_MUMPS" 180 PetscErrorCode MatSolve_MUMPS(Mat A,Vec b,Vec x) 181 { 182 Mat_MUMPS *lu=(Mat_MUMPS*)A->spptr; 183 PetscScalar *array; 184 Vec x_seq; 185 IS is_iden,is_petsc; 186 PetscErrorCode ierr; 187 PetscInt i; 188 189 PetscFunctionBegin; 190 lu->id.nrhs = 1; 191 x_seq = lu->b_seq; 192 if (lu->size > 1){ 193 /* MUMPS only supports centralized rhs. Scatter b into a seqential rhs vector */ 194 ierr = VecScatterBegin(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195 ierr = VecScatterEnd(lu->scat_rhs,b,x_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 196 if (!lu->myid) {ierr = VecGetArray(x_seq,&array);CHKERRQ(ierr);} 197 } else { /* size == 1 */ 198 ierr = VecCopy(b,x);CHKERRQ(ierr); 199 ierr = VecGetArray(x,&array);CHKERRQ(ierr); 200 } 201 if (!lu->myid) { /* define rhs on the host */ 202 #if defined(PETSC_USE_COMPLEX) 203 lu->id.rhs = (mumps_double_complex*)array; 204 #else 205 lu->id.rhs = array; 206 #endif 207 } 208 if (lu->size == 1){ 209 ierr = VecRestoreArray(x,&array);CHKERRQ(ierr); 210 } else if (!lu->myid){ 211 ierr = VecRestoreArray(x_seq,&array);CHKERRQ(ierr); 212 } 213 214 if (lu->size > 1){ 215 /* distributed solution */ 216 lu->id.ICNTL(21) = 1; 217 if (!lu->nSolve){ 218 /* Create x_seq=sol_loc for repeated use */ 219 PetscInt lsol_loc; 220 PetscScalar *sol_loc; 221 lsol_loc = lu->id.INFO(23); /* length of sol_loc */ 222 ierr = PetscMalloc((1+lsol_loc)*(sizeof(PetscScalar)+sizeof(PetscInt)),&sol_loc);CHKERRQ(ierr); 223 lu->id.isol_loc = (PetscInt *)(sol_loc + lsol_loc); 224 lu->id.lsol_loc = lsol_loc; 225 #if defined(PETSC_USE_COMPLEX) 226 lu->id.sol_loc = (ZMUMPS_DOUBLE *)sol_loc; 227 #else 228 lu->id.sol_loc = (DMUMPS_DOUBLE *)sol_loc; 229 #endif 230 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,lsol_loc,sol_loc,&lu->x_seq);CHKERRQ(ierr); 231 } 232 } 233 234 /* solve phase */ 235 /*-------------*/ 236 lu->id.job = 3; 237 #if defined(PETSC_USE_COMPLEX) 238 zmumps_c(&lu->id); 239 #else 240 dmumps_c(&lu->id); 241 #endif 242 if (lu->id.INFOG(1) < 0) { 243 SETERRQ1(PETSC_ERR_LIB,"Error reported by MUMPS in solve phase: INFOG(1)=%d\n",lu->id.INFOG(1)); 244 } 245 246 if (lu->size > 1) { /* convert mumps distributed solution to petsc mpi x */ 247 if (!lu->nSolve){ /* create scatter scat_sol */ 248 ierr = ISCreateStride(PETSC_COMM_SELF,lu->id.lsol_loc,0,1,&is_iden);CHKERRQ(ierr); /* from */ 249 for (i=0; i<lu->id.lsol_loc; i++){ 250 lu->id.isol_loc[i] -= 1; /* change Fortran style to C style */ 251 } 252 ierr = ISCreateGeneral(PETSC_COMM_SELF,lu->id.lsol_loc,lu->id.isol_loc,&is_petsc);CHKERRQ(ierr); /* to */ 253 ierr = VecScatterCreate(lu->x_seq,is_iden,x,is_petsc,&lu->scat_sol);CHKERRQ(ierr); 254 ierr = ISDestroy(is_iden);CHKERRQ(ierr); 255 ierr = ISDestroy(is_petsc);CHKERRQ(ierr); 256 } 257 ierr = VecScatterBegin(lu->scat_sol,lu->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 258 ierr = VecScatterEnd(lu->scat_sol,lu->x_seq,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 259 } 260 lu->nSolve++; 261 PetscFunctionReturn(0); 262 } 263 264 /* 265 input: 266 F: numeric factor 267 output: 268 nneg: total number of negative pivots 269 nzero: 0 270 npos: (global dimension of F) - nneg 271 */ 272 273 #undef __FUNCT__ 274 #define __FUNCT__ "MatGetInertia_SBAIJMUMPS" 275 PetscErrorCode MatGetInertia_SBAIJMUMPS(Mat F,int *nneg,int *nzero,int *npos) 276 { 277 Mat_MUMPS *lu =(Mat_MUMPS*)F->spptr; 278 PetscErrorCode ierr; 279 PetscMPIInt size; 280 281 PetscFunctionBegin; 282 ierr = MPI_Comm_size(((PetscObject)F)->comm,&size);CHKERRQ(ierr); 283 /* MUMPS 4.3.1 calls ScaLAPACK when ICNTL(13)=0 (default), which does not offer the possibility to compute the inertia of a dense matrix. Set ICNTL(13)=1 to skip ScaLAPACK */ 284 if (size > 1 && lu->id.ICNTL(13) != 1){ 285 SETERRQ1(PETSC_ERR_ARG_WRONG,"ICNTL(13)=%d. -mat_mumps_icntl_13 must be set as 1 for correct global matrix inertia\n",lu->id.INFOG(13)); 286 } 287 if (nneg){ 288 if (!lu->myid){ 289 *nneg = lu->id.INFOG(12); 290 } 291 ierr = MPI_Bcast(nneg,1,MPI_INT,0,lu->comm_mumps);CHKERRQ(ierr); 292 } 293 if (nzero) *nzero = 0; 294 if (npos) *npos = F->rmap.N - (*nneg); 295 PetscFunctionReturn(0); 296 } 297 298 #undef __FUNCT__ 299 #define __FUNCT__ "MatFactorNumeric_MUMPS" 300 PetscErrorCode MatFactorNumeric_MUMPS(Mat A,MatFactorInfo *info,Mat *F) 301 { 302 Mat_MUMPS *lu =(Mat_MUMPS*)(*F)->spptr; 303 Mat_MUMPS *lua=(Mat_MUMPS*)(A)->spptr; 304 PetscErrorCode ierr; 305 PetscInt rnz,nnz,nz=0,i,M=A->rmap.N,*ai,*aj,icntl; 306 PetscTruth valOnly,flg; 307 Mat F_diag; 308 IS is_iden; 309 Vec b; 310 311 PetscFunctionBegin; 312 if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){ 313 (*F)->ops->solve = MatSolve_MUMPS; 314 315 /* Initialize a MUMPS instance */ 316 ierr = MPI_Comm_rank(((PetscObject)A)->comm, &lu->myid); 317 ierr = MPI_Comm_size(((PetscObject)A)->comm,&lu->size);CHKERRQ(ierr); 318 lua->myid = lu->myid; lua->size = lu->size; 319 lu->id.job = JOB_INIT; 320 ierr = MPI_Comm_dup(((PetscObject)A)->comm,&(lu->comm_mumps));CHKERRQ(ierr); 321 lu->id.comm_fortran = MPI_Comm_c2f(lu->comm_mumps); 322 323 /* Set mumps options */ 324 ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"MUMPS Options","Mat");CHKERRQ(ierr); 325 lu->id.par=1; /* host participates factorizaton and solve */ 326 lu->id.sym=lu->sym; 327 if (lu->sym == 2){ 328 ierr = PetscOptionsInt("-mat_mumps_sym","SYM: (1,2)","None",lu->id.sym,&icntl,&flg);CHKERRQ(ierr); 329 if (flg && icntl == 1) lu->id.sym=icntl; /* matrix is spd */ 330 } 331 #if defined(PETSC_USE_COMPLEX) 332 zmumps_c(&lu->id); 333 #else 334 dmumps_c(&lu->id); 335 #endif 336 337 if (lu->size == 1){ 338 lu->id.ICNTL(18) = 0; /* centralized assembled matrix input */ 339 } else { 340 lu->id.ICNTL(18) = 3; /* distributed assembled matrix input */ 341 } 342 343 icntl=-1; 344 lu->id.ICNTL(4) = 0; /* level of printing; overwrite mumps default ICNTL(4)=2 */ 345 ierr = PetscOptionsInt("-mat_mumps_icntl_4","ICNTL(4): level of printing (0 to 4)","None",lu->id.ICNTL(4),&icntl,&flg);CHKERRQ(ierr); 346 if ((flg && icntl > 0) || PetscLogPrintInfo) { 347 lu->id.ICNTL(4)=icntl; /* and use mumps default icntl(i), i=1,2,3 */ 348 } else { /* no output */ 349 lu->id.ICNTL(1) = 0; /* error message, default= 6 */ 350 lu->id.ICNTL(2) = -1; /* output stream for diagnostic printing, statistics, and warning. default=0 */ 351 lu->id.ICNTL(3) = -1; /* output stream for global information, default=6 */ 352 } 353 ierr = PetscOptionsInt("-mat_mumps_icntl_6","ICNTL(6): matrix prescaling (0 to 7)","None",lu->id.ICNTL(6),&lu->id.ICNTL(6),PETSC_NULL);CHKERRQ(ierr); 354 icntl=-1; 355 ierr = PetscOptionsInt("-mat_mumps_icntl_7","ICNTL(7): matrix ordering (0 to 7)","None",lu->id.ICNTL(7),&icntl,&flg);CHKERRQ(ierr); 356 if (flg) { 357 if (icntl== 1){ 358 SETERRQ(PETSC_ERR_SUP,"pivot order be set by the user in PERM_IN -- not supported by the PETSc/MUMPS interface\n"); 359 } else { 360 lu->id.ICNTL(7) = icntl; 361 } 362 } 363 ierr = PetscOptionsInt("-mat_mumps_icntl_9","ICNTL(9): A or A^T x=b to be solved. 1: A; otherwise: A^T","None",lu->id.ICNTL(9),&lu->id.ICNTL(9),PETSC_NULL);CHKERRQ(ierr); 364 ierr = PetscOptionsInt("-mat_mumps_icntl_10","ICNTL(10): max num of refinements","None",lu->id.ICNTL(10),&lu->id.ICNTL(10),PETSC_NULL);CHKERRQ(ierr); 365 ierr = PetscOptionsInt("-mat_mumps_icntl_11","ICNTL(11): error analysis, a positive value returns statistics (by -ksp_view)","None",lu->id.ICNTL(11),&lu->id.ICNTL(11),PETSC_NULL);CHKERRQ(ierr); 366 ierr = PetscOptionsInt("-mat_mumps_icntl_12","ICNTL(12): efficiency control","None",lu->id.ICNTL(12),&lu->id.ICNTL(12),PETSC_NULL);CHKERRQ(ierr); 367 ierr = PetscOptionsInt("-mat_mumps_icntl_13","ICNTL(13): efficiency control","None",lu->id.ICNTL(13),&lu->id.ICNTL(13),PETSC_NULL);CHKERRQ(ierr); 368 ierr = PetscOptionsInt("-mat_mumps_icntl_14","ICNTL(14): percentage of estimated workspace increase","None",lu->id.ICNTL(14),&lu->id.ICNTL(14),PETSC_NULL);CHKERRQ(ierr); 369 ierr = PetscOptionsInt("-mat_mumps_icntl_15","ICNTL(15): efficiency control","None",lu->id.ICNTL(15),&lu->id.ICNTL(15),PETSC_NULL);CHKERRQ(ierr); 370 371 ierr = PetscOptionsReal("-mat_mumps_cntl_1","CNTL(1): relative pivoting threshold","None",lu->id.CNTL(1),&lu->id.CNTL(1),PETSC_NULL);CHKERRQ(ierr); 372 ierr = PetscOptionsReal("-mat_mumps_cntl_2","CNTL(2): stopping criterion of refinement","None",lu->id.CNTL(2),&lu->id.CNTL(2),PETSC_NULL);CHKERRQ(ierr); 373 ierr = PetscOptionsReal("-mat_mumps_cntl_3","CNTL(3): absolute pivoting threshold","None",lu->id.CNTL(3),&lu->id.CNTL(3),PETSC_NULL);CHKERRQ(ierr); 374 ierr = PetscOptionsReal("-mat_mumps_cntl_4","CNTL(4): value for static pivoting","None",lu->id.CNTL(4),&lu->id.CNTL(4),PETSC_NULL);CHKERRQ(ierr); 375 PetscOptionsEnd(); 376 } 377 378 /* define matrix A */ 379 switch (lu->id.ICNTL(18)){ 380 case 0: /* centralized assembled matrix input (size=1) */ 381 if (!lu->myid) { 382 if (lua->isAIJ){ 383 Mat_SeqAIJ *aa = (Mat_SeqAIJ*)A->data; 384 nz = aa->nz; 385 ai = aa->i; aj = aa->j; lu->val = aa->a; 386 } else { 387 Mat_SeqSBAIJ *aa = (Mat_SeqSBAIJ*)A->data; 388 nz = aa->nz; 389 ai = aa->i; aj = aa->j; lu->val = aa->a; 390 } 391 if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){ /* first numeric factorization, get irn and jcn */ 392 ierr = PetscMalloc(nz*sizeof(PetscInt),&lu->irn);CHKERRQ(ierr); 393 ierr = PetscMalloc(nz*sizeof(PetscInt),&lu->jcn);CHKERRQ(ierr); 394 nz = 0; 395 for (i=0; i<M; i++){ 396 rnz = ai[i+1] - ai[i]; 397 while (rnz--) { /* Fortran row/col index! */ 398 lu->irn[nz] = i+1; lu->jcn[nz] = (*aj)+1; aj++; nz++; 399 } 400 } 401 } 402 } 403 break; 404 case 3: /* distributed assembled matrix input (size>1) */ 405 if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){ 406 valOnly = PETSC_FALSE; 407 } else { 408 valOnly = PETSC_TRUE; /* only update mat values, not row and col index */ 409 } 410 ierr = MatConvertToTriples(A,1,valOnly, &nnz, &lu->irn, &lu->jcn, &lu->val);CHKERRQ(ierr); 411 break; 412 default: SETERRQ(PETSC_ERR_SUP,"Matrix input format is not supported by MUMPS."); 413 } 414 415 /* analysis phase */ 416 /*----------------*/ 417 if (lu->matstruc == DIFFERENT_NONZERO_PATTERN){ 418 lu->id.job = 1; 419 420 lu->id.n = M; 421 switch (lu->id.ICNTL(18)){ 422 case 0: /* centralized assembled matrix input */ 423 if (!lu->myid) { 424 lu->id.nz =nz; lu->id.irn=lu->irn; lu->id.jcn=lu->jcn; 425 if (lu->id.ICNTL(6)>1){ 426 #if defined(PETSC_USE_COMPLEX) 427 lu->id.a = (mumps_double_complex*)lu->val; 428 #else 429 lu->id.a = lu->val; 430 #endif 431 } 432 } 433 break; 434 case 3: /* distributed assembled matrix input (size>1) */ 435 lu->id.nz_loc = nnz; 436 lu->id.irn_loc=lu->irn; lu->id.jcn_loc=lu->jcn; 437 if (lu->id.ICNTL(6)>1) { 438 #if defined(PETSC_USE_COMPLEX) 439 lu->id.a_loc = (mumps_double_complex*)lu->val; 440 #else 441 lu->id.a_loc = lu->val; 442 #endif 443 } 444 /* MUMPS only supports centralized rhs. Create scatter scat_rhs for repeated use in MatSolve() */ 445 if (!lu->myid){ 446 ierr = VecCreateSeq(PETSC_COMM_SELF,A->cmap.N,&lu->b_seq);CHKERRQ(ierr); 447 ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap.N,0,1,&is_iden);CHKERRQ(ierr); 448 } else { 449 ierr = VecCreateSeq(PETSC_COMM_SELF,0,&lu->b_seq);CHKERRQ(ierr); 450 ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is_iden);CHKERRQ(ierr); 451 } 452 ierr = VecCreate(((PetscObject)A)->comm,&b);CHKERRQ(ierr); 453 ierr = VecSetSizes(b,A->rmap.n,PETSC_DECIDE);CHKERRQ(ierr); 454 ierr = VecSetFromOptions(b);CHKERRQ(ierr); 455 456 ierr = VecScatterCreate(b,is_iden,lu->b_seq,is_iden,&lu->scat_rhs);CHKERRQ(ierr); 457 ierr = ISDestroy(is_iden);CHKERRQ(ierr); 458 ierr = VecDestroy(b);CHKERRQ(ierr); 459 break; 460 } 461 #if defined(PETSC_USE_COMPLEX) 462 zmumps_c(&lu->id); 463 #else 464 dmumps_c(&lu->id); 465 #endif 466 if (lu->id.INFOG(1) < 0) { 467 SETERRQ1(PETSC_ERR_LIB,"Error reported by MUMPS in analysis phase: INFOG(1)=%d\n",lu->id.INFOG(1)); 468 } 469 } 470 471 /* numerical factorization phase */ 472 /*-------------------------------*/ 473 lu->id.job = 2; 474 if(!lu->id.ICNTL(18)) { 475 if (!lu->myid) { 476 #if defined(PETSC_USE_COMPLEX) 477 lu->id.a = (mumps_double_complex*)lu->val; 478 #else 479 lu->id.a = lu->val; 480 #endif 481 } 482 } else { 483 #if defined(PETSC_USE_COMPLEX) 484 lu->id.a_loc = (mumps_double_complex*)lu->val; 485 #else 486 lu->id.a_loc = lu->val; 487 #endif 488 } 489 #if defined(PETSC_USE_COMPLEX) 490 zmumps_c(&lu->id); 491 #else 492 dmumps_c(&lu->id); 493 #endif 494 if (lu->id.INFOG(1) < 0) { 495 if (lu->id.INFO(1) == -13) { 496 SETERRQ1(PETSC_ERR_LIB,"Error reported by MUMPS in numerical factorization phase: Cannot allocate required memory %d megabytes\n",lu->id.INFO(2)); 497 } else { 498 SETERRQ2(PETSC_ERR_LIB,"Error reported by MUMPS in numerical factorization phase: INFO(1)=%d, INFO(2)=%d\n",lu->id.INFO(1),lu->id.INFO(2)); 499 } 500 } 501 502 if (!lu->myid && lu->id.ICNTL(16) > 0){ 503 SETERRQ1(PETSC_ERR_LIB," lu->id.ICNTL(16):=%d\n",lu->id.INFOG(16)); 504 } 505 506 if (lu->size > 1){ 507 if ((*F)->factor == FACTOR_LU){ 508 F_diag = ((Mat_MPIAIJ *)(*F)->data)->A; 509 } else { 510 F_diag = ((Mat_MPISBAIJ *)(*F)->data)->A; 511 } 512 F_diag->assembled = PETSC_TRUE; 513 if (lu->nSolve){ 514 ierr = VecScatterDestroy(lu->scat_sol);CHKERRQ(ierr); 515 ierr = PetscFree(lu->id.sol_loc);CHKERRQ(ierr); 516 ierr = VecDestroy(lu->x_seq);CHKERRQ(ierr); 517 } 518 } 519 (*F)->assembled = PETSC_TRUE; 520 lu->matstruc = SAME_NONZERO_PATTERN; 521 lu->CleanUpMUMPS = PETSC_TRUE; 522 lu->nSolve = 0; 523 PetscFunctionReturn(0); 524 } 525 526 527 /* Note the Petsc r and c permutations are ignored */ 528 #undef __FUNCT__ 529 #define __FUNCT__ "MatLUFactorSymbolic_AIJMUMPS" 530 PetscErrorCode MatLUFactorSymbolic_AIJMUMPS(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) 531 { 532 Mat_MUMPS *lu; 533 PetscErrorCode ierr; 534 535 PetscFunctionBegin; 536 537 /* Create the factorization matrix */ 538 lu = (Mat_MUMPS*)(*F)->spptr; 539 lu->sym = 0; 540 lu->matstruc = DIFFERENT_NONZERO_PATTERN; 541 PetscFunctionReturn(0); 542 } 543 544 #undef __FUNCT__ 545 #define __FUNCT__ "MatGetFactor_mpiaij_mumps" 546 PetscErrorCode MatGetFactor_mpiaij_mumps(Mat A,Mat *F) 547 { 548 Mat B; 549 PetscErrorCode ierr; 550 Mat_MUMPS *mumps; 551 552 PetscFunctionBegin; 553 /* Create the factorization matrix */ 554 ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 555 ierr = MatSetSizes(B,A->rmap.n,A->cmap.n,A->rmap.N,A->cmap.N);CHKERRQ(ierr); 556 ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 557 ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 558 ierr = MatMPIAIJSetPreallocation(B,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 559 560 B->ops->lufactornumeric = MatFactorNumeric_MUMPS; 561 B->ops->lufactorsymbolic = MatLUFactorSymbolic_AIJMUMPS; 562 B->factor = FACTOR_LU; 563 564 ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr); 565 mumps->CleanUpMUMPS = PETSC_FALSE; 566 mumps->isAIJ = PETSC_TRUE; 567 mumps->scat_rhs = PETSC_NULL; 568 mumps->scat_sol = PETSC_NULL; 569 mumps->nSolve = 0; 570 571 B->spptr = (void*)mumps; 572 573 *F = B; 574 PetscFunctionReturn(0); 575 } 576 577 578 /* Note the Petsc r permutation is ignored */ 579 #undef __FUNCT__ 580 #define __FUNCT__ "MatCholeskyFactorSymbolic_SBAIJMUMPS" 581 PetscErrorCode MatCholeskyFactorSymbolic_SBAIJMUMPS(Mat A,IS r,MatFactorInfo *info,Mat *F) 582 { 583 Mat_MUMPS *lu; 584 PetscErrorCode ierr; 585 586 PetscFunctionBegin; 587 lu = (Mat_MUMPS*)(*F)->spptr; 588 lu->sym = 2; 589 lu->matstruc = DIFFERENT_NONZERO_PATTERN; 590 PetscFunctionReturn(0); 591 } 592 593 #undef __FUNCT__ 594 #define __FUNCT__ "MatGetFactor_mpisbaij_mumps" 595 PetscErrorCode MatGetFactor_mpisbaij_mumps(Mat A,Mat *F) 596 { 597 Mat B; 598 PetscErrorCode ierr; 599 Mat_MUMPS *mumps; 600 601 PetscFunctionBegin; 602 /* Create the factorization matrix */ 603 ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 604 ierr = MatSetSizes(B,A->rmap.n,A->cmap.n,A->rmap.N,A->cmap.N);CHKERRQ(ierr); 605 ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 606 ierr = MatSeqSBAIJSetPreallocation(B,1,0,PETSC_NULL);CHKERRQ(ierr); 607 ierr = MatMPISBAIJSetPreallocation(B,1,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); 608 609 B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SBAIJMUMPS; 610 B->ops->choleskyfactornumeric = MatFactorNumeric_MUMPS; 611 B->ops->getinertia = MatGetInertia_SBAIJMUMPS; 612 B->factor = FACTOR_CHOLESKY; 613 614 ierr = PetscNewLog(B,Mat_MUMPS,&mumps);CHKERRQ(ierr); 615 mumps->CleanUpMUMPS = PETSC_FALSE; 616 mumps->isAIJ = PETSC_TRUE; 617 mumps->scat_rhs = PETSC_NULL; 618 mumps->scat_sol = PETSC_NULL; 619 mumps->nSolve = 0; 620 B->spptr = (void*)mumps; 621 *F = B; 622 PetscFunctionReturn(0); 623 } 624 625 #undef __FUNCT__ 626 #define __FUNCT__ "MatFactorInfo_MUMPS" 627 PetscErrorCode MatFactorInfo_MUMPS(Mat A,PetscViewer viewer) { 628 Mat_MUMPS *lu=(Mat_MUMPS*)A->spptr; 629 PetscErrorCode ierr; 630 631 PetscFunctionBegin; 632 /* check if matrix is mumps type */ 633 if (A->ops->solve != MatSolve_MUMPS) PetscFunctionReturn(0); 634 635 ierr = PetscViewerASCIIPrintf(viewer,"MUMPS run parameters:\n");CHKERRQ(ierr); 636 ierr = PetscViewerASCIIPrintf(viewer," SYM (matrix type): %d \n",lu->id.sym);CHKERRQ(ierr); 637 ierr = PetscViewerASCIIPrintf(viewer," PAR (host participation): %d \n",lu->id.par);CHKERRQ(ierr); 638 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(1) (output for error): %d \n",lu->id.ICNTL(1));CHKERRQ(ierr); 639 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(2) (output of diagnostic msg):%d \n",lu->id.ICNTL(2));CHKERRQ(ierr); 640 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(3) (output for global info): %d \n",lu->id.ICNTL(3));CHKERRQ(ierr); 641 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(4) (level of printing): %d \n",lu->id.ICNTL(4));CHKERRQ(ierr); 642 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(5) (input mat struct): %d \n",lu->id.ICNTL(5));CHKERRQ(ierr); 643 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(6) (matrix prescaling): %d \n",lu->id.ICNTL(6));CHKERRQ(ierr); 644 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(7) (matrix ordering): %d \n",lu->id.ICNTL(7));CHKERRQ(ierr); 645 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(8) (scalling strategy): %d \n",lu->id.ICNTL(8));CHKERRQ(ierr); 646 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(9) (A/A^T x=b is solved): %d \n",lu->id.ICNTL(9));CHKERRQ(ierr); 647 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(10) (max num of refinements): %d \n",lu->id.ICNTL(10));CHKERRQ(ierr); 648 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(11) (error analysis): %d \n",lu->id.ICNTL(11));CHKERRQ(ierr); 649 if (!lu->myid && lu->id.ICNTL(11)>0) { 650 ierr = PetscPrintf(PETSC_COMM_SELF," RINFOG(4) (inf norm of input mat): %g\n",lu->id.RINFOG(4));CHKERRQ(ierr); 651 ierr = PetscPrintf(PETSC_COMM_SELF," RINFOG(5) (inf norm of solution): %g\n",lu->id.RINFOG(5));CHKERRQ(ierr); 652 ierr = PetscPrintf(PETSC_COMM_SELF," RINFOG(6) (inf norm of residual): %g\n",lu->id.RINFOG(6));CHKERRQ(ierr); 653 ierr = PetscPrintf(PETSC_COMM_SELF," RINFOG(7),RINFOG(8) (backward error est): %g, %g\n",lu->id.RINFOG(7),lu->id.RINFOG(8));CHKERRQ(ierr); 654 ierr = PetscPrintf(PETSC_COMM_SELF," RINFOG(9) (error estimate): %g \n",lu->id.RINFOG(9));CHKERRQ(ierr); 655 ierr = PetscPrintf(PETSC_COMM_SELF," RINFOG(10),RINFOG(11)(condition numbers): %g, %g\n",lu->id.RINFOG(10),lu->id.RINFOG(11));CHKERRQ(ierr); 656 657 } 658 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(12) (efficiency control): %d \n",lu->id.ICNTL(12));CHKERRQ(ierr); 659 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(13) (efficiency control): %d \n",lu->id.ICNTL(13));CHKERRQ(ierr); 660 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(14) (percentage of estimated workspace increase): %d \n",lu->id.ICNTL(14));CHKERRQ(ierr); 661 /* ICNTL(15-17) not used */ 662 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(18) (input mat struct): %d \n",lu->id.ICNTL(18));CHKERRQ(ierr); 663 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(19) (Shur complement info): %d \n",lu->id.ICNTL(19));CHKERRQ(ierr); 664 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(20) (rhs sparse pattern): %d \n",lu->id.ICNTL(20));CHKERRQ(ierr); 665 ierr = PetscViewerASCIIPrintf(viewer," ICNTL(21) (solution struct): %d \n",lu->id.ICNTL(21));CHKERRQ(ierr); 666 667 ierr = PetscViewerASCIIPrintf(viewer," CNTL(1) (relative pivoting threshold): %g \n",lu->id.CNTL(1));CHKERRQ(ierr); 668 ierr = PetscViewerASCIIPrintf(viewer," CNTL(2) (stopping criterion of refinement): %g \n",lu->id.CNTL(2));CHKERRQ(ierr); 669 ierr = PetscViewerASCIIPrintf(viewer," CNTL(3) (absolute pivoting threshold): %g \n",lu->id.CNTL(3));CHKERRQ(ierr); 670 ierr = PetscViewerASCIIPrintf(viewer," CNTL(4) (value of static pivoting): %g \n",lu->id.CNTL(4));CHKERRQ(ierr); 671 672 /* infomation local to each processor */ 673 if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, " RINFO(1) (local estimated flops for the elimination after analysis): \n");CHKERRQ(ierr);} 674 ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm," [%d] %g \n",lu->myid,lu->id.RINFO(1));CHKERRQ(ierr); 675 ierr = PetscSynchronizedFlush(((PetscObject)A)->comm); 676 if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, " RINFO(2) (local estimated flops for the assembly after factorization): \n");CHKERRQ(ierr);} 677 ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm," [%d] %g \n",lu->myid,lu->id.RINFO(2));CHKERRQ(ierr); 678 ierr = PetscSynchronizedFlush(((PetscObject)A)->comm); 679 if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, " RINFO(3) (local estimated flops for the elimination after factorization): \n");CHKERRQ(ierr);} 680 ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm," [%d] %g \n",lu->myid,lu->id.RINFO(3));CHKERRQ(ierr); 681 ierr = PetscSynchronizedFlush(((PetscObject)A)->comm); 682 /* 683 if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, " INFO(2) (info about error or warning ): \n");CHKERRQ(ierr);} 684 ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm," [%d] %d \n",lu->myid,lu->id.INFO(2));CHKERRQ(ierr); 685 ierr = PetscSynchronizedFlush(((PetscObject)A)->comm); 686 */ 687 688 if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, " INFO(15) (estimated size of (in MB) MUMPS internal data for running numerical factorization): \n");CHKERRQ(ierr);} 689 ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm," [%d] %d \n",lu->myid,lu->id.INFO(15));CHKERRQ(ierr); 690 ierr = PetscSynchronizedFlush(((PetscObject)A)->comm); 691 692 if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, " INFO(16) (size of (in MB) MUMPS internal data used during numerical factorization): \n");CHKERRQ(ierr);} 693 ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm," [%d] %d \n",lu->myid,lu->id.INFO(16));CHKERRQ(ierr); 694 ierr = PetscSynchronizedFlush(((PetscObject)A)->comm); 695 696 if (!lu->myid) {ierr = PetscPrintf(PETSC_COMM_SELF, " INFO(23) (num of pivots eliminated on this processor after factorization): \n");CHKERRQ(ierr);} 697 ierr = PetscSynchronizedPrintf(((PetscObject)A)->comm," [%d] %d \n",lu->myid,lu->id.INFO(23));CHKERRQ(ierr); 698 ierr = PetscSynchronizedFlush(((PetscObject)A)->comm); 699 700 if (!lu->myid){ /* information from the host */ 701 ierr = PetscViewerASCIIPrintf(viewer," RINFOG(1) (global estimated flops for the elimination after analysis): %g \n",lu->id.RINFOG(1));CHKERRQ(ierr); 702 ierr = PetscViewerASCIIPrintf(viewer," RINFOG(2) (global estimated flops for the assembly after factorization): %g \n",lu->id.RINFOG(2));CHKERRQ(ierr); 703 ierr = PetscViewerASCIIPrintf(viewer," RINFOG(3) (global estimated flops for the elimination after factorization): %g \n",lu->id.RINFOG(3));CHKERRQ(ierr); 704 705 ierr = PetscViewerASCIIPrintf(viewer," INFOG(3) (estimated real workspace for factors on all processors after analysis): %d \n",lu->id.INFOG(3));CHKERRQ(ierr); 706 ierr = PetscViewerASCIIPrintf(viewer," INFOG(4) (estimated integer workspace for factors on all processors after analysis): %d \n",lu->id.INFOG(4));CHKERRQ(ierr); 707 ierr = PetscViewerASCIIPrintf(viewer," INFOG(5) (estimated maximum front size in the complete tree): %d \n",lu->id.INFOG(5));CHKERRQ(ierr); 708 ierr = PetscViewerASCIIPrintf(viewer," INFOG(6) (number of nodes in the complete tree): %d \n",lu->id.INFOG(6));CHKERRQ(ierr); 709 ierr = PetscViewerASCIIPrintf(viewer," INFOG(7) (ordering option effectively uese after analysis): %d \n",lu->id.INFOG(7));CHKERRQ(ierr); 710 ierr = PetscViewerASCIIPrintf(viewer," INFOG(8) (structural symmetry in percent of the permuted matrix after analysis): %d \n",lu->id.INFOG(8));CHKERRQ(ierr); 711 ierr = PetscViewerASCIIPrintf(viewer," INFOG(9) (total real/complex workspace to store the matrix factors after factorization): %d \n",lu->id.INFOG(9));CHKERRQ(ierr); 712 ierr = PetscViewerASCIIPrintf(viewer," INFOG(10) (total integer space store the matrix factors after factorization): %d \n",lu->id.INFOG(10));CHKERRQ(ierr); 713 ierr = PetscViewerASCIIPrintf(viewer," INFOG(11) (order of largest frontal matrix after factorization): %d \n",lu->id.INFOG(11));CHKERRQ(ierr); 714 ierr = PetscViewerASCIIPrintf(viewer," INFOG(12) (number of off-diagonal pivots): %d \n",lu->id.INFOG(12));CHKERRQ(ierr); 715 ierr = PetscViewerASCIIPrintf(viewer," INFOG(13) (number of delayed pivots after factorization): %d \n",lu->id.INFOG(13));CHKERRQ(ierr); 716 ierr = PetscViewerASCIIPrintf(viewer," INFOG(14) (number of memory compress after factorization): %d \n",lu->id.INFOG(14));CHKERRQ(ierr); 717 ierr = PetscViewerASCIIPrintf(viewer," INFOG(15) (number of steps of iterative refinement after solution): %d \n",lu->id.INFOG(15));CHKERRQ(ierr); 718 ierr = PetscViewerASCIIPrintf(viewer," INFOG(16) (estimated size (in MB) of all MUMPS internal data for factorization after analysis: value on the most memory consuming processor): %d \n",lu->id.INFOG(16));CHKERRQ(ierr); 719 ierr = PetscViewerASCIIPrintf(viewer," INFOG(17) (estimated size of all MUMPS internal data for factorization after analysis: sum over all processors): %d \n",lu->id.INFOG(17));CHKERRQ(ierr); 720 ierr = PetscViewerASCIIPrintf(viewer," INFOG(18) (size of all MUMPS internal data allocated during factorization: value on the most memory consuming processor): %d \n",lu->id.INFOG(18));CHKERRQ(ierr); 721 ierr = PetscViewerASCIIPrintf(viewer," INFOG(19) (size of all MUMPS internal data allocated during factorization: sum over all processors): %d \n",lu->id.INFOG(19));CHKERRQ(ierr); 722 ierr = PetscViewerASCIIPrintf(viewer," INFOG(20) (estimated number of entries in the factors): %d \n",lu->id.INFOG(20));CHKERRQ(ierr); 723 ierr = PetscViewerASCIIPrintf(viewer," INFOG(21) (size in MB of memory effectively used during factorization - value on the most memory consuming processor): %d \n",lu->id.INFOG(21));CHKERRQ(ierr); 724 ierr = PetscViewerASCIIPrintf(viewer," INFOG(22) (size in MB of memory effectively used during factorization - sum over all processors): %d \n",lu->id.INFOG(22));CHKERRQ(ierr); 725 ierr = PetscViewerASCIIPrintf(viewer," INFOG(23) (after analysis: value of ICNTL(6) effectively used): %d \n",lu->id.INFOG(23));CHKERRQ(ierr); 726 ierr = PetscViewerASCIIPrintf(viewer," INFOG(24) (after analysis: value of ICNTL(12) effectively used): %d \n",lu->id.INFOG(24));CHKERRQ(ierr); 727 ierr = PetscViewerASCIIPrintf(viewer," INFOG(25) (after factorization: number of pivots modified by static pivoting): %d \n",lu->id.INFOG(25));CHKERRQ(ierr); 728 } 729 730 PetscFunctionReturn(0); 731 } 732 733 #undef __FUNCT__ 734 #define __FUNCT__ "MatView_MUMPS" 735 PetscErrorCode MatView_MUMPS(Mat A,PetscViewer viewer) 736 { 737 PetscErrorCode ierr; 738 PetscTruth iascii; 739 PetscViewerFormat format; 740 Mat_MUMPS *mumps=(Mat_MUMPS*)(A->spptr); 741 742 PetscFunctionBegin; 743 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 744 if (iascii) { 745 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 746 if (format == PETSC_VIEWER_ASCII_INFO){ 747 ierr = MatFactorInfo_MUMPS(A,viewer);CHKERRQ(ierr); 748 } 749 } 750 PetscFunctionReturn(0); 751 } 752 753 754 /*MC 755 MATAIJMUMPS - MATAIJMUMPS = "aijmumps" - A matrix type providing direct solvers (LU) for distributed 756 and sequential matrices via the external package MUMPS. 757 758 If MUMPS is installed (see the manual for instructions 759 on how to declare the existence of external packages), 760 a matrix type can be constructed which invokes MUMPS solvers. 761 After calling MatCreate(...,A), simply call MatSetType(A,MATAIJMUMPS), then 762 optionally call MatSeqAIJSetPreallocation() or MatMPIAIJSetPreallocation() etc DO NOT 763 call MatCreateSeqAIJ/MPIAIJ() directly or the preallocation information will be LOST! 764 765 If created with a single process communicator, this matrix type inherits from MATSEQAIJ. 766 Otherwise, this matrix type inherits from MATMPIAIJ. Hence for single process communicators, 767 MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 768 for communicators controlling multiple processes. It is recommended that you call both of 769 the above preallocation routines for simplicity. One can also call MatConvert() for an inplace 770 conversion to or from the MATSEQAIJ or MATMPIAIJ type (depending on the communicator size) 771 without data copy AFTER the matrix values are set. 772 773 Options Database Keys: 774 + -mat_type aijmumps - sets the matrix type to "aijmumps" during a call to MatSetFromOptions() 775 . -mat_mumps_sym <0,1,2> - 0 the matrix is unsymmetric, 1 symmetric positive definite, 2 symmetric 776 . -mat_mumps_icntl_4 <0,1,2,3,4> - print level 777 . -mat_mumps_icntl_6 <0,...,7> - matrix prescaling options (see MUMPS User's Guide) 778 . -mat_mumps_icntl_7 <0,...,7> - matrix orderings (see MUMPS User's Guide) 779 . -mat_mumps_icntl_9 <1,2> - A or A^T x=b to be solved: 1 denotes A, 2 denotes A^T 780 . -mat_mumps_icntl_10 <n> - maximum number of iterative refinements 781 . -mat_mumps_icntl_11 <n> - error analysis, a positive value returns statistics during -ksp_view 782 . -mat_mumps_icntl_12 <n> - efficiency control (see MUMPS User's Guide) 783 . -mat_mumps_icntl_13 <n> - efficiency control (see MUMPS User's Guide) 784 . -mat_mumps_icntl_14 <n> - efficiency control (see MUMPS User's Guide) 785 . -mat_mumps_icntl_15 <n> - efficiency control (see MUMPS User's Guide) 786 . -mat_mumps_cntl_1 <delta> - relative pivoting threshold 787 . -mat_mumps_cntl_2 <tol> - stopping criterion for refinement 788 - -mat_mumps_cntl_3 <adelta> - absolute pivoting threshold 789 790 Level: beginner 791 792 .seealso: MATSBAIJMUMPS 793 M*/ 794 795 796 /*MC 797 MATSBAIJMUMPS - MATSBAIJMUMPS = "sbaijmumps" - A symmetric matrix type providing direct solvers (Cholesky) for 798 distributed and sequential matrices via the external package MUMPS. 799 800 If MUMPS is installed (see the manual for instructions 801 on how to declare the existence of external packages), 802 a matrix type can be constructed which invokes MUMPS solvers. 803 After calling MatCreate(...,A), simply call MatSetType(A,MATSBAIJMUMPS), then 804 optionally call MatSeqSBAIJSetPreallocation() or MatMPISBAIJSetPreallocation() DO NOT 805 call MatCreateSeqSBAIJ/MPISBAIJ() directly or the preallocation information will be LOST! 806 807 If created with a single process communicator, this matrix type inherits from MATSEQSBAIJ. 808 Otherwise, this matrix type inherits from MATMPISBAIJ. Hence for single process communicators, 809 MatSeqSBAIJSetPreallocation() is supported, and similarly MatMPISBAIJSetPreallocation() is supported 810 for communicators controlling multiple processes. It is recommended that you call both of 811 the above preallocation routines for simplicity. One can also call MatConvert() for an inplace 812 conversion to or from the MATSEQSBAIJ or MATMPISBAIJ type (depending on the communicator size) 813 without data copy AFTER the matrix values have been set. 814 815 Options Database Keys: 816 + -mat_type sbaijmumps - sets the matrix type to "sbaijmumps" during a call to MatSetFromOptions() 817 . -mat_mumps_sym <0,1,2> - 0 the matrix is unsymmetric, 1 symmetric positive definite, 2 symmetric 818 . -mat_mumps_icntl_4 <0,...,4> - print level 819 . -mat_mumps_icntl_6 <0,...,7> - matrix prescaling options (see MUMPS User's Guide) 820 . -mat_mumps_icntl_7 <0,...,7> - matrix orderings (see MUMPS User's Guide) 821 . -mat_mumps_icntl_9 <1,2> - A or A^T x=b to be solved: 1 denotes A, 2 denotes A^T 822 . -mat_mumps_icntl_10 <n> - maximum number of iterative refinements 823 . -mat_mumps_icntl_11 <n> - error analysis, a positive value returns statistics during -ksp_view 824 . -mat_mumps_icntl_12 <n> - efficiency control (see MUMPS User's Guide) 825 . -mat_mumps_icntl_13 <n> - efficiency control (see MUMPS User's Guide) 826 . -mat_mumps_icntl_14 <n> - efficiency control (see MUMPS User's Guide) 827 . -mat_mumps_icntl_15 <n> - efficiency control (see MUMPS User's Guide) 828 . -mat_mumps_cntl_1 <delta> - relative pivoting threshold 829 . -mat_mumps_cntl_2 <tol> - stopping criterion for refinement 830 - -mat_mumps_cntl_3 <adelta> - absolute pivoting threshold 831 832 Level: beginner 833 834 .seealso: MATAIJMUMPS 835 M*/ 836 837