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