1 #define PETSCKSP_DLL 2 3 /* 4 Defines a direct factorization preconditioner for any Mat implementation 5 Note: this need not be consided a preconditioner since it supplies 6 a direct solver. 7 */ 8 9 #include "src/ksp/pc/pcimpl.h" /*I "petscpc.h" I*/ 10 #include "src/ksp/pc/impls/factor/lu/lu.h" 11 12 EXTERN_C_BEGIN 13 #undef __FUNCT__ 14 #define __FUNCT__ "PCFactorSetZeroPivot_LU" 15 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetZeroPivot_LU(PC pc,PetscReal z) 16 { 17 PC_LU *lu; 18 19 PetscFunctionBegin; 20 lu = (PC_LU*)pc->data; 21 lu->info.zeropivot = z; 22 PetscFunctionReturn(0); 23 } 24 EXTERN_C_END 25 26 EXTERN_C_BEGIN 27 #undef __FUNCT__ 28 #define __FUNCT__ "PCFactorSetShiftNonzero_LU" 29 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftNonzero_LU(PC pc,PetscReal shift) 30 { 31 PC_LU *dir; 32 33 PetscFunctionBegin; 34 dir = (PC_LU*)pc->data; 35 if (shift == (PetscReal) PETSC_DECIDE) { 36 dir->info.shiftnz = 1.e-12; 37 } else { 38 dir->info.shiftnz = shift; 39 } 40 PetscFunctionReturn(0); 41 } 42 EXTERN_C_END 43 44 EXTERN_C_BEGIN 45 #undef __FUNCT__ 46 #define __FUNCT__ "PCFactorSetShiftPd_LU" 47 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftPd_LU(PC pc,PetscTruth shift) 48 { 49 PC_LU *dir; 50 51 PetscFunctionBegin; 52 dir = (PC_LU*)pc->data; 53 if (shift) { 54 dir->info.shift_fraction = 0.0; 55 dir->info.shiftpd = 1.0; 56 } else { 57 dir->info.shiftpd = 0.0; 58 } 59 PetscFunctionReturn(0); 60 } 61 EXTERN_C_END 62 63 EXTERN_C_BEGIN 64 #undef __FUNCT__ 65 #define __FUNCT__ "PCLUReorderForNonzeroDiagonal_LU" 66 PetscErrorCode PETSCKSP_DLLEXPORT PCLUReorderForNonzeroDiagonal_LU(PC pc,PetscReal z) 67 { 68 PC_LU *lu = (PC_LU*)pc->data; 69 70 PetscFunctionBegin; 71 lu->nonzerosalongdiagonal = PETSC_TRUE; 72 if (z == PETSC_DECIDE) { 73 lu->nonzerosalongdiagonaltol = 1.e-10; 74 } else { 75 lu->nonzerosalongdiagonaltol = z; 76 } 77 PetscFunctionReturn(0); 78 } 79 EXTERN_C_END 80 81 EXTERN_C_BEGIN 82 #undef __FUNCT__ 83 #define __FUNCT__ "PCLUSetReuseOrdering_LU" 84 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseOrdering_LU(PC pc,PetscTruth flag) 85 { 86 PC_LU *lu; 87 88 PetscFunctionBegin; 89 lu = (PC_LU*)pc->data; 90 lu->reuseordering = flag; 91 PetscFunctionReturn(0); 92 } 93 EXTERN_C_END 94 95 EXTERN_C_BEGIN 96 #undef __FUNCT__ 97 #define __FUNCT__ "PCLUSetReuseFill_LU" 98 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseFill_LU(PC pc,PetscTruth flag) 99 { 100 PC_LU *lu; 101 102 PetscFunctionBegin; 103 lu = (PC_LU*)pc->data; 104 lu->reusefill = flag; 105 PetscFunctionReturn(0); 106 } 107 EXTERN_C_END 108 109 #undef __FUNCT__ 110 #define __FUNCT__ "PCSetFromOptions_LU" 111 static PetscErrorCode PCSetFromOptions_LU(PC pc) 112 { 113 PC_LU *lu = (PC_LU*)pc->data; 114 PetscErrorCode ierr; 115 PetscTruth flg,set; 116 char tname[256]; 117 PetscFList ordlist; 118 PetscReal tol; 119 120 PetscFunctionBegin; 121 ierr = MatOrderingRegisterAll(PETSC_NULL);CHKERRQ(ierr); 122 ierr = PetscOptionsHead("LU options");CHKERRQ(ierr); 123 ierr = PetscOptionsName("-pc_lu_in_place","Form LU in the same memory as the matrix","PCLUSetUseInPlace",&flg);CHKERRQ(ierr); 124 if (flg) { 125 ierr = PCLUSetUseInPlace(pc);CHKERRQ(ierr); 126 } 127 ierr = PetscOptionsReal("-pc_lu_fill","Expected non-zeros in LU/non-zeros in matrix","PCLUSetFill",lu->info.fill,&lu->info.fill,0);CHKERRQ(ierr); 128 129 ierr = PetscOptionsName("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",&flg);CHKERRQ(ierr); 130 if (flg) { 131 ierr = PCFactorSetShiftNonzero(pc,(PetscReal) PETSC_DECIDE);CHKERRQ(ierr); 132 } 133 ierr = PetscOptionsReal("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",lu->info.shiftnz,&lu->info.shiftnz,0);CHKERRQ(ierr); 134 ierr = PetscOptionsName("-pc_factor_shift_positive_definite","Manteuffel shift applied to diagonal","PCFactorSetShiftPd",&flg);CHKERRQ(ierr); 135 if (flg) { 136 ierr = PCFactorSetShiftPd(pc,PETSC_TRUE);CHKERRQ(ierr); 137 } 138 ierr = PetscOptionsReal("-pc_factor_zeropivot","Pivot is considered zero if less than","PCFactorSetZeroPivot",lu->info.zeropivot,&lu->info.zeropivot,0);CHKERRQ(ierr); 139 140 ierr = PetscOptionsName("-pc_lu_reuse_fill","Use fill from previous factorization","PCLUSetReuseFill",&flg);CHKERRQ(ierr); 141 if (flg) { 142 ierr = PCLUSetReuseFill(pc,PETSC_TRUE);CHKERRQ(ierr); 143 } 144 ierr = PetscOptionsName("-pc_lu_reuse_ordering","Reuse ordering from previous factorization","PCLUSetReuseOrdering",&flg);CHKERRQ(ierr); 145 if (flg) { 146 ierr = PCLUSetReuseOrdering(pc,PETSC_TRUE);CHKERRQ(ierr); 147 } 148 149 ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr); 150 ierr = PetscOptionsList("-pc_lu_mat_ordering_type","Reordering to reduce nonzeros in LU","PCLUSetMatOrdering",ordlist,lu->ordering,tname,256,&flg);CHKERRQ(ierr); 151 if (flg) { 152 ierr = PCLUSetMatOrdering(pc,tname);CHKERRQ(ierr); 153 } 154 155 ierr = PetscOptionsName("-pc_lu_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCLUReorderForNonzeroDiagonal",&flg);CHKERRQ(ierr); 156 if (flg) { 157 tol = PETSC_DECIDE; 158 ierr = PetscOptionsReal("-pc_lu_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCLUReorderForNonzeroDiagonal",lu->nonzerosalongdiagonaltol,&tol,0);CHKERRQ(ierr); 159 ierr = PCLUReorderForNonzeroDiagonal(pc,tol);CHKERRQ(ierr); 160 } 161 162 ierr = PetscOptionsReal("-pc_lu_pivoting","Pivoting tolerance (used only for some factorization)","PCLUSetPivoting",lu->info.dtcol,&lu->info.dtcol,&flg);CHKERRQ(ierr); 163 164 flg = lu->info.pivotinblocks ? PETSC_TRUE : PETSC_FALSE; 165 ierr = PetscOptionsTruth("-pc_lu_pivot_in_blocks","Pivot inside matrix blocks for BAIJ and SBAIJ","PCLUSetPivotInBlocks",flg,&flg,&set);CHKERRQ(ierr); 166 if (set) { 167 ierr = PCLUSetPivotInBlocks(pc,flg);CHKERRQ(ierr); 168 } 169 ierr = PetscOptionsTail();CHKERRQ(ierr); 170 PetscFunctionReturn(0); 171 } 172 173 #undef __FUNCT__ 174 #define __FUNCT__ "PCView_LU" 175 static PetscErrorCode PCView_LU(PC pc,PetscViewer viewer) 176 { 177 PC_LU *lu = (PC_LU*)pc->data; 178 PetscErrorCode ierr; 179 PetscTruth iascii,isstring; 180 181 PetscFunctionBegin; 182 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 183 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr); 184 if (iascii) { 185 MatInfo info; 186 187 if (lu->inplace) {ierr = PetscViewerASCIIPrintf(viewer," LU: in-place factorization\n");CHKERRQ(ierr);} 188 else {ierr = PetscViewerASCIIPrintf(viewer," LU: out-of-place factorization\n");CHKERRQ(ierr);} 189 ierr = PetscViewerASCIIPrintf(viewer," matrix ordering: %s\n",lu->ordering);CHKERRQ(ierr); 190 ierr = PetscViewerASCIIPrintf(viewer," LU: tolerance for zero pivot %g\n",lu->info.zeropivot);CHKERRQ(ierr); 191 if (lu->info.shiftpd) {ierr = PetscViewerASCIIPrintf(viewer," LU: using Manteuffel shift\n");CHKERRQ(ierr);} 192 if (lu->fact) { 193 ierr = MatGetInfo(lu->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 194 ierr = PetscViewerASCIIPrintf(viewer," LU nonzeros %g\n",info.nz_used);CHKERRQ(ierr); 195 ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_FACTOR_INFO);CHKERRQ(ierr); 196 ierr = MatView(lu->fact,viewer);CHKERRQ(ierr); 197 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 198 } 199 if (lu->reusefill) {ierr = PetscViewerASCIIPrintf(viewer," Reusing fill from past factorization\n");CHKERRQ(ierr);} 200 if (lu->reuseordering) {ierr = PetscViewerASCIIPrintf(viewer," Reusing reordering from past factorization\n");CHKERRQ(ierr);} 201 } else if (isstring) { 202 ierr = PetscViewerStringSPrintf(viewer," order=%s",lu->ordering);CHKERRQ(ierr);CHKERRQ(ierr); 203 } else { 204 SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCLU",((PetscObject)viewer)->type_name); 205 } 206 PetscFunctionReturn(0); 207 } 208 209 #undef __FUNCT__ 210 #define __FUNCT__ "PCGetFactoredMatrix_LU" 211 static PetscErrorCode PCGetFactoredMatrix_LU(PC pc,Mat *mat) 212 { 213 PC_LU *dir = (PC_LU*)pc->data; 214 215 PetscFunctionBegin; 216 if (!dir->fact) SETERRQ(PETSC_ERR_ORDER,"Matrix not yet factored; call after KSPSetUp() or PCSetUp()"); 217 *mat = dir->fact; 218 PetscFunctionReturn(0); 219 } 220 221 #undef __FUNCT__ 222 #define __FUNCT__ "PCSetUp_LU" 223 static PetscErrorCode PCSetUp_LU(PC pc) 224 { 225 PetscErrorCode ierr; 226 PC_LU *dir = (PC_LU*)pc->data; 227 228 PetscFunctionBegin; 229 if (dir->reusefill && pc->setupcalled) dir->info.fill = dir->actualfill; 230 231 if (dir->inplace) { 232 if (dir->row && dir->col && dir->row != dir->col) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);} 233 if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);} 234 ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr); 235 if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row); CHKERRQ(ierr); ierr = PetscLogObjectParent(pc,dir->col);CHKERRQ(ierr);} 236 ierr = MatLUFactor(pc->pmat,dir->row,dir->col,&dir->info);CHKERRQ(ierr); 237 dir->fact = pc->pmat; 238 } else { 239 MatInfo info; 240 if (!pc->setupcalled) { 241 ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr); 242 if (dir->nonzerosalongdiagonal) { 243 ierr = MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);CHKERRQ(ierr); 244 } 245 if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr); ierr = PetscLogObjectParent(pc,dir->col);CHKERRQ(ierr);} 246 ierr = MatLUFactorSymbolic(pc->pmat,dir->row,dir->col,&dir->info,&dir->fact);CHKERRQ(ierr); 247 ierr = MatGetInfo(dir->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 248 dir->actualfill = info.fill_ratio_needed; 249 ierr = PetscLogObjectParent(pc,dir->fact);CHKERRQ(ierr); 250 } else if (pc->flag != SAME_NONZERO_PATTERN) { 251 if (!dir->reuseordering) { 252 if (dir->row && dir->col && dir->row != dir->col) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);} 253 if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);} 254 ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr); 255 if (dir->nonzerosalongdiagonal) { 256 ierr = MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);CHKERRQ(ierr); 257 } 258 if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);ierr = PetscLogObjectParent(pc,dir->col);CHKERRQ(ierr);} 259 } 260 ierr = MatDestroy(dir->fact);CHKERRQ(ierr); 261 ierr = MatLUFactorSymbolic(pc->pmat,dir->row,dir->col,&dir->info,&dir->fact);CHKERRQ(ierr); 262 ierr = MatGetInfo(dir->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 263 dir->actualfill = info.fill_ratio_needed; 264 ierr = PetscLogObjectParent(pc,dir->fact);CHKERRQ(ierr); 265 } 266 ierr = MatLUFactorNumeric(pc->pmat,&dir->info,&dir->fact);CHKERRQ(ierr); 267 } 268 PetscFunctionReturn(0); 269 } 270 271 #undef __FUNCT__ 272 #define __FUNCT__ "PCDestroy_LU" 273 static PetscErrorCode PCDestroy_LU(PC pc) 274 { 275 PC_LU *dir = (PC_LU*)pc->data; 276 PetscErrorCode ierr; 277 278 PetscFunctionBegin; 279 if (!dir->inplace && dir->fact) {ierr = MatDestroy(dir->fact);CHKERRQ(ierr);} 280 if (dir->row && dir->col && dir->row != dir->col) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);} 281 if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);} 282 ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr); 283 ierr = PetscFree(dir);CHKERRQ(ierr); 284 PetscFunctionReturn(0); 285 } 286 287 #undef __FUNCT__ 288 #define __FUNCT__ "PCApply_LU" 289 static PetscErrorCode PCApply_LU(PC pc,Vec x,Vec y) 290 { 291 PC_LU *dir = (PC_LU*)pc->data; 292 PetscErrorCode ierr; 293 294 PetscFunctionBegin; 295 if (dir->inplace) {ierr = MatSolve(pc->pmat,x,y);CHKERRQ(ierr);} 296 else {ierr = MatSolve(dir->fact,x,y);CHKERRQ(ierr);} 297 PetscFunctionReturn(0); 298 } 299 300 #undef __FUNCT__ 301 #define __FUNCT__ "PCApplyTranspose_LU" 302 static PetscErrorCode PCApplyTranspose_LU(PC pc,Vec x,Vec y) 303 { 304 PC_LU *dir = (PC_LU*)pc->data; 305 PetscErrorCode ierr; 306 307 PetscFunctionBegin; 308 if (dir->inplace) {ierr = MatSolveTranspose(pc->pmat,x,y);CHKERRQ(ierr);} 309 else {ierr = MatSolveTranspose(dir->fact,x,y);CHKERRQ(ierr);} 310 PetscFunctionReturn(0); 311 } 312 313 /* -----------------------------------------------------------------------------------*/ 314 315 EXTERN_C_BEGIN 316 #undef __FUNCT__ 317 #define __FUNCT__ "PCLUSetFill_LU" 318 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetFill_LU(PC pc,PetscReal fill) 319 { 320 PC_LU *dir; 321 322 PetscFunctionBegin; 323 dir = (PC_LU*)pc->data; 324 dir->info.fill = fill; 325 PetscFunctionReturn(0); 326 } 327 EXTERN_C_END 328 329 EXTERN_C_BEGIN 330 #undef __FUNCT__ 331 #define __FUNCT__ "PCLUSetUseInPlace_LU" 332 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetUseInPlace_LU(PC pc) 333 { 334 PC_LU *dir; 335 336 PetscFunctionBegin; 337 dir = (PC_LU*)pc->data; 338 dir->inplace = PETSC_TRUE; 339 PetscFunctionReturn(0); 340 } 341 EXTERN_C_END 342 343 EXTERN_C_BEGIN 344 #undef __FUNCT__ 345 #define __FUNCT__ "PCLUSetMatOrdering_LU" 346 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetMatOrdering_LU(PC pc,MatOrderingType ordering) 347 { 348 PC_LU *dir = (PC_LU*)pc->data; 349 PetscErrorCode ierr; 350 351 PetscFunctionBegin; 352 ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr); 353 ierr = PetscStrallocpy(ordering,&dir->ordering);CHKERRQ(ierr); 354 PetscFunctionReturn(0); 355 } 356 EXTERN_C_END 357 358 EXTERN_C_BEGIN 359 #undef __FUNCT__ 360 #define __FUNCT__ "PCLUSetPivoting_LU" 361 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivoting_LU(PC pc,PetscReal dtcol) 362 { 363 PC_LU *dir = (PC_LU*)pc->data; 364 365 PetscFunctionBegin; 366 if (dtcol < 0.0 || dtcol > 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column pivot tolerance is %g must be between 0 and 1",dtcol); 367 dir->info.dtcol = dtcol; 368 PetscFunctionReturn(0); 369 } 370 EXTERN_C_END 371 372 EXTERN_C_BEGIN 373 #undef __FUNCT__ 374 #define __FUNCT__ "PCLUSetPivotInBlocks_LU" 375 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivotInBlocks_LU(PC pc,PetscTruth pivot) 376 { 377 PC_LU *dir = (PC_LU*)pc->data; 378 379 PetscFunctionBegin; 380 dir->info.pivotinblocks = pivot ? 1.0 : 0.0; 381 PetscFunctionReturn(0); 382 } 383 EXTERN_C_END 384 385 /* -----------------------------------------------------------------------------------*/ 386 387 #undef __FUNCT__ 388 #define __FUNCT__ "PCLUReorderForNonzeroDiagonal" 389 /*@ 390 PCLUReorderForNonzeroDiagonal - reorders rows/columns of matrix to remove zeros from diagonal 391 392 Collective on PC 393 394 Input Parameters: 395 + pc - the preconditioner context 396 - tol - diagonal entries smaller than this in absolute value are considered zero 397 398 Options Database Key: 399 . -pc_lu_nonzeros_along_diagonal 400 401 Level: intermediate 402 403 .keywords: PC, set, factorization, direct, fill 404 405 .seealso: PCLUSetFill(), PCFactorSetShiftNonzero(), PCFactorSetZeroPivot(), MatReorderForNonzeroDiagonal() 406 @*/ 407 PetscErrorCode PETSCKSP_DLLEXPORT PCLUReorderForNonzeroDiagonal(PC pc,PetscReal rtol) 408 { 409 PetscErrorCode ierr,(*f)(PC,PetscReal); 410 411 PetscFunctionBegin; 412 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 413 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUReorderForNonzeroDiagonal_C",(void (**)(void))&f);CHKERRQ(ierr); 414 if (f) { 415 ierr = (*f)(pc,rtol);CHKERRQ(ierr); 416 } 417 PetscFunctionReturn(0); 418 } 419 420 #undef __FUNCT__ 421 #define __FUNCT__ "PCLUSetReuseOrdering" 422 /*@ 423 PCLUSetReuseOrdering - When similar matrices are factored, this 424 causes the ordering computed in the first factor to be used for all 425 following factors; applies to both fill and drop tolerance LUs. 426 427 Collective on PC 428 429 Input Parameters: 430 + pc - the preconditioner context 431 - flag - PETSC_TRUE to reuse else PETSC_FALSE 432 433 Options Database Key: 434 . -pc_lu_reuse_ordering - Activate PCLUSetReuseOrdering() 435 436 Level: intermediate 437 438 .keywords: PC, levels, reordering, factorization, incomplete, LU 439 440 .seealso: PCLUSetReuseFill(), PCILUSetReuseOrdering(), PCILUDTSetReuseFill() 441 @*/ 442 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseOrdering(PC pc,PetscTruth flag) 443 { 444 PetscErrorCode ierr,(*f)(PC,PetscTruth); 445 446 PetscFunctionBegin; 447 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 448 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetReuseOrdering_C",(void (**)(void))&f);CHKERRQ(ierr); 449 if (f) { 450 ierr = (*f)(pc,flag);CHKERRQ(ierr); 451 } 452 PetscFunctionReturn(0); 453 } 454 455 #undef __FUNCT__ 456 #define __FUNCT__ "PCLUSetReuseFill" 457 /*@ 458 PCLUSetReuseFill - When matrices with same nonzero structure are LU factored, 459 this causes later ones to use the fill computed in the initial factorization. 460 461 Collective on PC 462 463 Input Parameters: 464 + pc - the preconditioner context 465 - flag - PETSC_TRUE to reuse else PETSC_FALSE 466 467 Options Database Key: 468 . -pc_lu_reuse_fill - Activates PCLUSetReuseFill() 469 470 Level: intermediate 471 472 .keywords: PC, levels, reordering, factorization, incomplete, LU 473 474 .seealso: PCILUSetReuseOrdering(), PCLUSetReuseOrdering(), PCILUDTSetReuseFill() 475 @*/ 476 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseFill(PC pc,PetscTruth flag) 477 { 478 PetscErrorCode ierr,(*f)(PC,PetscTruth); 479 480 PetscFunctionBegin; 481 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 482 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetReuseFill_C",(void (**)(void))&f);CHKERRQ(ierr); 483 if (f) { 484 ierr = (*f)(pc,flag);CHKERRQ(ierr); 485 } 486 PetscFunctionReturn(0); 487 } 488 489 #undef __FUNCT__ 490 #define __FUNCT__ "PCLUSetFill" 491 /*@ 492 PCLUSetFill - Indicate the amount of fill you expect in the factored matrix, 493 fill = number nonzeros in factor/number nonzeros in original matrix. 494 495 Collective on PC 496 497 Input Parameters: 498 + pc - the preconditioner context 499 - fill - amount of expected fill 500 501 Options Database Key: 502 . -pc_lu_fill <fill> - Sets fill amount 503 504 Level: intermediate 505 506 Note: 507 For sparse matrix factorizations it is difficult to predict how much 508 fill to expect. By running with the option -log_info PETSc will print the 509 actual amount of fill used; allowing you to set the value accurately for 510 future runs. Default PETSc uses a value of 5.0 511 512 .keywords: PC, set, factorization, direct, fill 513 514 .seealso: PCILUSetFill() 515 @*/ 516 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetFill(PC pc,PetscReal fill) 517 { 518 PetscErrorCode ierr,(*f)(PC,PetscReal); 519 520 PetscFunctionBegin; 521 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 522 if (fill < 1.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Fill factor cannot be less then 1.0"); 523 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetFill_C",(void (**)(void))&f);CHKERRQ(ierr); 524 if (f) { 525 ierr = (*f)(pc,fill);CHKERRQ(ierr); 526 } 527 PetscFunctionReturn(0); 528 } 529 530 #undef __FUNCT__ 531 #define __FUNCT__ "PCLUSetUseInPlace" 532 /*@ 533 PCLUSetUseInPlace - Tells the system to do an in-place factorization. 534 For dense matrices, this enables the solution of much larger problems. 535 For sparse matrices the factorization cannot be done truly in-place 536 so this does not save memory during the factorization, but after the matrix 537 is factored, the original unfactored matrix is freed, thus recovering that 538 space. 539 540 Collective on PC 541 542 Input Parameters: 543 . pc - the preconditioner context 544 545 Options Database Key: 546 . -pc_lu_in_place - Activates in-place factorization 547 548 Notes: 549 PCLUSetUseInplace() can only be used with the KSP method KSPPREONLY or when 550 a different matrix is provided for the multiply and the preconditioner in 551 a call to KSPSetOperators(). 552 This is because the Krylov space methods require an application of the 553 matrix multiplication, which is not possible here because the matrix has 554 been factored in-place, replacing the original matrix. 555 556 Level: intermediate 557 558 .keywords: PC, set, factorization, direct, inplace, in-place, LU 559 560 .seealso: PCILUSetUseInPlace() 561 @*/ 562 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetUseInPlace(PC pc) 563 { 564 PetscErrorCode ierr,(*f)(PC); 565 566 PetscFunctionBegin; 567 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 568 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetUseInPlace_C",(void (**)(void))&f);CHKERRQ(ierr); 569 if (f) { 570 ierr = (*f)(pc);CHKERRQ(ierr); 571 } 572 PetscFunctionReturn(0); 573 } 574 575 #undef __FUNCT__ 576 #define __FUNCT__ "PCLUSetMatOrdering" 577 /*@C 578 PCLUSetMatOrdering - Sets the ordering routine (to reduce fill) to 579 be used in the LU factorization. 580 581 Collective on PC 582 583 Input Parameters: 584 + pc - the preconditioner context 585 - ordering - the matrix ordering name, for example, MATORDERING_ND or MATORDERING_RCM 586 587 Options Database Key: 588 . -pc_lu_mat_ordering_type <nd,rcm,...> - Sets ordering routine 589 590 Level: intermediate 591 592 Notes: nested dissection is used by default 593 594 .seealso: PCILUSetMatOrdering() 595 @*/ 596 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetMatOrdering(PC pc,MatOrderingType ordering) 597 { 598 PetscErrorCode ierr,(*f)(PC,MatOrderingType); 599 600 PetscFunctionBegin; 601 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetMatOrdering_C",(void (**)(void))&f);CHKERRQ(ierr); 602 if (f) { 603 ierr = (*f)(pc,ordering);CHKERRQ(ierr); 604 } 605 PetscFunctionReturn(0); 606 } 607 608 #undef __FUNCT__ 609 #define __FUNCT__ "PCLUSetPivoting" 610 /*@ 611 PCLUSetPivoting - Determines when pivoting is done during LU. 612 For PETSc dense matrices column pivoting is always done, for PETSc sparse matrices 613 it is never done. For the Matlab and SuperLU factorization this is used. 614 615 Collective on PC 616 617 Input Parameters: 618 + pc - the preconditioner context 619 - dtcol - 0.0 implies no pivoting, 1.0 complete pivoting (slower, requires more memory but more stable) 620 621 Options Database Key: 622 . -pc_lu_pivoting <dtcol> 623 624 Level: intermediate 625 626 .seealso: PCILUSetMatOrdering(), PCLUSetPivotInBlocks() 627 @*/ 628 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivoting(PC pc,PetscReal dtcol) 629 { 630 PetscErrorCode ierr,(*f)(PC,PetscReal); 631 632 PetscFunctionBegin; 633 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetPivoting_C",(void (**)(void))&f);CHKERRQ(ierr); 634 if (f) { 635 ierr = (*f)(pc,dtcol);CHKERRQ(ierr); 636 } 637 PetscFunctionReturn(0); 638 } 639 640 #undef __FUNCT__ 641 #define __FUNCT__ "PCLUSetPivotInBlocks" 642 /*@ 643 PCLUSetPivotInBlocks - Determines if pivoting is done while factoring each block 644 with BAIJ or SBAIJ matrices 645 646 Collective on PC 647 648 Input Parameters: 649 + pc - the preconditioner context 650 - pivot - PETSC_TRUE or PETSC_FALSE 651 652 Options Database Key: 653 . -pc_lu_pivot_in_blocks <true,false> 654 655 Level: intermediate 656 657 .seealso: PCILUSetMatOrdering(), PCLUSetPivoting() 658 @*/ 659 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivotInBlocks(PC pc,PetscTruth pivot) 660 { 661 PetscErrorCode ierr,(*f)(PC,PetscTruth); 662 663 PetscFunctionBegin; 664 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetPivotInBlocks_C",(void (**)(void))&f);CHKERRQ(ierr); 665 if (f) { 666 ierr = (*f)(pc,pivot);CHKERRQ(ierr); 667 } 668 PetscFunctionReturn(0); 669 } 670 671 /* ------------------------------------------------------------------------ */ 672 673 /*MC 674 PCLU - Uses a direct solver, based on LU factorization, as a preconditioner 675 676 Options Database Keys: 677 + -pc_lu_reuse_ordering - Activate PCLUSetReuseOrdering() 678 . -pc_lu_reuse_fill - Activates PCLUSetReuseFill() 679 . -pc_lu_fill <fill> - Sets fill amount 680 . -pc_lu_in_place - Activates in-place factorization 681 . -pc_lu_mat_ordering_type <nd,rcm,...> - Sets ordering routine 682 . -pc_lu_pivot_in_blocks <true,false> - allow pivoting within the small blocks during factorization (may increase 683 stability of factorization. 684 . -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default 685 - -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value 686 is optional with PETSC_TRUE being the default 687 688 Notes: Not all options work for all matrix formats 689 Run with -help to see additional options for particular matrix formats or factorization 690 algorithms 691 692 Level: beginner 693 694 Concepts: LU factorization, direct solver 695 696 Notes: Usually this will compute an "exact" solution in one iteration and does 697 not need a Krylov method (i.e. you can use -ksp_type preonly, or 698 KSPSetType(ksp,KSPPREONLY) for the Krylov method 699 700 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 701 PCILU, PCCHOLESKY, PCICC, PCLUSetReuseOrdering(), PCLUSetReuseFill(), PCGetFactoredMatrix(), 702 PCLUSetFill(), PCLUSetUseInPlace(), PCLUSetMatOrdering(), PCFactorSetPivoting(), 703 PCLUSetPivotingInBlocks(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd() 704 M*/ 705 706 EXTERN_C_BEGIN 707 #undef __FUNCT__ 708 #define __FUNCT__ "PCCreate_LU" 709 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_LU(PC pc) 710 { 711 PetscErrorCode ierr; 712 PetscMPIInt size; 713 PC_LU *dir; 714 715 PetscFunctionBegin; 716 ierr = PetscNew(PC_LU,&dir);CHKERRQ(ierr); 717 ierr = PetscLogObjectMemory(pc,sizeof(PC_LU));CHKERRQ(ierr); 718 719 ierr = MatFactorInfoInitialize(&dir->info);CHKERRQ(ierr); 720 dir->fact = 0; 721 dir->inplace = PETSC_FALSE; 722 dir->nonzerosalongdiagonal = PETSC_FALSE; 723 724 dir->info.fill = 5.0; 725 dir->info.dtcol = 1.e-6; /* default to pivoting; this is only thing PETSc LU supports */ 726 dir->info.shiftnz = 0.0; 727 dir->info.zeropivot = 1.e-12; 728 dir->info.pivotinblocks = 1.0; 729 dir->info.shiftpd = 0.0; /* false */ 730 dir->info.shift_fraction = 0.0; 731 dir->col = 0; 732 dir->row = 0; 733 ierr = MPI_Comm_size(pc->comm,&size);CHKERRQ(ierr); 734 if (size == 1) { 735 ierr = PetscStrallocpy(MATORDERING_ND,&dir->ordering);CHKERRQ(ierr); 736 } else { 737 ierr = PetscStrallocpy(MATORDERING_NATURAL,&dir->ordering);CHKERRQ(ierr); 738 } 739 dir->reusefill = PETSC_FALSE; 740 dir->reuseordering = PETSC_FALSE; 741 pc->data = (void*)dir; 742 743 pc->ops->destroy = PCDestroy_LU; 744 pc->ops->apply = PCApply_LU; 745 pc->ops->applytranspose = PCApplyTranspose_LU; 746 pc->ops->setup = PCSetUp_LU; 747 pc->ops->setfromoptions = PCSetFromOptions_LU; 748 pc->ops->view = PCView_LU; 749 pc->ops->applyrichardson = 0; 750 pc->ops->getfactoredmatrix = PCGetFactoredMatrix_LU; 751 752 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_LU", 753 PCFactorSetZeroPivot_LU);CHKERRQ(ierr); 754 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_LU", 755 PCFactorSetShiftNonzero_LU);CHKERRQ(ierr); 756 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_LU", 757 PCFactorSetShiftPd_LU);CHKERRQ(ierr); 758 759 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetFill_C","PCLUSetFill_LU", 760 PCLUSetFill_LU);CHKERRQ(ierr); 761 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetUseInPlace_C","PCLUSetUseInPlace_LU", 762 PCLUSetUseInPlace_LU);CHKERRQ(ierr); 763 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetMatOrdering_C","PCLUSetMatOrdering_LU", 764 PCLUSetMatOrdering_LU);CHKERRQ(ierr); 765 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetReuseOrdering_C","PCLUSetReuseOrdering_LU", 766 PCLUSetReuseOrdering_LU);CHKERRQ(ierr); 767 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetReuseFill_C","PCLUSetReuseFill_LU", 768 PCLUSetReuseFill_LU);CHKERRQ(ierr); 769 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetPivoting_C","PCLUSetPivoting_LU", 770 PCLUSetPivoting_LU);CHKERRQ(ierr); 771 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetPivotInBlocks_C","PCLUSetPivotInBlocks_LU", 772 PCLUSetPivotInBlocks_LU);CHKERRQ(ierr); 773 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUReorderForNonzeroDiagonal_C","PCLUReorderForNonzeroDiagonal_LU", 774 PCLUReorderForNonzeroDiagonal_LU);CHKERRQ(ierr); 775 PetscFunctionReturn(0); 776 } 777 EXTERN_C_END 778