1 #define PETSCMAT_DLL 2 3 /* 4 Provides an interface to the UMFPACKv4.3 sparse solver 5 */ 6 7 #include "src/mat/impls/aij/seq/aij.h" 8 9 EXTERN_C_BEGIN 10 #include "umfpack.h" 11 EXTERN_C_END 12 13 typedef struct { 14 void *Symbolic, *Numeric; 15 double Info[UMFPACK_INFO], Control[UMFPACK_CONTROL],*W; 16 int *Wi,*ai,*aj,*perm_c; 17 PetscScalar *av; 18 MatStructure flg; 19 PetscTruth PetscMatOdering; 20 21 /* A few function pointers for inheritance */ 22 PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*); 23 PetscErrorCode (*MatView)(Mat,PetscViewer); 24 PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType); 25 PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*); 26 PetscErrorCode (*MatDestroy)(Mat); 27 28 /* Flag to clean up UMFPACK objects during Destroy */ 29 PetscTruth CleanUpUMFPACK; 30 } Mat_UMFPACK; 31 32 EXTERN PetscErrorCode MatDuplicate_UMFPACK(Mat,MatDuplicateOption,Mat*); 33 34 EXTERN_C_BEGIN 35 #undef __FUNCT__ 36 #define __FUNCT__ "MatConvert_UMFPACK_SeqAIJ" 37 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_UMFPACK_SeqAIJ(Mat A,const MatType type,MatReuse reuse,Mat *newmat) 38 { 39 /* This routine is only called to convert an unfactored PETSc-UMFPACK matrix */ 40 /* to its base PETSc type, so we will ignore 'MatType type'. */ 41 PetscErrorCode ierr; 42 Mat B=*newmat; 43 Mat_UMFPACK *lu=(Mat_UMFPACK*)A->spptr; 44 45 PetscFunctionBegin; 46 if (reuse == MAT_INITIAL_MATRIX) { 47 ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 48 } 49 /* Reset the original function pointers */ 50 B->ops->duplicate = lu->MatDuplicate; 51 B->ops->view = lu->MatView; 52 B->ops->assemblyend = lu->MatAssemblyEnd; 53 B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic; 54 B->ops->destroy = lu->MatDestroy; 55 56 ierr = PetscFree(lu);CHKERRQ(ierr); 57 58 ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_umfpack_C","",PETSC_NULL);CHKERRQ(ierr); 59 ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_umfpack_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 60 61 ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 62 *newmat = B; 63 PetscFunctionReturn(0); 64 } 65 EXTERN_C_END 66 67 #undef __FUNCT__ 68 #define __FUNCT__ "MatDestroy_UMFPACK" 69 PetscErrorCode MatDestroy_UMFPACK(Mat A) 70 { 71 PetscErrorCode ierr; 72 Mat_UMFPACK *lu=(Mat_UMFPACK*)A->spptr; 73 74 PetscFunctionBegin; 75 if (lu->CleanUpUMFPACK) { 76 umfpack_di_free_symbolic(&lu->Symbolic); 77 umfpack_di_free_numeric(&lu->Numeric); 78 ierr = PetscFree(lu->Wi);CHKERRQ(ierr); 79 ierr = PetscFree(lu->W);CHKERRQ(ierr); 80 if (lu->PetscMatOdering) { 81 ierr = PetscFree(lu->perm_c);CHKERRQ(ierr); 82 } 83 } 84 ierr = MatConvert_UMFPACK_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 85 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 86 PetscFunctionReturn(0); 87 } 88 89 #undef __FUNCT__ 90 #define __FUNCT__ "MatSolve_UMFPACK" 91 PetscErrorCode MatSolve_UMFPACK(Mat A,Vec b,Vec x) 92 { 93 Mat_UMFPACK *lu = (Mat_UMFPACK*)A->spptr; 94 PetscScalar *av=lu->av,*ba,*xa; 95 PetscErrorCode ierr; 96 int *ai=lu->ai,*aj=lu->aj,status; 97 98 PetscFunctionBegin; 99 /* solve Ax = b by umfpack_di_wsolve */ 100 /* ----------------------------------*/ 101 ierr = VecGetArray(b,&ba); 102 ierr = VecGetArray(x,&xa); 103 104 status = umfpack_di_wsolve(UMFPACK_At,ai,aj,av,xa,ba,lu->Numeric,lu->Control,lu->Info,lu->Wi,lu->W); 105 umfpack_di_report_info(lu->Control, lu->Info); 106 if (status < 0){ 107 umfpack_di_report_status(lu->Control, status); 108 SETERRQ(PETSC_ERR_LIB,"umfpack_di_wsolve failed"); 109 } 110 111 ierr = VecRestoreArray(b,&ba); 112 ierr = VecRestoreArray(x,&xa); 113 114 PetscFunctionReturn(0); 115 } 116 117 #undef __FUNCT__ 118 #define __FUNCT__ "MatLUFactorNumeric_UMFPACK" 119 PetscErrorCode MatLUFactorNumeric_UMFPACK(Mat A,MatFactorInfo *info,Mat *F) 120 { 121 Mat_UMFPACK *lu=(Mat_UMFPACK*)(*F)->spptr; 122 PetscErrorCode ierr; 123 int *ai=lu->ai,*aj=lu->aj,m=A->m,status; 124 PetscScalar *av=lu->av; 125 126 PetscFunctionBegin; 127 /* numeric factorization of A' */ 128 /* ----------------------------*/ 129 if (lu->flg == SAME_NONZERO_PATTERN && lu->Numeric){ 130 umfpack_di_free_numeric(&lu->Numeric); 131 } 132 status = umfpack_di_numeric (ai,aj,av,lu->Symbolic,&lu->Numeric,lu->Control,lu->Info); 133 if (status < 0) SETERRQ(PETSC_ERR_LIB,"umfpack_di_numeric failed"); 134 /* report numeric factorization of A' when Control[PRL] > 3 */ 135 (void) umfpack_di_report_numeric (lu->Numeric, lu->Control); 136 137 if (lu->flg == DIFFERENT_NONZERO_PATTERN){ /* first numeric factorization */ 138 /* allocate working space to be used by Solve */ 139 ierr = PetscMalloc(m * sizeof(int), &lu->Wi);CHKERRQ(ierr); 140 ierr = PetscMalloc(5*m * sizeof(double), &lu->W);CHKERRQ(ierr); 141 } 142 lu->flg = SAME_NONZERO_PATTERN; 143 lu->CleanUpUMFPACK = PETSC_TRUE; 144 PetscFunctionReturn(0); 145 } 146 147 /* 148 Note the r permutation is ignored 149 */ 150 #undef __FUNCT__ 151 #define __FUNCT__ "MatLUFactorSymbolic_UMFPACK" 152 PetscErrorCode MatLUFactorSymbolic_UMFPACK(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) 153 { 154 Mat B; 155 Mat_SeqAIJ *mat=(Mat_SeqAIJ*)A->data; 156 Mat_UMFPACK *lu; 157 PetscErrorCode ierr; 158 int m=A->m,n=A->n,*ai=mat->i,*aj=mat->j,status,*ra,idx; 159 PetscScalar *av=mat->a; 160 const char *strategy[]={"AUTO","UNSYMMETRIC","SYMMETRIC","2BY2"}, 161 *scale[]={"NONE","SUM","MAX"}; 162 PetscTruth flg; 163 164 PetscFunctionBegin; 165 /* Create the factorization matrix F */ 166 ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,m,n,&B);CHKERRQ(ierr); 167 ierr = MatSetType(B,A->type_name);CHKERRQ(ierr); 168 ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr); 169 170 B->ops->lufactornumeric = MatLUFactorNumeric_UMFPACK; 171 B->ops->solve = MatSolve_UMFPACK; 172 B->factor = FACTOR_LU; 173 B->assembled = PETSC_TRUE; /* required by -ksp_view */ 174 175 lu = (Mat_UMFPACK*)(B->spptr); 176 177 /* initializations */ 178 /* ------------------------------------------------*/ 179 /* get the default control parameters */ 180 umfpack_di_defaults (lu->Control); 181 lu->perm_c = PETSC_NULL; /* use defaul UMFPACK col permutation */ 182 lu->Control[UMFPACK_IRSTEP] = 0; /* max num of iterative refinement steps to attempt */ 183 184 ierr = PetscOptionsBegin(A->comm,A->prefix,"UMFPACK Options","Mat");CHKERRQ(ierr); 185 /* Control parameters used by reporting routiones */ 186 ierr = PetscOptionsReal("-mat_umfpack_prl","Control[UMFPACK_PRL]","None",lu->Control[UMFPACK_PRL],&lu->Control[UMFPACK_PRL],PETSC_NULL);CHKERRQ(ierr); 187 188 /* Control parameters for symbolic factorization */ 189 ierr = PetscOptionsEList("-mat_umfpack_strategy","ordering and pivoting strategy","None",strategy,4,strategy[0],&idx,&flg);CHKERRQ(ierr); 190 if (flg) { 191 switch (idx){ 192 case 0: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_AUTO; break; 193 case 1: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_UNSYMMETRIC; break; 194 case 2: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_SYMMETRIC; break; 195 case 3: lu->Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_2BY2; break; 196 } 197 } 198 ierr = PetscOptionsReal("-mat_umfpack_dense_col","Control[UMFPACK_DENSE_COL]","None",lu->Control[UMFPACK_DENSE_COL],&lu->Control[UMFPACK_DENSE_COL],PETSC_NULL);CHKERRQ(ierr); 199 ierr = PetscOptionsReal("-mat_umfpack_dense_row","Control[UMFPACK_DENSE_ROW]","None",lu->Control[UMFPACK_DENSE_ROW],&lu->Control[UMFPACK_DENSE_ROW],PETSC_NULL);CHKERRQ(ierr); 200 ierr = PetscOptionsReal("-mat_umfpack_amd_dense","Control[UMFPACK_AMD_DENSE]","None",lu->Control[UMFPACK_AMD_DENSE],&lu->Control[UMFPACK_AMD_DENSE],PETSC_NULL);CHKERRQ(ierr); 201 ierr = PetscOptionsReal("-mat_umfpack_block_size","Control[UMFPACK_BLOCK_SIZE]","None",lu->Control[UMFPACK_BLOCK_SIZE],&lu->Control[UMFPACK_BLOCK_SIZE],PETSC_NULL);CHKERRQ(ierr); 202 ierr = PetscOptionsReal("-mat_umfpack_2by2_tolerance","Control[UMFPACK_2BY2_TOLERANCE]","None",lu->Control[UMFPACK_2BY2_TOLERANCE],&lu->Control[UMFPACK_2BY2_TOLERANCE],PETSC_NULL);CHKERRQ(ierr); 203 ierr = PetscOptionsReal("-mat_umfpack_fixq","Control[UMFPACK_FIXQ]","None",lu->Control[UMFPACK_FIXQ],&lu->Control[UMFPACK_FIXQ],PETSC_NULL);CHKERRQ(ierr); 204 ierr = PetscOptionsReal("-mat_umfpack_aggressive","Control[UMFPACK_AGGRESSIVE]","None",lu->Control[UMFPACK_AGGRESSIVE],&lu->Control[UMFPACK_AGGRESSIVE],PETSC_NULL);CHKERRQ(ierr); 205 206 /* Control parameters used by numeric factorization */ 207 ierr = PetscOptionsReal("-mat_umfpack_pivot_tolerance","Control[UMFPACK_PIVOT_TOLERANCE]","None",lu->Control[UMFPACK_PIVOT_TOLERANCE],&lu->Control[UMFPACK_PIVOT_TOLERANCE],PETSC_NULL);CHKERRQ(ierr); 208 ierr = PetscOptionsReal("-mat_umfpack_sym_pivot_tolerance","Control[UMFPACK_SYM_PIVOT_TOLERANCE]","None",lu->Control[UMFPACK_SYM_PIVOT_TOLERANCE],&lu->Control[UMFPACK_SYM_PIVOT_TOLERANCE],PETSC_NULL);CHKERRQ(ierr); 209 ierr = PetscOptionsEList("-mat_umfpack_scale","Control[UMFPACK_SCALE]","None",scale,3,scale[0],&idx,&flg);CHKERRQ(ierr); 210 if (flg) { 211 switch (idx){ 212 case 0: lu->Control[UMFPACK_SCALE] = UMFPACK_SCALE_NONE; break; 213 case 1: lu->Control[UMFPACK_SCALE] = UMFPACK_SCALE_SUM; break; 214 case 2: lu->Control[UMFPACK_SCALE] = UMFPACK_SCALE_MAX; break; 215 } 216 } 217 ierr = PetscOptionsReal("-mat_umfpack_alloc_init","Control[UMFPACK_ALLOC_INIT]","None",lu->Control[UMFPACK_ALLOC_INIT],&lu->Control[UMFPACK_ALLOC_INIT],PETSC_NULL);CHKERRQ(ierr); 218 ierr = PetscOptionsReal("-mat_umfpack_front_alloc_init","Control[UMFPACK_FRONT_ALLOC_INIT]","None",lu->Control[UMFPACK_FRONT_ALLOC_INIT],&lu->Control[UMFPACK_ALLOC_INIT],PETSC_NULL);CHKERRQ(ierr); 219 ierr = PetscOptionsReal("-mat_umfpack_droptol","Control[UMFPACK_DROPTOL]","None",lu->Control[UMFPACK_DROPTOL],&lu->Control[UMFPACK_DROPTOL],PETSC_NULL);CHKERRQ(ierr); 220 221 /* Control parameters used by solve */ 222 ierr = PetscOptionsReal("-mat_umfpack_irstep","Control[UMFPACK_IRSTEP]","None",lu->Control[UMFPACK_IRSTEP],&lu->Control[UMFPACK_IRSTEP],PETSC_NULL);CHKERRQ(ierr); 223 224 /* use Petsc mat ordering (note: size is for the transpose, and PETSc r = Umfpack perm_c) */ 225 ierr = PetscOptionsHasName(PETSC_NULL,"-pc_lu_mat_ordering_type",&lu->PetscMatOdering);CHKERRQ(ierr); 226 if (lu->PetscMatOdering) { 227 ierr = ISGetIndices(r,&ra);CHKERRQ(ierr); 228 ierr = PetscMalloc(A->m*sizeof(int),&lu->perm_c);CHKERRQ(ierr); 229 ierr = PetscMemcpy(lu->perm_c,ra,A->m*sizeof(int));CHKERRQ(ierr); 230 ierr = ISRestoreIndices(r,&ra);CHKERRQ(ierr); 231 } 232 PetscOptionsEnd(); 233 234 /* print the control parameters */ 235 if( lu->Control[UMFPACK_PRL] > 1 ) umfpack_di_report_control (lu->Control); 236 237 /* symbolic factorization of A' */ 238 /* ---------------------------------------------------------------------- */ 239 if (lu->PetscMatOdering) { /* use Petsc row ordering */ 240 status = umfpack_di_qsymbolic(n,m,ai,aj,av,lu->perm_c,&lu->Symbolic,lu->Control,lu->Info); 241 } else { /* use Umfpack col ordering */ 242 status = umfpack_di_symbolic(n,m,ai,aj,av,&lu->Symbolic,lu->Control,lu->Info); 243 } 244 if (status < 0){ 245 umfpack_di_report_info(lu->Control, lu->Info); 246 umfpack_di_report_status(lu->Control, status); 247 SETERRQ(PETSC_ERR_LIB,"umfpack_di_symbolic failed"); 248 } 249 /* report sumbolic factorization of A' when Control[PRL] > 3 */ 250 (void) umfpack_di_report_symbolic(lu->Symbolic, lu->Control); 251 252 lu->flg = DIFFERENT_NONZERO_PATTERN; 253 lu->ai = ai; 254 lu->aj = aj; 255 lu->av = av; 256 lu->CleanUpUMFPACK = PETSC_TRUE; 257 *F = B; 258 PetscFunctionReturn(0); 259 } 260 261 #undef __FUNCT__ 262 #define __FUNCT__ "MatAssemblyEnd_UMFPACK" 263 PetscErrorCode MatAssemblyEnd_UMFPACK(Mat A,MatAssemblyType mode) 264 { 265 PetscErrorCode ierr; 266 Mat_UMFPACK *lu=(Mat_UMFPACK*)(A->spptr); 267 268 PetscFunctionBegin; 269 ierr = (*lu->MatAssemblyEnd)(A,mode);CHKERRQ(ierr); 270 lu->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 271 A->ops->lufactorsymbolic = MatLUFactorSymbolic_UMFPACK; 272 PetscFunctionReturn(0); 273 } 274 275 /* used by -ksp_view */ 276 #undef __FUNCT__ 277 #define __FUNCT__ "MatFactorInfo_UMFPACK" 278 PetscErrorCode MatFactorInfo_UMFPACK(Mat A,PetscViewer viewer) 279 { 280 Mat_UMFPACK *lu= (Mat_UMFPACK*)A->spptr; 281 PetscErrorCode ierr; 282 283 PetscFunctionBegin; 284 /* check if matrix is UMFPACK type */ 285 if (A->ops->solve != MatSolve_UMFPACK) PetscFunctionReturn(0); 286 287 ierr = PetscViewerASCIIPrintf(viewer,"UMFPACK run parameters:\n");CHKERRQ(ierr); 288 /* Control parameters used by reporting routiones */ 289 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_PRL]: %g\n",lu->Control[UMFPACK_PRL]);CHKERRQ(ierr); 290 291 /* Control parameters used by symbolic factorization */ 292 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_STRATEGY]: %g\n",lu->Control[UMFPACK_STRATEGY]);CHKERRQ(ierr); 293 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_DENSE_COL]: %g\n",lu->Control[UMFPACK_DENSE_COL]);CHKERRQ(ierr); 294 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_DENSE_ROW]: %g\n",lu->Control[UMFPACK_DENSE_ROW]);CHKERRQ(ierr); 295 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_AMD_DENSE]: %g\n",lu->Control[UMFPACK_AMD_DENSE]);CHKERRQ(ierr); 296 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_BLOCK_SIZE]: %g\n",lu->Control[UMFPACK_BLOCK_SIZE]);CHKERRQ(ierr); 297 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_2BY2_TOLERANCE]: %g\n",lu->Control[UMFPACK_2BY2_TOLERANCE]);CHKERRQ(ierr); 298 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_FIXQ]: %g\n",lu->Control[UMFPACK_FIXQ]);CHKERRQ(ierr); 299 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_AGGRESSIVE]: %g\n",lu->Control[UMFPACK_AGGRESSIVE]);CHKERRQ(ierr); 300 301 /* Control parameters used by numeric factorization */ 302 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_PIVOT_TOLERANCE]: %g\n",lu->Control[UMFPACK_PIVOT_TOLERANCE]);CHKERRQ(ierr); 303 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_SYM_PIVOT_TOLERANCE]: %g\n",lu->Control[UMFPACK_SYM_PIVOT_TOLERANCE]);CHKERRQ(ierr); 304 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_SCALE]: %g\n",lu->Control[UMFPACK_SCALE]);CHKERRQ(ierr); 305 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_ALLOC_INIT]: %g\n",lu->Control[UMFPACK_ALLOC_INIT]);CHKERRQ(ierr); 306 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_DROPTOL]: %g\n",lu->Control[UMFPACK_DROPTOL]);CHKERRQ(ierr); 307 308 /* Control parameters used by solve */ 309 ierr = PetscViewerASCIIPrintf(viewer," Control[UMFPACK_IRSTEP]: %g\n",lu->Control[UMFPACK_IRSTEP]);CHKERRQ(ierr); 310 311 /* mat ordering */ 312 if(!lu->PetscMatOdering) ierr = PetscViewerASCIIPrintf(viewer," UMFPACK default matrix ordering is used (not the PETSc matrix ordering) \n");CHKERRQ(ierr); 313 314 PetscFunctionReturn(0); 315 } 316 317 #undef __FUNCT__ 318 #define __FUNCT__ "MatView_UMFPACK" 319 PetscErrorCode MatView_UMFPACK(Mat A,PetscViewer viewer) 320 { 321 PetscErrorCode ierr; 322 PetscTruth iascii; 323 PetscViewerFormat format; 324 Mat_UMFPACK *lu=(Mat_UMFPACK*)(A->spptr); 325 326 PetscFunctionBegin; 327 ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr); 328 329 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 330 if (iascii) { 331 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 332 if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 333 ierr = MatFactorInfo_UMFPACK(A,viewer);CHKERRQ(ierr); 334 } 335 } 336 PetscFunctionReturn(0); 337 } 338 339 EXTERN_C_BEGIN 340 #undef __FUNCT__ 341 #define __FUNCT__ "MatConvert_SeqAIJ_UMFPACK" 342 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_UMFPACK(Mat A,const MatType type,MatReuse reuse,Mat *newmat) 343 { 344 /* This routine is only called to convert to MATUMFPACK */ 345 /* from MATSEQAIJ, so we will ignore 'MatType type'. */ 346 PetscErrorCode ierr; 347 Mat B=*newmat; 348 Mat_UMFPACK *lu; 349 350 PetscFunctionBegin; 351 if (reuse == MAT_INITIAL_MATRIX) { 352 ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 353 } 354 355 ierr = PetscNew(Mat_UMFPACK,&lu);CHKERRQ(ierr); 356 lu->MatDuplicate = A->ops->duplicate; 357 lu->MatView = A->ops->view; 358 lu->MatAssemblyEnd = A->ops->assemblyend; 359 lu->MatLUFactorSymbolic = A->ops->lufactorsymbolic; 360 lu->MatDestroy = A->ops->destroy; 361 lu->CleanUpUMFPACK = PETSC_FALSE; 362 363 B->spptr = (void*)lu; 364 B->ops->duplicate = MatDuplicate_UMFPACK; 365 B->ops->view = MatView_UMFPACK; 366 B->ops->assemblyend = MatAssemblyEnd_UMFPACK; 367 B->ops->lufactorsymbolic = MatLUFactorSymbolic_UMFPACK; 368 B->ops->destroy = MatDestroy_UMFPACK; 369 370 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_umfpack_C", 371 "MatConvert_SeqAIJ_UMFPACK",MatConvert_SeqAIJ_UMFPACK);CHKERRQ(ierr); 372 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_umfpack_seqaij_C", 373 "MatConvert_UMFPACK_SeqAIJ",MatConvert_UMFPACK_SeqAIJ);CHKERRQ(ierr); 374 ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_UMFPACK:Using UMFPACK for SeqAIJ LU factorization and solves.\n"));CHKERRQ(ierr); 375 ierr = PetscObjectChangeTypeName((PetscObject)B,MATUMFPACK);CHKERRQ(ierr); 376 *newmat = B; 377 PetscFunctionReturn(0); 378 } 379 EXTERN_C_END 380 381 #undef __FUNCT__ 382 #define __FUNCT__ "MatDuplicate_UMFPACK" 383 PetscErrorCode MatDuplicate_UMFPACK(Mat A, MatDuplicateOption op, Mat *M) 384 { 385 PetscErrorCode ierr; 386 Mat_UMFPACK *lu=(Mat_UMFPACK*)A->spptr; 387 388 PetscFunctionBegin; 389 ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr); 390 ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_UMFPACK));CHKERRQ(ierr); 391 PetscFunctionReturn(0); 392 } 393 394 /*MC 395 MATUMFPACK - MATUMFPACK = "umfpack" - A matrix type providing direct solvers (LU) for sequential matrices 396 via the external package UMFPACK. 397 398 If UMFPACK is installed (see the manual for 399 instructions on how to declare the existence of external packages), 400 a matrix type can be constructed which invokes UMFPACK solvers. 401 After calling MatCreate(...,A), simply call MatSetType(A,UMFPACK). 402 This matrix type is only supported for double precision real. 403 404 This matrix inherits from MATSEQAIJ. As a result, MatSeqAIJSetPreallocation is 405 supported for this matrix type. One can also call MatConvert for an inplace conversion to or from 406 the MATSEQAIJ type without data copy. 407 408 Consult UMFPACK documentation for more information about the Control parameters 409 which correspond to the options database keys below. 410 411 Options Database Keys: 412 + -mat_type umfpack - sets the matrix type to "umfpack" during a call to MatSetFromOptions() 413 . -mat_umfpack_prl - UMFPACK print level: Control[UMFPACK_PRL] 414 . -mat_umfpack_dense_col <alpha_c> - UMFPACK dense column threshold: Control[UMFPACK_DENSE_COL] 415 . -mat_umfpack_block_size <bs> - UMFPACK block size for BLAS-Level 3 calls: Control[UMFPACK_BLOCK_SIZE] 416 . -mat_umfpack_pivot_tolerance <delta> - UMFPACK partial pivot tolerance: Control[UMFPACK_PIVOT_TOLERANCE] 417 . -mat_umfpack_alloc_init <delta> - UMFPACK factorized matrix allocation modifier: Control[UMFPACK_ALLOC_INIT] 418 - -mat_umfpack_irstep <maxit> - UMFPACK maximum number of iterative refinement steps: Control[UMFPACK_IRSTEP] 419 420 Level: beginner 421 422 .seealso: PCLU 423 M*/ 424 425 EXTERN_C_BEGIN 426 #undef __FUNCT__ 427 #define __FUNCT__ "MatCreate_UMFPACK" 428 PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_UMFPACK(Mat A) 429 { 430 PetscErrorCode ierr; 431 432 PetscFunctionBegin; 433 /* Change type name before calling MatSetType to force proper construction of SeqAIJ and UMFPACK types */ 434 ierr = PetscObjectChangeTypeName((PetscObject)A,MATUMFPACK);CHKERRQ(ierr); 435 ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr); 436 ierr = MatConvert_SeqAIJ_UMFPACK(A,MATUMFPACK,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); 437 PetscFunctionReturn(0); 438 } 439 EXTERN_C_END 440