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 "private/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) { 236 ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr); 237 ierr = PetscLogObjectParent(pc,dir->col);CHKERRQ(ierr); 238 } 239 ierr = MatLUFactor(pc->pmat,dir->row,dir->col,&dir->info);CHKERRQ(ierr); 240 dir->fact = pc->pmat; 241 } else { 242 MatInfo info; 243 if (!pc->setupcalled) { 244 ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr); 245 if (dir->nonzerosalongdiagonal) { 246 ierr = MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);CHKERRQ(ierr); 247 } 248 if (dir->row) { 249 ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr); 250 ierr = PetscLogObjectParent(pc,dir->col);CHKERRQ(ierr); 251 } 252 ierr = MatLUFactorSymbolic(pc->pmat,dir->row,dir->col,&dir->info,&dir->fact);CHKERRQ(ierr); 253 ierr = MatGetInfo(dir->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 254 dir->actualfill = info.fill_ratio_needed; 255 ierr = PetscLogObjectParent(pc,dir->fact);CHKERRQ(ierr); 256 } else if (pc->flag != SAME_NONZERO_PATTERN) { 257 if (!dir->reuseordering) { 258 if (dir->row && dir->col && dir->row != dir->col) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);} 259 if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);} 260 ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr); 261 if (dir->nonzerosalongdiagonal) { 262 ierr = MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);CHKERRQ(ierr); 263 } 264 if (dir->row) { 265 ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr); 266 ierr = PetscLogObjectParent(pc,dir->col);CHKERRQ(ierr); 267 } 268 } 269 ierr = MatDestroy(dir->fact);CHKERRQ(ierr); 270 ierr = MatLUFactorSymbolic(pc->pmat,dir->row,dir->col,&dir->info,&dir->fact);CHKERRQ(ierr); 271 ierr = MatGetInfo(dir->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 272 dir->actualfill = info.fill_ratio_needed; 273 ierr = PetscLogObjectParent(pc,dir->fact);CHKERRQ(ierr); 274 } 275 ierr = MatLUFactorNumeric(pc->pmat,&dir->info,&dir->fact);CHKERRQ(ierr); 276 } 277 PetscFunctionReturn(0); 278 } 279 280 #undef __FUNCT__ 281 #define __FUNCT__ "PCDestroy_LU" 282 static PetscErrorCode PCDestroy_LU(PC pc) 283 { 284 PC_LU *dir = (PC_LU*)pc->data; 285 PetscErrorCode ierr; 286 287 PetscFunctionBegin; 288 if (!dir->inplace && dir->fact) {ierr = MatDestroy(dir->fact);CHKERRQ(ierr);} 289 if (dir->row && dir->col && dir->row != dir->col) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);} 290 if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);} 291 ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr); 292 ierr = PetscFree(dir);CHKERRQ(ierr); 293 PetscFunctionReturn(0); 294 } 295 296 #undef __FUNCT__ 297 #define __FUNCT__ "PCApply_LU" 298 static PetscErrorCode PCApply_LU(PC pc,Vec x,Vec y) 299 { 300 PC_LU *dir = (PC_LU*)pc->data; 301 PetscErrorCode ierr; 302 303 PetscFunctionBegin; 304 if (dir->inplace) {ierr = MatSolve(pc->pmat,x,y);CHKERRQ(ierr);} 305 else {ierr = MatSolve(dir->fact,x,y);CHKERRQ(ierr);} 306 PetscFunctionReturn(0); 307 } 308 309 #undef __FUNCT__ 310 #define __FUNCT__ "PCApplyTranspose_LU" 311 static PetscErrorCode PCApplyTranspose_LU(PC pc,Vec x,Vec y) 312 { 313 PC_LU *dir = (PC_LU*)pc->data; 314 PetscErrorCode ierr; 315 316 PetscFunctionBegin; 317 if (dir->inplace) {ierr = MatSolveTranspose(pc->pmat,x,y);CHKERRQ(ierr);} 318 else {ierr = MatSolveTranspose(dir->fact,x,y);CHKERRQ(ierr);} 319 PetscFunctionReturn(0); 320 } 321 322 /* -----------------------------------------------------------------------------------*/ 323 324 EXTERN_C_BEGIN 325 #undef __FUNCT__ 326 #define __FUNCT__ "PCLUSetFill_LU" 327 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetFill_LU(PC pc,PetscReal fill) 328 { 329 PC_LU *dir; 330 331 PetscFunctionBegin; 332 dir = (PC_LU*)pc->data; 333 dir->info.fill = fill; 334 PetscFunctionReturn(0); 335 } 336 EXTERN_C_END 337 338 EXTERN_C_BEGIN 339 #undef __FUNCT__ 340 #define __FUNCT__ "PCLUSetUseInPlace_LU" 341 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetUseInPlace_LU(PC pc) 342 { 343 PC_LU *dir; 344 345 PetscFunctionBegin; 346 dir = (PC_LU*)pc->data; 347 dir->inplace = PETSC_TRUE; 348 PetscFunctionReturn(0); 349 } 350 EXTERN_C_END 351 352 EXTERN_C_BEGIN 353 #undef __FUNCT__ 354 #define __FUNCT__ "PCLUSetMatOrdering_LU" 355 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetMatOrdering_LU(PC pc,MatOrderingType ordering) 356 { 357 PC_LU *dir = (PC_LU*)pc->data; 358 PetscErrorCode ierr; 359 360 PetscFunctionBegin; 361 ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr); 362 ierr = PetscStrallocpy(ordering,&dir->ordering);CHKERRQ(ierr); 363 PetscFunctionReturn(0); 364 } 365 EXTERN_C_END 366 367 EXTERN_C_BEGIN 368 #undef __FUNCT__ 369 #define __FUNCT__ "PCLUSetPivoting_LU" 370 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivoting_LU(PC pc,PetscReal dtcol) 371 { 372 PC_LU *dir = (PC_LU*)pc->data; 373 374 PetscFunctionBegin; 375 if (dtcol < 0.0 || dtcol > 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column pivot tolerance is %G must be between 0 and 1",dtcol); 376 dir->info.dtcol = dtcol; 377 PetscFunctionReturn(0); 378 } 379 EXTERN_C_END 380 381 EXTERN_C_BEGIN 382 #undef __FUNCT__ 383 #define __FUNCT__ "PCLUSetPivotInBlocks_LU" 384 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivotInBlocks_LU(PC pc,PetscTruth pivot) 385 { 386 PC_LU *dir = (PC_LU*)pc->data; 387 388 PetscFunctionBegin; 389 dir->info.pivotinblocks = pivot ? 1.0 : 0.0; 390 PetscFunctionReturn(0); 391 } 392 EXTERN_C_END 393 394 /* -----------------------------------------------------------------------------------*/ 395 396 #undef __FUNCT__ 397 #define __FUNCT__ "PCLUReorderForNonzeroDiagonal" 398 /*@ 399 PCLUReorderForNonzeroDiagonal - reorders rows/columns of matrix to remove zeros from diagonal 400 401 Collective on PC 402 403 Input Parameters: 404 + pc - the preconditioner context 405 - tol - diagonal entries smaller than this in absolute value are considered zero 406 407 Options Database Key: 408 . -pc_lu_nonzeros_along_diagonal 409 410 Level: intermediate 411 412 .keywords: PC, set, factorization, direct, fill 413 414 .seealso: PCLUSetFill(), PCFactorSetShiftNonzero(), PCFactorSetZeroPivot(), MatReorderForNonzeroDiagonal() 415 @*/ 416 PetscErrorCode PETSCKSP_DLLEXPORT PCLUReorderForNonzeroDiagonal(PC pc,PetscReal rtol) 417 { 418 PetscErrorCode ierr,(*f)(PC,PetscReal); 419 420 PetscFunctionBegin; 421 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 422 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUReorderForNonzeroDiagonal_C",(void (**)(void))&f);CHKERRQ(ierr); 423 if (f) { 424 ierr = (*f)(pc,rtol);CHKERRQ(ierr); 425 } 426 PetscFunctionReturn(0); 427 } 428 429 #undef __FUNCT__ 430 #define __FUNCT__ "PCLUSetReuseOrdering" 431 /*@ 432 PCLUSetReuseOrdering - When similar matrices are factored, this 433 causes the ordering computed in the first factor to be used for all 434 following factors; applies to both fill and drop tolerance LUs. 435 436 Collective on PC 437 438 Input Parameters: 439 + pc - the preconditioner context 440 - flag - PETSC_TRUE to reuse else PETSC_FALSE 441 442 Options Database Key: 443 . -pc_lu_reuse_ordering - Activate PCLUSetReuseOrdering() 444 445 Level: intermediate 446 447 .keywords: PC, levels, reordering, factorization, incomplete, LU 448 449 .seealso: PCLUSetReuseFill(), PCILUSetReuseOrdering(), PCILUDTSetReuseFill() 450 @*/ 451 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseOrdering(PC pc,PetscTruth flag) 452 { 453 PetscErrorCode ierr,(*f)(PC,PetscTruth); 454 455 PetscFunctionBegin; 456 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 457 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetReuseOrdering_C",(void (**)(void))&f);CHKERRQ(ierr); 458 if (f) { 459 ierr = (*f)(pc,flag);CHKERRQ(ierr); 460 } 461 PetscFunctionReturn(0); 462 } 463 464 #undef __FUNCT__ 465 #define __FUNCT__ "PCLUSetReuseFill" 466 /*@ 467 PCLUSetReuseFill - When matrices with same nonzero structure are LU factored, 468 this causes later ones to use the fill computed in the initial factorization. 469 470 Collective on PC 471 472 Input Parameters: 473 + pc - the preconditioner context 474 - flag - PETSC_TRUE to reuse else PETSC_FALSE 475 476 Options Database Key: 477 . -pc_lu_reuse_fill - Activates PCLUSetReuseFill() 478 479 Level: intermediate 480 481 .keywords: PC, levels, reordering, factorization, incomplete, LU 482 483 .seealso: PCILUSetReuseOrdering(), PCLUSetReuseOrdering(), PCILUDTSetReuseFill() 484 @*/ 485 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseFill(PC pc,PetscTruth flag) 486 { 487 PetscErrorCode ierr,(*f)(PC,PetscTruth); 488 489 PetscFunctionBegin; 490 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 491 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetReuseFill_C",(void (**)(void))&f);CHKERRQ(ierr); 492 if (f) { 493 ierr = (*f)(pc,flag);CHKERRQ(ierr); 494 } 495 PetscFunctionReturn(0); 496 } 497 498 #undef __FUNCT__ 499 #define __FUNCT__ "PCLUSetFill" 500 /*@ 501 PCLUSetFill - Indicate the amount of fill you expect in the factored matrix, 502 fill = number nonzeros in factor/number nonzeros in original matrix. 503 504 Collective on PC 505 506 Input Parameters: 507 + pc - the preconditioner context 508 - fill - amount of expected fill 509 510 Options Database Key: 511 . -pc_lu_fill <fill> - Sets fill amount 512 513 Level: intermediate 514 515 Note: 516 For sparse matrix factorizations it is difficult to predict how much 517 fill to expect. By running with the option -verbose_info PETSc will print the 518 actual amount of fill used; allowing you to set the value accurately for 519 future runs. Default PETSc uses a value of 5.0 520 521 .keywords: PC, set, factorization, direct, fill 522 523 .seealso: PCILUSetFill() 524 @*/ 525 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetFill(PC pc,PetscReal fill) 526 { 527 PetscErrorCode ierr,(*f)(PC,PetscReal); 528 529 PetscFunctionBegin; 530 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 531 if (fill < 1.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Fill factor cannot be less then 1.0"); 532 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetFill_C",(void (**)(void))&f);CHKERRQ(ierr); 533 if (f) { 534 ierr = (*f)(pc,fill);CHKERRQ(ierr); 535 } 536 PetscFunctionReturn(0); 537 } 538 539 #undef __FUNCT__ 540 #define __FUNCT__ "PCLUSetUseInPlace" 541 /*@ 542 PCLUSetUseInPlace - Tells the system to do an in-place factorization. 543 For dense matrices, this enables the solution of much larger problems. 544 For sparse matrices the factorization cannot be done truly in-place 545 so this does not save memory during the factorization, but after the matrix 546 is factored, the original unfactored matrix is freed, thus recovering that 547 space. 548 549 Collective on PC 550 551 Input Parameters: 552 . pc - the preconditioner context 553 554 Options Database Key: 555 . -pc_lu_in_place - Activates in-place factorization 556 557 Notes: 558 PCLUSetUseInplace() can only be used with the KSP method KSPPREONLY or when 559 a different matrix is provided for the multiply and the preconditioner in 560 a call to KSPSetOperators(). 561 This is because the Krylov space methods require an application of the 562 matrix multiplication, which is not possible here because the matrix has 563 been factored in-place, replacing the original matrix. 564 565 Level: intermediate 566 567 .keywords: PC, set, factorization, direct, inplace, in-place, LU 568 569 .seealso: PCILUSetUseInPlace() 570 @*/ 571 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetUseInPlace(PC pc) 572 { 573 PetscErrorCode ierr,(*f)(PC); 574 575 PetscFunctionBegin; 576 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 577 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetUseInPlace_C",(void (**)(void))&f);CHKERRQ(ierr); 578 if (f) { 579 ierr = (*f)(pc);CHKERRQ(ierr); 580 } 581 PetscFunctionReturn(0); 582 } 583 584 #undef __FUNCT__ 585 #define __FUNCT__ "PCLUSetMatOrdering" 586 /*@C 587 PCLUSetMatOrdering - Sets the ordering routine (to reduce fill) to 588 be used in the LU factorization. 589 590 Collective on PC 591 592 Input Parameters: 593 + pc - the preconditioner context 594 - ordering - the matrix ordering name, for example, MATORDERING_ND or MATORDERING_RCM 595 596 Options Database Key: 597 . -pc_lu_mat_ordering_type <nd,rcm,...> - Sets ordering routine 598 599 Level: intermediate 600 601 Notes: nested dissection is used by default 602 603 .seealso: PCILUSetMatOrdering() 604 @*/ 605 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetMatOrdering(PC pc,MatOrderingType ordering) 606 { 607 PetscErrorCode ierr,(*f)(PC,MatOrderingType); 608 609 PetscFunctionBegin; 610 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetMatOrdering_C",(void (**)(void))&f);CHKERRQ(ierr); 611 if (f) { 612 ierr = (*f)(pc,ordering);CHKERRQ(ierr); 613 } 614 PetscFunctionReturn(0); 615 } 616 617 #undef __FUNCT__ 618 #define __FUNCT__ "PCLUSetPivoting" 619 /*@ 620 PCLUSetPivoting - Determines when pivoting is done during LU. 621 For PETSc dense matrices column pivoting is always done, for PETSc sparse matrices 622 it is never done. For the Matlab and SuperLU factorization this is used. 623 624 Collective on PC 625 626 Input Parameters: 627 + pc - the preconditioner context 628 - dtcol - 0.0 implies no pivoting, 1.0 complete pivoting (slower, requires more memory but more stable) 629 630 Options Database Key: 631 . -pc_lu_pivoting <dtcol> 632 633 Level: intermediate 634 635 .seealso: PCILUSetMatOrdering(), PCLUSetPivotInBlocks() 636 @*/ 637 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivoting(PC pc,PetscReal dtcol) 638 { 639 PetscErrorCode ierr,(*f)(PC,PetscReal); 640 641 PetscFunctionBegin; 642 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetPivoting_C",(void (**)(void))&f);CHKERRQ(ierr); 643 if (f) { 644 ierr = (*f)(pc,dtcol);CHKERRQ(ierr); 645 } 646 PetscFunctionReturn(0); 647 } 648 649 #undef __FUNCT__ 650 #define __FUNCT__ "PCLUSetPivotInBlocks" 651 /*@ 652 PCLUSetPivotInBlocks - Determines if pivoting is done while factoring each block 653 with BAIJ or SBAIJ matrices 654 655 Collective on PC 656 657 Input Parameters: 658 + pc - the preconditioner context 659 - pivot - PETSC_TRUE or PETSC_FALSE 660 661 Options Database Key: 662 . -pc_lu_pivot_in_blocks <true,false> 663 664 Level: intermediate 665 666 .seealso: PCILUSetMatOrdering(), PCLUSetPivoting() 667 @*/ 668 PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivotInBlocks(PC pc,PetscTruth pivot) 669 { 670 PetscErrorCode ierr,(*f)(PC,PetscTruth); 671 672 PetscFunctionBegin; 673 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCLUSetPivotInBlocks_C",(void (**)(void))&f);CHKERRQ(ierr); 674 if (f) { 675 ierr = (*f)(pc,pivot);CHKERRQ(ierr); 676 } 677 PetscFunctionReturn(0); 678 } 679 680 /* ------------------------------------------------------------------------ */ 681 682 /*MC 683 PCLU - Uses a direct solver, based on LU factorization, as a preconditioner 684 685 Options Database Keys: 686 + -pc_lu_reuse_ordering - Activate PCLUSetReuseOrdering() 687 . -pc_lu_reuse_fill - Activates PCLUSetReuseFill() 688 . -pc_lu_fill <fill> - Sets fill amount 689 . -pc_lu_in_place - Activates in-place factorization 690 . -pc_lu_mat_ordering_type <nd,rcm,...> - Sets ordering routine 691 . -pc_lu_pivot_in_blocks <true,false> - allow pivoting within the small blocks during factorization (may increase 692 stability of factorization. 693 . -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default 694 - -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value 695 is optional with PETSC_TRUE being the default 696 697 Notes: Not all options work for all matrix formats 698 Run with -help to see additional options for particular matrix formats or factorization 699 algorithms 700 701 Level: beginner 702 703 Concepts: LU factorization, direct solver 704 705 Notes: Usually this will compute an "exact" solution in one iteration and does 706 not need a Krylov method (i.e. you can use -ksp_type preonly, or 707 KSPSetType(ksp,KSPPREONLY) for the Krylov method 708 709 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 710 PCILU, PCCHOLESKY, PCICC, PCLUSetReuseOrdering(), PCLUSetReuseFill(), PCGetFactoredMatrix(), 711 PCLUSetFill(), PCLUSetUseInPlace(), PCLUSetMatOrdering(), PCFactorSetPivoting(), 712 PCLUSetPivotingInBlocks(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd() 713 M*/ 714 715 EXTERN_C_BEGIN 716 #undef __FUNCT__ 717 #define __FUNCT__ "PCCreate_LU" 718 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_LU(PC pc) 719 { 720 PetscErrorCode ierr; 721 PetscMPIInt size; 722 PC_LU *dir; 723 724 PetscFunctionBegin; 725 ierr = PetscNew(PC_LU,&dir);CHKERRQ(ierr); 726 ierr = PetscLogObjectMemory(pc,sizeof(PC_LU));CHKERRQ(ierr); 727 728 ierr = MatFactorInfoInitialize(&dir->info);CHKERRQ(ierr); 729 dir->fact = 0; 730 dir->inplace = PETSC_FALSE; 731 dir->nonzerosalongdiagonal = PETSC_FALSE; 732 733 dir->info.fill = 5.0; 734 dir->info.dtcol = 1.e-6; /* default to pivoting; this is only thing PETSc LU supports */ 735 dir->info.shiftnz = 0.0; 736 dir->info.zeropivot = 1.e-12; 737 dir->info.pivotinblocks = 1.0; 738 dir->info.shiftpd = 0.0; /* false */ 739 dir->info.shift_fraction = 0.0; 740 dir->col = 0; 741 dir->row = 0; 742 ierr = MPI_Comm_size(pc->comm,&size);CHKERRQ(ierr); 743 if (size == 1) { 744 ierr = PetscStrallocpy(MATORDERING_ND,&dir->ordering);CHKERRQ(ierr); 745 } else { 746 ierr = PetscStrallocpy(MATORDERING_NATURAL,&dir->ordering);CHKERRQ(ierr); 747 } 748 dir->reusefill = PETSC_FALSE; 749 dir->reuseordering = PETSC_FALSE; 750 pc->data = (void*)dir; 751 752 pc->ops->destroy = PCDestroy_LU; 753 pc->ops->apply = PCApply_LU; 754 pc->ops->applytranspose = PCApplyTranspose_LU; 755 pc->ops->setup = PCSetUp_LU; 756 pc->ops->setfromoptions = PCSetFromOptions_LU; 757 pc->ops->view = PCView_LU; 758 pc->ops->applyrichardson = 0; 759 pc->ops->getfactoredmatrix = PCGetFactoredMatrix_LU; 760 761 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_LU", 762 PCFactorSetZeroPivot_LU);CHKERRQ(ierr); 763 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_LU", 764 PCFactorSetShiftNonzero_LU);CHKERRQ(ierr); 765 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_LU", 766 PCFactorSetShiftPd_LU);CHKERRQ(ierr); 767 768 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetFill_C","PCLUSetFill_LU", 769 PCLUSetFill_LU);CHKERRQ(ierr); 770 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetUseInPlace_C","PCLUSetUseInPlace_LU", 771 PCLUSetUseInPlace_LU);CHKERRQ(ierr); 772 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetMatOrdering_C","PCLUSetMatOrdering_LU", 773 PCLUSetMatOrdering_LU);CHKERRQ(ierr); 774 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetReuseOrdering_C","PCLUSetReuseOrdering_LU", 775 PCLUSetReuseOrdering_LU);CHKERRQ(ierr); 776 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetReuseFill_C","PCLUSetReuseFill_LU", 777 PCLUSetReuseFill_LU);CHKERRQ(ierr); 778 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetPivoting_C","PCLUSetPivoting_LU", 779 PCLUSetPivoting_LU);CHKERRQ(ierr); 780 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetPivotInBlocks_C","PCLUSetPivotInBlocks_LU", 781 PCLUSetPivotInBlocks_LU);CHKERRQ(ierr); 782 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUReorderForNonzeroDiagonal_C","PCLUReorderForNonzeroDiagonal_LU", 783 PCLUReorderForNonzeroDiagonal_LU);CHKERRQ(ierr); 784 PetscFunctionReturn(0); 785 } 786 EXTERN_C_END 787