Actual source code: lu.c

  1: #define PETSCKSP_DLL

  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: */

 9:  #include src/ksp/pc/pcimpl.h
 10:  #include src/ksp/pc/impls/factor/lu/lu.h

 15: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetZeroPivot_LU(PC pc,PetscReal z)
 16: {
 17:   PC_LU *lu;

 20:   lu                 = (PC_LU*)pc->data;
 21:   lu->info.zeropivot = z;
 22:   return(0);
 23: }

 29: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftNonzero_LU(PC pc,PetscReal shift)
 30: {
 31:   PC_LU *dir;

 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:   return(0);
 41: }

 47: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftPd_LU(PC pc,PetscTruth shift)
 48: {
 49:   PC_LU *dir;
 50: 
 52:   dir = (PC_LU*)pc->data;
 53:   dir->info.shiftpd = shift;
 54:   if (shift) dir->info.shift_fraction = 0.0;
 55:   return(0);
 56: }

 62: PetscErrorCode PETSCKSP_DLLEXPORT PCLUReorderForNonzeroDiagonal_LU(PC pc,PetscReal z)
 63: {
 64:   PC_LU *lu = (PC_LU*)pc->data;

 67:   lu->nonzerosalongdiagonal = PETSC_TRUE;
 68:   if (z == PETSC_DECIDE) {
 69:     lu->nonzerosalongdiagonaltol = 1.e-10;
 70:   } else {
 71:     lu->nonzerosalongdiagonaltol = z;
 72:   }
 73:   return(0);
 74: }

 80: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseOrdering_LU(PC pc,PetscTruth flag)
 81: {
 82:   PC_LU *lu;

 85:   lu                = (PC_LU*)pc->data;
 86:   lu->reuseordering = flag;
 87:   return(0);
 88: }

 94: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseFill_LU(PC pc,PetscTruth flag)
 95: {
 96:   PC_LU *lu;

 99:   lu = (PC_LU*)pc->data;
100:   lu->reusefill = flag;
101:   return(0);
102: }

107: static PetscErrorCode PCSetFromOptions_LU(PC pc)
108: {
109:   PC_LU          *lu = (PC_LU*)pc->data;
111:   PetscTruth     flg,set;
112:   char           tname[256];
113:   PetscFList     ordlist;
114:   PetscReal      tol;

117:   MatOrderingRegisterAll(PETSC_NULL);
118:   PetscOptionsHead("LU options");
119:     PetscOptionsName("-pc_lu_in_place","Form LU in the same memory as the matrix","PCLUSetUseInPlace",&flg);
120:     if (flg) {
121:       PCLUSetUseInPlace(pc);
122:     }
123:     PetscOptionsReal("-pc_lu_fill","Expected non-zeros in LU/non-zeros in matrix","PCLUSetFill",lu->info.fill,&lu->info.fill,0);

125:     PetscOptionsName("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",&flg);
126:     if (flg) {
127:         PCFactorSetShiftNonzero(pc,(PetscReal) PETSC_DECIDE);
128:     }
129:     PetscOptionsReal("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",lu->info.shiftnz,&lu->info.shiftnz,0);
130:     PetscOptionsName("-pc_factor_shift_positive_definite","Manteuffel shift applied to diagonal","PCFactorSetShiftPd",&flg);
131:     if (flg) {
132:       PCFactorSetShiftPd(pc,PETSC_TRUE);
133:     }
134:     PetscOptionsReal("-pc_factor_zeropivot","Pivot is considered zero if less than","PCFactorSetZeroPivot",lu->info.zeropivot,&lu->info.zeropivot,0);

136:     PetscOptionsName("-pc_lu_reuse_fill","Use fill from previous factorization","PCLUSetReuseFill",&flg);
137:     if (flg) {
138:       PCLUSetReuseFill(pc,PETSC_TRUE);
139:     }
140:     PetscOptionsName("-pc_lu_reuse_ordering","Reuse ordering from previous factorization","PCLUSetReuseOrdering",&flg);
141:     if (flg) {
142:       PCLUSetReuseOrdering(pc,PETSC_TRUE);
143:     }

145:     MatGetOrderingList(&ordlist);
146:     PetscOptionsList("-pc_lu_mat_ordering_type","Reordering to reduce nonzeros in LU","PCLUSetMatOrdering",ordlist,lu->ordering,tname,256,&flg);
147:     if (flg) {
148:       PCLUSetMatOrdering(pc,tname);
149:     }

151:     PetscOptionsName("-pc_lu_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCLUReorderForNonzeroDiagonal",&flg);
152:     if (flg) {
153:       tol = PETSC_DECIDE;
154:       PetscOptionsReal("-pc_lu_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCLUReorderForNonzeroDiagonal",lu->nonzerosalongdiagonaltol,&tol,0);
155:       PCLUReorderForNonzeroDiagonal(pc,tol);
156:     }

158:     PetscOptionsReal("-pc_lu_pivoting","Pivoting tolerance (used only for some factorization)","PCLUSetPivoting",lu->info.dtcol,&lu->info.dtcol,&flg);

160:     flg = lu->info.pivotinblocks ? PETSC_TRUE : PETSC_FALSE;
161:     PetscOptionsTruth("-pc_lu_pivot_in_blocks","Pivot inside matrix blocks for BAIJ and SBAIJ","PCLUSetPivotInBlocks",flg,&flg,&set);
162:     if (set) {
163:       PCLUSetPivotInBlocks(pc,flg);
164:     }
165:   PetscOptionsTail();
166:   return(0);
167: }

171: static PetscErrorCode PCView_LU(PC pc,PetscViewer viewer)
172: {
173:   PC_LU          *lu = (PC_LU*)pc->data;
175:   PetscTruth     iascii,isstring;

178:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
179:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
180:   if (iascii) {
181:     MatInfo info;

183:     if (lu->inplace) {PetscViewerASCIIPrintf(viewer,"  LU: in-place factorization\n");}
184:     else             {PetscViewerASCIIPrintf(viewer,"  LU: out-of-place factorization\n");}
185:     PetscViewerASCIIPrintf(viewer,"    matrix ordering: %s\n",lu->ordering);
186:     PetscViewerASCIIPrintf(viewer,"  LU: tolerance for zero pivot %g\n",lu->info.zeropivot);
187:     if (lu->info.shiftpd) {PetscViewerASCIIPrintf(viewer,"  LU: using Manteuffel shift\n");}
188:     if (lu->fact) {
189:       MatGetInfo(lu->fact,MAT_LOCAL,&info);
190:       PetscViewerASCIIPrintf(viewer,"    LU nonzeros %g\n",info.nz_used);
191:       PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_FACTOR_INFO);
192:       MatView(lu->fact,viewer);
193:       PetscViewerPopFormat(viewer);
194:     }
195:     if (lu->reusefill)    {PetscViewerASCIIPrintf(viewer,"       Reusing fill from past factorization\n");}
196:     if (lu->reuseordering) {PetscViewerASCIIPrintf(viewer,"       Reusing reordering from past factorization\n");}
197:   } else if (isstring) {
198:     PetscViewerStringSPrintf(viewer," order=%s",lu->ordering);
199:   } else {
200:     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCLU",((PetscObject)viewer)->type_name);
201:   }
202:   return(0);
203: }

207: static PetscErrorCode PCGetFactoredMatrix_LU(PC pc,Mat *mat)
208: {
209:   PC_LU *dir = (PC_LU*)pc->data;

212:   if (!dir->fact) SETERRQ(PETSC_ERR_ORDER,"Matrix not yet factored; call after KSPSetUp() or PCSetUp()");
213:   *mat = dir->fact;
214:   return(0);
215: }

219: static PetscErrorCode PCSetUp_LU(PC pc)
220: {
222:   PC_LU          *dir = (PC_LU*)pc->data;

225:   if (dir->reusefill && pc->setupcalled) dir->info.fill = dir->actualfill;

227:   if (dir->inplace) {
228:     if (dir->row && dir->col && dir->row != dir->col) {ISDestroy(dir->row);}
229:     if (dir->col) {ISDestroy(dir->col);}
230:     MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);
231:     if (dir->row) {PetscLogObjectParent(pc,dir->row);  PetscLogObjectParent(pc,dir->col);}
232:     MatLUFactor(pc->pmat,dir->row,dir->col,&dir->info);
233:     dir->fact = pc->pmat;
234:   } else {
235:     MatInfo info;
236:     if (!pc->setupcalled) {
237:       MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);
238:       if (dir->nonzerosalongdiagonal) {
239:         MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);
240:       }
241:       if (dir->row) {PetscLogObjectParent(pc,dir->row); PetscLogObjectParent(pc,dir->col);}
242:       MatLUFactorSymbolic(pc->pmat,dir->row,dir->col,&dir->info,&dir->fact);
243:       MatGetInfo(dir->fact,MAT_LOCAL,&info);
244:       dir->actualfill = info.fill_ratio_needed;
245:       PetscLogObjectParent(pc,dir->fact);
246:     } else if (pc->flag != SAME_NONZERO_PATTERN) {
247:       if (!dir->reuseordering) {
248:         if (dir->row && dir->col && dir->row != dir->col) {ISDestroy(dir->row);}
249:         if (dir->col) {ISDestroy(dir->col);}
250:         MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);
251:         if (dir->nonzerosalongdiagonal) {
252:          MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);
253:         }
254:         if (dir->row) {PetscLogObjectParent(pc,dir->row); PetscLogObjectParent(pc,dir->col);}
255:       }
256:       MatDestroy(dir->fact);
257:       MatLUFactorSymbolic(pc->pmat,dir->row,dir->col,&dir->info,&dir->fact);
258:       MatGetInfo(dir->fact,MAT_LOCAL,&info);
259:       dir->actualfill = info.fill_ratio_needed;
260:       PetscLogObjectParent(pc,dir->fact);
261:     }
262:     MatLUFactorNumeric(pc->pmat,&dir->info,&dir->fact);
263:   }
264:   return(0);
265: }

269: static PetscErrorCode PCDestroy_LU(PC pc)
270: {
271:   PC_LU          *dir = (PC_LU*)pc->data;

275:   if (!dir->inplace && dir->fact) {MatDestroy(dir->fact);}
276:   if (dir->row && dir->col && dir->row != dir->col) {ISDestroy(dir->row);}
277:   if (dir->col) {ISDestroy(dir->col);}
278:   PetscStrfree(dir->ordering);
279:   PetscFree(dir);
280:   return(0);
281: }

285: static PetscErrorCode PCApply_LU(PC pc,Vec x,Vec y)
286: {
287:   PC_LU          *dir = (PC_LU*)pc->data;

291:   if (dir->inplace) {MatSolve(pc->pmat,x,y);}
292:   else              {MatSolve(dir->fact,x,y);}
293:   return(0);
294: }

298: static PetscErrorCode PCApplyTranspose_LU(PC pc,Vec x,Vec y)
299: {
300:   PC_LU          *dir = (PC_LU*)pc->data;

304:   if (dir->inplace) {MatSolveTranspose(pc->pmat,x,y);}
305:   else              {MatSolveTranspose(dir->fact,x,y);}
306:   return(0);
307: }

309: /* -----------------------------------------------------------------------------------*/

314: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetFill_LU(PC pc,PetscReal fill)
315: {
316:   PC_LU *dir;

319:   dir = (PC_LU*)pc->data;
320:   dir->info.fill = fill;
321:   return(0);
322: }

328: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetUseInPlace_LU(PC pc)
329: {
330:   PC_LU *dir;

333:   dir = (PC_LU*)pc->data;
334:   dir->inplace = PETSC_TRUE;
335:   return(0);
336: }

342: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetMatOrdering_LU(PC pc,MatOrderingType ordering)
343: {
344:   PC_LU          *dir = (PC_LU*)pc->data;

348:   PetscStrfree(dir->ordering);
349:   PetscStrallocpy(ordering,&dir->ordering);
350:   return(0);
351: }

357: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivoting_LU(PC pc,PetscReal dtcol)
358: {
359:   PC_LU *dir = (PC_LU*)pc->data;

362:   if (dtcol < 0.0 || dtcol > 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column pivot tolerance is %g must be between 0 and 1",dtcol);
363:   dir->info.dtcol = dtcol;
364:   return(0);
365: }

371: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivotInBlocks_LU(PC pc,PetscTruth pivot)
372: {
373:   PC_LU *dir = (PC_LU*)pc->data;

376:   dir->info.pivotinblocks = pivot ? 1.0 : 0.0;
377:   return(0);
378: }

381: /* -----------------------------------------------------------------------------------*/

385: /*@
386:    PCLUReorderForNonzeroDiagonal - reorders rows/columns of matrix to remove zeros from diagonal

388:    Collective on PC
389:    
390:    Input Parameters:
391: +  pc - the preconditioner context
392: -  tol - diagonal entries smaller than this in absolute value are considered zero

394:    Options Database Key:
395: .  -pc_lu_nonzeros_along_diagonal

397:    Level: intermediate

399: .keywords: PC, set, factorization, direct, fill

401: .seealso: PCLUSetFill(), PCFactorSetShiftNonzero(), PCFactorSetZeroPivot(), MatReorderForNonzeroDiagonal()
402: @*/
403: PetscErrorCode PETSCKSP_DLLEXPORT PCLUReorderForNonzeroDiagonal(PC pc,PetscReal rtol)
404: {
405:   PetscErrorCode ierr,(*f)(PC,PetscReal);

409:   PetscObjectQueryFunction((PetscObject)pc,"PCLUReorderForNonzeroDiagonal_C",(void (**)(void))&f);
410:   if (f) {
411:     (*f)(pc,rtol);
412:   }
413:   return(0);
414: }

418: /*@
419:    PCLUSetReuseOrdering - When similar matrices are factored, this
420:    causes the ordering computed in the first factor to be used for all
421:    following factors; applies to both fill and drop tolerance LUs.

423:    Collective on PC

425:    Input Parameters:
426: +  pc - the preconditioner context
427: -  flag - PETSC_TRUE to reuse else PETSC_FALSE

429:    Options Database Key:
430: .  -pc_lu_reuse_ordering - Activate PCLUSetReuseOrdering()

432:    Level: intermediate

434: .keywords: PC, levels, reordering, factorization, incomplete, LU

436: .seealso: PCLUSetReuseFill(), PCILUSetReuseOrdering(), PCILUDTSetReuseFill()
437: @*/
438: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseOrdering(PC pc,PetscTruth flag)
439: {
440:   PetscErrorCode ierr,(*f)(PC,PetscTruth);

444:   PetscObjectQueryFunction((PetscObject)pc,"PCLUSetReuseOrdering_C",(void (**)(void))&f);
445:   if (f) {
446:     (*f)(pc,flag);
447:   }
448:   return(0);
449: }

453: /*@
454:    PCLUSetReuseFill - When matrices with same nonzero structure are LU factored,
455:    this causes later ones to use the fill computed in the initial factorization.

457:    Collective on PC

459:    Input Parameters:
460: +  pc - the preconditioner context
461: -  flag - PETSC_TRUE to reuse else PETSC_FALSE

463:    Options Database Key:
464: .  -pc_lu_reuse_fill - Activates PCLUSetReuseFill()

466:    Level: intermediate

468: .keywords: PC, levels, reordering, factorization, incomplete, LU

470: .seealso: PCILUSetReuseOrdering(), PCLUSetReuseOrdering(), PCILUDTSetReuseFill()
471: @*/
472: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetReuseFill(PC pc,PetscTruth flag)
473: {
474:   PetscErrorCode ierr,(*f)(PC,PetscTruth);

478:   PetscObjectQueryFunction((PetscObject)pc,"PCLUSetReuseFill_C",(void (**)(void))&f);
479:   if (f) {
480:     (*f)(pc,flag);
481:   }
482:   return(0);
483: }

487: /*@
488:    PCLUSetFill - Indicate the amount of fill you expect in the factored matrix,
489:    fill = number nonzeros in factor/number nonzeros in original matrix.

491:    Collective on PC
492:    
493:    Input Parameters:
494: +  pc - the preconditioner context
495: -  fill - amount of expected fill

497:    Options Database Key:
498: .  -pc_lu_fill <fill> - Sets fill amount

500:    Level: intermediate

502:    Note:
503:    For sparse matrix factorizations it is difficult to predict how much 
504:    fill to expect. By running with the option -log_info PETSc will print the 
505:    actual amount of fill used; allowing you to set the value accurately for
506:    future runs. Default PETSc uses a value of 5.0

508: .keywords: PC, set, factorization, direct, fill

510: .seealso: PCILUSetFill()
511: @*/
512: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetFill(PC pc,PetscReal fill)
513: {
514:   PetscErrorCode ierr,(*f)(PC,PetscReal);

518:   if (fill < 1.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Fill factor cannot be less then 1.0");
519:   PetscObjectQueryFunction((PetscObject)pc,"PCLUSetFill_C",(void (**)(void))&f);
520:   if (f) {
521:     (*f)(pc,fill);
522:   }
523:   return(0);
524: }

528: /*@
529:    PCLUSetUseInPlace - Tells the system to do an in-place factorization.
530:    For dense matrices, this enables the solution of much larger problems. 
531:    For sparse matrices the factorization cannot be done truly in-place 
532:    so this does not save memory during the factorization, but after the matrix
533:    is factored, the original unfactored matrix is freed, thus recovering that
534:    space.

536:    Collective on PC

538:    Input Parameters:
539: .  pc - the preconditioner context

541:    Options Database Key:
542: .  -pc_lu_in_place - Activates in-place factorization

544:    Notes:
545:    PCLUSetUseInplace() can only be used with the KSP method KSPPREONLY or when 
546:    a different matrix is provided for the multiply and the preconditioner in 
547:    a call to KSPSetOperators().
548:    This is because the Krylov space methods require an application of the 
549:    matrix multiplication, which is not possible here because the matrix has 
550:    been factored in-place, replacing the original matrix.

552:    Level: intermediate

554: .keywords: PC, set, factorization, direct, inplace, in-place, LU

556: .seealso: PCILUSetUseInPlace()
557: @*/
558: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetUseInPlace(PC pc)
559: {
560:   PetscErrorCode ierr,(*f)(PC);

564:   PetscObjectQueryFunction((PetscObject)pc,"PCLUSetUseInPlace_C",(void (**)(void))&f);
565:   if (f) {
566:     (*f)(pc);
567:   }
568:   return(0);
569: }

573: /*@C
574:     PCLUSetMatOrdering - Sets the ordering routine (to reduce fill) to 
575:     be used in the LU factorization.

577:     Collective on PC

579:     Input Parameters:
580: +   pc - the preconditioner context
581: -   ordering - the matrix ordering name, for example, MATORDERING_ND or MATORDERING_RCM

583:     Options Database Key:
584: .   -pc_lu_mat_ordering_type <nd,rcm,...> - Sets ordering routine

586:     Level: intermediate

588:     Notes: nested dissection is used by default

590: .seealso: PCILUSetMatOrdering()
591: @*/
592: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetMatOrdering(PC pc,MatOrderingType ordering)
593: {
594:   PetscErrorCode ierr,(*f)(PC,MatOrderingType);

597:   PetscObjectQueryFunction((PetscObject)pc,"PCLUSetMatOrdering_C",(void (**)(void))&f);
598:   if (f) {
599:     (*f)(pc,ordering);
600:   }
601:   return(0);
602: }

606: /*@
607:     PCLUSetPivoting - Determines when pivoting is done during LU. 
608:       For PETSc dense matrices column pivoting is always done, for PETSc sparse matrices
609:       it is never done. For the Matlab and SuperLU factorization this is used.

611:     Collective on PC

613:     Input Parameters:
614: +   pc - the preconditioner context
615: -   dtcol - 0.0 implies no pivoting, 1.0 complete pivoting (slower, requires more memory but more stable)

617:     Options Database Key:
618: .   -pc_lu_pivoting <dtcol>

620:     Level: intermediate

622: .seealso: PCILUSetMatOrdering(), PCLUSetPivotInBlocks()
623: @*/
624: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivoting(PC pc,PetscReal dtcol)
625: {
626:   PetscErrorCode ierr,(*f)(PC,PetscReal);

629:   PetscObjectQueryFunction((PetscObject)pc,"PCLUSetPivoting_C",(void (**)(void))&f);
630:   if (f) {
631:     (*f)(pc,dtcol);
632:   }
633:   return(0);
634: }

638: /*@
639:     PCLUSetPivotInBlocks - Determines if pivoting is done while factoring each block
640:       with BAIJ or SBAIJ matrices

642:     Collective on PC

644:     Input Parameters:
645: +   pc - the preconditioner context
646: -   pivot - PETSC_TRUE or PETSC_FALSE

648:     Options Database Key:
649: .   -pc_lu_pivot_in_blocks <true,false>

651:     Level: intermediate

653: .seealso: PCILUSetMatOrdering(), PCLUSetPivoting()
654: @*/
655: PetscErrorCode PETSCKSP_DLLEXPORT PCLUSetPivotInBlocks(PC pc,PetscTruth pivot)
656: {
657:   PetscErrorCode ierr,(*f)(PC,PetscTruth);

660:   PetscObjectQueryFunction((PetscObject)pc,"PCLUSetPivotInBlocks_C",(void (**)(void))&f);
661:   if (f) {
662:     (*f)(pc,pivot);
663:   }
664:   return(0);
665: }

667: /* ------------------------------------------------------------------------ */

669: /*MC
670:    PCLU - Uses a direct solver, based on LU factorization, as a preconditioner

672:    Options Database Keys:
673: +  -pc_lu_reuse_ordering - Activate PCLUSetReuseOrdering()
674: .  -pc_lu_reuse_fill - Activates PCLUSetReuseFill()
675: .  -pc_lu_fill <fill> - Sets fill amount
676: .  -pc_lu_in_place - Activates in-place factorization
677: .  -pc_lu_mat_ordering_type <nd,rcm,...> - Sets ordering routine
678: .  -pc_lu_pivot_in_blocks <true,false> - allow pivoting within the small blocks during factorization (may increase
679:                                          stability of factorization.
680: .  -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default
681: -  -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value
682:    is optional with PETSC_TRUE being the default

684:    Notes: Not all options work for all matrix formats
685:           Run with -help to see additional options for particular matrix formats or factorization
686:           algorithms

688:    Level: beginner

690:    Concepts: LU factorization, direct solver

692:    Notes: Usually this will compute an "exact" solution in one iteration and does 
693:           not need a Krylov method (i.e. you can use -ksp_type preonly, or 
694:           KSPSetType(ksp,KSPPREONLY) for the Krylov method

696: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
697:            PCILU, PCCHOLESKY, PCICC, PCLUSetReuseOrdering(), PCLUSetReuseFill(), PCGetFactoredMatrix(),
698:            PCLUSetFill(), PCLUSetUseInPlace(), PCLUSetMatOrdering(), PCFactorSetPivoting(),
699:            PCLUSetPivotingInBlocks(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd()
700: M*/

705: PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_LU(PC pc)
706: {
708:   PetscMPIInt    size;
709:   PC_LU          *dir;

712:   PetscNew(PC_LU,&dir);
713:   PetscLogObjectMemory(pc,sizeof(PC_LU));

715:   MatFactorInfoInitialize(&dir->info);
716:   dir->fact                  = 0;
717:   dir->inplace               = PETSC_FALSE;
718:   dir->nonzerosalongdiagonal = PETSC_FALSE;

720:   dir->info.fill           = 5.0;
721:   dir->info.dtcol          = 1.e-6; /* default to pivoting; this is only thing PETSc LU supports */
722:   dir->info.shiftnz        = 0.0;
723:   dir->info.zeropivot      = 1.e-12;
724:   dir->info.pivotinblocks  = 1.0;
725:   dir->info.shiftpd        = PETSC_FALSE;
726:   dir->info.shift_fraction = 0.0;
727:   dir->col                 = 0;
728:   dir->row                 = 0;
729:   MPI_Comm_size(pc->comm,&size);
730:   if (size == 1) {
731:     PetscStrallocpy(MATORDERING_ND,&dir->ordering);
732:   } else {
733:     PetscStrallocpy(MATORDERING_NATURAL,&dir->ordering);
734:   }
735:   dir->reusefill        = PETSC_FALSE;
736:   dir->reuseordering    = PETSC_FALSE;
737:   pc->data              = (void*)dir;

739:   pc->ops->destroy           = PCDestroy_LU;
740:   pc->ops->apply             = PCApply_LU;
741:   pc->ops->applytranspose    = PCApplyTranspose_LU;
742:   pc->ops->setup             = PCSetUp_LU;
743:   pc->ops->setfromoptions    = PCSetFromOptions_LU;
744:   pc->ops->view              = PCView_LU;
745:   pc->ops->applyrichardson   = 0;
746:   pc->ops->getfactoredmatrix = PCGetFactoredMatrix_LU;

748:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_LU",
749:                     PCFactorSetZeroPivot_LU);
750:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_LU",
751:                     PCFactorSetShiftNonzero_LU);
752:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_LU",
753:                     PCFactorSetShiftPd_LU);

755:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetFill_C","PCLUSetFill_LU",
756:                     PCLUSetFill_LU);
757:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetUseInPlace_C","PCLUSetUseInPlace_LU",
758:                     PCLUSetUseInPlace_LU);
759:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetMatOrdering_C","PCLUSetMatOrdering_LU",
760:                     PCLUSetMatOrdering_LU);
761:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetReuseOrdering_C","PCLUSetReuseOrdering_LU",
762:                     PCLUSetReuseOrdering_LU);
763:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetReuseFill_C","PCLUSetReuseFill_LU",
764:                     PCLUSetReuseFill_LU);
765:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetPivoting_C","PCLUSetPivoting_LU",
766:                     PCLUSetPivoting_LU);
767:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUSetPivotInBlocks_C","PCLUSetPivotInBlocks_LU",
768:                     PCLUSetPivotInBlocks_LU);
769:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCLUReorderForNonzeroDiagonal_C","PCLUReorderForNonzeroDiagonal_LU",
770:                     PCLUReorderForNonzeroDiagonal_LU);
771:   return(0);
772: }