1 #define PETSCMAT_DLL 2 3 /* -------------------------------------------------------------------- 4 5 This file implements a subclass of the SeqAIJ matrix class that uses 6 the SuperLU 3.0 sparse solver. You can use this as a starting point for 7 implementing your own subclass of a PETSc matrix class. 8 9 This demonstrates a way to make an implementation inheritence of a PETSc 10 matrix type. This means constructing a new matrix type (SuperLU) by changing some 11 of the methods of the previous type (SeqAIJ), adding additional data, and possibly 12 additional method. (See any book on object oriented programming). 13 */ 14 15 /* 16 Defines the data structure for the base matrix type (SeqAIJ) 17 */ 18 #include "src/mat/impls/aij/seq/aij.h" 19 20 /* 21 SuperLU include files 22 */ 23 EXTERN_C_BEGIN 24 #if defined(PETSC_USE_COMPLEX) 25 #include "slu_zdefs.h" 26 #else 27 #include "slu_ddefs.h" 28 #endif 29 #include "slu_util.h" 30 EXTERN_C_END 31 32 /* 33 This is the data we are "ADDING" to the SeqAIJ matrix type to get the SuperLU matrix type 34 */ 35 typedef struct { 36 SuperMatrix A,L,U,B,X; 37 superlu_options_t options; 38 PetscInt *perm_c; /* column permutation vector */ 39 PetscInt *perm_r; /* row permutations from partial pivoting */ 40 PetscInt *etree; 41 PetscReal *R, *C; 42 char equed[1]; 43 PetscInt lwork; 44 void *work; 45 PetscReal rpg, rcond; 46 mem_usage_t mem_usage; 47 MatStructure flg; 48 49 /* Flag to clean up (non-global) SuperLU objects during Destroy */ 50 PetscTruth CleanUpSuperLU; 51 } Mat_SuperLU; 52 53 extern PetscErrorCode MatFactorInfo_SuperLU(Mat,PetscViewer); 54 extern PetscErrorCode MatLUFactorNumeric_SuperLU(Mat,MatFactorInfo *,Mat *); 55 extern PetscErrorCode MatDestroy_SuperLU(Mat); 56 extern PetscErrorCode MatView_SuperLU(Mat,PetscViewer); 57 extern PetscErrorCode MatAssemblyEnd_SuperLU(Mat,MatAssemblyType); 58 extern PetscErrorCode MatSolve_SuperLU(Mat,Vec,Vec); 59 extern PetscErrorCode MatSolveTranspose_SuperLU(Mat,Vec,Vec); 60 extern PetscErrorCode MatLUFactorSymbolic_SuperLU(Mat,IS,IS,MatFactorInfo *,Mat *); 61 extern PetscErrorCode MatDuplicate_SuperLU(Mat, MatDuplicateOption, Mat *); 62 63 /* 64 Utility function 65 */ 66 #undef __FUNCT__ 67 #define __FUNCT__ "MatFactorInfo_SuperLU" 68 PetscErrorCode MatFactorInfo_SuperLU(Mat A,PetscViewer viewer) 69 { 70 Mat_SuperLU *lu= (Mat_SuperLU*)A->spptr; 71 PetscErrorCode ierr; 72 superlu_options_t options; 73 74 PetscFunctionBegin; 75 /* check if matrix is superlu_dist type */ 76 if (A->ops->solve != MatSolve_SuperLU) PetscFunctionReturn(0); 77 78 options = lu->options; 79 ierr = PetscViewerASCIIPrintf(viewer,"SuperLU run parameters:\n");CHKERRQ(ierr); 80 ierr = PetscViewerASCIIPrintf(viewer," Equil: %s\n",(options.Equil != NO) ? "YES": "NO");CHKERRQ(ierr); 81 ierr = PetscViewerASCIIPrintf(viewer," ColPerm: %D\n",options.ColPerm);CHKERRQ(ierr); 82 ierr = PetscViewerASCIIPrintf(viewer," IterRefine: %D\n",options.IterRefine);CHKERRQ(ierr); 83 ierr = PetscViewerASCIIPrintf(viewer," SymmetricMode: %s\n",(options.SymmetricMode != NO) ? "YES": "NO");CHKERRQ(ierr); 84 ierr = PetscViewerASCIIPrintf(viewer," DiagPivotThresh: %g\n",options.DiagPivotThresh);CHKERRQ(ierr); 85 ierr = PetscViewerASCIIPrintf(viewer," PivotGrowth: %s\n",(options.PivotGrowth != NO) ? "YES": "NO");CHKERRQ(ierr); 86 ierr = PetscViewerASCIIPrintf(viewer," ConditionNumber: %s\n",(options.ConditionNumber != NO) ? "YES": "NO");CHKERRQ(ierr); 87 ierr = PetscViewerASCIIPrintf(viewer," RowPerm: %D\n",options.RowPerm);CHKERRQ(ierr); 88 ierr = PetscViewerASCIIPrintf(viewer," ReplaceTinyPivot: %s\n",(options.ReplaceTinyPivot != NO) ? "YES": "NO");CHKERRQ(ierr); 89 ierr = PetscViewerASCIIPrintf(viewer," PrintStat: %s\n",(options.PrintStat != NO) ? "YES": "NO");CHKERRQ(ierr); 90 ierr = PetscViewerASCIIPrintf(viewer," lwork: %D\n",lu->lwork);CHKERRQ(ierr); 91 92 PetscFunctionReturn(0); 93 } 94 95 /* 96 These are the methods provided to REPLACE the corresponding methods of the 97 SeqAIJ matrix class. Other methods of SeqAIJ are not replaced 98 */ 99 #undef __FUNCT__ 100 #define __FUNCT__ "MatLUFactorNumeric_SuperLU" 101 PetscErrorCode MatLUFactorNumeric_SuperLU(Mat A,MatFactorInfo *info,Mat *F) 102 { 103 Mat_SeqAIJ *aa = (Mat_SeqAIJ*)(A)->data; 104 Mat_SuperLU *lu = (Mat_SuperLU*)(*F)->spptr; 105 PetscErrorCode ierr; 106 PetscInt sinfo; 107 SuperLUStat_t stat; 108 PetscReal ferr, berr; 109 NCformat *Ustore; 110 SCformat *Lstore; 111 112 PetscFunctionBegin; 113 if (lu->flg == SAME_NONZERO_PATTERN){ /* successing numerical factorization */ 114 lu->options.Fact = SamePattern; 115 /* Ref: ~SuperLU_3.0/EXAMPLE/dlinsolx2.c */ 116 Destroy_SuperMatrix_Store(&lu->A); 117 if ( lu->lwork >= 0 ) { 118 Destroy_SuperNode_Matrix(&lu->L); 119 Destroy_CompCol_Matrix(&lu->U); 120 lu->options.Fact = SamePattern; 121 } 122 } 123 124 /* Create the SuperMatrix for lu->A=A^T: 125 Since SuperLU likes column-oriented matrices,we pass it the transpose, 126 and then solve A^T X = B in MatSolve(). */ 127 #if defined(PETSC_USE_COMPLEX) 128 zCreate_CompCol_Matrix(&lu->A,A->cmap.n,A->rmap.n,aa->nz,(doublecomplex*)aa->a,aa->j,aa->i, 129 SLU_NC,SLU_Z,SLU_GE); 130 #else 131 dCreate_CompCol_Matrix(&lu->A,A->cmap.n,A->rmap.n,aa->nz,aa->a,aa->j,aa->i, 132 SLU_NC,SLU_D,SLU_GE); 133 #endif 134 135 /* Initialize the statistics variables. */ 136 StatInit(&stat); 137 138 /* Numerical factorization */ 139 lu->B.ncol = 0; /* Indicate not to solve the system */ 140 #if defined(PETSC_USE_COMPLEX) 141 zgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 142 &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 143 &lu->mem_usage, &stat, &sinfo); 144 #else 145 dgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 146 &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 147 &lu->mem_usage, &stat, &sinfo); 148 #endif 149 if ( !sinfo || sinfo == lu->A.ncol+1 ) { 150 if ( lu->options.PivotGrowth ) 151 ierr = PetscPrintf(PETSC_COMM_SELF," Recip. pivot growth = %e\n", lu->rpg); 152 if ( lu->options.ConditionNumber ) 153 ierr = PetscPrintf(PETSC_COMM_SELF," Recip. condition number = %e\n", lu->rcond); 154 } else if ( sinfo > 0 ){ 155 if ( lu->lwork == -1 ) { 156 ierr = PetscPrintf(PETSC_COMM_SELF," ** Estimated memory: %D bytes\n", sinfo - lu->A.ncol); 157 } else { 158 ierr = PetscPrintf(PETSC_COMM_SELF," Warning: gssvx() returns info %D\n",sinfo); 159 } 160 } else { /* sinfo < 0 */ 161 SETERRQ2(PETSC_ERR_LIB, "info = %D, the %D-th argument in gssvx() had an illegal value", sinfo,-sinfo); 162 } 163 164 if ( lu->options.PrintStat ) { 165 ierr = PetscPrintf(PETSC_COMM_SELF,"MatLUFactorNumeric_SuperLU():\n"); 166 StatPrint(&stat); 167 Lstore = (SCformat *) lu->L.Store; 168 Ustore = (NCformat *) lu->U.Store; 169 ierr = PetscPrintf(PETSC_COMM_SELF," No of nonzeros in factor L = %D\n", Lstore->nnz); 170 ierr = PetscPrintf(PETSC_COMM_SELF," No of nonzeros in factor U = %D\n", Ustore->nnz); 171 ierr = PetscPrintf(PETSC_COMM_SELF," No of nonzeros in L+U = %D\n", Lstore->nnz + Ustore->nnz - lu->A.ncol); 172 ierr = PetscPrintf(PETSC_COMM_SELF," L\\U MB %.3f\ttotal MB needed %.3f\texpansions %D\n", 173 lu->mem_usage.for_lu/1e6, lu->mem_usage.total_needed/1e6, 174 lu->mem_usage.expansions); 175 } 176 StatFree(&stat); 177 178 lu->flg = SAME_NONZERO_PATTERN; 179 PetscFunctionReturn(0); 180 } 181 182 #undef __FUNCT__ 183 #define __FUNCT__ "MatDestroy_SuperLU" 184 PetscErrorCode MatDestroy_SuperLU(Mat A) 185 { 186 PetscErrorCode ierr; 187 Mat_SuperLU *lu=(Mat_SuperLU*)A->spptr; 188 189 PetscFunctionBegin; 190 if (lu->CleanUpSuperLU) { /* Free the SuperLU datastructures */ 191 Destroy_SuperMatrix_Store(&lu->A); 192 Destroy_SuperMatrix_Store(&lu->B); 193 Destroy_SuperMatrix_Store(&lu->X); 194 195 ierr = PetscFree(lu->etree);CHKERRQ(ierr); 196 ierr = PetscFree(lu->perm_r);CHKERRQ(ierr); 197 ierr = PetscFree(lu->perm_c);CHKERRQ(ierr); 198 ierr = PetscFree(lu->R);CHKERRQ(ierr); 199 ierr = PetscFree(lu->C);CHKERRQ(ierr); 200 if ( lu->lwork >= 0 ) { 201 Destroy_SuperNode_Matrix(&lu->L); 202 Destroy_CompCol_Matrix(&lu->U); 203 } 204 } 205 ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr); 206 PetscFunctionReturn(0); 207 } 208 209 #undef __FUNCT__ 210 #define __FUNCT__ "MatView_SuperLU" 211 PetscErrorCode MatView_SuperLU(Mat A,PetscViewer viewer) 212 { 213 PetscErrorCode ierr; 214 PetscTruth iascii; 215 PetscViewerFormat format; 216 Mat_SuperLU *lu=(Mat_SuperLU*)(A->spptr); 217 218 PetscFunctionBegin; 219 ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr); 220 221 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 222 if (iascii) { 223 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 224 if (format == PETSC_VIEWER_ASCII_INFO) { 225 ierr = MatFactorInfo_SuperLU(A,viewer);CHKERRQ(ierr); 226 } 227 } 228 PetscFunctionReturn(0); 229 } 230 231 232 #undef __FUNCT__ 233 #define __FUNCT__ "MatSolve_SuperLU_Private" 234 PetscErrorCode MatSolve_SuperLU_Private(Mat A,Vec b,Vec x) 235 { 236 Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 237 PetscScalar *barray,*xarray; 238 PetscErrorCode ierr; 239 PetscInt info,i; 240 SuperLUStat_t stat; 241 PetscReal ferr,berr; 242 243 PetscFunctionBegin; 244 if ( lu->lwork == -1 ) { 245 PetscFunctionReturn(0); 246 } 247 lu->B.ncol = 1; /* Set the number of right-hand side */ 248 ierr = VecGetArray(b,&barray);CHKERRQ(ierr); 249 ierr = VecGetArray(x,&xarray);CHKERRQ(ierr); 250 251 #if defined(PETSC_USE_COMPLEX) 252 ((DNformat*)lu->B.Store)->nzval = (doublecomplex*)barray; 253 ((DNformat*)lu->X.Store)->nzval = (doublecomplex*)xarray; 254 #else 255 ((DNformat*)lu->B.Store)->nzval = barray; 256 ((DNformat*)lu->X.Store)->nzval = xarray; 257 #endif 258 259 /* Initialize the statistics variables. */ 260 StatInit(&stat); 261 262 lu->options.Fact = FACTORED; /* Indicate the factored form of A is supplied. */ 263 #if defined(PETSC_USE_COMPLEX) 264 zgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 265 &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 266 &lu->mem_usage, &stat, &info); 267 #else 268 dgssvx(&lu->options, &lu->A, lu->perm_c, lu->perm_r, lu->etree, lu->equed, lu->R, lu->C, 269 &lu->L, &lu->U, lu->work, lu->lwork, &lu->B, &lu->X, &lu->rpg, &lu->rcond, &ferr, &berr, 270 &lu->mem_usage, &stat, &info); 271 #endif 272 ierr = VecRestoreArray(b,&barray);CHKERRQ(ierr); 273 ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr); 274 275 if ( !info || info == lu->A.ncol+1 ) { 276 if ( lu->options.IterRefine ) { 277 ierr = PetscPrintf(PETSC_COMM_SELF,"Iterative Refinement:\n"); 278 ierr = PetscPrintf(PETSC_COMM_SELF," %8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); 279 for (i = 0; i < 1; ++i) 280 ierr = PetscPrintf(PETSC_COMM_SELF," %8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr, berr); 281 } 282 } else if ( info > 0 ){ 283 if ( lu->lwork == -1 ) { 284 ierr = PetscPrintf(PETSC_COMM_SELF," ** Estimated memory: %D bytes\n", info - lu->A.ncol); 285 } else { 286 ierr = PetscPrintf(PETSC_COMM_SELF," Warning: gssvx() returns info %D\n",info); 287 } 288 } else if (info < 0){ 289 SETERRQ2(PETSC_ERR_LIB, "info = %D, the %D-th argument in gssvx() had an illegal value", info,-info); 290 } 291 292 if ( lu->options.PrintStat ) { 293 ierr = PetscPrintf(PETSC_COMM_SELF,"MatSolve__SuperLU():\n"); 294 StatPrint(&stat); 295 } 296 StatFree(&stat); 297 PetscFunctionReturn(0); 298 } 299 300 #undef __FUNCT__ 301 #define __FUNCT__ "MatSolve_SuperLU" 302 PetscErrorCode MatSolve_SuperLU(Mat A,Vec b,Vec x) 303 { 304 Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 305 PetscErrorCode ierr; 306 307 PetscFunctionBegin; 308 lu->options.Trans = TRANS; 309 ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr); 310 PetscFunctionReturn(0); 311 } 312 313 #undef __FUNCT__ 314 #define __FUNCT__ "MatSolveTranspose_SuperLU" 315 PetscErrorCode MatSolveTranspose_SuperLU(Mat A,Vec b,Vec x) 316 { 317 Mat_SuperLU *lu = (Mat_SuperLU*)A->spptr; 318 PetscErrorCode ierr; 319 320 PetscFunctionBegin; 321 lu->options.Trans = NOTRANS; 322 ierr = MatSolve_SuperLU_Private(A,b,x);CHKERRQ(ierr); 323 PetscFunctionReturn(0); 324 } 325 326 327 /* 328 Note the r permutation is ignored 329 */ 330 #undef __FUNCT__ 331 #define __FUNCT__ "MatLUFactorSymbolic_SuperLU" 332 PetscErrorCode MatLUFactorSymbolic_SuperLU(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) 333 { 334 Mat_SuperLU *lu = (Mat_SuperLU*)((*F)->spptr); 335 PetscErrorCode ierr; 336 PetscInt m=A->rmap.n,n=A->cmap.n,indx; 337 338 PetscFunctionBegin; 339 340 /* Allocate spaces (notice sizes are for the transpose) */ 341 ierr = PetscMalloc(m*sizeof(PetscInt),&lu->etree);CHKERRQ(ierr); 342 ierr = PetscMalloc(n*sizeof(PetscInt),&lu->perm_r);CHKERRQ(ierr); 343 ierr = PetscMalloc(m*sizeof(PetscInt),&lu->perm_c);CHKERRQ(ierr); 344 ierr = PetscMalloc(n*sizeof(PetscInt),&lu->R);CHKERRQ(ierr); 345 ierr = PetscMalloc(m*sizeof(PetscInt),&lu->C);CHKERRQ(ierr); 346 347 /* create rhs and solution x without allocate space for .Store */ 348 #if defined(PETSC_USE_COMPLEX) 349 zCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE); 350 zCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_Z, SLU_GE); 351 #else 352 dCreate_Dense_Matrix(&lu->B, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE); 353 dCreate_Dense_Matrix(&lu->X, m, 1, PETSC_NULL, m, SLU_DN, SLU_D, SLU_GE); 354 #endif 355 356 lu->flg = DIFFERENT_NONZERO_PATTERN; 357 lu->CleanUpSuperLU = PETSC_TRUE; 358 PetscFunctionReturn(0); 359 } 360 361 362 /*MC 363 MAT_SOLVER_SUPERLU = "superlu" - A matrix type providing direct solvers (LU) for sequential matrices 364 via the external package SuperLU. 365 366 Use config/configure.py --download-superlu to have PETSc installed with SuperLU 367 368 Options Database Keys: 369 + -mat_superlu_ordering <0,1,2,3> - 0: natural ordering, 370 1: MMD applied to A'*A, 371 2: MMD applied to A'+A, 372 3: COLAMD, approximate minimum degree column ordering 373 . -mat_superlu_iterrefine - have SuperLU do iterative refinement after the triangular solve 374 choices: NOREFINE, SINGLE, DOUBLE, EXTRA; default is NOREFINE 375 - -mat_superlu_printstat - print SuperLU statistics about the factorization 376 377 Notes: Do not confuse this with MAT_SOLVER_SUPERLU_DIST which is for parallel sparse solves 378 379 Level: beginner 380 381 .seealso: PCLU, MAT_SOLVER_SUPERLU_DIST, MAT_SOLVER_MUMPS, MAT_SOLVER_SPOOLES 382 M*/ 383 384 EXTERN_C_BEGIN 385 #undef __FUNCT__ 386 #define __FUNCT__ "MatGetFactor_seqaij_superlu" 387 PetscErrorCode MatGetFactor_seqaij_superlu(Mat A,MatFactorType ftype,Mat *F) 388 { 389 Mat B; 390 Mat_SuperLU *lu; 391 PetscErrorCode ierr; 392 PetscInt m=A->rmap.n,n=A->cmap.n,indx; 393 PetscTruth flg; 394 const char *colperm[]={"NATURAL","MMD_ATA","MMD_AT_PLUS_A","COLAMD"}; /* MY_PERMC - not supported by the petsc interface yet */ 395 const char *iterrefine[]={"NOREFINE", "SINGLE", "DOUBLE", "EXTRA"}; 396 const char *rowperm[]={"NOROWPERM", "LargeDiag"}; /* MY_PERMC - not supported by the petsc interface yet */ 397 398 PetscFunctionBegin; 399 ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); 400 ierr = MatSetSizes(B,A->rmap.n,A->cmap.n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 401 ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 402 ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 403 404 B->ops->lufactornumeric = MatLUFactorNumeric_SuperLU; 405 B->ops->lufactorsymbolic = MatLUFactorSymbolic_SuperLU; 406 B->ops->solve = MatSolve_SuperLU; 407 B->ops->solvetranspose = MatSolveTranspose_SuperLU; 408 B->ops->destroy = MatDestroy_SuperLU; 409 B->factor = MAT_FACTOR_LU; 410 B->assembled = PETSC_TRUE; /* required by -ksp_view */ 411 B->preallocated = PETSC_TRUE; 412 413 ierr = PetscNewLog(B,Mat_SuperLU,&lu);CHKERRQ(ierr); 414 set_default_options(&lu->options); 415 /* equilibration causes error in solve(), thus not supported here. See dgssvx.c for possible reason. */ 416 lu->options.Equil = NO; 417 lu->options.PrintStat = NO; 418 lu->lwork = 0; /* allocate space internally by system malloc */ 419 420 ierr = PetscOptionsBegin(((PetscObject)A)->comm,((PetscObject)A)->prefix,"SuperLU Options","Mat");CHKERRQ(ierr); 421 ierr = PetscOptionsEList("-mat_superlu_colperm","ColPerm","None",colperm,4,colperm[3],&indx,&flg);CHKERRQ(ierr); 422 if (flg) {lu->options.ColPerm = (colperm_t)indx;} 423 ierr = PetscOptionsEList("-mat_superlu_iterrefine","IterRefine","None",iterrefine,4,iterrefine[0],&indx,&flg);CHKERRQ(ierr); 424 if (flg) { lu->options.IterRefine = (IterRefine_t)indx;} 425 ierr = PetscOptionsTruth("-mat_superlu_symmetricmode","SymmetricMode","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 426 if (flg) lu->options.SymmetricMode = YES; 427 ierr = PetscOptionsReal("-mat_superlu_diagpivotthresh","DiagPivotThresh","None",lu->options.DiagPivotThresh,&lu->options.DiagPivotThresh,PETSC_NULL);CHKERRQ(ierr); 428 ierr = PetscOptionsTruth("-mat_superlu_pivotgrowth","PivotGrowth","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 429 if (flg) lu->options.PivotGrowth = YES; 430 ierr = PetscOptionsTruth("-mat_superlu_conditionnumber","ConditionNumber","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 431 if (flg) lu->options.ConditionNumber = YES; 432 ierr = PetscOptionsEList("-mat_superlu_rowperm","rowperm","None",rowperm,2,rowperm[0],&indx,&flg);CHKERRQ(ierr); 433 if (flg) {lu->options.RowPerm = (rowperm_t)indx;} 434 ierr = PetscOptionsTruth("-mat_superlu_replacetinypivot","ReplaceTinyPivot","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 435 if (flg) lu->options.ReplaceTinyPivot = YES; 436 ierr = PetscOptionsTruth("-mat_superlu_printstat","PrintStat","None",PETSC_FALSE,&flg,0);CHKERRQ(ierr); 437 if (flg) lu->options.PrintStat = YES; 438 ierr = PetscOptionsInt("-mat_superlu_lwork","size of work array in bytes used by factorization","None",lu->lwork,&lu->lwork,PETSC_NULL);CHKERRQ(ierr); 439 if (lu->lwork > 0 ){ 440 ierr = PetscMalloc(lu->lwork,&lu->work);CHKERRQ(ierr); 441 } else if (lu->lwork != 0 && lu->lwork != -1){ 442 ierr = PetscPrintf(PETSC_COMM_SELF," Warning: lwork %D is not supported by SUPERLU. The default lwork=0 is used.\n",lu->lwork); 443 lu->lwork = 0; 444 } 445 PetscOptionsEnd(); 446 447 #ifdef SUPERLU2 448 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatCreateNull","MatCreateNull_SuperLU",(void(*)(void))MatCreateNull_SuperLU);CHKERRQ(ierr); 449 #endif 450 B->spptr = lu; 451 *F = B; 452 PetscFunctionReturn(0); 453 } 454 EXTERN_C_END 455