xref: /petsc/src/ksp/pc/impls/deflation/deflation.c (revision bb9edbfadda61c326e22413d632aab58aaebba9a)
137eeb815SJakub Kruzik 
237eeb815SJakub Kruzik /*  --------------------------------------------------------------------
337eeb815SJakub Kruzik 
437eeb815SJakub Kruzik      This file implements a Deflation preconditioner in PETSc as part of PC.
537eeb815SJakub Kruzik      You can use this as a starting point for implementing your own
637eeb815SJakub Kruzik      preconditioner that is not provided with PETSc. (You might also consider
737eeb815SJakub Kruzik      just using PCSHELL)
837eeb815SJakub Kruzik 
937eeb815SJakub Kruzik      The following basic routines are required for each preconditioner.
1037eeb815SJakub Kruzik           PCCreate_XXX()          - Creates a preconditioner context
1137eeb815SJakub Kruzik           PCSetFromOptions_XXX()  - Sets runtime options
1237eeb815SJakub Kruzik           PCApply_XXX()           - Applies the preconditioner
1337eeb815SJakub Kruzik           PCDestroy_XXX()         - Destroys the preconditioner context
1437eeb815SJakub Kruzik      where the suffix "_XXX" denotes a particular implementation, in
1537eeb815SJakub Kruzik      this case we use _Deflation (e.g., PCCreate_Deflation, PCApply_Deflation).
1637eeb815SJakub Kruzik      These routines are actually called via the common user interface
1737eeb815SJakub Kruzik      routines PCCreate(), PCSetFromOptions(), PCApply(), and PCDestroy(),
1837eeb815SJakub Kruzik      so the application code interface remains identical for all
1937eeb815SJakub Kruzik      preconditioners.
2037eeb815SJakub Kruzik 
2137eeb815SJakub Kruzik      Another key routine is:
2237eeb815SJakub Kruzik           PCSetUp_XXX()           - Prepares for the use of a preconditioner
2337eeb815SJakub Kruzik      by setting data structures and options.   The interface routine PCSetUp()
2437eeb815SJakub Kruzik      is not usually called directly by the user, but instead is called by
2537eeb815SJakub Kruzik      PCApply() if necessary.
2637eeb815SJakub Kruzik 
2737eeb815SJakub Kruzik      Additional basic routines are:
2837eeb815SJakub Kruzik           PCView_XXX()            - Prints details of runtime options that
2937eeb815SJakub Kruzik                                     have actually been used.
3037eeb815SJakub Kruzik      These are called by application codes via the interface routines
3137eeb815SJakub Kruzik      PCView().
3237eeb815SJakub Kruzik 
3337eeb815SJakub Kruzik      The various types of solvers (preconditioners, Krylov subspace methods,
3437eeb815SJakub Kruzik      nonlinear solvers, timesteppers) are all organized similarly, so the
3537eeb815SJakub Kruzik      above description applies to these categories also.  One exception is
3637eeb815SJakub Kruzik      that the analogues of PCApply() for these components are KSPSolve(),
3737eeb815SJakub Kruzik      SNESSolve(), and TSSolve().
3837eeb815SJakub Kruzik 
3937eeb815SJakub Kruzik      Additional optional functionality unique to preconditioners is left and
4037eeb815SJakub Kruzik      right symmetric preconditioner application via PCApplySymmetricLeft()
4137eeb815SJakub Kruzik      and PCApplySymmetricRight().  The Deflation implementation is
4237eeb815SJakub Kruzik      PCApplySymmetricLeftOrRight_Deflation().
4337eeb815SJakub Kruzik 
4437eeb815SJakub Kruzik     -------------------------------------------------------------------- */
4537eeb815SJakub Kruzik 
4637eeb815SJakub Kruzik /*
4737eeb815SJakub Kruzik    Include files needed for the Deflation preconditioner:
4837eeb815SJakub Kruzik      pcimpl.h - private include file intended for use by all preconditioners
4937eeb815SJakub Kruzik */
5037eeb815SJakub Kruzik 
5137eeb815SJakub Kruzik #include <petsc/private/pcimpl.h>   /*I "petscpc.h" I*/
5237eeb815SJakub Kruzik 
5337eeb815SJakub Kruzik const char *const PCDeflationTypes[]    = {"INIT","PRE","POST","PCDeflationType","PC_DEFLATION_",0};
5437eeb815SJakub Kruzik 
5537eeb815SJakub Kruzik /*
5637eeb815SJakub Kruzik    Private context (data structure) for the deflation preconditioner.
5737eeb815SJakub Kruzik */
5837eeb815SJakub Kruzik typedef struct {
5937eeb815SJakub Kruzik   PetscBool init;            /* do only init step - error correction of direction is omitted */
6037eeb815SJakub Kruzik   PetscBool pre;             /* start with x0 being the solution in the deflation space */
6137eeb815SJakub Kruzik   PetscBool correct;         /* add CP (Qr) correction to descent direction */
6237eeb815SJakub Kruzik   PetscBool truenorm;
6337eeb815SJakub Kruzik   PetscBool adaptiveconv;
6437eeb815SJakub Kruzik   PetscReal adaptiveconst;
6537eeb815SJakub Kruzik   PetscInt  reductionfact;
6637eeb815SJakub Kruzik   Mat       W,Wt,AW,WtAW;    /* deflation space, coarse problem mats */
6737eeb815SJakub Kruzik   KSP       WtAWinv;         /* deflation coarse problem */
6837eeb815SJakub Kruzik   Vec       *work;
6937eeb815SJakub Kruzik 
7037eeb815SJakub Kruzik   PCDEFLATIONSpaceType spacetype;
7137eeb815SJakub Kruzik   PetscInt             spacesize;
7237eeb815SJakub Kruzik   PetscInt             nestedlvl;
7337eeb815SJakub Kruzik   PetscInt             maxnestedlvl;
7437eeb815SJakub Kruzik   PetscBool            extendsp;
7537eeb815SJakub Kruzik } PC_Deflation;
7637eeb815SJakub Kruzik 
7737eeb815SJakub Kruzik static PetscErrorCode  PCDeflationSetType_Deflation(PC pc,PCDeflationType type)
7837eeb815SJakub Kruzik {
7937eeb815SJakub Kruzik   PC_Deflation *def = (PC_Deflation*)pc->data;
8037eeb815SJakub Kruzik 
8137eeb815SJakub Kruzik   PetscFunctionBegin;
8237eeb815SJakub Kruzik   def->init = PETSC_FALSE;
8337eeb815SJakub Kruzik   def->pre = PETSC_FALSE;
8437eeb815SJakub Kruzik   if (type == PC_DEFLATION_INIT) {
8537eeb815SJakub Kruzik     def->init = PETSC_TRUE;
8637eeb815SJakub Kruzik     def->pre  = PETSC_TRUE;
8737eeb815SJakub Kruzik   } else if (type == PC_DEFLATION_PRE) {
8837eeb815SJakub Kruzik     def->pre  = PETSC_TRUE;
8937eeb815SJakub Kruzik   }
9037eeb815SJakub Kruzik   PetscFunctionReturn(0);
9137eeb815SJakub Kruzik }
9237eeb815SJakub Kruzik 
93*bb9edbfaSJakub Kruzik /*@
94*bb9edbfaSJakub Kruzik    PCDeflationSetType - Causes the deflation preconditioner to use only a special
95*bb9edbfaSJakub Kruzik     initial gues or pre/post solve solution update
96*bb9edbfaSJakub Kruzik 
97*bb9edbfaSJakub Kruzik    Logically Collective on PC
98*bb9edbfaSJakub Kruzik 
99*bb9edbfaSJakub Kruzik    Input Parameters:
100*bb9edbfaSJakub Kruzik +  pc - the preconditioner context
101*bb9edbfaSJakub Kruzik -  type - PC_DEFLATION_PRE, PC_DEFLATION_INIT, PC_DEFLATION_POST
102*bb9edbfaSJakub Kruzik 
103*bb9edbfaSJakub Kruzik    Options Database Key:
104*bb9edbfaSJakub Kruzik .  -pc_deflation_type <pre,init,post>
105*bb9edbfaSJakub Kruzik 
106*bb9edbfaSJakub Kruzik    Level: intermediate
107*bb9edbfaSJakub Kruzik 
108*bb9edbfaSJakub Kruzik    Concepts: Deflation preconditioner
109*bb9edbfaSJakub Kruzik 
110*bb9edbfaSJakub Kruzik .seealso: PCDeflationGetType()
111*bb9edbfaSJakub Kruzik @*/
112*bb9edbfaSJakub Kruzik PetscErrorCode  PCDeflationSetType(PC pc,PCDeflationType type)
113*bb9edbfaSJakub Kruzik {
114*bb9edbfaSJakub Kruzik   PetscErrorCode ierr;
115*bb9edbfaSJakub Kruzik 
116*bb9edbfaSJakub Kruzik   PetscFunctionBegin;
117*bb9edbfaSJakub Kruzik   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
118*bb9edbfaSJakub Kruzik   ierr = PetscTryMethod(pc,"PCDeflationSetType_C",(PC,PCDeflationType),(pc,type));CHKERRQ(ierr);
119*bb9edbfaSJakub Kruzik   PetscFunctionReturn(0);
120*bb9edbfaSJakub Kruzik }
121*bb9edbfaSJakub Kruzik 
12237eeb815SJakub Kruzik static PetscErrorCode  PCDeflationGetType_Deflation(PC pc,PCDeflationType *type)
12337eeb815SJakub Kruzik {
12437eeb815SJakub Kruzik   PC_Deflation *def = (PC_Deflation*)pc->data;
12537eeb815SJakub Kruzik 
12637eeb815SJakub Kruzik   PetscFunctionBegin;
12737eeb815SJakub Kruzik   if (def->init) {
12837eeb815SJakub Kruzik     *type = PC_DEFLATION_INIT;
12937eeb815SJakub Kruzik   } else if (def->pre) {
13037eeb815SJakub Kruzik     *type = PC_DEFLATION_PRE;
13137eeb815SJakub Kruzik   } else {
13237eeb815SJakub Kruzik     *type = PC_DEFLATION_POST;
13337eeb815SJakub Kruzik   }
13437eeb815SJakub Kruzik   PetscFunctionReturn(0);
13537eeb815SJakub Kruzik }
13637eeb815SJakub Kruzik 
137*bb9edbfaSJakub Kruzik /*@
138*bb9edbfaSJakub Kruzik    PCDeflationGetType - Gets how the diagonal matrix is produced for the preconditioner
139*bb9edbfaSJakub Kruzik 
140*bb9edbfaSJakub Kruzik    Not Collective on PC
141*bb9edbfaSJakub Kruzik 
142*bb9edbfaSJakub Kruzik    Input Parameter:
143*bb9edbfaSJakub Kruzik .  pc - the preconditioner context
144*bb9edbfaSJakub Kruzik 
145*bb9edbfaSJakub Kruzik    Output Parameter:
146*bb9edbfaSJakub Kruzik -  type - PC_DEFLATION_PRE, PC_DEFLATION_INIT, PC_DEFLATION_POST
147*bb9edbfaSJakub Kruzik 
148*bb9edbfaSJakub Kruzik    Level: intermediate
149*bb9edbfaSJakub Kruzik 
150*bb9edbfaSJakub Kruzik    Concepts: Deflation preconditioner
151*bb9edbfaSJakub Kruzik 
152*bb9edbfaSJakub Kruzik .seealso: PCDeflationSetType()
153*bb9edbfaSJakub Kruzik @*/
154*bb9edbfaSJakub Kruzik PetscErrorCode  PCDeflationGetType(PC pc,PCDeflationType *type)
155*bb9edbfaSJakub Kruzik {
156*bb9edbfaSJakub Kruzik   PetscErrorCode ierr;
157*bb9edbfaSJakub Kruzik 
158*bb9edbfaSJakub Kruzik   PetscFunctionBegin;
159*bb9edbfaSJakub Kruzik   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
160*bb9edbfaSJakub Kruzik   ierr = PetscUseMethod(pc,"PCDeflationGetType_C",(PC,PCDeflationType*),(pc,type));CHKERRQ(ierr);
161*bb9edbfaSJakub Kruzik   PetscFunctionReturn(0);
162*bb9edbfaSJakub Kruzik }
163*bb9edbfaSJakub Kruzik 
164e662bc50SJakub Kruzik static PetscErrorCode PCDeflationSetSpace_Deflation(PC pc,Mat W,PetscBool transpose)
165e662bc50SJakub Kruzik {
166e662bc50SJakub Kruzik   PC_Deflation   *def = (PC_Deflation*)pc->data;
167e662bc50SJakub Kruzik   PetscErrorCode ierr;
168e662bc50SJakub Kruzik 
169e662bc50SJakub Kruzik   PetscFunctionBegin;
170e662bc50SJakub Kruzik   if (transpose) {
171e662bc50SJakub Kruzik     def->Wt = W;
172e662bc50SJakub Kruzik     def->W = NULL;
173e662bc50SJakub Kruzik   } else {
174e662bc50SJakub Kruzik     def->W = W;
175e662bc50SJakub Kruzik   }
176e662bc50SJakub Kruzik   ierr = PetscObjectReference((PetscObject)W);CHKERRQ(ierr);
177e662bc50SJakub Kruzik   PetscFunctionReturn(0);
178e662bc50SJakub Kruzik }
179e662bc50SJakub Kruzik 
180e662bc50SJakub Kruzik /* TODO create PCDeflationSetSpaceTranspose? */
181e662bc50SJakub Kruzik /*@
182e662bc50SJakub Kruzik    PCDeflationSetSpace - Set deflation space matrix (or its transpose).
183e662bc50SJakub Kruzik 
184e662bc50SJakub Kruzik    Logically Collective on PC
185e662bc50SJakub Kruzik 
186e662bc50SJakub Kruzik    Input Parameters:
187e662bc50SJakub Kruzik +  pc - the preconditioner context
188e662bc50SJakub Kruzik .  W  - deflation matrix
189e662bc50SJakub Kruzik -  tranpose - indicates that W is an explicit transpose of the deflation matrix
190e662bc50SJakub Kruzik 
191e662bc50SJakub Kruzik    Level: intermediate
192e662bc50SJakub Kruzik 
193e662bc50SJakub Kruzik .seealso: PCDEFLATION
194e662bc50SJakub Kruzik @*/
195e662bc50SJakub Kruzik PetscErrorCode PCDeflationSetSpace(PC pc,Mat W,PetscBool transpose)
196e662bc50SJakub Kruzik {
197e662bc50SJakub Kruzik   PetscErrorCode ierr;
198e662bc50SJakub Kruzik 
199e662bc50SJakub Kruzik   PetscFunctionBegin;
200e662bc50SJakub Kruzik   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
201e662bc50SJakub Kruzik   PetscValidHeaderSpecific(W,MAT_CLASSID,2);
202e662bc50SJakub Kruzik   PetscValidLogicalCollectiveBool(pc,transpose,3);
203e662bc50SJakub Kruzik   ierr = PetscTryMethod(pc,"PCDeflationSetSpace_C",(PC,Mat,PetscBool),(pc,W,transpose));CHKERRQ(ierr);
204e662bc50SJakub Kruzik   PetscFunctionReturn(0);
205e662bc50SJakub Kruzik }
206e662bc50SJakub Kruzik 
207e662bc50SJakub Kruzik 
20837eeb815SJakub Kruzik /* -------------------------------------------------------------------------- */
20937eeb815SJakub Kruzik /*
21037eeb815SJakub Kruzik    PCSetUp_Deflation - Prepares for the use of the Deflation preconditioner
21137eeb815SJakub Kruzik                     by setting data structures and options.
21237eeb815SJakub Kruzik 
21337eeb815SJakub Kruzik    Input Parameter:
21437eeb815SJakub Kruzik .  pc - the preconditioner context
21537eeb815SJakub Kruzik 
21637eeb815SJakub Kruzik    Application Interface Routine: PCSetUp()
21737eeb815SJakub Kruzik 
21837eeb815SJakub Kruzik    Notes:
21937eeb815SJakub Kruzik    The interface routine PCSetUp() is not usually called directly by
22037eeb815SJakub Kruzik    the user, but instead is called by PCApply() if necessary.
22137eeb815SJakub Kruzik */
22237eeb815SJakub Kruzik static PetscErrorCode PCSetUp_Deflation(PC pc)
22337eeb815SJakub Kruzik {
22437eeb815SJakub Kruzik   PC_Deflation      *jac = (PC_Deflation*)pc->data;
22537eeb815SJakub Kruzik   Vec            diag,diagsqrt;
22637eeb815SJakub Kruzik   PetscErrorCode ierr;
22737eeb815SJakub Kruzik   PetscInt       n,i;
22837eeb815SJakub Kruzik   PetscScalar    *x;
22937eeb815SJakub Kruzik   PetscBool      zeroflag = PETSC_FALSE;
23037eeb815SJakub Kruzik 
23137eeb815SJakub Kruzik   PetscFunctionBegin;
23237eeb815SJakub Kruzik   /*
23337eeb815SJakub Kruzik        For most preconditioners the code would begin here something like
23437eeb815SJakub Kruzik 
23537eeb815SJakub Kruzik   if (pc->setupcalled == 0) { allocate space the first time this is ever called
23637eeb815SJakub Kruzik     ierr = MatCreateVecs(pc->mat,&jac->diag);CHKERRQ(ierr);
23737eeb815SJakub Kruzik     PetscLogObjectParent((PetscObject)pc,(PetscObject)jac->diag);
23837eeb815SJakub Kruzik   }
23937eeb815SJakub Kruzik 
24037eeb815SJakub Kruzik     But for this preconditioner we want to support use of both the matrix' diagonal
24137eeb815SJakub Kruzik     elements (for left or right preconditioning) and square root of diagonal elements
24237eeb815SJakub Kruzik     (for symmetric preconditioning).  Hence we do not allocate space here, since we
24337eeb815SJakub Kruzik     don't know at this point which will be needed (diag and/or diagsqrt) until the user
24437eeb815SJakub Kruzik     applies the preconditioner, and we don't want to allocate BOTH unless we need
24537eeb815SJakub Kruzik     them both.  Thus, the diag and diagsqrt are allocated in PCSetUp_Deflation_NonSymmetric()
24637eeb815SJakub Kruzik     and PCSetUp_Deflation_Symmetric(), respectively.
24737eeb815SJakub Kruzik   */
24837eeb815SJakub Kruzik 
24937eeb815SJakub Kruzik   /*
25037eeb815SJakub Kruzik     Here we set up the preconditioner; that is, we copy the diagonal values from
25137eeb815SJakub Kruzik     the matrix and put them into a format to make them quick to apply as a preconditioner.
25237eeb815SJakub Kruzik   */
25337eeb815SJakub Kruzik   if (zeroflag) {
25437eeb815SJakub Kruzik     ierr = PetscInfo(pc,"Zero detected in diagonal of matrix, using 1 at those locations\n");CHKERRQ(ierr);
25537eeb815SJakub Kruzik   }
25637eeb815SJakub Kruzik   PetscFunctionReturn(0);
25737eeb815SJakub Kruzik }
25837eeb815SJakub Kruzik /* -------------------------------------------------------------------------- */
25937eeb815SJakub Kruzik /*
26037eeb815SJakub Kruzik    PCApply_Deflation - Applies the Deflation preconditioner to a vector.
26137eeb815SJakub Kruzik 
26237eeb815SJakub Kruzik    Input Parameters:
26337eeb815SJakub Kruzik .  pc - the preconditioner context
26437eeb815SJakub Kruzik .  x - input vector
26537eeb815SJakub Kruzik 
26637eeb815SJakub Kruzik    Output Parameter:
26737eeb815SJakub Kruzik .  y - output vector
26837eeb815SJakub Kruzik 
26937eeb815SJakub Kruzik    Application Interface Routine: PCApply()
27037eeb815SJakub Kruzik  */
27137eeb815SJakub Kruzik static PetscErrorCode PCApply_Deflation(PC pc,Vec x,Vec y)
27237eeb815SJakub Kruzik {
27337eeb815SJakub Kruzik   PC_Deflation      *jac = (PC_Deflation*)pc->data;
27437eeb815SJakub Kruzik   PetscErrorCode ierr;
27537eeb815SJakub Kruzik 
27637eeb815SJakub Kruzik   PetscFunctionBegin;
27737eeb815SJakub Kruzik   PetscFunctionReturn(0);
27837eeb815SJakub Kruzik }
27937eeb815SJakub Kruzik /* -------------------------------------------------------------------------- */
28037eeb815SJakub Kruzik static PetscErrorCode PCReset_Deflation(PC pc)
28137eeb815SJakub Kruzik {
28237eeb815SJakub Kruzik   PC_Deflation      *jac = (PC_Deflation*)pc->data;
28337eeb815SJakub Kruzik   PetscErrorCode ierr;
28437eeb815SJakub Kruzik 
28537eeb815SJakub Kruzik   PetscFunctionBegin;
28637eeb815SJakub Kruzik   PetscFunctionReturn(0);
28737eeb815SJakub Kruzik }
28837eeb815SJakub Kruzik 
28937eeb815SJakub Kruzik /*
29037eeb815SJakub Kruzik    PCDestroy_Deflation - Destroys the private context for the Deflation preconditioner
29137eeb815SJakub Kruzik    that was created with PCCreate_Deflation().
29237eeb815SJakub Kruzik 
29337eeb815SJakub Kruzik    Input Parameter:
29437eeb815SJakub Kruzik .  pc - the preconditioner context
29537eeb815SJakub Kruzik 
29637eeb815SJakub Kruzik    Application Interface Routine: PCDestroy()
29737eeb815SJakub Kruzik */
29837eeb815SJakub Kruzik static PetscErrorCode PCDestroy_Deflation(PC pc)
29937eeb815SJakub Kruzik {
30037eeb815SJakub Kruzik   PetscErrorCode ierr;
30137eeb815SJakub Kruzik 
30237eeb815SJakub Kruzik   PetscFunctionBegin;
30337eeb815SJakub Kruzik   ierr = PCReset_Deflation(pc);CHKERRQ(ierr);
30437eeb815SJakub Kruzik 
30537eeb815SJakub Kruzik   /*
30637eeb815SJakub Kruzik       Free the private data structure that was hanging off the PC
30737eeb815SJakub Kruzik   */
30837eeb815SJakub Kruzik   ierr = PetscFree(pc->data);CHKERRQ(ierr);
30937eeb815SJakub Kruzik   PetscFunctionReturn(0);
31037eeb815SJakub Kruzik }
31137eeb815SJakub Kruzik 
31237eeb815SJakub Kruzik static PetscErrorCode PCSetFromOptions_Deflation(PetscOptionItems *PetscOptionsObject,PC pc)
31337eeb815SJakub Kruzik {
31437eeb815SJakub Kruzik   PC_Deflation      *jac = (PC_Deflation*)pc->data;
31537eeb815SJakub Kruzik   PetscErrorCode ierr;
31637eeb815SJakub Kruzik   PetscBool      flg;
31737eeb815SJakub Kruzik   PCDeflationType   deflt,type;
31837eeb815SJakub Kruzik 
31937eeb815SJakub Kruzik   PetscFunctionBegin;
32037eeb815SJakub Kruzik   ierr = PCDeflationGetType(pc,&deflt);CHKERRQ(ierr);
32137eeb815SJakub Kruzik   ierr = PetscOptionsHead(PetscOptionsObject,"Deflation options");CHKERRQ(ierr);
32237eeb815SJakub Kruzik   ierr = PetscOptionsEnum("-pc_jacobi_type","How to construct diagonal matrix","PCDeflationSetType",PCDeflationTypes,(PetscEnum)deflt,(PetscEnum*)&type,&flg);CHKERRQ(ierr);
32337eeb815SJakub Kruzik   if (flg) {
32437eeb815SJakub Kruzik     ierr = PCDeflationSetType(pc,type);CHKERRQ(ierr);
32537eeb815SJakub Kruzik   }
32637eeb815SJakub Kruzik   ierr = PetscOptionsTail();CHKERRQ(ierr);
32737eeb815SJakub Kruzik   PetscFunctionReturn(0);
32837eeb815SJakub Kruzik }
32937eeb815SJakub Kruzik 
33037eeb815SJakub Kruzik /*MC
331e361f8b5SJakub Kruzik      PCDEFLATION - Deflation preconditioner shifts part of the spectrum to zero (deflates)
332e361f8b5SJakub Kruzik      or to a predefined value
33337eeb815SJakub Kruzik 
33437eeb815SJakub Kruzik    Options Database Key:
335e361f8b5SJakub Kruzik +    -pc_deflation_type <init,pre,post> - selects approach to deflation (default: pre)
33637eeb815SJakub Kruzik -    -pc_jacobi_abs - use the absolute value of the diagonal entry
33737eeb815SJakub Kruzik 
33837eeb815SJakub Kruzik    Level: beginner
33937eeb815SJakub Kruzik 
340e361f8b5SJakub Kruzik   Concepts: Deflation, preconditioners
34137eeb815SJakub Kruzik 
34237eeb815SJakub Kruzik   Notes:
343e361f8b5SJakub Kruzik     todo
34437eeb815SJakub Kruzik 
34537eeb815SJakub Kruzik .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
346e662bc50SJakub Kruzik            PCDeflationSetType(), PCDeflationSetSpace()
34737eeb815SJakub Kruzik M*/
34837eeb815SJakub Kruzik 
34937eeb815SJakub Kruzik PETSC_EXTERN PetscErrorCode PCCreate_Deflation(PC pc)
35037eeb815SJakub Kruzik {
35137eeb815SJakub Kruzik   PC_Deflation   *def;
35237eeb815SJakub Kruzik   PetscErrorCode ierr;
35337eeb815SJakub Kruzik 
35437eeb815SJakub Kruzik   PetscFunctionBegin;
35537eeb815SJakub Kruzik   ierr     = PetscNewLog(pc,&def);CHKERRQ(ierr);
35637eeb815SJakub Kruzik   pc->data = (void*)def;
35737eeb815SJakub Kruzik 
358e662bc50SJakub Kruzik   def->init          = PETSC_FALSE;
359e662bc50SJakub Kruzik   def->pre           = PETSC_TRUE;
360e662bc50SJakub Kruzik   def->correct       = PETSC_FALSE;
361e662bc50SJakub Kruzik   def->truenorm      = PETSC_TRUE;
362e662bc50SJakub Kruzik   def->reductionfact = -1;
363e662bc50SJakub Kruzik   def->spacetype     = PC_DEFLATION_SPACE_HAAR;
364e662bc50SJakub Kruzik   def->spacesize     = 1;
365e662bc50SJakub Kruzik   def->extendsp      = PETSC_FALSE;
366e662bc50SJakub Kruzik   def->nestedlvl     = 0;
367e662bc50SJakub Kruzik   def->maxnestedlvl  = 0;
368e662bc50SJakub Kruzik   def->adaptiveconv  = PETSC_FALSE;
369e662bc50SJakub Kruzik   def->adaptiveconst = 1.0;
37037eeb815SJakub Kruzik 
37137eeb815SJakub Kruzik   /*
37237eeb815SJakub Kruzik       Set the pointers for the functions that are provided above.
37337eeb815SJakub Kruzik       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
37437eeb815SJakub Kruzik       are called, they will automatically call these functions.  Note we
37537eeb815SJakub Kruzik       choose not to provide a couple of these functions since they are
37637eeb815SJakub Kruzik       not needed.
37737eeb815SJakub Kruzik   */
37837eeb815SJakub Kruzik   pc->ops->apply               = PCApply_Deflation;
37937eeb815SJakub Kruzik   pc->ops->applytranspose      = PCApply_Deflation;
38037eeb815SJakub Kruzik   pc->ops->setup               = PCSetUp_Deflation;
38137eeb815SJakub Kruzik   pc->ops->reset               = PCReset_Deflation;
38237eeb815SJakub Kruzik   pc->ops->destroy             = PCDestroy_Deflation;
38337eeb815SJakub Kruzik   pc->ops->setfromoptions      = PCSetFromOptions_Deflation;
38437eeb815SJakub Kruzik   pc->ops->view                = 0;
38537eeb815SJakub Kruzik   pc->ops->applyrichardson     = 0;
38637eeb815SJakub Kruzik   pc->ops->applysymmetricleft  = 0;
38737eeb815SJakub Kruzik   pc->ops->applysymmetricright = 0;
38837eeb815SJakub Kruzik 
38937eeb815SJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetType_C",PCDeflationSetType_Deflation);CHKERRQ(ierr);
39037eeb815SJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationGetType_C",PCDeflationGetType_Deflation);CHKERRQ(ierr);
391e662bc50SJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCDeflationSetSpace_C",PCDeflationSetSpace_Deflation);CHKERRQ(ierr);
39237eeb815SJakub Kruzik   PetscFunctionReturn(0);
39337eeb815SJakub Kruzik }
39437eeb815SJakub Kruzik 
395