xref: /petsc/src/ksp/pc/impls/factor/cholesky/cholesky.c (revision 1d2e40055fe3bf783df36eeeccf2d7d5fcfab0fd)
1 #define PETSCKSP_DLL
2 
3 /*
4    Defines a direct factorization preconditioner for any Mat implementation
5    Note: this need not be consided a preconditioner since it supplies
6          a direct solver.
7 */
8 #include "private/pcimpl.h"                /*I "petscpc.h" I*/
9 
10 typedef struct {
11   Mat             fact;             /* factored matrix */
12   PetscReal       actualfill;       /* actual fill in factor */
13   PetscTruth      inplace;          /* flag indicating in-place factorization */
14   IS              row,col;          /* index sets used for reordering */
15   MatOrderingType ordering;         /* matrix ordering */
16   PetscTruth      reuseordering;    /* reuses previous reordering computed */
17   PetscTruth      reusefill;        /* reuse fill from previous Cholesky */
18   MatFactorInfo   info;
19 } PC_Cholesky;
20 
21 EXTERN_C_BEGIN
22 #undef __FUNCT__
23 #define __FUNCT__ "PCFactorSetZeroPivot_Cholesky"
24 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetZeroPivot_Cholesky(PC pc,PetscReal z)
25 {
26   PC_Cholesky *ch;
27 
28   PetscFunctionBegin;
29   ch                 = (PC_Cholesky*)pc->data;
30   ch->info.zeropivot = z;
31   PetscFunctionReturn(0);
32 }
33 EXTERN_C_END
34 
35 EXTERN_C_BEGIN
36 #undef __FUNCT__
37 #define __FUNCT__ "PCFactorSetShiftNonzero_Cholesky"
38 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftNonzero_Cholesky(PC pc,PetscReal shift)
39 {
40   PC_Cholesky *dir;
41 
42   PetscFunctionBegin;
43   dir = (PC_Cholesky*)pc->data;
44   if (shift == (PetscReal) PETSC_DECIDE) {
45     dir->info.shiftnz = 1.e-12;
46   } else {
47     dir->info.shiftnz = shift;
48   }
49   PetscFunctionReturn(0);
50 }
51 EXTERN_C_END
52 
53 EXTERN_C_BEGIN
54 #undef __FUNCT__
55 #define __FUNCT__ "PCFactorSetShiftPd_Cholesky"
56 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftPd_Cholesky(PC pc,PetscTruth shift)
57 {
58   PC_Cholesky *dir;
59 
60   PetscFunctionBegin;
61   dir = (PC_Cholesky*)pc->data;
62   if (shift) {
63     dir->info.shift_fraction = 0.0;
64     dir->info.shiftpd = 1.0;
65   } else {
66     dir->info.shiftpd = 0.0;
67   }
68   PetscFunctionReturn(0);
69 }
70 EXTERN_C_END
71 
72 EXTERN_C_BEGIN
73 #undef __FUNCT__
74 #define __FUNCT__ "PCFactorSetReuseOrdering_Cholesky"
75 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseOrdering_Cholesky(PC pc,PetscTruth flag)
76 {
77   PC_Cholesky *lu;
78 
79   PetscFunctionBegin;
80   lu               = (PC_Cholesky*)pc->data;
81   lu->reuseordering = flag;
82   PetscFunctionReturn(0);
83 }
84 EXTERN_C_END
85 
86 EXTERN_C_BEGIN
87 #undef __FUNCT__
88 #define __FUNCT__ "PCFactorSetReuseFill_Cholesky"
89 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseFill_Cholesky(PC pc,PetscTruth flag)
90 {
91   PC_Cholesky *lu;
92 
93   PetscFunctionBegin;
94   lu = (PC_Cholesky*)pc->data;
95   lu->reusefill = flag;
96   PetscFunctionReturn(0);
97 }
98 EXTERN_C_END
99 
100 #undef __FUNCT__
101 #define __FUNCT__ "PCSetFromOptions_Cholesky"
102 static PetscErrorCode PCSetFromOptions_Cholesky(PC pc)
103 {
104   PC_Cholesky    *lu = (PC_Cholesky*)pc->data;
105   PetscErrorCode ierr;
106   PetscTruth     flg;
107   char           tname[256];
108   PetscFList     ordlist;
109 
110   PetscFunctionBegin;
111   ierr = MatOrderingRegisterAll(PETSC_NULL);CHKERRQ(ierr);
112   ierr = PetscOptionsHead("Cholesky options");CHKERRQ(ierr);
113   ierr = PetscOptionsName("-pc_factor_in_place","Form Cholesky in the same memory as the matrix","PCFactorSetUseInPlace",&flg);CHKERRQ(ierr);
114   if (flg) {
115     ierr = PCFactorSetUseInPlace(pc);CHKERRQ(ierr);
116   }
117   ierr = PetscOptionsReal("-pc_factor_fill","Expected non-zeros in Cholesky/non-zeros in matrix","PCFactorSetFill",lu->info.fill,&lu->info.fill,0);CHKERRQ(ierr);
118 
119   ierr = PetscOptionsName("-pc_factor_reuse_fill","Use fill from previous factorization","PCFactorSetReuseFill",&flg);CHKERRQ(ierr);
120   if (flg) {
121     ierr = PCFactorSetReuseFill(pc,PETSC_TRUE);CHKERRQ(ierr);
122   }
123   ierr = PetscOptionsName("-pc_factor_reuse_ordering","Reuse ordering from previous factorization","PCFactorSetReuseOrdering",&flg);CHKERRQ(ierr);
124   if (flg) {
125     ierr = PCFactorSetReuseOrdering(pc,PETSC_TRUE);CHKERRQ(ierr);
126   }
127 
128   ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr);
129   ierr = PetscOptionsList("-pc_factor_mat_ordering_type","Reordering to reduce nonzeros in Cholesky","PCFactorSetMatOrdering",ordlist,lu->ordering,tname,256,&flg);CHKERRQ(ierr);
130   if (flg) {
131     ierr = PCFactorSetMatOrdering(pc,tname);CHKERRQ(ierr);
132   }
133   ierr = PetscOptionsName("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",&flg);CHKERRQ(ierr);
134   if (flg) {
135     ierr = PCFactorSetShiftNonzero(pc,(PetscReal) PETSC_DECIDE);CHKERRQ(ierr);
136   }
137   ierr = PetscOptionsReal("-pc_factor_shift_nonzero","Shift added to diagonal","PCFactorSetShiftNonzero",lu->info.shiftnz,&lu->info.shiftnz,0);CHKERRQ(ierr);
138   ierr = PetscOptionsName("-pc_factor_shift_positive_definite","Manteuffel shift applied to diagonal","PCFactorSetShiftPd",&flg);CHKERRQ(ierr);
139   if (flg) {
140     ierr = PCFactorSetShiftPd(pc,PETSC_TRUE);CHKERRQ(ierr);
141   }
142   ierr = PetscOptionsReal("-pc_factor_zeropivot","Pivot is considered zero if less than","PCFactorSetZeroPivot",lu->info.zeropivot,&lu->info.zeropivot,0);CHKERRQ(ierr);
143 
144   ierr = PetscOptionsTail();CHKERRQ(ierr);
145   PetscFunctionReturn(0);
146 }
147 
148 #undef __FUNCT__
149 #define __FUNCT__ "PCView_Cholesky"
150 static PetscErrorCode PCView_Cholesky(PC pc,PetscViewer viewer)
151 {
152   PC_Cholesky    *lu = (PC_Cholesky*)pc->data;
153   PetscErrorCode ierr;
154   PetscTruth     iascii,isstring;
155 
156   PetscFunctionBegin;
157   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
158   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr);
159   if (iascii) {
160     MatInfo info;
161 
162     if (lu->inplace) {ierr = PetscViewerASCIIPrintf(viewer,"  Cholesky: in-place factorization\n");CHKERRQ(ierr);}
163     else             {ierr = PetscViewerASCIIPrintf(viewer,"  Cholesky: out-of-place factorization\n");CHKERRQ(ierr);}
164     ierr = PetscViewerASCIIPrintf(viewer,"    matrix ordering: %s\n",lu->ordering);CHKERRQ(ierr);
165     if (lu->fact) {
166       ierr = MatGetInfo(lu->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
167       ierr = PetscViewerASCIIPrintf(viewer,"    Cholesky nonzeros %G\n",info.nz_used);CHKERRQ(ierr);
168       ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_FACTOR_INFO);CHKERRQ(ierr);
169       ierr = MatView(lu->fact,viewer);CHKERRQ(ierr);
170       ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
171     }
172     if (lu->reusefill)    {ierr = PetscViewerASCIIPrintf(viewer,"       Reusing fill from past factorization\n");CHKERRQ(ierr);}
173     if (lu->reuseordering) {ierr = PetscViewerASCIIPrintf(viewer,"       Reusing reordering from past factorization\n");CHKERRQ(ierr);}
174   } else if (isstring) {
175     ierr = PetscViewerStringSPrintf(viewer," order=%s",lu->ordering);CHKERRQ(ierr);CHKERRQ(ierr);
176   } else {
177     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for PCCHOLESKY",((PetscObject)viewer)->type_name);
178   }
179   PetscFunctionReturn(0);
180 }
181 
182 #undef __FUNCT__
183 #define __FUNCT__ "PCGetFactoredMatrix_Cholesky"
184 static PetscErrorCode PCGetFactoredMatrix_Cholesky(PC pc,Mat *mat)
185 {
186   PC_Cholesky *dir = (PC_Cholesky*)pc->data;
187 
188   PetscFunctionBegin;
189   if (!dir->fact) SETERRQ(PETSC_ERR_ORDER,"Matrix not yet factored; call after KSPSetUp() or PCSetUp()");
190   *mat = dir->fact;
191   PetscFunctionReturn(0);
192 }
193 
194 #undef __FUNCT__
195 #define __FUNCT__ "PCSetUp_Cholesky"
196 static PetscErrorCode PCSetUp_Cholesky(PC pc)
197 {
198   PetscErrorCode ierr;
199   PetscTruth     flg;
200   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
201 
202   PetscFunctionBegin;
203   if (dir->reusefill && pc->setupcalled) dir->info.fill = dir->actualfill;
204 
205   if (dir->inplace) {
206     if (dir->row && dir->col && (dir->row != dir->col)) {
207       ierr = ISDestroy(dir->row);CHKERRQ(ierr);
208       dir->row = 0;
209     }
210     if (dir->col) {
211       ierr = ISDestroy(dir->col);CHKERRQ(ierr);
212       dir->col = 0;
213     }
214     ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr);
215     if (dir->col && (dir->row != dir->col)) {  /* only use row ordering for SBAIJ */
216       ierr = ISDestroy(dir->col);CHKERRQ(ierr);
217       dir->col=0;
218     }
219     if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);}
220     ierr = MatCholeskyFactor(pc->pmat,dir->row,&dir->info);CHKERRQ(ierr);
221     dir->fact = pc->pmat;
222   } else {
223     MatInfo info;
224     if (!pc->setupcalled) {
225       ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr);
226       if (dir->col && (dir->row != dir->col)) {  /* only use row ordering for SBAIJ */
227         ierr = ISDestroy(dir->col);CHKERRQ(ierr);
228         dir->col=0;
229       }
230       ierr = PetscOptionsHasName(pc->prefix,"-pc_factor_nonzeros_along_diagonal",&flg);CHKERRQ(ierr);
231       if (flg) {
232         PetscReal tol = 1.e-10;
233         ierr = PetscOptionsGetReal(pc->prefix,"-pc_factor_nonzeros_along_diagonal",&tol,PETSC_NULL);CHKERRQ(ierr);
234         ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);CHKERRQ(ierr);
235       }
236       if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);}
237       ierr = MatCholeskyFactorSymbolic(pc->pmat,dir->row,&dir->info,&dir->fact);CHKERRQ(ierr);
238       ierr = MatGetInfo(dir->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
239       dir->actualfill = info.fill_ratio_needed;
240       ierr = PetscLogObjectParent(pc,dir->fact);CHKERRQ(ierr);
241     } else if (pc->flag != SAME_NONZERO_PATTERN) {
242       if (!dir->reuseordering) {
243         if (dir->row && dir->col && (dir->row != dir->col)) {
244           ierr = ISDestroy(dir->row);CHKERRQ(ierr);
245           dir->row = 0;
246         }
247         if (dir->col) {
248           ierr = ISDestroy(dir->col);CHKERRQ(ierr);
249           dir->col =0;
250         }
251         ierr = MatGetOrdering(pc->pmat,dir->ordering,&dir->row,&dir->col);CHKERRQ(ierr);
252         if (dir->col && (dir->row != dir->col)) {  /* only use row ordering for SBAIJ */
253           ierr = ISDestroy(dir->col);CHKERRQ(ierr);
254           dir->col=0;
255         }
256         ierr = PetscOptionsHasName(pc->prefix,"-pc_factor_nonzeros_along_diagonal",&flg);CHKERRQ(ierr);
257         if (flg) {
258           PetscReal tol = 1.e-10;
259           ierr = PetscOptionsGetReal(pc->prefix,"-pc_factor_nonzeros_along_diagonal",&tol,PETSC_NULL);CHKERRQ(ierr);
260           ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);CHKERRQ(ierr);
261         }
262         if (dir->row) {ierr = PetscLogObjectParent(pc,dir->row);CHKERRQ(ierr);}
263       }
264       ierr = MatDestroy(dir->fact);CHKERRQ(ierr);
265       ierr = MatCholeskyFactorSymbolic(pc->pmat,dir->row,&dir->info,&dir->fact);CHKERRQ(ierr);
266       ierr = MatGetInfo(dir->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
267       dir->actualfill = info.fill_ratio_needed;
268       ierr = PetscLogObjectParent(pc,dir->fact);CHKERRQ(ierr);
269     }
270     ierr = MatCholeskyFactorNumeric(pc->pmat,&dir->info,&dir->fact);CHKERRQ(ierr);
271   }
272   PetscFunctionReturn(0);
273 }
274 
275 #undef __FUNCT__
276 #define __FUNCT__ "PCDestroy_Cholesky"
277 static PetscErrorCode PCDestroy_Cholesky(PC pc)
278 {
279   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
280   PetscErrorCode ierr;
281 
282   PetscFunctionBegin;
283   if (!dir->inplace && dir->fact) {ierr = MatDestroy(dir->fact);CHKERRQ(ierr);}
284   if (dir->row) {ierr = ISDestroy(dir->row);CHKERRQ(ierr);}
285   if (dir->col) {ierr = ISDestroy(dir->col);CHKERRQ(ierr);}
286   ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr);
287   ierr = PetscFree(dir);CHKERRQ(ierr);
288   PetscFunctionReturn(0);
289 }
290 
291 #undef __FUNCT__
292 #define __FUNCT__ "PCApply_Cholesky"
293 static PetscErrorCode PCApply_Cholesky(PC pc,Vec x,Vec y)
294 {
295   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
296   PetscErrorCode ierr;
297 
298   PetscFunctionBegin;
299   if (dir->inplace) {ierr = MatSolve(pc->pmat,x,y);CHKERRQ(ierr);}
300   else              {ierr = MatSolve(dir->fact,x,y);CHKERRQ(ierr);}
301   PetscFunctionReturn(0);
302 }
303 
304 #undef __FUNCT__
305 #define __FUNCT__ "PCApplyTranspose_Cholesky"
306 static PetscErrorCode PCApplyTranspose_Cholesky(PC pc,Vec x,Vec y)
307 {
308   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
309   PetscErrorCode ierr;
310 
311   PetscFunctionBegin;
312   if (dir->inplace) {ierr = MatSolveTranspose(pc->pmat,x,y);CHKERRQ(ierr);}
313   else              {ierr = MatSolveTranspose(dir->fact,x,y);CHKERRQ(ierr);}
314   PetscFunctionReturn(0);
315 }
316 
317 /* -----------------------------------------------------------------------------------*/
318 
319 EXTERN_C_BEGIN
320 #undef __FUNCT__
321 #define __FUNCT__ "PCFactorSetFill_Cholesky"
322 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetFill_Cholesky(PC pc,PetscReal fill)
323 {
324   PC_Cholesky *dir;
325 
326   PetscFunctionBegin;
327   dir = (PC_Cholesky*)pc->data;
328   dir->info.fill = fill;
329   PetscFunctionReturn(0);
330 }
331 EXTERN_C_END
332 
333 EXTERN_C_BEGIN
334 #undef __FUNCT__
335 #define __FUNCT__ "PCFactorSetUseInPlace_Cholesky"
336 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetUseInPlace_Cholesky(PC pc)
337 {
338   PC_Cholesky *dir;
339 
340   PetscFunctionBegin;
341   dir = (PC_Cholesky*)pc->data;
342   dir->inplace = PETSC_TRUE;
343   PetscFunctionReturn(0);
344 }
345 EXTERN_C_END
346 
347 EXTERN_C_BEGIN
348 #undef __FUNCT__
349 #define __FUNCT__ "PCFactorSetMatOrdering_Cholesky"
350 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetMatOrdering_Cholesky(PC pc,MatOrderingType ordering)
351 {
352   PC_Cholesky    *dir = (PC_Cholesky*)pc->data;
353   PetscErrorCode ierr;
354 
355   PetscFunctionBegin;
356   ierr = PetscStrfree(dir->ordering);CHKERRQ(ierr);
357   ierr = PetscStrallocpy(ordering,&dir->ordering);CHKERRQ(ierr);
358   PetscFunctionReturn(0);
359 }
360 EXTERN_C_END
361 
362 /* -----------------------------------------------------------------------------------*/
363 
364 #undef __FUNCT__
365 #define __FUNCT__ "PCFactorSetReuseOrdering"
366 /*@
367    PCFactorSetReuseOrdering - When similar matrices are factored, this
368    causes the ordering computed in the first factor to be used for all
369    following factors.
370 
371    Collective on PC
372 
373    Input Parameters:
374 +  pc - the preconditioner context
375 -  flag - PETSC_TRUE to reuse else PETSC_FALSE
376 
377    Options Database Key:
378 .  -pc_factor_reuse_ordering - Activate PCFactorSetReuseOrdering()
379 
380    Level: intermediate
381 
382 .keywords: PC, levels, reordering, factorization, incomplete, LU
383 
384 .seealso: PCFactorSetReuseFill()
385 @*/
386 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseOrdering(PC pc,PetscTruth flag)
387 {
388   PetscErrorCode ierr,(*f)(PC,PetscTruth);
389 
390   PetscFunctionBegin;
391   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
392   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetReuseOrdering_C",(void (**)(void))&f);CHKERRQ(ierr);
393   if (f) {
394     ierr = (*f)(pc,flag);CHKERRQ(ierr);
395   }
396   PetscFunctionReturn(0);
397 }
398 
399 #undef __FUNCT__
400 #define __FUNCT__ "PCFactorSetReuseFill"
401 /*@
402    PCFactorSetReuseFill - When matrices with same different nonzero structure are factored,
403    this causes later ones to use the fill ratio computed in the initial factorization.
404 
405    Collective on PC
406 
407    Input Parameters:
408 +  pc - the preconditioner context
409 -  flag - PETSC_TRUE to reuse else PETSC_FALSE
410 
411    Options Database Key:
412 .  -pc_factor_reuse_fill - Activates PCFactorSetReuseFill()
413 
414    Level: intermediate
415 
416 .keywords: PC, levels, reordering, factorization, incomplete, Cholesky
417 
418 .seealso: PCFactorSetReuseOrdering()
419 @*/
420 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseFill(PC pc,PetscTruth flag)
421 {
422   PetscErrorCode ierr,(*f)(PC,PetscTruth);
423 
424   PetscFunctionBegin;
425   PetscValidHeaderSpecific(pc,PC_COOKIE,2);
426   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCFactorSetReuseFill_C",(void (**)(void))&f);CHKERRQ(ierr);
427   if (f) {
428     ierr = (*f)(pc,flag);CHKERRQ(ierr);
429   }
430   PetscFunctionReturn(0);
431 }
432 
433 /*MC
434    PCCholesky - Uses a direct solver, based on Cholesky factorization, as a preconditioner
435 
436    Options Database Keys:
437 +  -pc_factor_reuse_ordering - Activate PCFactorSetReuseOrdering()
438 .  -pc_factor_reuse_fill - Activates PCFactorSetReuseFill()
439 .  -pc_factor_fill <fill> - Sets fill amount
440 .  -pc_factor_in_place - Activates in-place factorization
441 .  -pc_factor_mat_ordering_type <nd,rcm,...> - Sets ordering routine
442 .  -pc_factor_shift_nonzero <shift> - Sets shift amount or PETSC_DECIDE for the default
443 -  -pc_factor_shift_positive_definite [PETSC_TRUE/PETSC_FALSE] - Activate/Deactivate PCFactorSetShiftPd(); the value
444    is optional with PETSC_TRUE being the default
445 
446    Notes: Not all options work for all matrix formats
447 
448    Level: beginner
449 
450    Concepts: Cholesky factorization, direct solver
451 
452    Notes: Usually this will compute an "exact" solution in one iteration and does
453           not need a Krylov method (i.e. you can use -ksp_type preonly, or
454           KSPSetType(ksp,KSPPREONLY) for the Krylov method
455 
456 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
457            PCILU, PCLU, PCICC, PCFactorSetReuseOrdering(), PCFactorSetReuseFill(), PCGetFactoredMatrix(),
458            PCFactorSetFill(), PCFactorSetShiftNonzero(), PCFactorSetShiftPd(),
459 	   PCFactorSetUseInPlace(), PCFactorSetMatOrdering(),PCFactorSetShiftNonzero(),PCFactorSetShiftPd()
460 
461 M*/
462 
463 EXTERN_C_BEGIN
464 #undef __FUNCT__
465 #define __FUNCT__ "PCCreate_Cholesky"
466 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Cholesky(PC pc)
467 {
468   PetscErrorCode ierr;
469   PC_Cholesky    *dir;
470 
471   PetscFunctionBegin;
472   ierr = PetscNew(PC_Cholesky,&dir);CHKERRQ(ierr);
473   ierr = PetscLogObjectMemory(pc,sizeof(PC_Cholesky));CHKERRQ(ierr);
474 
475   dir->fact                   = 0;
476   dir->inplace                = PETSC_FALSE;
477   ierr = MatFactorInfoInitialize(&dir->info);CHKERRQ(ierr);
478   dir->info.fill              = 5.0;
479   dir->info.shiftnz           = 0.0;
480   dir->info.shiftpd           = 0.0; /* false */
481   dir->info.shift_fraction    = 0.0;
482   dir->info.pivotinblocks     = 1.0;
483   dir->col                    = 0;
484   dir->row                    = 0;
485   ierr = PetscStrallocpy(MATORDERING_NATURAL,&dir->ordering);CHKERRQ(ierr);
486   dir->reusefill        = PETSC_FALSE;
487   dir->reuseordering    = PETSC_FALSE;
488   pc->data              = (void*)dir;
489 
490   pc->ops->destroy           = PCDestroy_Cholesky;
491   pc->ops->apply             = PCApply_Cholesky;
492   pc->ops->applytranspose    = PCApplyTranspose_Cholesky;
493   pc->ops->setup             = PCSetUp_Cholesky;
494   pc->ops->setfromoptions    = PCSetFromOptions_Cholesky;
495   pc->ops->view              = PCView_Cholesky;
496   pc->ops->applyrichardson   = 0;
497   pc->ops->getfactoredmatrix = PCGetFactoredMatrix_Cholesky;
498 
499   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetZeroPivot_C","PCFactorSetZeroPivot_Cholesky",
500                     PCFactorSetZeroPivot_Cholesky);CHKERRQ(ierr);
501   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftNonzero_C","PCFactorSetShiftNonzero_Cholesky",
502                     PCFactorSetShiftNonzero_Cholesky);CHKERRQ(ierr);
503   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetShiftPd_C","PCFactorSetShiftPd_Cholesky",
504                     PCFactorSetShiftPd_Cholesky);CHKERRQ(ierr);
505 
506   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetFill_C","PCFactorSetFill_Cholesky",
507                     PCFactorSetFill_Cholesky);CHKERRQ(ierr);
508   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetUseInPlace_C","PCFactorSetUseInPlace_Cholesky",
509                     PCFactorSetUseInPlace_Cholesky);CHKERRQ(ierr);
510   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetMatOrdering_C","PCFactorSetMatOrdering_Cholesky",
511                     PCFactorSetMatOrdering_Cholesky);CHKERRQ(ierr);
512   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetReuseOrdering_C","PCFactorSetReuseOrdering_Cholesky",
513                     PCFactorSetReuseOrdering_Cholesky);CHKERRQ(ierr);
514   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCFactorSetReuseFill_C","PCFactorSetReuseFill_Cholesky",
515                     PCFactorSetReuseFill_Cholesky);CHKERRQ(ierr);
516   PetscFunctionReturn(0);
517 }
518 EXTERN_C_END
519