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 private/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:   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:   return(0);
 60: }

 66: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorReorderForNonzeroDiagonal_LU(PC pc,PetscReal z)
 67: {
 68:   PC_LU *lu = (PC_LU*)pc->data;

 71:   lu->nonzerosalongdiagonal = PETSC_TRUE;
 72:   if (z == PETSC_DECIDE) {
 73:     lu->nonzerosalongdiagonaltol = 1.e-10;
 74:   } else {
 75:     lu->nonzerosalongdiagonaltol = z;
 76:   }
 77:   return(0);
 78: }

 84: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseOrdering_LU(PC pc,PetscTruth flag)
 85: {
 86:   PC_LU *lu;

 89:   lu                = (PC_LU*)pc->data;
 90:   lu->reuseordering = flag;
 91:   return(0);
 92: }

 98: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseFill_LU(PC pc,PetscTruth flag)
 99: {
100:   PC_LU *lu;

103:   lu = (PC_LU*)pc->data;
104:   lu->reusefill = flag;
105:   return(0);
106: }

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

121:   MatOrderingRegisterAll(PETSC_NULL);
122:   PetscOptionsHead("LU options");
123:     PetscOptionsName("-pc_factor_in_place","Form LU in the same memory as the matrix","PCFactorSetUseInPlace",&flg);
124:     if (flg) {
125:       PCFactorSetUseInPlace(pc);
126:     }
127:     PetscOptionsReal("-pc_factor_fill","Expected non-zeros in LU/non-zeros in matrix","PCFactorSetFill",lu->info.fill,&lu->info.fill,0);

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

140:     PetscOptionsName("-pc_factor_reuse_fill","Use fill from previous factorization","PCFactorSetReuseFill",&flg);
141:     if (flg) {
142:       PCFactorSetReuseFill(pc,PETSC_TRUE);
143:     }
144:     PetscOptionsName("-pc_factor_reuse_ordering","Reuse ordering from previous factorization","PCFactorSetReuseOrdering",&flg);
145:     if (flg) {
146:       PCFactorSetReuseOrdering(pc,PETSC_TRUE);
147:     }

149:     MatGetOrderingList(&ordlist);
150:     PetscOptionsList("-pc_factor_mat_ordering_type","Reordering to reduce nonzeros in LU","PCFactorSetMatOrdering",ordlist,lu->ordering,tname,256,&flg);
151:     if (flg) {
152:       PCFactorSetMatOrdering(pc,tname);
153:     }

155:     PetscOptionsName("-pc_factor_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCFactorReorderForNonzeroDiagonal",&flg);
156:     if (flg) {
157:       tol = PETSC_DECIDE;
158:       PetscOptionsReal("-pc_factor_nonzeros_along_diagonal","Reorder to remove zeros from diagonal","PCFactorReorderForNonzeroDiagonal",lu->nonzerosalongdiagonaltol,&tol,0);
159:       PCFactorReorderForNonzeroDiagonal(pc,tol);
160:     }

162:     PetscOptionsReal("-pc_factor_pivoting","Pivoting tolerance (used only for some factorization)","PCFactorSetPivoting",lu->info.dtcol,&lu->info.dtcol,&flg);

164:     flg = lu->info.pivotinblocks ? PETSC_TRUE : PETSC_FALSE;
165:     PetscOptionsTruth("-pc_factor_pivot_in_blocks","Pivot inside matrix blocks for BAIJ and SBAIJ","PCFactorSetPivotInBlocks",flg,&flg,&set);
166:     if (set) {
167:       PCFactorSetPivotInBlocks(pc,flg);
168:     }
169:   PetscOptionsTail();
170:   return(0);
171: }

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

182:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
183:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
184:   if (iascii) {
185:     MatInfo info;

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

211: static PetscErrorCode PCGetFactoredMatrix_LU(PC pc,Mat *mat)
212: {
213:   PC_LU *dir = (PC_LU*)pc->data;

216:   if (!dir->fact) SETERRQ(PETSC_ERR_ORDER,"Matrix not yet factored; call after KSPSetUp() or PCSetUp()");
217:   *mat = dir->fact;
218:   return(0);
219: }

223: static PetscErrorCode PCSetUp_LU(PC pc)
224: {
226:   PC_LU          *dir = (PC_LU*)pc->data;

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

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

282: static PetscErrorCode PCDestroy_LU(PC pc)
283: {
284:   PC_LU          *dir = (PC_LU*)pc->data;

288:   if (!dir->inplace && dir->fact) {MatDestroy(dir->fact);}
289:   if (dir->row && dir->col && dir->row != dir->col) {ISDestroy(dir->row);}
290:   if (dir->col) {ISDestroy(dir->col);}
291:   PetscStrfree(dir->ordering);
292:   PetscFree(dir);
293:   return(0);
294: }

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

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

311: static PetscErrorCode PCApplyTranspose_LU(PC pc,Vec x,Vec y)
312: {
313:   PC_LU          *dir = (PC_LU*)pc->data;

317:   if (dir->inplace) {MatSolveTranspose(pc->pmat,x,y);}
318:   else              {MatSolveTranspose(dir->fact,x,y);}
319:   return(0);
320: }

322: /* -----------------------------------------------------------------------------------*/

327: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetFill_LU(PC pc,PetscReal fill)
328: {
329:   PC_LU *dir;

332:   dir = (PC_LU*)pc->data;
333:   dir->info.fill = fill;
334:   return(0);
335: }

341: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetUseInPlace_LU(PC pc)
342: {
343:   PC_LU *dir;

346:   dir = (PC_LU*)pc->data;
347:   dir->inplace = PETSC_TRUE;
348:   return(0);
349: }

355: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetMatOrdering_LU(PC pc,MatOrderingType ordering)
356: {
357:   PC_LU          *dir = (PC_LU*)pc->data;

361:   PetscStrfree(dir->ordering);
362:   PetscStrallocpy(ordering,&dir->ordering);
363:   return(0);
364: }

370: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetPivoting_LU(PC pc,PetscReal dtcol)
371: {
372:   PC_LU *dir = (PC_LU*)pc->data;

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

384: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetPivotInBlocks_LU(PC pc,PetscTruth pivot)
385: {
386:   PC_LU *dir = (PC_LU*)pc->data;

389:   dir->info.pivotinblocks = pivot ? 1.0 : 0.0;
390:   return(0);
391: }

394: /* -----------------------------------------------------------------------------------*/

398: /*@
399:    PCFactorReorderForNonzeroDiagonal - reorders rows/columns of matrix to remove zeros from diagonal

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

407:    Options Database Key:
408: .  -pc_factor_nonzeros_along_diagonal

410:    Level: intermediate

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

414: .seealso: PCFactorSetFill(), PCFactorSetShiftNonzero(), PCFactorSetZeroPivot(), MatReorderForNonzeroDiagonal()
415: @*/
416: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorReorderForNonzeroDiagonal(PC pc,PetscReal rtol)
417: {
418:   PetscErrorCode ierr,(*f)(PC,PetscReal);

422:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorReorderForNonzeroDiagonal_C",(void (**)(void))&f);
423:   if (f) {
424:     (*f)(pc,rtol);
425:   }
426:   return(0);
427: }

431: /*@
432:    PCFactorSetFill - Indicate the amount of fill you expect in the factored matrix,
433:    fill = number nonzeros in factor/number nonzeros in original matrix.

435:    Collective on PC
436:    
437:    Input Parameters:
438: +  pc - the preconditioner context
439: -  fill - amount of expected fill

441:    Options Database Key:
442: .  -pc_factor_fill <fill> - Sets fill amount

444:    Level: intermediate

446:    Note:
447:    For sparse matrix factorizations it is difficult to predict how much 
448:    fill to expect. By running with the option -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

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

454: @*/
455: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetFill(PC pc,PetscReal fill)
456: {
457:   PetscErrorCode ierr,(*f)(PC,PetscReal);

461:   if (fill < 1.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Fill factor cannot be less then 1.0");
462:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetFill_C",(void (**)(void))&f);
463:   if (f) {
464:     (*f)(pc,fill);
465:   }
466:   return(0);
467: }

471: /*@
472:    PCFactorSetUseInPlace - Tells the system to do an in-place factorization.
473:    For dense matrices, this enables the solution of much larger problems. 
474:    For sparse matrices the factorization cannot be done truly in-place 
475:    so this does not save memory during the factorization, but after the matrix
476:    is factored, the original unfactored matrix is freed, thus recovering that
477:    space.

479:    Collective on PC

481:    Input Parameters:
482: .  pc - the preconditioner context

484:    Options Database Key:
485: .  -pc_factor_in_place - Activates in-place factorization

487:    Notes:
488:    PCFactorSetUseInplace() can only be used with the KSP method KSPPREONLY or when 
489:    a different matrix is provided for the multiply and the preconditioner in 
490:    a call to KSPSetOperators().
491:    This is because the Krylov space methods require an application of the 
492:    matrix multiplication, which is not possible here because the matrix has 
493:    been factored in-place, replacing the original matrix.

495:    Level: intermediate

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

499: .seealso: PCILUSetUseInPlace()
500: @*/
501: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetUseInPlace(PC pc)
502: {
503:   PetscErrorCode ierr,(*f)(PC);

507:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetUseInPlace_C",(void (**)(void))&f);
508:   if (f) {
509:     (*f)(pc);
510:   }
511:   return(0);
512: }

516: /*@C
517:     PCFactorSetMatOrdering - Sets the ordering routine (to reduce fill) to 
518:     be used in the LU factorization.

520:     Collective on PC

522:     Input Parameters:
523: +   pc - the preconditioner context
524: -   ordering - the matrix ordering name, for example, MATORDERING_ND or MATORDERING_RCM

526:     Options Database Key:
527: .   -pc_factor_mat_ordering_type <nd,rcm,...> - Sets ordering routine

529:     Level: intermediate

531:     Notes: nested dissection is used by default

533: .seealso: PCILUSetMatOrdering()
534: @*/
535: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetMatOrdering(PC pc,MatOrderingType ordering)
536: {
537:   PetscErrorCode ierr,(*f)(PC,MatOrderingType);

540:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetMatOrdering_C",(void (**)(void))&f);
541:   if (f) {
542:     (*f)(pc,ordering);
543:   }
544:   return(0);
545: }

549: /*@
550:     PCFactorSetPivoting - Determines when pivoting is done during LU. 
551:       For PETSc dense matrices column pivoting is always done, for PETSc sparse matrices
552:       it is never done. For the Matlab and SuperLU factorization this is used.

554:     Collective on PC

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

560:     Options Database Key:
561: .   -pc_factor_pivoting <dtcol>

563:     Level: intermediate

565: .seealso: PCILUSetMatOrdering(), PCFactorSetPivotInBlocks()
566: @*/
567: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetPivoting(PC pc,PetscReal dtcol)
568: {
569:   PetscErrorCode ierr,(*f)(PC,PetscReal);

572:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetPivoting_C",(void (**)(void))&f);
573:   if (f) {
574:     (*f)(pc,dtcol);
575:   }
576:   return(0);
577: }

581: /*@
582:     PCFactorSetPivotInBlocks - Determines if pivoting is done while factoring each block
583:       with BAIJ or SBAIJ matrices

585:     Collective on PC

587:     Input Parameters:
588: +   pc - the preconditioner context
589: -   pivot - PETSC_TRUE or PETSC_FALSE

591:     Options Database Key:
592: .   -pc_factor_pivot_in_blocks <true,false>

594:     Level: intermediate

596: .seealso: PCILUSetMatOrdering(), PCFactorSetPivoting()
597: @*/
598: PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetPivotInBlocks(PC pc,PetscTruth pivot)
599: {
600:   PetscErrorCode ierr,(*f)(PC,PetscTruth);

603:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetPivotInBlocks_C",(void (**)(void))&f);
604:   if (f) {
605:     (*f)(pc,pivot);
606:   }
607:   return(0);
608: }

610: /* ------------------------------------------------------------------------ */

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

615:    Options Database Keys:
616: +  -pc_factor_reuse_ordering - Activate PCFactorSetReuseOrdering()
617: .  -pc_factor_reuse_fill - Activates PCFactorSetReuseFill()
618: .  -pc_factor_fill <fill> - Sets fill amount
619: .  -pc_factor_in_place - Activates in-place factorization
620: .  -pc_factor_mat_ordering_type <nd,rcm,...> - Sets ordering routine
621: .  -pc_factor_pivot_in_blocks <true,false> - allow pivoting within the small blocks during factorization (may increase
622:                                          stability of factorization.
623: .  -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default
624: -  -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value
625:    is optional with PETSC_TRUE being the default

627:    Notes: Not all options work for all matrix formats
628:           Run with -help to see additional options for particular matrix formats or factorization
629:           algorithms

631:    Level: beginner

633:    Concepts: LU factorization, direct solver

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

639: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
640:            PCILU, PCCHOLESKY, PCICC, PCFactorSetReuseOrdering(), PCFactorSetReuseFill(), PCGetFactoredMatrix(),
641:            PCFactorSetFill(), PCFactorSetUseInPlace(), PCFactorSetMatOrdering(), PCFactorSetPivoting(),
642:            PCFactorSetPivotingInBlocks(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd()
643: M*/

648: PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_LU(PC pc)
649: {
651:   PetscMPIInt    size;
652:   PC_LU          *dir;

655:   PetscNew(PC_LU,&dir);
656:   PetscLogObjectMemory(pc,sizeof(PC_LU));

658:   MatFactorInfoInitialize(&dir->info);
659:   dir->fact                  = 0;
660:   dir->inplace               = PETSC_FALSE;
661:   dir->nonzerosalongdiagonal = PETSC_FALSE;

663:   dir->info.fill           = 5.0;
664:   dir->info.dtcol          = 1.e-6; /* default to pivoting; this is only thing PETSc LU supports */
665:   dir->info.shiftnz        = 0.0;
666:   dir->info.zeropivot      = 1.e-12;
667:   dir->info.pivotinblocks  = 1.0;
668:   dir->info.shiftpd        = 0.0; /* false */
669:   dir->info.shift_fraction = 0.0;
670:   dir->col                 = 0;
671:   dir->row                 = 0;
672:   MPI_Comm_size(pc->comm,&size);
673:   if (size == 1) {
674:     PetscStrallocpy(MATORDERING_ND,&dir->ordering);
675:   } else {
676:     PetscStrallocpy(MATORDERING_NATURAL,&dir->ordering);
677:   }
678:   dir->reusefill        = PETSC_FALSE;
679:   dir->reuseordering    = PETSC_FALSE;
680:   pc->data              = (void*)dir;

682:   pc->ops->destroy           = PCDestroy_LU;
683:   pc->ops->apply             = PCApply_LU;
684:   pc->ops->applytranspose    = PCApplyTranspose_LU;
685:   pc->ops->setup             = PCSetUp_LU;
686:   pc->ops->setfromoptions    = PCSetFromOptions_LU;
687:   pc->ops->view              = PCView_LU;
688:   pc->ops->applyrichardson   = 0;
689:   pc->ops->getfactoredmatrix = PCGetFactoredMatrix_LU;

691:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_LU",
692:                     PCFactorSetZeroPivot_LU);
693:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_LU",
694:                     PCFactorSetShiftNonzero_LU);
695:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_LU",
696:                     PCFactorSetShiftPd_LU);

698:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetFill_C","PCFactorSetFill_LU",
699:                     PCFactorSetFill_LU);
700:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetUseInPlace_C","PCFactorSetUseInPlace_LU",
701:                     PCFactorSetUseInPlace_LU);
702:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetMatOrdering_C","PCFactorSetMatOrdering_LU",
703:                     PCFactorSetMatOrdering_LU);
704:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetReuseOrdering_C","PCFactorSetReuseOrdering_LU",
705:                     PCFactorSetReuseOrdering_LU);
706:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetReuseFill_C","PCFactorSetReuseFill_LU",
707:                     PCFactorSetReuseFill_LU);
708:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetPivoting_C","PCFactorSetPivoting_LU",
709:                     PCFactorSetPivoting_LU);
710:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetPivotInBlocks_C","PCFactorSetPivotInBlocks_LU",
711:                     PCFactorSetPivotInBlocks_LU);
712:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorReorderForNonzeroDiagonal_C","PCFactorReorderForNonzeroDiagonal_LU",
713:                     PCFactorReorderForNonzeroDiagonal_LU);
714:   return(0);
715: }