xref: /petsc/src/ksp/pc/impls/deflation/deflation.c (revision 1fdb00f988be8a1800bb0e9f9be4e7bc64bf28d3)
1 #include <../src/ksp/pc/impls/deflation/deflation.h> /*I "petscksp.h" I*/  /* includes for fortran wrappers */
2 
3 const char *const PCDeflationSpaceTypes[] = {
4   "haar",
5   "db2",
6   "db4",
7   "db8",
8   "db16",
9   "biorth22",
10   "meyer",
11   "aggregation",
12   "user",
13   "PCDeflationSpaceType",
14   "PC_DEFLATION_SPACE_",
15   0
16 };
17 
18 static PetscErrorCode PCDeflationSetInitOnly_Deflation(PC pc,PetscBool flg)
19 {
20   PC_Deflation   *def = (PC_Deflation*)pc->data;
21 
22   PetscFunctionBegin;
23   def->init = flg;
24   PetscFunctionReturn(0);
25 }
26 
27 /*@
28    PCDeflationSetInitOnly - Do only initialization step.
29     Sets initial guess to the solution on the deflation space but does not apply
30     the deflation preconditioner. The additional preconditioner is still applied.
31 
32    Logically Collective
33 
34    Input Parameters:
35 +  pc  - the preconditioner context
36 -  flg - default PETSC_FALSE
37 
38    Options Database Keys:
39 .    -pc_deflation_init_only <false> - if true computes only the special guess
40 
41    Level: intermediate
42 
43 .seealso: PCDEFLATION
44 @*/
45 PetscErrorCode PCDeflationSetInitOnly(PC pc,PetscBool flg)
46 {
47   PetscErrorCode ierr;
48 
49   PetscFunctionBegin;
50   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
51   PetscValidLogicalCollectiveBool(pc,flg,2);
52   ierr = PetscTryMethod(pc,"PCDeflationSetInitOnly_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr);
53   PetscFunctionReturn(0);
54 }
55 
56 
57 static PetscErrorCode PCDeflationSetLvl_Deflation(PC pc,PetscInt current,PetscInt max)
58 {
59   PC_Deflation   *def = (PC_Deflation*)pc->data;
60 
61   PetscFunctionBegin;
62   if (current) def->lvl = current;
63   def->maxlvl = max;
64   PetscFunctionReturn(0);
65 }
66 
67 /*@
68    PCDeflationSetMaxLvl - Set the maximum level of deflation nesting.
69 
70    Logically Collective
71 
72    Input Parameters:
73 +  pc  - the preconditioner context
74 -  max - maximum deflation level
75 
76    Options Database Keys:
77 .    -pc_deflation_max_lvl <0> - maximum number of levels for multilevel deflation
78 
79    Level: intermediate
80 
81 .seealso: PCDeflationSetSpaceToCompute(), PCDeflationSetSpace(), PCDEFLATION
82 @*/
83 PetscErrorCode PCDeflationSetMaxLvl(PC pc,PetscInt max)
84 {
85   PetscErrorCode ierr;
86 
87   PetscFunctionBegin;
88   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
89   PetscValidLogicalCollectiveInt(pc,max,2);
90   ierr = PetscTryMethod(pc,"PCDeflationSetLvl_C",(PC,PetscInt,PetscInt),(pc,0,max));CHKERRQ(ierr);
91   PetscFunctionReturn(0);
92 }
93 
94 static PetscErrorCode PCDeflationSetReductionFactor_Deflation(PC pc,PetscInt red)
95 {
96   PC_Deflation   *def = (PC_Deflation*)pc->data;
97 
98   PetscFunctionBegin;
99   def->reductionfact = red;
100   PetscFunctionReturn(0);
101 }
102 
103 /*@
104    PCDeflationSetReductionFactor - Set reduction factor for the bottom PCTELESCOPE coarse problem solver.
105 
106    Logically Collective
107 
108    Input Parameters:
109 +  pc  - the preconditioner context
110 -  red - reduction factor (or PETSC_DETERMINE)
111 
112    Options Database Keys:
113 .    -pc_deflation_reduction_factor <-1> - reduction factor on bottom level coarse problem for PCTELESCOPE
114 
115    Notes:
116      Default is computed based on the size of the coarse problem.
117 
118    Level: intermediate
119 
120 .seealso: PCTELESCOPE, PCDEFLATION
121 @*/
122 PetscErrorCode PCDeflationSetReductionFactor(PC pc,PetscInt red)
123 {
124   PetscErrorCode ierr;
125 
126   PetscFunctionBegin;
127   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
128   PetscValidLogicalCollectiveInt(pc,red,2);
129   ierr = PetscTryMethod(pc,"PCDeflationSetReductionFactor_C",(PC,PetscInt),(pc,red));CHKERRQ(ierr);
130   PetscFunctionReturn(0);
131 }
132 
133 static PetscErrorCode PCDeflationSetCorrectionFactor_Deflation(PC pc,PetscScalar fact)
134 {
135   PC_Deflation   *def = (PC_Deflation*)pc->data;
136 
137   PetscFunctionBegin;
138   /* TODO PETSC_DETERMINE -> compute max eigenvalue with power method */
139   def->correct = PETSC_TRUE;
140   def->correctfact = fact;
141   if (def->correct == 0.0) {
142     def->correct = PETSC_FALSE;
143   }
144   PetscFunctionReturn(0);
145 }
146 
147 /*@
148    PCDeflationSetCorrectionFactor - Set coarse problem correction factor.
149     The Preconditioner becomes P*M^{-1} + fact*Q.
150 
151    Logically Collective
152 
153    Input Parameters:
154 +  pc   - the preconditioner context
155 -  fact - correction factor
156 
157    Options Database Keys:
158 +    -pc_deflation_correction        <false> - if true apply coarse problem correction
159 -    -pc_deflation_correction_factor <1.0>   - sets coarse problem correction factor
160 
161    Notes:
162     Any non-zero fact enables the coarse problem correction.
163 
164    Level: intermediate
165 
166 .seealso: PCDEFLATION
167 @*/
168 PetscErrorCode PCDeflationSetCorrectionFactor(PC pc,PetscScalar fact)
169 {
170   PetscErrorCode ierr;
171 
172   PetscFunctionBegin;
173   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
174   PetscValidLogicalCollectiveScalar(pc,fact,2);
175   ierr = PetscTryMethod(pc,"PCDeflationSetCorrectionFactor_C",(PC,PetscScalar),(pc,fact));CHKERRQ(ierr);
176   PetscFunctionReturn(0);
177 }
178 
179 static PetscErrorCode PCDeflationSetSpaceToCompute_Deflation(PC pc,PCDeflationSpaceType type,PetscInt size)
180 {
181   PC_Deflation   *def = (PC_Deflation*)pc->data;
182 
183   PetscFunctionBegin;
184   if (type) def->spacetype = type;
185   if (size > 0) def->spacesize = size;
186   PetscFunctionReturn(0);
187 }
188 
189 /*@
190    PCDeflationSetSpaceToCompute - Set deflation space type and size to compute.
191 
192    Logically Collective
193 
194    Input Parameters:
195 +  pc   - the preconditioner context
196 .  type - deflation space type to compute (or PETSC_IGNORE)
197 -  size - size of the space to compute (or PETSC_DEFAULT)
198 
199    Options Database Keys:
200 +    -pc_deflation_compute_space      <haar> - compute PCDeflationSpaceType deflation space
201 -    -pc_deflation_compute_space_size <1>    - size of the deflation space
202 
203    Notes:
204     For wavelet-based deflation, size represents number of levels.
205 
206     The deflation space is computed in PCSetUP().
207 
208    Level: intermediate
209 
210 .seealso: PCDeflationSetMaxLvl(), PCDEFLATION
211 @*/
212 PetscErrorCode PCDeflationSetSpaceToCompute(PC pc,PCDeflationSpaceType type,PetscInt size)
213 {
214   PetscErrorCode ierr;
215 
216   PetscFunctionBegin;
217   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
218   if (type) PetscValidLogicalCollectiveEnum(pc,type,2);
219   if (size > 0) PetscValidLogicalCollectiveInt(pc,size,3);
220   ierr = PetscTryMethod(pc,"PCDeflationSetSpaceToCompute_C",(PC,PCDeflationSpaceType,PetscInt),(pc,type,size));CHKERRQ(ierr);
221   PetscFunctionReturn(0);
222 }
223 
224 static PetscErrorCode PCDeflationSetSpace_Deflation(PC pc,Mat W,PetscBool transpose)
225 {
226   PC_Deflation   *def = (PC_Deflation*)pc->data;
227   PetscErrorCode ierr;
228 
229   PetscFunctionBegin;
230   if (transpose) {
231     def->Wt = W;
232     def->W = NULL;
233   } else {
234     def->W = W;
235   }
236   ierr = PetscObjectReference((PetscObject)W);CHKERRQ(ierr);
237   PetscFunctionReturn(0);
238 }
239 
240 /*@
241    PCDeflationSetSpace - Set the deflation space matrix (or its (hermitian) transpose).
242 
243    Logically Collective
244 
245    Input Parameters:
246 +  pc        - the preconditioner context
247 .  W         - deflation matrix
248 -  transpose - indicates that W is an explicit transpose of the deflation matrix
249 
250    Notes:
251     Setting W as a multipliplicative MATCOMPOSITE enables use of the multilevel
252     deflation. If W = W0*W1*W2*...*Wn, W0 is taken as the first deflation space and
253     the coarse problem (W0'*A*W0)^{-1} is again preconditioned by deflation with
254     W1 as the deflation matrix. This repeats until the maximum level set by
255     PCDeflationSetMaxLvl is reached or there are no more matrices available.
256     If there are matrices left after reaching the maximum level,
257     they are merged into a deflation matrix ...*W{n-1}*Wn.
258 
259    Level: intermediate
260 
261 .seealso: PCDeflationSetMaxLvl(), PCDEFLATION
262 @*/
263 PetscErrorCode PCDeflationSetSpace(PC pc,Mat W,PetscBool transpose)
264 {
265   PetscErrorCode ierr;
266 
267   PetscFunctionBegin;
268   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
269   PetscValidHeaderSpecific(W,MAT_CLASSID,2);
270   PetscValidLogicalCollectiveBool(pc,transpose,3);
271   ierr = PetscTryMethod(pc,"PCDeflationSetSpace_C",(PC,Mat,PetscBool),(pc,W,transpose));CHKERRQ(ierr);
272   PetscFunctionReturn(0);
273 }
274 
275 static PetscErrorCode PCDeflationSetProjectionNullSpaceMat_Deflation(PC pc,Mat mat)
276 {
277   PC_Deflation     *def = (PC_Deflation*)pc->data;
278   PetscErrorCode   ierr;
279 
280   PetscFunctionBegin;
281   ierr = MatDestroy(&def->WtA);CHKERRQ(ierr);
282   def->WtA = mat;
283   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
284   ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtA);CHKERRQ(ierr);
285   PetscFunctionReturn(0);
286 }
287 
288 /*@
289    PCDeflationSetProjectionNullSpaceMat - Set the projection null space matrix (W'*A).
290 
291    Collective
292 
293    Input Parameters:
294 +  pc  - preconditioner context
295 -  mat - projection null space matrix
296 
297    Level: developer
298 
299 .seealso: PCDEFLATION
300 @*/
301 PetscErrorCode  PCDeflationSetProjectionNullSpaceMat(PC pc,Mat mat)
302 {
303   PetscErrorCode ierr;
304 
305   PetscFunctionBegin;
306   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
307   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
308   ierr = PetscTryMethod(pc,"PCDeflationSetProjectionNullSpaceMat_C",(PC,Mat),(pc,mat));CHKERRQ(ierr);
309   PetscFunctionReturn(0);
310 }
311 
312 static PetscErrorCode PCDeflationSetCoarseMat_Deflation(PC pc,Mat mat)
313 {
314   PC_Deflation     *def = (PC_Deflation*)pc->data;
315   PetscErrorCode   ierr;
316 
317   PetscFunctionBegin;
318   ierr = MatDestroy(&def->WtAW);CHKERRQ(ierr);
319   def->WtAW = mat;
320   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
321   ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtAW);CHKERRQ(ierr);
322   PetscFunctionReturn(0);
323 }
324 
325 /*@
326    PCDeflationSetCoarseMat - Set the coarse problem Mat.
327 
328    Collective
329 
330    Input Parameters:
331 +  pc  - preconditioner context
332 -  mat - coarse problem mat
333 
334    Level: developer
335 
336 .seealso: PCDEFLATION
337 @*/
338 PetscErrorCode  PCDeflationSetCoarseMat(PC pc,Mat mat)
339 {
340   PetscErrorCode ierr;
341 
342   PetscFunctionBegin;
343   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
344   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
345   ierr = PetscTryMethod(pc,"PCDeflationSetCoarseMat_C",(PC,Mat),(pc,mat));CHKERRQ(ierr);
346   PetscFunctionReturn(0);
347 }
348 
349 static PetscErrorCode PCDeflationGetCoarseKSP_Deflation(PC pc,KSP *ksp)
350 {
351   PC_Deflation     *def = (PC_Deflation*)pc->data;
352 
353   PetscFunctionBegin;
354   *ksp = def->WtAWinv;
355   PetscFunctionReturn(0);
356 }
357 
358 /*@
359    PCDeflationGetCoarseKSP - Returns a pointer to the coarse problem KSP.
360 
361    Not Collective
362 
363    Input Parameters:
364 .  pc - preconditioner context
365 
366    Output Parameters:
367 .  ksp - coarse problem KSP context
368 
369    Level: advanced
370 
371 .seealso: PCDeflationSetCoarseKSP(), PCDEFLATION
372 @*/
373 PetscErrorCode  PCDeflationGetCoarseKSP(PC pc,KSP *ksp)
374 {
375   PetscErrorCode ierr;
376 
377   PetscFunctionBegin;
378   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
379   PetscValidPointer(ksp,2);
380   ierr = PetscTryMethod(pc,"PCDeflationGetCoarseKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr);
381   PetscFunctionReturn(0);
382 }
383 
384 static PetscErrorCode PCDeflationSetCoarseKSP_Deflation(PC pc,KSP ksp)
385 {
386   PC_Deflation     *def = (PC_Deflation*)pc->data;
387   PetscErrorCode   ierr;
388 
389   PetscFunctionBegin;
390   ierr = KSPDestroy(&def->WtAWinv);CHKERRQ(ierr);
391   def->WtAWinv = ksp;
392   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
393   ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->WtAWinv);CHKERRQ(ierr);
394   PetscFunctionReturn(0);
395 }
396 
397 /*@
398    PCDeflationSetCoarseKSP - Set the coarse problem KSP.
399 
400    Collective
401 
402    Input Parameters:
403 +  pc  - preconditioner context
404 -  ksp - coarse problem KSP context
405 
406    Level: developer
407 
408 .seealso: PCDeflationGetCoarseKSP(), PCDEFLATION
409 @*/
410 PetscErrorCode  PCDeflationSetCoarseKSP(PC pc,KSP ksp)
411 {
412   PetscErrorCode ierr;
413 
414   PetscFunctionBegin;
415   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
416   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
417   PetscCheckSameComm(pc,1,ksp,2);
418   ierr = PetscTryMethod(pc,"PCDeflationSetCoarseKSP_C",(PC,KSP),(pc,ksp));CHKERRQ(ierr);
419   PetscFunctionReturn(0);
420 }
421 
422 static PetscErrorCode PCDeflationGetPC_Deflation(PC pc,PC *apc)
423 {
424   PC_Deflation   *def = (PC_Deflation*)pc->data;
425 
426   PetscFunctionBegin;
427   *apc = def->pc;
428   PetscFunctionReturn(0);
429 }
430 
431 /*@
432    PCDeflationGetPC - Returns a pointer to the additional preconditioner.
433 
434    Not Collective
435 
436    Input Parameters:
437 .  pc  - the preconditioner context
438 
439    Output Parameters:
440 .  apc - additional preconditioner
441 
442    Level: advanced
443 
444 .seealso: PCDeflationSetPC(), PCDEFLATION
445 @*/
446 PetscErrorCode PCDeflationGetPC(PC pc,PC *apc)
447 {
448   PetscErrorCode ierr;
449 
450   PetscFunctionBegin;
451   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
452   PetscValidPointer(pc,2);
453   ierr = PetscTryMethod(pc,"PCDeflationGetPC_C",(PC,PC*),(pc,apc));CHKERRQ(ierr);
454   PetscFunctionReturn(0);
455 }
456 
457 static PetscErrorCode PCDeflationSetPC_Deflation(PC pc,PC apc)
458 {
459   PC_Deflation   *def = (PC_Deflation*)pc->data;
460   PetscErrorCode ierr;
461 
462   PetscFunctionBegin;
463   ierr = PCDestroy(&def->pc);CHKERRQ(ierr);
464   def->pc = apc;
465   ierr = PetscObjectReference((PetscObject)apc);CHKERRQ(ierr);
466   ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)def->pc);CHKERRQ(ierr);
467   PetscFunctionReturn(0);
468 }
469 
470 /*@
471    PCDeflationSetPC - Set the additional preconditioner.
472 
473    Collective
474 
475    Input Parameters:
476 +  pc  - the preconditioner context
477 -  apc - additional preconditioner
478 
479    Level: developer
480 
481 .seealso: PCDeflationGetPC(), PCDEFLATION
482 @*/
483 PetscErrorCode PCDeflationSetPC(PC pc,PC apc)
484 {
485   PetscErrorCode ierr;
486 
487   PetscFunctionBegin;
488   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
489   PetscValidHeaderSpecific(apc,PC_CLASSID,2);
490   PetscCheckSameComm(pc,1,apc,2);
491   ierr = PetscTryMethod(pc,"PCDeflationSetPC_C",(PC,PC),(pc,apc));CHKERRQ(ierr);
492   PetscFunctionReturn(0);
493 }
494 
495 /*
496   x <- x + W*(W'*A*W)^{-1}*W'*r  = x + Q*r
497 */
498 static PetscErrorCode PCPreSolve_Deflation(PC pc,KSP ksp,Vec b, Vec x)
499 {
500   PC_Deflation     *def = (PC_Deflation*)pc->data;
501   Mat              A;
502   Vec              r,w1,w2;
503   PetscBool        nonzero;
504   PetscErrorCode   ierr;
505 
506   PetscFunctionBegin;
507   w1 = def->workcoarse[0];
508   w2 = def->workcoarse[1];
509   r  = def->work;
510   ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr);
511 
512   ierr = KSPGetInitialGuessNonzero(ksp,&nonzero);CHKERRQ(ierr);
513   ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr);
514   if (nonzero) {
515     ierr = MatMult(A,x,r);CHKERRQ(ierr);                          /*    r  <- b - Ax              */
516     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
517   } else {
518     ierr = VecCopy(b,r);CHKERRQ(ierr);                            /*    r  <- b (x is 0)          */
519   }
520 
521   if (def->Wt) {
522     ierr = MatMult(def->Wt,r,w1);CHKERRQ(ierr);                   /*    w1 <- W'*r                */
523   } else {
524     ierr = MatMultHermitianTranspose(def->W,r,w1);CHKERRQ(ierr);  /*    w1 <- W'*r                */
525   }
526   ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr);              /*    w2 <- (W'*A*W)^{-1}*w1    */
527   ierr = MatMult(def->W,w2,r);CHKERRQ(ierr);                      /*    r  <- W*w2                */
528   ierr = VecAYPX(x,1.0,r);CHKERRQ(ierr);
529   PetscFunctionReturn(0);
530 }
531 
532 /*
533   if (def->correct) {
534     z <- M^{-1}r - W*(W'*A*W)^{-1}*(W'*A*M^{-1}r - l*W'*r) = (P*M^{-1} + l*Q)*r
535   } else {
536     z <- M^{-1}*r - W*(W'*A*W)^{-1}*W'*A*M{-1}*r = P*M^{-1}*r
537   }
538 */
539 static PetscErrorCode PCApply_Deflation(PC pc,Vec r,Vec z)
540 {
541   PC_Deflation     *def = (PC_Deflation*)pc->data;
542   Mat              A;
543   Vec              u,w1,w2;
544   PetscErrorCode   ierr;
545 
546   PetscFunctionBegin;
547   w1 = def->workcoarse[0];
548   w2 = def->workcoarse[1];
549   u  = def->work;
550   ierr = PCGetOperators(pc,NULL,&A);CHKERRQ(ierr);
551 
552   ierr = PCApply(def->pc,r,z);CHKERRQ(ierr);                          /*    z <- M^{-1}*r             */
553   if (!def->init) {
554     ierr = MatMult(def->WtA,z,w1);CHKERRQ(ierr);                      /*    w1 <- W'*A*z              */
555     if (def->correct) {
556       if (def->Wt) {
557         ierr = MatMult(def->Wt,r,w2);CHKERRQ(ierr);                   /*    w2 <- W'*r                */
558       } else {
559         ierr = MatMultHermitianTranspose(def->W,r,w2);CHKERRQ(ierr);  /*    w2 <- W'*r                */
560       }
561       ierr = VecAXPY(w1,-1.0*def->correctfact,w2);CHKERRQ(ierr);      /*    w1 <- w1 - l*w2           */
562     }
563     ierr = KSPSolve(def->WtAWinv,w1,w2);CHKERRQ(ierr);                /*    w2 <- (W'*A*W)^{-1}*w1    */
564     ierr = MatMult(def->W,w2,u);CHKERRQ(ierr);                        /*    u  <- W*w2                */
565     ierr = VecAXPY(z,-1.0,u);CHKERRQ(ierr);                           /*    z  <- z - u               */
566   }
567   PetscFunctionReturn(0);
568 }
569 
570 static PetscErrorCode PCSetUp_Deflation(PC pc)
571 {
572   PC_Deflation     *def = (PC_Deflation*)pc->data;
573   KSP              innerksp;
574   PC               pcinner;
575   Mat              Amat,nextDef=NULL,*mats;
576   PetscInt         i,m,red,size,commsize;
577   PetscBool        match,flgspd,transp=PETSC_FALSE;
578   MatCompositeType ctype;
579   MPI_Comm         comm;
580   char             prefix[128]="";
581   PetscErrorCode   ierr;
582 
583   PetscFunctionBegin;
584   if (pc->setupcalled) PetscFunctionReturn(0);
585   ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr);
586   ierr = PCGetOperators(pc,NULL,&Amat);CHKERRQ(ierr);
587   if (!def->lvl && !def->prefix) {
588     ierr = PCGetOptionsPrefix(pc,&def->prefix);CHKERRQ(ierr);
589   }
590   if (def->lvl) {
591     sprintf(prefix,"%d_",(int)def->lvl);
592   }
593 
594   /* compute a deflation space */
595   if (def->W || def->Wt) {
596     def->spacetype = PC_DEFLATION_SPACE_USER;
597   } else {
598     ierr = PCDeflationComputeSpace(pc);CHKERRQ(ierr);
599   }
600 
601   /* nested deflation */
602   if (def->W) {
603     ierr = PetscObjectTypeCompare((PetscObject)def->W,MATCOMPOSITE,&match);CHKERRQ(ierr);
604     if (match) {
605       ierr = MatCompositeGetType(def->W,&ctype);CHKERRQ(ierr);
606       ierr = MatCompositeGetNumberMat(def->W,&size);CHKERRQ(ierr);
607     }
608   } else {
609     ierr = MatCreateHermitianTranspose(def->Wt,&def->W);CHKERRQ(ierr);
610     ierr = PetscObjectTypeCompare((PetscObject)def->Wt,MATCOMPOSITE,&match);CHKERRQ(ierr);
611     if (match) {
612       ierr = MatCompositeGetType(def->Wt,&ctype);CHKERRQ(ierr);
613       ierr = MatCompositeGetNumberMat(def->Wt,&size);CHKERRQ(ierr);
614     }
615     transp = PETSC_TRUE;
616   }
617   if (match && ctype == MAT_COMPOSITE_MULTIPLICATIVE) {
618     if (!transp) {
619       if (def->lvl < def->maxlvl) {
620         ierr = PetscMalloc1(size,&mats);CHKERRQ(ierr);
621         for (i=0; i<size; i++) {
622           ierr = MatCompositeGetMat(def->W,i,&mats[i]);CHKERRQ(ierr);
623         }
624         size -= 1;
625         ierr = MatDestroy(&def->W);CHKERRQ(ierr);
626         def->W = mats[size];
627         ierr = PetscObjectReference((PetscObject)mats[size]);CHKERRQ(ierr);
628         if (size > 1) {
629           ierr = MatCreateComposite(comm,size,mats,&nextDef);CHKERRQ(ierr);
630           ierr = MatCompositeSetType(nextDef,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr);
631         } else {
632           nextDef = mats[0];
633           ierr = PetscObjectReference((PetscObject)mats[0]);CHKERRQ(ierr);
634         }
635         ierr = PetscFree(mats);CHKERRQ(ierr);
636       } else {
637         /* TODO test merge side performance */
638         /* ierr = MatCompositeSetMergeType(def->W,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); */
639         ierr = MatCompositeMerge(def->W);CHKERRQ(ierr);
640       }
641     } else {
642       if (def->lvl < def->maxlvl) {
643         ierr = PetscMalloc1(size,&mats);CHKERRQ(ierr);
644         for (i=0; i<size; i++) {
645           ierr = MatCompositeGetMat(def->Wt,i,&mats[i]);CHKERRQ(ierr);
646         }
647         size -= 1;
648         ierr = MatDestroy(&def->Wt);CHKERRQ(ierr);
649         def->Wt = mats[0];
650         ierr = PetscObjectReference((PetscObject)mats[0]);CHKERRQ(ierr);
651         if (size > 1) {
652           ierr = MatCreateComposite(comm,size,&mats[1],&nextDef);CHKERRQ(ierr);
653           ierr = MatCompositeSetType(nextDef,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr);
654         } else {
655           nextDef = mats[1];
656           ierr = PetscObjectReference((PetscObject)mats[1]);CHKERRQ(ierr);
657         }
658         ierr = PetscFree(mats);CHKERRQ(ierr);
659       } else {
660         /* ierr = MatCompositeSetMergeType(def->W,MAT_COMPOSITE_MERGE_LEFT);CHKERRQ(ierr); */
661         ierr = MatCompositeMerge(def->Wt);CHKERRQ(ierr);
662       }
663     }
664   }
665 
666   if (transp) {
667     ierr = MatDestroy(&def->W);CHKERRQ(ierr);
668     ierr = MatHermitianTranspose(def->Wt,MAT_INITIAL_MATRIX,&def->W);CHKERRQ(ierr);
669   }
670 
671   /* assemble WtA */
672   if (!def->WtA) {
673     if (def->Wt) {
674       ierr = MatMatMult(def->Wt,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr);
675     } else {
676 #if defined(PETSC_USE_COMPLEX)
677       ierr = MatHermitianTranspose(def->W,MAT_INITIAL_MATRIX,&def->Wt);CHKERRQ(ierr);
678       ierr = MatMatMult(def->Wt,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr);
679 #else
680       ierr = MatTransposeMatMult(def->W,Amat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtA);CHKERRQ(ierr);
681 #endif
682     }
683   }
684   /* setup coarse problem */
685   if (!def->WtAWinv) {
686     ierr = MatGetSize(def->W,NULL,&m);CHKERRQ(ierr);
687     if (!def->WtAW) {
688       ierr = MatMatMult(def->WtA,def->W,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&def->WtAW);CHKERRQ(ierr);
689       /* TODO create MatInheritOption(Mat,MatOption) */
690       ierr = MatGetOption(Amat,MAT_SPD,&flgspd);CHKERRQ(ierr);
691       ierr = MatSetOption(def->WtAW,MAT_SPD,flgspd);CHKERRQ(ierr);
692 #if defined(PETSC_USE_DEBUG)
693       /* Check columns of W are not in kernel of A */
694       PetscReal *norms;
695       ierr = PetscMalloc1(m,&norms);CHKERRQ(ierr);
696       ierr = MatGetColumnNorms(def->WtAW,NORM_INFINITY,norms);CHKERRQ(ierr);
697       for (i=0; i<m; i++) {
698         if (norms[i] < 100*PETSC_MACHINE_EPSILON) {
699           SETERRQ1(comm,PETSC_ERR_SUP,"Column %D of W is in kernel of A.",i);
700         }
701       }
702       ierr = PetscFree(norms);CHKERRQ(ierr);
703 #endif
704     } else {
705       ierr = MatGetOption(def->WtAW,MAT_SPD,&flgspd);CHKERRQ(ierr);
706     }
707     /* TODO use MATINV ? */
708     ierr = KSPCreate(comm,&def->WtAWinv);CHKERRQ(ierr);
709     ierr = KSPSetOperators(def->WtAWinv,def->WtAW,def->WtAW);CHKERRQ(ierr);
710     ierr = KSPGetPC(def->WtAWinv,&pcinner);CHKERRQ(ierr);
711     /* Setup KSP and PC */
712     if (nextDef) { /* next level for multilevel deflation */
713       innerksp = def->WtAWinv;
714       /* set default KSPtype */
715       if (!def->ksptype) {
716         def->ksptype = KSPFGMRES;
717         if (flgspd) { /* SPD system */
718           def->ksptype = KSPFCG;
719         }
720       }
721       ierr = KSPSetType(innerksp,def->ksptype);CHKERRQ(ierr); /* TODO iherit from KSP + tolerances */
722       ierr = PCSetType(pcinner,PCDEFLATION);CHKERRQ(ierr); /* TODO create coarse preconditinoner M_c = WtMW ? */
723       ierr = PCDeflationSetSpace(pcinner,nextDef,transp);CHKERRQ(ierr);
724       ierr = PCDeflationSetLvl_Deflation(pcinner,def->lvl+1,def->maxlvl);CHKERRQ(ierr);
725       /* inherit options */
726       if (def->prefix) ((PC_Deflation*)(pcinner->data))->prefix = def->prefix;
727       ((PC_Deflation*)(pcinner->data))->init          = def->init;
728       ((PC_Deflation*)(pcinner->data))->ksptype       = def->ksptype;
729       ((PC_Deflation*)(pcinner->data))->correct       = def->correct;
730       ((PC_Deflation*)(pcinner->data))->correctfact   = def->correctfact;
731       ((PC_Deflation*)(pcinner->data))->reductionfact = def->reductionfact;
732       ierr = MatDestroy(&nextDef);CHKERRQ(ierr);
733     } else { /* the last level */
734       ierr = KSPSetType(def->WtAWinv,KSPPREONLY);CHKERRQ(ierr);
735       ierr = PCSetType(pcinner,PCTELESCOPE);CHKERRQ(ierr);
736       /* do not overwrite PCTELESCOPE */
737       if (def->prefix) {
738         ierr = KSPSetOptionsPrefix(def->WtAWinv,def->prefix);CHKERRQ(ierr);
739       }
740       ierr = KSPAppendOptionsPrefix(def->WtAWinv,"def_tel_");CHKERRQ(ierr);
741       ierr = PCSetFromOptions(pcinner);CHKERRQ(ierr);
742       /* Reduction factor choice */
743       red = def->reductionfact;
744       if (red < 0) {
745         ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr);
746         red  = ceil((float)commsize/ceil((float)m/commsize));
747         ierr = PetscObjectTypeCompareAny((PetscObject)(def->WtAW),&match,MATSEQDENSE,MATMPIDENSE,MATDENSE,"");CHKERRQ(ierr);
748         if (match) red = commsize;
749         ierr = PetscInfo1(pc,"Auto choosing reduction factor %D\n",red);CHKERRQ(ierr);
750       }
751       ierr = PCTelescopeSetReductionFactor(pcinner,red);CHKERRQ(ierr);
752       ierr = PCSetUp(pcinner);CHKERRQ(ierr);
753       ierr = PCTelescopeGetKSP(pcinner,&innerksp);CHKERRQ(ierr);
754       if (innerksp) {
755         ierr = KSPGetPC(innerksp,&pcinner);CHKERRQ(ierr);
756         ierr = PCSetType(pcinner,PCLU);CHKERRQ(ierr);
757 #if defined(PETSC_HAVE_SUPERLU)
758         ierr = MatGetFactorAvailable(def->WtAW,MATSOLVERSUPERLU,MAT_FACTOR_LU,&match);CHKERRQ(ierr);
759         if (match) {
760           ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU);CHKERRQ(ierr);
761         }
762 #endif
763 #if defined(PETSC_HAVE_SUPERLU_DIST)
764         ierr = MatGetFactorAvailable(def->WtAW,MATSOLVERSUPERLU_DIST,MAT_FACTOR_LU,&match);CHKERRQ(ierr);
765         if (match) {
766           ierr = PCFactorSetMatSolverType(pcinner,MATSOLVERSUPERLU_DIST);CHKERRQ(ierr);
767         }
768 #endif
769       }
770     }
771 
772     if (innerksp) {
773       if (def->prefix) {
774         ierr = KSPSetOptionsPrefix(innerksp,def->prefix);CHKERRQ(ierr);
775         ierr = KSPAppendOptionsPrefix(innerksp,"def_");CHKERRQ(ierr);
776       } else {
777         ierr = KSPSetOptionsPrefix(innerksp,"def_");CHKERRQ(ierr);
778       }
779       ierr = KSPAppendOptionsPrefix(innerksp,prefix);CHKERRQ(ierr);
780       ierr = KSPSetFromOptions(innerksp);CHKERRQ(ierr);
781       ierr = KSPSetUp(innerksp);CHKERRQ(ierr);
782     }
783   }
784   ierr = KSPSetFromOptions(def->WtAWinv);CHKERRQ(ierr);
785   ierr = KSPSetUp(def->WtAWinv);CHKERRQ(ierr);
786 
787   /* create preconditioner */
788   if (!def->pc) {
789     ierr = PCCreate(comm,&def->pc);CHKERRQ(ierr);
790     ierr = PCSetOperators(def->pc,Amat,Amat);CHKERRQ(ierr);
791     ierr = PCSetType(def->pc,PCNONE);CHKERRQ(ierr);
792     if (def->prefix) {
793       ierr = PCSetOptionsPrefix(def->pc,def->prefix);CHKERRQ(ierr);
794     }
795     ierr = PCAppendOptionsPrefix(def->pc,"def_");CHKERRQ(ierr);
796     ierr = PCAppendOptionsPrefix(def->pc,prefix);CHKERRQ(ierr);
797     ierr = PCAppendOptionsPrefix(def->pc,"pc_");CHKERRQ(ierr);
798     ierr = PCSetFromOptions(def->pc);CHKERRQ(ierr);
799     ierr = PCSetUp(def->pc);CHKERRQ(ierr);
800   }
801 
802   /* create work vecs */
803   ierr = MatCreateVecs(Amat,NULL,&def->work);CHKERRQ(ierr);
804   ierr = KSPCreateVecs(def->WtAWinv,2,&def->workcoarse,0,NULL);CHKERRQ(ierr);
805   PetscFunctionReturn(0);
806 }
807 
808 static PetscErrorCode PCReset_Deflation(PC pc)
809 {
810   PC_Deflation      *def = (PC_Deflation*)pc->data;
811   PetscErrorCode    ierr;
812 
813   PetscFunctionBegin;
814   ierr = VecDestroy(&def->work);CHKERRQ(ierr);
815   ierr = VecDestroyVecs(2,&def->workcoarse);CHKERRQ(ierr);
816   ierr = MatDestroy(&def->W);CHKERRQ(ierr);
817   ierr = MatDestroy(&def->Wt);CHKERRQ(ierr);
818   ierr = MatDestroy(&def->WtA);CHKERRQ(ierr);
819   ierr = MatDestroy(&def->WtAW);CHKERRQ(ierr);
820   ierr = KSPDestroy(&def->WtAWinv);CHKERRQ(ierr);
821   ierr = PCDestroy(&def->pc);CHKERRQ(ierr);
822   PetscFunctionReturn(0);
823 }
824 
825 static PetscErrorCode PCDestroy_Deflation(PC pc)
826 {
827   PetscErrorCode ierr;
828 
829   PetscFunctionBegin;
830   ierr = PCReset_Deflation(pc);CHKERRQ(ierr);
831   ierr = PetscFree(pc->data);CHKERRQ(ierr);
832   PetscFunctionReturn(0);
833 }
834 
835 static PetscErrorCode PCView_Deflation(PC pc,PetscViewer viewer)
836 {
837   PC_Deflation      *def = (PC_Deflation*)pc->data;
838   PetscInt          its;
839   PetscBool         iascii;
840   PetscErrorCode    ierr;
841 
842   PetscFunctionBegin;
843   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
844   if (iascii) {
845     if (def->correct) {
846       ierr = PetscViewerASCIIPrintf(viewer,"using CP correction, factor = %g+%gi\n",
847                                     (double)PetscRealPart(def->correctfact),
848                                     (double)PetscImaginaryPart(def->correctfact));CHKERRQ(ierr);
849     }
850     if (!def->lvl) {
851       ierr = PetscViewerASCIIPrintf(viewer,"deflation space type: %s\n",PCDeflationSpaceTypes[def->spacetype]);CHKERRQ(ierr);
852     }
853 
854     ierr = PetscViewerASCIIPrintf(viewer,"--- Additional PC:\n");CHKERRQ(ierr);
855     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
856     ierr = PCView(def->pc,viewer);CHKERRQ(ierr);
857     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
858 
859     ierr = PetscViewerASCIIPrintf(viewer,"--- Coarse problem solver:\n");CHKERRQ(ierr);
860     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
861     ierr = KSPGetTotalIterations(def->WtAWinv,&its);CHKERRQ(ierr);
862     ierr = PetscViewerASCIIPrintf(viewer,"total number of iterations: %D\n",its);CHKERRQ(ierr);
863     ierr = KSPView(def->WtAWinv,viewer);CHKERRQ(ierr);
864     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
865   }
866   PetscFunctionReturn(0);
867 }
868 
869 static PetscErrorCode PCSetFromOptions_Deflation(PetscOptionItems *PetscOptionsObject,PC pc)
870 {
871   PC_Deflation      *def = (PC_Deflation*)pc->data;
872   PetscErrorCode    ierr;
873 
874   PetscFunctionBegin;
875   ierr = PetscOptionsHead(PetscOptionsObject,"Deflation options");CHKERRQ(ierr);
876   ierr = PetscOptionsBool("-pc_deflation_init_only","Use only initialization step - Initdef","PCDeflationSetInitOnly",def->init,&def->init,NULL);CHKERRQ(ierr);
877   ierr = PetscOptionsInt("-pc_deflation_max_lvl","Maximum of deflation levels","PCDeflationSetMaxLvl",def->maxlvl,&def->maxlvl,NULL);CHKERRQ(ierr);
878   ierr = PetscOptionsInt("-pc_deflation_reduction_factor","Reduction factor for coarse problem solution using PCTELESCOPE","PCDeflationSetReductionFactor",def->reductionfact,&def->reductionfact,NULL);CHKERRQ(ierr);
879   ierr = PetscOptionsBool("-pc_deflation_correction","Add coarse problem correction Q to P","PCDeflationSetCorrectionFactor",def->correct,&def->correct,NULL);CHKERRQ(ierr);
880   ierr = PetscOptionsScalar("-pc_deflation_correction_factor","Set multiple of Q to use as coarse problem correction","PCDeflationSetCorrectionFactor",def->correctfact,&def->correctfact,NULL);CHKERRQ(ierr);
881   ierr = PetscOptionsEnum("-pc_deflation_compute_space","Compute deflation space","PCDeflationSetSpace",PCDeflationSpaceTypes,(PetscEnum)def->spacetype,(PetscEnum*)&def->spacetype,NULL);CHKERRQ(ierr);
882   ierr = PetscOptionsInt("-pc_deflation_compute_space_size","Set size of the deflation space to compute","PCDeflationSetSpace",def->spacesize,&def->spacesize,NULL);CHKERRQ(ierr);
883   ierr = PetscOptionsBool("-pc_deflation_space_extend","Extend deflation space instead of truncating (wavelets)","PCDeflation",def->extendsp,&def->extendsp,NULL);CHKERRQ(ierr);
884   ierr = PetscOptionsTail();CHKERRQ(ierr);
885   PetscFunctionReturn(0);
886 }
887 
888 /*MC
889    PCDEFLATION - Deflation preconditioner shifts (deflates) part of the spectrum to zero or to a predefined value.
890 
891    Options Database Keys:
892 +    -pc_deflation_init_only          <false> - if true computes only the special guess
893 .    -pc_deflation_max_lvl            <0>     - maximum number of levels for multilevel deflation
894 .    -pc_deflation_reduction_factor <-1>      - reduction factor on bottom level coarse problem for PCTELESCOPE (default based on the size of the coarse problem)
895 .    -pc_deflation_correction         <false> - if true apply coarse problem correction
896 .    -pc_deflation_correction_factor  <1.0>   - sets coarse problem correction factor
897 .    -pc_deflation_compute_space      <haar>  - compute PCDeflationSpaceType deflation space
898 -    -pc_deflation_compute_space_size <1>     - size of the deflation space (corresponds to number of levels for wavelet-based deflation)
899 
900    Notes:
901     Given a (complex - transpose is always hermitian) full rank deflation matrix W, the deflation (introduced in [1,2])
902     preconditioner uses projections Q = W*(W'*A*W)^{-1}*W' and P = I - Q*A, where A is pmat.
903 
904     The deflation computes initial guess x0 = x_{-1} - Q*r_{-1}, which is the solution on the deflation space.
905     If PCDeflationSetInitOnly() or -pc_deflation_init_only is set to PETSC_TRUE (InitDef scheme), the application of the
906     preconditioner consists only of application of the additional preconditioner M^{-1}. Otherwise, the preconditioner
907     application consists of P*M^{-1} + factor*Q. The first part of the preconditioner (PM^{-1}) shifts some eigenvalues
908     to zero while the addition of the coarse problem correction (factor*Q) makes the preconditioner to shift some
909     eigenvalues to the given factor. The InitDef scheme is recommended for deflation using high accuracy estimates
910     of eigenvectors of A when it exhibits similar convergence to the full deflation but is cheaper.
911 
912     The deflation matrix is by default automatically computed. The type of deflation matrix and its size to compute can
913     be controlled by PCDeflationSetSpaceToCompute() or -pc_deflation_compute_space and -pc_deflation_compute_space_size.
914     User can set an arbitrary deflation space matrix with PCDeflationSetSpace(). If the deflation matrix
915     is a multiplicative MATCOMPOSITE, a multilevel deflation [3] is used. The first matrix in the composite is used as the
916     deflation matrix, and the coarse problem (W'*A*W)^{-1} is solved by KSPFCG (if A is MAT_SPD) or KSPFGMRES preconditioned
917     by deflation with deflation matrix being the next matrix in the MATCOMPOSITE. This scheme repeats until the maximum
918     level is reached or there are no more matrices. If the maximum level is reached, the remaining matrices are merged
919     (multiplied) to create the last deflation matrix. The maximum level defaults to 0 and can be set by
920     PCDeflationSetMaxLvl() or by -pc_deflation_max_lvl.
921 
922     The coarse problem KSP can be controlled from the command line with prefix -def_ for the first level and -def_[lvl-1]
923     from the second level onward. You can also use
924     PCDeflationGetCoarseKSP() or PCDeflationSetCoarseKSP() to control it from code. The bottom level KSP defaults to
925     KSPPREONLY with PCLU direct solver (MATSOLVERSUPERLU/MATSOLVERSUPERLU_DIST if available) wrapped into PCTELESCOPE.
926     For convenience, the reduction factor can be set by PCDeflationSetReductionFactor()
927     or -pc_deflation_recduction_factor. The default is chosen heuristically based on the coarse problem size.
928 
929     The additional preconditioner can be controlled from command line with prefix -def_[lvl]_pc (same rules used for
930     coarse problem KSP apply for [lvl]_ part of prefix), e.g., -def_1_pc_pc_type bjacobi. You can also use
931     PCDeflationGetPC() or PCDeflationSetPC() to control the additional preconditioner from code. It defaults to PCNONE.
932 
933     The coarse problem correction term (factor*Q) can be turned on by -pc_deflation_correction and the factor value can
934     be set by pc_deflation_correction_factor or by PCDeflationSetCorrectionFactor(). The coarse problem can
935     significantly improve convergence when the deflation coarse problem is not solved with high enough accuracy. We
936     recommend setting factor to some eigenvalue, e.g., the largest eigenvalue so that the preconditioner does not create
937     an isolated eigenvalue.
938 
939     The options are automatically inherited from the previous deflation level.
940 
941     The preconditioner supports KSPMonitorDynamicTolerance(). This is useful for the multilevel scheme for which we also
942     recommend limiting the number of iterations for the coarse problems.
943 
944     See section 3 of [4] for additional references and decription of the algorithm when used for conjugate gradients.
945     Section 4 describes some possible choices for the deflation space.
946 
947    Developer Notes:
948      Contributed by Jakub Kruzik (PERMON), Institute of Geonics of the Czech
949      Academy of Sciences and VSB - TU Ostrava.
950 
951      Developed from PERMON code used in [4] while on a research stay with
952      Prof. Reinhard Nabben at the Institute of Mathematics, TU Berlin.
953 
954    References:
955 +    [1] - A. Nicolaides. “Deflation of conjugate gradients with applications to boundary valueproblems”, SIAM J. Numer. Anal. 24.2, 1987.
956 .    [2] - Z. Dostal. "Conjugate gradient method with preconditioning by projector", Int J. Comput. Math. 23.3-4, 1988.
957 .    [3] - Y. A. Erlangga and R. Nabben. "Multilevel Projection-Based Nested Krylov Iteration for Boundary Value Problems", SIAM J. Sci. Comput. 30.3, 2008.
958 -    [4] - J. Kruzik "Implementation of the Deflated Variants of the Conjugate Gradient Method", Master's thesis, VSB-TUO, 2018 - http://dspace5.vsb.cz/bitstream/handle/10084/130303/KRU0097_USP_N2658_2612T078_2018.pdf
959 
960    Level: intermediate
961 
962 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
963            PCDeflationSetInitOnly(), PCDeflationSetMaxLvl(), PCDeflationSetReductionFactor(),
964            PCDeflationSetCorrectionFactor(), PCDeflationSetSpaceToCompute(),
965            PCDeflationSetSpace(), PCDeflationSpaceType, PCDeflationSetProjectionNullSpaceMat(),
966            PCDeflationSetCoarseMat(), PCDeflationSetCoarseKSP(), PCDeflationGetCoarseKSP(),
967            PCDeflationGetPC(), PCDeflationSetPC()
968 M*/
969 
970 PETSC_EXTERN PetscErrorCode PCCreate_Deflation(PC pc)
971 {
972   PC_Deflation   *def;
973   PetscErrorCode ierr;
974 
975   PetscFunctionBegin;
976   ierr     = PetscNewLog(pc,&def);CHKERRQ(ierr);
977   pc->data = (void*)def;
978 
979   def->init          = PETSC_FALSE;
980   def->correct       = PETSC_FALSE;
981   def->correctfact   = 1.0;
982   def->reductionfact = -1;
983   def->spacetype     = PC_DEFLATION_SPACE_HAAR;
984   def->spacesize     = 1;
985   def->extendsp      = PETSC_FALSE;
986   def->lvl           = 0;
987   def->maxlvl        = 0;
988 
989   pc->ops->apply          = PCApply_Deflation;
990   pc->ops->presolve       = PCPreSolve_Deflation;
991   pc->ops->setup          = PCSetUp_Deflation;
992   pc->ops->reset          = PCReset_Deflation;
993   pc->ops->destroy        = PCDestroy_Deflation;
994   pc->ops->setfromoptions = PCSetFromOptions_Deflation;
995   pc->ops->view           = PCView_Deflation;
996 
997   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetInitOnly_C",PCDeflationSetInitOnly_Deflation);CHKERRQ(ierr);
998   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetLvl_C",PCDeflationSetLvl_Deflation);CHKERRQ(ierr);
999   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetReductionFactor_C",PCDeflationSetReductionFactor_Deflation);CHKERRQ(ierr);
1000   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCorrectionFactor_C",PCDeflationSetCorrectionFactor_Deflation);CHKERRQ(ierr);
1001   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetSpaceToCompute_C",PCDeflationSetSpaceToCompute_Deflation);CHKERRQ(ierr);
1002   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetSpace_C",PCDeflationSetSpace_Deflation);CHKERRQ(ierr);
1003   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetProjectionNullSpaceMat_C",PCDeflationSetProjectionNullSpaceMat_Deflation);CHKERRQ(ierr);
1004   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCoarseMat_C",PCDeflationSetCoarseMat_Deflation);CHKERRQ(ierr);
1005   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetCoarseKSP_C",PCDeflationGetCoarseKSP_Deflation);CHKERRQ(ierr);
1006   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetCoarseKSP_C",PCDeflationSetCoarseKSP_Deflation);CHKERRQ(ierr);
1007   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetPC_C",PCDeflationGetPC_Deflation);CHKERRQ(ierr);
1008   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetPC_C",PCDeflationSetPC_Deflation);CHKERRQ(ierr);
1009   PetscFunctionReturn(0);
1010 }
1011 
1012