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  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  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  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  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  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  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) {

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

216: static PetscErrorCode PCGetFactoredMatrix_LU(PC pc,Mat *mat)
217: {
218:   PC_LU *dir = (PC_LU*)pc->data;

221:   if (!dir->fact) SETERRQ(PETSC_ERR_ORDER,"Matrix not yet factored; call after KSPSetUp() or PCSetUp()");
222:   *mat = dir->fact;
223:   return(0);
224: }

228: static PetscErrorCode PCSetUp_LU(PC pc)
229: {
231:   PC_LU          *dir = (PC_LU*)pc->data;

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

236:   if (dir->inplace) {
237:     if (dir->row && dir->col && dir->row != dir->col) {ISDestroy(dir->row);}
238:     if (dir->col) {ISDestroy(dir->col);}
239:     MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);
240:     if (dir->row) {
241:       PetscLogObjectParent(pc,dir->row);
242:       PetscLogObjectParent(pc,dir->col);
243:     }
244:     MatLUFactor(pc->pmat,dir->row,dir->col,&dir->info);
245:     dir->fact = pc->pmat;
246:   } else {
247:     MatInfo info;
248:     if (!pc->setupcalled) {
249:       MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);
250:       if (dir->nonzerosalongdiagonal) {
251:         MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);
252:       }
253:       if (dir->row) {
254:         PetscLogObjectParent(pc,dir->row);
255:         PetscLogObjectParent(pc,dir->col);
256:       }
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:     } else if (pc->flag != SAME_NONZERO_PATTERN) {
262:       if (!dir->reuseordering) {
263:         if (dir->row && dir->col && dir->row != dir->col) {ISDestroy(dir->row);}
264:         if (dir->col) {ISDestroy(dir->col);}
265:         MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);
266:         if (dir->nonzerosalongdiagonal) {
267:           MatReorderForNonzeroDiagonal(pc->pmat,dir->nonzerosalongdiagonaltol,dir->row,dir->col);
268:         }
269:         if (dir->row) {
270:           PetscLogObjectParent(pc,dir->row);
271:           PetscLogObjectParent(pc,dir->col);
272:         }
273:       }
274:       MatDestroy(dir->fact);
275:       MatLUFactorSymbolic(pc->pmat,dir->row,dir->col,&dir->info,&dir->fact);
276:       MatGetInfo(dir->fact,MAT_LOCAL,&info);
277:       dir->actualfill = info.fill_ratio_needed;
278:       PetscLogObjectParent(pc,dir->fact);
279:     }
280:     MatLUFactorNumeric(pc->pmat,&dir->info,&dir->fact);
281:   }
282:   return(0);
283: }

287: static PetscErrorCode PCDestroy_LU(PC pc)
288: {
289:   PC_LU          *dir = (PC_LU*)pc->data;

293:   if (!dir->inplace && dir->fact) {MatDestroy(dir->fact);}
294:   if (dir->row && dir->col && dir->row != dir->col) {ISDestroy(dir->row);}
295:   if (dir->col) {ISDestroy(dir->col);}
296:   PetscStrfree(dir->ordering);
297:   PetscFree(dir);
298:   return(0);
299: }

303: static PetscErrorCode PCApply_LU(PC pc,Vec x,Vec y)
304: {
305:   PC_LU          *dir = (PC_LU*)pc->data;

309:   if (dir->inplace) {MatSolve(pc->pmat,x,y);}
310:   else              {MatSolve(dir->fact,x,y);}
311:   return(0);
312: }

316: static PetscErrorCode PCApplyTranspose_LU(PC pc,Vec x,Vec y)
317: {
318:   PC_LU          *dir = (PC_LU*)pc->data;

322:   if (dir->inplace) {MatSolveTranspose(pc->pmat,x,y);}
323:   else              {MatSolveTranspose(dir->fact,x,y);}
324:   return(0);
325: }

327: /* -----------------------------------------------------------------------------------*/

332: PetscErrorCode  PCFactorSetFill_LU(PC pc,PetscReal fill)
333: {
334:   PC_LU *dir;

337:   dir = (PC_LU*)pc->data;
338:   dir->info.fill = fill;
339:   return(0);
340: }

346: PetscErrorCode  PCFactorSetUseInPlace_LU(PC pc)
347: {
348:   PC_LU *dir;

351:   dir = (PC_LU*)pc->data;
352:   dir->inplace = PETSC_TRUE;
353:   return(0);
354: }

360: PetscErrorCode  PCFactorSetMatOrdering_LU(PC pc,MatOrderingType ordering)
361: {
362:   PC_LU          *dir = (PC_LU*)pc->data;

366:   PetscStrfree(dir->ordering);
367:   PetscStrallocpy(ordering,&dir->ordering);
368:   return(0);
369: }

375: PetscErrorCode  PCFactorSetPivoting_LU(PC pc,PetscReal dtcol)
376: {
377:   PC_LU *dir = (PC_LU*)pc->data;

380:   if (dtcol < 0.0 || dtcol > 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column pivot tolerance is %G must be between 0 and 1",dtcol);
381:   dir->info.dtcol = dtcol;
382:   return(0);
383: }

389: PetscErrorCode  PCFactorSetPivotInBlocks_LU(PC pc,PetscTruth pivot)
390: {
391:   PC_LU *dir = (PC_LU*)pc->data;

394:   dir->info.pivotinblocks = pivot ? 1.0 : 0.0;
395:   return(0);
396: }

399: /* -----------------------------------------------------------------------------------*/

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

406:    Collective on PC
407:    
408:    Input Parameters:
409: +  pc - the preconditioner context
410: -  tol - diagonal entries smaller than this in absolute value are considered zero

412:    Options Database Key:
413: .  -pc_factor_nonzeros_along_diagonal

415:    Level: intermediate

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

419: .seealso: PCFactorSetFill(), PCFactorSetShiftNonzero(), PCFactorSetZeroPivot(), MatReorderForNonzeroDiagonal()
420: @*/
421: PetscErrorCode  PCFactorReorderForNonzeroDiagonal(PC pc,PetscReal rtol)
422: {
423:   PetscErrorCode ierr,(*f)(PC,PetscReal);

427:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorReorderForNonzeroDiagonal_C",(void (**)(void))&f);
428:   if (f) {
429:     (*f)(pc,rtol);
430:   }
431:   return(0);
432: }

436: /*@
437:    PCFactorSetFill - Indicate the amount of fill you expect in the factored matrix,
438:    fill = number nonzeros in factor/number nonzeros in original matrix.

440:    Collective on PC
441:    
442:    Input Parameters:
443: +  pc - the preconditioner context
444: -  fill - amount of expected fill

446:    Options Database Key:
447: .  -pc_factor_fill <fill> - Sets fill amount

449:    Level: intermediate

451:    Note:
452:    For sparse matrix factorizations it is difficult to predict how much 
453:    fill to expect. By running with the option -info PETSc will print the 
454:    actual amount of fill used; allowing you to set the value accurately for
455:    future runs. Default PETSc uses a value of 5.0

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

459: @*/
460: PetscErrorCode  PCFactorSetFill(PC pc,PetscReal fill)
461: {
462:   PetscErrorCode ierr,(*f)(PC,PetscReal);

466:   if (fill < 1.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Fill factor cannot be less then 1.0");
467:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetFill_C",(void (**)(void))&f);
468:   if (f) {
469:     (*f)(pc,fill);
470:   }
471:   return(0);
472: }

476: /*@
477:    PCFactorSetUseInPlace - 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.

484:    Collective on PC

486:    Input Parameters:
487: .  pc - the preconditioner context

489:    Options Database Key:
490: .  -pc_factor_in_place - Activates in-place factorization

492:    Notes:
493:    PCFactorSetUseInplace() 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.

500:    Level: intermediate

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

504: .seealso: PCILUSetUseInPlace()
505: @*/
506: PetscErrorCode  PCFactorSetUseInPlace(PC pc)
507: {
508:   PetscErrorCode ierr,(*f)(PC);

512:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetUseInPlace_C",(void (**)(void))&f);
513:   if (f) {
514:     (*f)(pc);
515:   }
516:   return(0);
517: }

521: /*@C
522:     PCFactorSetMatOrdering - Sets the ordering routine (to reduce fill) to 
523:     be used in the LU factorization.

525:     Collective on PC

527:     Input Parameters:
528: +   pc - the preconditioner context
529: -   ordering - the matrix ordering name, for example, MATORDERING_ND or MATORDERING_RCM

531:     Options Database Key:
532: .   -pc_factor_mat_ordering_type <nd,rcm,...> - Sets ordering routine

534:     Level: intermediate

536:     Notes: nested dissection is used by default

538: .seealso: PCILUSetMatOrdering()
539: @*/
540: PetscErrorCode  PCFactorSetMatOrdering(PC pc,MatOrderingType ordering)
541: {
542:   PetscErrorCode ierr,(*f)(PC,MatOrderingType);

545:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetMatOrdering_C",(void (**)(void))&f);
546:   if (f) {
547:     (*f)(pc,ordering);
548:   }
549:   return(0);
550: }

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

559:     Collective on PC

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

565:     Options Database Key:
566: .   -pc_factor_pivoting <dtcol>

568:     Level: intermediate

570: .seealso: PCILUSetMatOrdering(), PCFactorSetPivotInBlocks()
571: @*/
572: PetscErrorCode  PCFactorSetPivoting(PC pc,PetscReal dtcol)
573: {
574:   PetscErrorCode ierr,(*f)(PC,PetscReal);

577:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetPivoting_C",(void (**)(void))&f);
578:   if (f) {
579:     (*f)(pc,dtcol);
580:   }
581:   return(0);
582: }

586: /*@
587:     PCFactorSetPivotInBlocks - Determines if pivoting is done while factoring each block
588:       with BAIJ or SBAIJ matrices

590:     Collective on PC

592:     Input Parameters:
593: +   pc - the preconditioner context
594: -   pivot - PETSC_TRUE or PETSC_FALSE

596:     Options Database Key:
597: .   -pc_factor_pivot_in_blocks <true,false>

599:     Level: intermediate

601: .seealso: PCILUSetMatOrdering(), PCFactorSetPivoting()
602: @*/
603: PetscErrorCode  PCFactorSetPivotInBlocks(PC pc,PetscTruth pivot)
604: {
605:   PetscErrorCode ierr,(*f)(PC,PetscTruth);

608:   PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetPivotInBlocks_C",(void (**)(void))&f);
609:   if (f) {
610:     (*f)(pc,pivot);
611:   }
612:   return(0);
613: }

615: /* ------------------------------------------------------------------------ */

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

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

632:    Notes: Not all options work for all matrix formats
633:           Run with -help to see additional options for particular matrix formats or factorization
634:           algorithms

636:    Level: beginner

638:    Concepts: LU factorization, direct solver

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

644: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
645:            PCILU, PCCHOLESKY, PCICC, PCFactorSetReuseOrdering(), PCFactorSetReuseFill(), PCGetFactoredMatrix(),
646:            PCFactorSetFill(), PCFactorSetUseInPlace(), PCFactorSetMatOrdering(), PCFactorSetPivoting(),
647:            PCFactorSetPivotingInBlocks(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd()
648: M*/

653: PetscErrorCode  PCCreate_LU(PC pc)
654: {
656:   PetscMPIInt    size;
657:   PC_LU          *dir;

660:   PetscNew(PC_LU,&dir);
661:   PetscLogObjectMemory(pc,sizeof(PC_LU));

663:   MatFactorInfoInitialize(&dir->info);
664:   dir->fact                  = 0;
665:   dir->inplace               = PETSC_FALSE;
666:   dir->nonzerosalongdiagonal = PETSC_FALSE;

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

687:   pc->ops->destroy           = PCDestroy_LU;
688:   pc->ops->apply             = PCApply_LU;
689:   pc->ops->applytranspose    = PCApplyTranspose_LU;
690:   pc->ops->setup             = PCSetUp_LU;
691:   pc->ops->setfromoptions    = PCSetFromOptions_LU;
692:   pc->ops->view              = PCView_LU;
693:   pc->ops->applyrichardson   = 0;
694:   pc->ops->getfactoredmatrix = PCGetFactoredMatrix_LU;

696:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_LU",
697:                     PCFactorSetZeroPivot_LU);
698:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_LU",
699:                     PCFactorSetShiftNonzero_LU);
700:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_LU",
701:                     PCFactorSetShiftPd_LU);

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