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 #include "private/pcimpl.h" /*I "petscpc.h" I*/ 9 10 typedef struct { 11 Mat fact; /* factored matrix */ 12 PetscReal actualfill; /* actual fill in factor */ 13 PetscTruth inplace; /* flag indicating in-place factorization */ 14 IS row,col; /* index sets used for reordering */ 15 MatOrderingType ordering; /* matrix ordering */ 16 PetscTruth reuseordering; /* reuses previous reordering computed */ 17 PetscTruth reusefill; /* reuse fill from previous Cholesky */ 18 MatFactorInfo info; 19 } PC_Cholesky; 20 21 EXTERN_C_BEGIN 22 #undef __FUNCT__ 23 #define __FUNCT__ "PCFactorSetZeroPivot_Cholesky" 24 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetZeroPivot_Cholesky(PC pc,PetscReal z) 25 { 26 PC_Cholesky *ch; 27 28 PetscFunctionBegin; 29 ch = (PC_Cholesky*)pc->data; 30 ch->info.zeropivot = z; 31 PetscFunctionReturn(0); 32 } 33 EXTERN_C_END 34 35 EXTERN_C_BEGIN 36 #undef __FUNCT__ 37 #define __FUNCT__ "PCFactorSetShiftNonzero_Cholesky" 38 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftNonzero_Cholesky(PC pc,PetscReal shift) 39 { 40 PC_Cholesky *dir; 41 42 PetscFunctionBegin; 43 dir = (PC_Cholesky*)pc->data; 44 if (shift == (PetscReal) PETSC_DECIDE) { 45 dir->info.shiftnz = 1.e-12; 46 } else { 47 dir->info.shiftnz = shift; 48 } 49 PetscFunctionReturn(0); 50 } 51 EXTERN_C_END 52 53 EXTERN_C_BEGIN 54 #undef __FUNCT__ 55 #define __FUNCT__ "PCFactorSetShiftPd_Cholesky" 56 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftPd_Cholesky(PC pc,PetscTruth shift) 57 { 58 PC_Cholesky *dir; 59 60 PetscFunctionBegin; 61 dir = (PC_Cholesky*)pc->data; 62 if (shift) { 63 dir->info.shift_fraction = 0.0; 64 dir->info.shiftpd = 1.0; 65 } else { 66 dir->info.shiftpd = 0.0; 67 } 68 PetscFunctionReturn(0); 69 } 70 EXTERN_C_END 71 72 EXTERN_C_BEGIN 73 #undef __FUNCT__ 74 #define __FUNCT__ "PCCholeskySetReuseOrdering_Cholesky" 75 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetReuseOrdering_Cholesky(PC pc,PetscTruth flag) 76 { 77 PC_Cholesky *lu; 78 79 PetscFunctionBegin; 80 lu = (PC_Cholesky*)pc->data; 81 lu->reuseordering = flag; 82 PetscFunctionReturn(0); 83 } 84 EXTERN_C_END 85 86 EXTERN_C_BEGIN 87 #undef __FUNCT__ 88 #define __FUNCT__ "PCCholeskySetReuseFill_Cholesky" 89 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetReuseFill_Cholesky(PC pc,PetscTruth flag) 90 { 91 PC_Cholesky *lu; 92 93 PetscFunctionBegin; 94 lu = (PC_Cholesky*)pc->data; 95 lu->reusefill = flag; 96 PetscFunctionReturn(0); 97 } 98 EXTERN_C_END 99 100 #undef __FUNCT__ 101 #define __FUNCT__ "PCSetFromOptions_Cholesky" 102 static PetscErrorCode PCSetFromOptions_Cholesky(PC pc) 103 { 104 PC_Cholesky *lu = (PC_Cholesky*)pc->data; 105 PetscErrorCode ierr; 106 PetscTruth flg; 107 char tname[256]; 108 PetscFList ordlist; 109 110 PetscFunctionBegin; 111 ierr = MatOrderingRegisterAll(PETSC_NULL);CHKERRQ(ierr); 112 ierr = PetscOptionsHead("Cholesky options");CHKERRQ(ierr); 113 ierr = PetscOptionsName("-pc_cholesky_in_place","Form Cholesky in the same memory as the matrix","PCCholeskySetUseInPlace",&flg);CHKERRQ(ierr); 114 if (flg) { 115 ierr = PCCholeskySetUseInPlace(pc);CHKERRQ(ierr); 116 } 117 ierr = PetscOptionsReal("-pc_cholesky_fill","Expected non-zeros in Cholesky/non-zeros in matrix","PCCholeskySetFill",lu->info.fill,&lu->info.fill,0);CHKERRQ(ierr); 118 119 ierr = PetscOptionsName("-pc_cholesky_reuse_fill","Use fill from previous factorization","PCCholeskySetReuseFill",&flg);CHKERRQ(ierr); 120 if (flg) { 121 ierr = PCCholeskySetReuseFill(pc,PETSC_TRUE);CHKERRQ(ierr); 122 } 123 ierr = PetscOptionsName("-pc_cholesky_reuse_ordering","Reuse ordering from previous factorization","PCCholeskySetReuseOrdering",&flg);CHKERRQ(ierr); 124 if (flg) { 125 ierr = PCCholeskySetReuseOrdering(pc,PETSC_TRUE);CHKERRQ(ierr); 126 } 127 128 ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr); 129 ierr = PetscOptionsList("-pc_cholesky_mat_ordering_type","Reordering to reduce nonzeros in Cholesky","PCCholeskySetMatOrdering",ordlist,lu->ordering,tname,256,&flg);CHKERRQ(ierr); 130 if (flg) { 131 ierr = PCCholeskySetMatOrdering(pc,tname);CHKERRQ(ierr); 132 } 133 ierr = PetscOptionsName("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",&flg);CHKERRQ(ierr); 134 if (flg) { 135 ierr = PCFactorSetShiftNonzero(pc,(PetscReal) PETSC_DECIDE);CHKERRQ(ierr); 136 } 137 ierr = PetscOptionsReal("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",lu->info.shiftnz,&lu->info.shiftnz,0);CHKERRQ(ierr); 138 ierr = PetscOptionsName("-pc_factor_shift_positive_definite","Manteuffel shift applied to diagonal","PCFactorSetShiftPd",&flg);CHKERRQ(ierr); 139 if (flg) { 140 ierr = PCFactorSetShiftPd(pc,PETSC_TRUE);CHKERRQ(ierr); 141 } 142 ierr = PetscOptionsReal("-pc_factor_zeropivot","Pivot is considered zero if less than","PCFactorSetZeroPivot",lu->info.zeropivot,&lu->info.zeropivot,0);CHKERRQ(ierr); 143 144 ierr = PetscOptionsTail();CHKERRQ(ierr); 145 PetscFunctionReturn(0); 146 } 147 148 #undef __FUNCT__ 149 #define __FUNCT__ "PCView_Cholesky" 150 static PetscErrorCode PCView_Cholesky(PC pc,PetscViewer viewer) 151 { 152 PC_Cholesky *lu = (PC_Cholesky*)pc->data; 153 PetscErrorCode ierr; 154 PetscTruth iascii,isstring; 155 156 PetscFunctionBegin; 157 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 158 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr); 159 if (iascii) { 160 MatInfo info; 161 162 if (lu->inplace) {ierr = PetscViewerASCIIPrintf(viewer," Cholesky: in-place factorization\n");CHKERRQ(ierr);} 163 else {ierr = PetscViewerASCIIPrintf(viewer," Cholesky: out-of-place factorization\n");CHKERRQ(ierr);} 164 ierr = PetscViewerASCIIPrintf(viewer," matrix ordering: %s\n",lu->ordering);CHKERRQ(ierr); 165 if (lu->fact) { 166 ierr = MatGetInfo(lu->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 167 ierr = PetscViewerASCIIPrintf(viewer," Cholesky nonzeros %g\n",info.nz_used);CHKERRQ(ierr); 168 ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_FACTOR_INFO);CHKERRQ(ierr); 169 ierr = MatView(lu->fact,viewer);CHKERRQ(ierr); 170 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 171 } 172 if (lu->reusefill) {ierr = PetscViewerASCIIPrintf(viewer," Reusing fill from past factorization\n");CHKERRQ(ierr);} 173 if (lu->reuseordering) {ierr = PetscViewerASCIIPrintf(viewer," Reusing reordering from past factorization\n");CHKERRQ(ierr);} 174 } else if (isstring) { 175 ierr = PetscViewerStringSPrintf(viewer," order=%s",lu->ordering);CHKERRQ(ierr);CHKERRQ(ierr); 176 } else { 177 SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCCholesky",((PetscObject)viewer)->type_name); 178 } 179 PetscFunctionReturn(0); 180 } 181 182 #undef __FUNCT__ 183 #define __FUNCT__ "PCGetFactoredMatrix_Cholesky" 184 static PetscErrorCode PCGetFactoredMatrix_Cholesky(PC pc,Mat *mat) 185 { 186 PC_Cholesky *dir = (PC_Cholesky*)pc->data; 187 188 PetscFunctionBegin; 189 if (!dir->fact) SETERRQ(PETSC_ERR_ORDER,"Matrix not yet factored; call after KSPSetUp() or PCSetUp()"); 190 *mat = dir->fact; 191 PetscFunctionReturn(0); 192 } 193 194 #undef __FUNCT__ 195 #define __FUNCT__ "PCSetUp_Cholesky" 196 static PetscErrorCode PCSetUp_Cholesky(PC pc) 197 { 198 PetscErrorCode ierr; 199 PetscTruth flg; 200 PC_Cholesky *dir = (PC_Cholesky*)pc->data; 201 202 PetscFunctionBegin; 203 if (dir->reusefill && pc->setupcalled) dir->info.fill = dir->actualfill; 204 205 if (dir->inplace) { 206 if (dir->row && dir->col && (dir->row != dir->col)) { 207 ierr = ISDestroy(dir->row);CHKERRQ(ierr); 208 dir->row = 0; 209 } 210 if (dir->col) { 211 ierr = ISDestroy(dir->col);CHKERRQ(ierr); 212 dir->col = 0; 213 } 214 ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr); 215 if (dir->col && (dir->row != dir->col)) { /* only use row ordering for SBAIJ */ 216 ierr = ISDestroy(dir->col);CHKERRQ(ierr); 217 dir->col=0; 218 } 219 if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);} 220 ierr = MatCholeskyFactor(pc->pmat,dir->row,&dir->info);CHKERRQ(ierr); 221 dir->fact = pc->pmat; 222 } else { 223 MatInfo info; 224 if (!pc->setupcalled) { 225 ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr); 226 if (dir->col && (dir->row != dir->col)) { /* only use row ordering for SBAIJ */ 227 ierr = ISDestroy(dir->col);CHKERRQ(ierr); 228 dir->col=0; 229 } 230 ierr = PetscOptionsHasName(pc->prefix,"-pc_cholesky_nonzeros_along_diagonal",&flg);CHKERRQ(ierr); 231 if (flg) { 232 PetscReal tol = 1.e-10; 233 ierr = PetscOptionsGetReal(pc->prefix,"-pc_cholesky_nonzeros_along_diagonal",&tol,PETSC_NULL);CHKERRQ(ierr); 234 ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);CHKERRQ(ierr); 235 } 236 if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);} 237 ierr = MatCholeskyFactorSymbolic(pc->pmat,dir->row,&dir->info,&dir->fact);CHKERRQ(ierr); 238 ierr = MatGetInfo(dir->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 239 dir->actualfill = info.fill_ratio_needed; 240 ierr = PetscLogObjectParent(pc,dir->fact);CHKERRQ(ierr); 241 } else if (pc->flag != SAME_NONZERO_PATTERN) { 242 if (!dir->reuseordering) { 243 if (dir->row && dir->col && (dir->row != dir->col)) { 244 ierr = ISDestroy(dir->row);CHKERRQ(ierr); 245 dir->row = 0; 246 } 247 if (dir->col) { 248 ierr = ISDestroy(dir->col);CHKERRQ(ierr); 249 dir->col =0; 250 } 251 ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr); 252 if (dir->col && (dir->row != dir->col)) { /* only use row ordering for SBAIJ */ 253 ierr = ISDestroy(dir->col);CHKERRQ(ierr); 254 dir->col=0; 255 } 256 ierr = PetscOptionsHasName(pc->prefix,"-pc_cholesky_nonzeros_along_diagonal",&flg);CHKERRQ(ierr); 257 if (flg) { 258 PetscReal tol = 1.e-10; 259 ierr = PetscOptionsGetReal(pc->prefix,"-pc_cholesky_nonzeros_along_diagonal",&tol,PETSC_NULL);CHKERRQ(ierr); 260 ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);CHKERRQ(ierr); 261 } 262 if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);} 263 } 264 ierr = MatDestroy(dir->fact);CHKERRQ(ierr); 265 ierr = MatCholeskyFactorSymbolic(pc->pmat,dir->row,&dir->info,&dir->fact);CHKERRQ(ierr); 266 ierr = MatGetInfo(dir->fact,MAT_LOCAL,&info);CHKERRQ(ierr); 267 dir->actualfill = info.fill_ratio_needed; 268 ierr = PetscLogObjectParent(pc,dir->fact);CHKERRQ(ierr); 269 } 270 ierr = MatCholeskyFactorNumeric(pc->pmat,&dir->info,&dir->fact);CHKERRQ(ierr); 271 } 272 PetscFunctionReturn(0); 273 } 274 275 #undef __FUNCT__ 276 #define __FUNCT__ "PCDestroy_Cholesky" 277 static PetscErrorCode PCDestroy_Cholesky(PC pc) 278 { 279 PC_Cholesky *dir = (PC_Cholesky*)pc->data; 280 PetscErrorCode ierr; 281 282 PetscFunctionBegin; 283 if (!dir->inplace && dir->fact) {ierr = MatDestroy(dir->fact);CHKERRQ(ierr);} 284 if (dir->row) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);} 285 if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);} 286 ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr); 287 ierr = PetscFree(dir);CHKERRQ(ierr); 288 PetscFunctionReturn(0); 289 } 290 291 #undef __FUNCT__ 292 #define __FUNCT__ "PCApply_Cholesky" 293 static PetscErrorCode PCApply_Cholesky(PC pc,Vec x,Vec y) 294 { 295 PC_Cholesky *dir = (PC_Cholesky*)pc->data; 296 PetscErrorCode ierr; 297 298 PetscFunctionBegin; 299 if (dir->inplace) {ierr = MatSolve(pc->pmat,x,y);CHKERRQ(ierr);} 300 else {ierr = MatSolve(dir->fact,x,y);CHKERRQ(ierr);} 301 PetscFunctionReturn(0); 302 } 303 304 #undef __FUNCT__ 305 #define __FUNCT__ "PCApplyTranspose_Cholesky" 306 static PetscErrorCode PCApplyTranspose_Cholesky(PC pc,Vec x,Vec y) 307 { 308 PC_Cholesky *dir = (PC_Cholesky*)pc->data; 309 PetscErrorCode ierr; 310 311 PetscFunctionBegin; 312 if (dir->inplace) {ierr = MatSolveTranspose(pc->pmat,x,y);CHKERRQ(ierr);} 313 else {ierr = MatSolveTranspose(dir->fact,x,y);CHKERRQ(ierr);} 314 PetscFunctionReturn(0); 315 } 316 317 /* -----------------------------------------------------------------------------------*/ 318 319 EXTERN_C_BEGIN 320 #undef __FUNCT__ 321 #define __FUNCT__ "PCCholeskySetFill_Cholesky" 322 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetFill_Cholesky(PC pc,PetscReal fill) 323 { 324 PC_Cholesky *dir; 325 326 PetscFunctionBegin; 327 dir = (PC_Cholesky*)pc->data; 328 dir->info.fill = fill; 329 PetscFunctionReturn(0); 330 } 331 EXTERN_C_END 332 333 EXTERN_C_BEGIN 334 #undef __FUNCT__ 335 #define __FUNCT__ "PCCholeskySetUseInPlace_Cholesky" 336 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetUseInPlace_Cholesky(PC pc) 337 { 338 PC_Cholesky *dir; 339 340 PetscFunctionBegin; 341 dir = (PC_Cholesky*)pc->data; 342 dir->inplace = PETSC_TRUE; 343 PetscFunctionReturn(0); 344 } 345 EXTERN_C_END 346 347 EXTERN_C_BEGIN 348 #undef __FUNCT__ 349 #define __FUNCT__ "PCCholeskySetMatOrdering_Cholesky" 350 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetMatOrdering_Cholesky(PC pc,MatOrderingType ordering) 351 { 352 PC_Cholesky *dir = (PC_Cholesky*)pc->data; 353 PetscErrorCode ierr; 354 355 PetscFunctionBegin; 356 ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr); 357 ierr = PetscStrallocpy(ordering,&dir->ordering);CHKERRQ(ierr); 358 PetscFunctionReturn(0); 359 } 360 EXTERN_C_END 361 362 /* -----------------------------------------------------------------------------------*/ 363 364 #undef __FUNCT__ 365 #define __FUNCT__ "PCCholeskySetReuseOrdering" 366 /*@ 367 PCCholeskySetReuseOrdering - When similar matrices are factored, this 368 causes the ordering computed in the first factor to be used for all 369 following factors. 370 371 Collective on PC 372 373 Input Parameters: 374 + pc - the preconditioner context 375 - flag - PETSC_TRUE to reuse else PETSC_FALSE 376 377 Options Database Key: 378 . -pc_cholesky_reuse_ordering - Activate PCCholeskySetReuseOrdering() 379 380 Level: intermediate 381 382 .keywords: PC, levels, reordering, factorization, incomplete, LU 383 384 .seealso: PCCholeskySetReuseFill(), PCICholeskySetReuseOrdering(), PCICholeskyDTSetReuseFill() 385 @*/ 386 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetReuseOrdering(PC pc,PetscTruth flag) 387 { 388 PetscErrorCode ierr,(*f)(PC,PetscTruth); 389 390 PetscFunctionBegin; 391 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 392 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCCholeskySetReuseOrdering_C",(void (**)(void))&f);CHKERRQ(ierr); 393 if (f) { 394 ierr = (*f)(pc,flag);CHKERRQ(ierr); 395 } 396 PetscFunctionReturn(0); 397 } 398 399 #undef __FUNCT__ 400 #define __FUNCT__ "PCCholeskySetReuseFill" 401 /*@ 402 PCCholeskySetReuseFill - When matrices with same nonzero structure are Cholesky factored, 403 this causes later ones to use the fill computed in the initial factorization. 404 405 Collective on PC 406 407 Input Parameters: 408 + pc - the preconditioner context 409 - flag - PETSC_TRUE to reuse else PETSC_FALSE 410 411 Options Database Key: 412 . -pc_cholesky_reuse_fill - Activates PCCholeskySetReuseFill() 413 414 Level: intermediate 415 416 .keywords: PC, levels, reordering, factorization, incomplete, Cholesky 417 418 .seealso: PCICholeskySetReuseOrdering(), PCCholeskySetReuseOrdering(), PCICholeskyDTSetReuseFill() 419 @*/ 420 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetReuseFill(PC pc,PetscTruth flag) 421 { 422 PetscErrorCode ierr,(*f)(PC,PetscTruth); 423 424 PetscFunctionBegin; 425 PetscValidHeaderSpecific(pc,PC_COOKIE,2); 426 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCCholeskySetReuseFill_C",(void (**)(void))&f);CHKERRQ(ierr); 427 if (f) { 428 ierr = (*f)(pc,flag);CHKERRQ(ierr); 429 } 430 PetscFunctionReturn(0); 431 } 432 433 #undef __FUNCT__ 434 #define __FUNCT__ "PCCholeskySetFill" 435 /*@ 436 PCCholeskySetFill - Indicates the amount of fill you expect in the factored matrix, 437 fill = number nonzeros in factor/number nonzeros in original matrix. 438 439 Collective on PC 440 441 Input Parameters: 442 + pc - the preconditioner context 443 - fill - amount of expected fill 444 445 Options Database Key: 446 . -pc_cholesky_fill <fill> - Sets fill amount 447 448 Level: intermediate 449 450 Note: 451 For sparse matrix factorizations it is difficult to predict how much 452 fill to expect. By running with the option -log_info PETSc will print the 453 actual amount of fill used; allowing you to set the value accurately for 454 future runs. Default PETSc uses a value of 5.0 455 456 .keywords: PC, set, factorization, direct, fill 457 458 .seealso: PCILUSetFill() 459 @*/ 460 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetFill(PC pc,PetscReal fill) 461 { 462 PetscErrorCode ierr,(*f)(PC,PetscReal); 463 464 PetscFunctionBegin; 465 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 466 if (fill < 1.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Fill factor cannot be less then 1.0"); 467 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCCholeskySetFill_C",(void (**)(void))&f);CHKERRQ(ierr); 468 if (f) { 469 ierr = (*f)(pc,fill);CHKERRQ(ierr); 470 } 471 PetscFunctionReturn(0); 472 } 473 474 #undef __FUNCT__ 475 #define __FUNCT__ "PCCholeskySetUseInPlace" 476 /*@ 477 PCCholeskySetUseInPlace - Tells the system to do an in-place factorization. 478 For dense matrices, this enables the solution of much larger problems. 479 For sparse matrices the factorization cannot be done truly in-place 480 so this does not save memory during the factorization, but after the matrix 481 is factored, the original unfactored matrix is freed, thus recovering that 482 space. 483 484 Collective on PC 485 486 Input Parameters: 487 . pc - the preconditioner context 488 489 Options Database Key: 490 . -pc_cholesky_in_place - Activates in-place factorization 491 492 Notes: 493 PCCholeskySetUseInplace() can only be used with the KSP method KSPPREONLY or when 494 a different matrix is provided for the multiply and the preconditioner in 495 a call to KSPSetOperators(). 496 This is because the Krylov space methods require an application of the 497 matrix multiplication, which is not possible here because the matrix has 498 been factored in-place, replacing the original matrix. 499 500 Level: intermediate 501 502 .keywords: PC, set, factorization, direct, inplace, in-place, Cholesky 503 504 .seealso: PCICholeskySetUseInPlace() 505 @*/ 506 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetUseInPlace(PC pc) 507 { 508 PetscErrorCode ierr,(*f)(PC); 509 510 PetscFunctionBegin; 511 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 512 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCCholeskySetUseInPlace_C",(void (**)(void))&f);CHKERRQ(ierr); 513 if (f) { 514 ierr = (*f)(pc);CHKERRQ(ierr); 515 } 516 PetscFunctionReturn(0); 517 } 518 519 #undef __FUNCT__ 520 #define __FUNCT__ "PCCholeskySetMatOrdering" 521 /*@ 522 PCCholeskySetMatOrdering - Sets the ordering routine (to reduce fill) to 523 be used it the Cholesky factorization. 524 525 Collective on PC 526 527 Input Parameters: 528 + pc - the preconditioner context 529 - ordering - the matrix ordering name, for example, MATORDERING_ND or MATORDERING_RCM 530 531 Options Database Key: 532 . -pc_cholesky_mat_ordering_type <nd,rcm,...> - Sets ordering routine 533 534 Level: intermediate 535 536 .seealso: PCICholeskySetMatOrdering() 537 @*/ 538 PetscErrorCode PETSCKSP_DLLEXPORT PCCholeskySetMatOrdering(PC pc,MatOrderingType ordering) 539 { 540 PetscErrorCode ierr,(*f)(PC,MatOrderingType); 541 542 PetscFunctionBegin; 543 ierr = PetscObjectQueryFunction((PetscObject)pc,"PCCholeskySetMatOrdering_C",(void (**)(void))&f);CHKERRQ(ierr); 544 if (f) { 545 ierr = (*f)(pc,ordering);CHKERRQ(ierr); 546 } 547 PetscFunctionReturn(0); 548 } 549 550 /*MC 551 PCCholesky - Uses a direct solver, based on Cholesky factorization, as a preconditioner 552 553 Options Database Keys: 554 + -pc_cholesky_reuse_ordering - Activate PCLUSetReuseOrdering() 555 . -pc_cholesky_reuse_fill - Activates PCLUSetReuseFill() 556 . -pc_cholesky_fill <fill> - Sets fill amount 557 . -pc_cholesky_in_place - Activates in-place factorization 558 . -pc_cholesky_mat_ordering_type <nd,rcm,...> - Sets ordering routine 559 . -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default 560 - -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value 561 is optional with PETSC_TRUE being the default 562 563 Notes: Not all options work for all matrix formats 564 565 Level: beginner 566 567 Concepts: Cholesky factorization, direct solver 568 569 Notes: Usually this will compute an "exact" solution in one iteration and does 570 not need a Krylov method (i.e. you can use -ksp_type preonly, or 571 KSPSetType(ksp,KSPPREONLY) for the Krylov method 572 573 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 574 PCILU, PCLU, PCICC, PCCholeskySetReuseOrdering(), PCCholeskySetReuseFill(), PCGetFactoredMatrix(), 575 PCCholeskySetFill(), PCFactorSetShiftNonzero(), PCFactorSetShiftPd(), 576 PCCholeskySetUseInPlace(), PCCholeskySetMatOrdering(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd() 577 578 M*/ 579 580 EXTERN_C_BEGIN 581 #undef __FUNCT__ 582 #define __FUNCT__ "PCCreate_Cholesky" 583 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Cholesky(PC pc) 584 { 585 PetscErrorCode ierr; 586 PC_Cholesky *dir; 587 588 PetscFunctionBegin; 589 ierr = PetscNew(PC_Cholesky,&dir);CHKERRQ(ierr); 590 ierr = PetscLogObjectMemory(pc,sizeof(PC_Cholesky));CHKERRQ(ierr); 591 592 dir->fact = 0; 593 dir->inplace = PETSC_FALSE; 594 ierr = MatFactorInfoInitialize(&dir->info);CHKERRQ(ierr); 595 dir->info.fill = 5.0; 596 dir->info.shiftnz = 0.0; 597 dir->info.shiftpd = 0.0; /* false */ 598 dir->info.shift_fraction = 0.0; 599 dir->info.pivotinblocks = 1.0; 600 dir->col = 0; 601 dir->row = 0; 602 ierr = PetscStrallocpy(MATORDERING_NATURAL,&dir->ordering);CHKERRQ(ierr); 603 dir->reusefill = PETSC_FALSE; 604 dir->reuseordering = PETSC_FALSE; 605 pc->data = (void*)dir; 606 607 pc->ops->destroy = PCDestroy_Cholesky; 608 pc->ops->apply = PCApply_Cholesky; 609 pc->ops->applytranspose = PCApplyTranspose_Cholesky; 610 pc->ops->setup = PCSetUp_Cholesky; 611 pc->ops->setfromoptions = PCSetFromOptions_Cholesky; 612 pc->ops->view = PCView_Cholesky; 613 pc->ops->applyrichardson = 0; 614 pc->ops->getfactoredmatrix = PCGetFactoredMatrix_Cholesky; 615 616 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_Cholesky", 617 PCFactorSetZeroPivot_Cholesky);CHKERRQ(ierr); 618 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_Cholesky", 619 PCFactorSetShiftNonzero_Cholesky);CHKERRQ(ierr); 620 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_Cholesky", 621 PCFactorSetShiftPd_Cholesky);CHKERRQ(ierr); 622 623 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCCholeskySetFill_C","PCCholeskySetFill_Cholesky", 624 PCCholeskySetFill_Cholesky);CHKERRQ(ierr); 625 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCCholeskySetUseInPlace_C","PCCholeskySetUseInPlace_Cholesky", 626 PCCholeskySetUseInPlace_Cholesky);CHKERRQ(ierr); 627 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCCholeskySetMatOrdering_C","PCCholeskySetMatOrdering_Cholesky", 628 PCCholeskySetMatOrdering_Cholesky);CHKERRQ(ierr); 629 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCCholeskySetReuseOrdering_C","PCCholeskySetReuseOrdering_Cholesky", 630 PCCholeskySetReuseOrdering_Cholesky);CHKERRQ(ierr); 631 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCCholeskySetReuseFill_C","PCCholeskySetReuseFill_Cholesky", 632 PCCholeskySetReuseFill_Cholesky);CHKERRQ(ierr); 633 PetscFunctionReturn(0); 634 } 635 EXTERN_C_END 636