Actual source code: supportgraph.c

petsc-3.4.4 2014-03-13
  2: /*  --------------------------------------------------------------------

  4:      This file implements a SupportGraph preconditioner in PETSc as part of PC.
  5:      You can use this as a starting point for implementing your own
  6:      preconditioner that is not provided with PETSc. (You might also consider
  7:      just using PCSHELL)

  9:      The following basic routines are required for each preconditioner.
 10:           PCCreate_XXX()          - Creates a preconditioner context
 11:           PCSetFromOptions_XXX()  - Sets runtime options
 12:           PCApply_XXX()           - Applies the preconditioner
 13:           PCDestroy_XXX()         - Destroys the preconditioner context
 14:      where the suffix "_XXX" denotes a particular implementation, in
 15:      this case we use _SupportGraph (e.g., PCCreate_SupportGraph, PCApply_SupportGraph).
 16:      These routines are actually called via the common user interface
 17:      routines PCCreate(), PCSetFromOptions(), PCApply(), and PCDestroy(),
 18:      so the application code interface remains identical for all
 19:      preconditioners.

 21:      Another key routine is:
 22:           PCSetUp_XXX()           - Prepares for the use of a preconditioner
 23:      by setting data structures and options.   The interface routine PCSetUp()
 24:      is not usually called directly by the user, but instead is called by
 25:      PCApply() if necessary.

 27:      Additional basic routines are:
 28:           PCView_XXX()            - Prints details of runtime options that
 29:                                     have actually been used.
 30:      These are called by application codes via the interface routines
 31:      PCView().

 33:      The various types of solvers (preconditioners, Krylov subspace methods,
 34:      nonlinear solvers, timesteppers) are all organized similarly, so the
 35:      above description applies to these categories also.  One exception is
 36:      that the analogues of PCApply() for these components are KSPSolve(),
 37:      SNESSolve(), and TSSolve().

 39:      Additional optional functionality unique to preconditioners is left and
 40:      right symmetric preconditioner application via PCApplySymmetricLeft()
 41:      and PCApplySymmetricRight().  The SupportGraph implementation is
 42:      PCApplySymmetricLeftOrRight_SupportGraph().

 44:     -------------------------------------------------------------------- */

 46: /*
 47:    Include files needed for the SupportGraph preconditioner:
 48:      pcimpl.h - private include file intended for use by all preconditioners
 49:      adjacency_list.hpp
 50: */

 52: #include <petsc-private/pcimpl.h>   /*I "petscpc.h" I*/

 54: /*
 55:    Private context (data structure) for the SupportGraph preconditioner.
 56: */
 57: typedef struct {
 58:   Mat       pre;       /* Cholesky factored preconditioner matrix */
 59:   PetscBool augment;   /* whether to augment the spanning tree */
 60:   PetscReal maxCong;   /* create subgraph with at most this much congestion (only used with augment) */
 61:   PetscReal tol;       /* throw out entries smaller than this */
 62: } PC_SupportGraph;

 66: static PetscErrorCode PCView_SupportGraph(PC pc,PetscViewer viewer)
 67: {
 68:   PC_SupportGraph *sg = (PC_SupportGraph*)pc->data;
 69:   PetscErrorCode  ierr;
 70:   PetscBool       iascii;

 73:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
 74:   if (iascii) {
 75:     PetscViewerASCIIPrintf(viewer,"  SupportGraph: maxCong = %f\n",sg->maxCong);
 76:     PetscViewerASCIIPrintf(viewer,"  SupportGraph: tol = %f\n",sg->tol);
 77:     PetscViewerASCIIPrintf(viewer,"  Factored Matrix:\n");
 78:     PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_INFO);
 79:     PetscViewerASCIIPushTab(viewer);
 80:     PetscViewerASCIIPushTab(viewer);
 81:     MatView(sg->pre, viewer);
 82:     PetscViewerASCIIPopTab(viewer);
 83:     PetscViewerASCIIPopTab(viewer);
 84:     PetscViewerPopFormat(viewer);
 85:   }
 86:   return(0);
 87: }

 89: extern PetscErrorCode AugmentedLowStretchSpanningTree(Mat mat,Mat *pre,PetscBool augment,PetscReal tol,PetscReal& maxCong);

 91: /* -------------------------------------------------------------------------- */
 92: /*
 93:    PCSetUp_SupportGraph - Prepares for the use of the SupportGraph preconditioner
 94:                     by setting data structures and options.

 96:    Input Parameter:
 97: .  pc - the preconditioner context

 99:    Application Interface Routine: PCSetUp()

101:    Notes:
102:    The interface routine PCSetUp() is not usually called directly by
103:    the user, but instead is called by PCApply() if necessary.
104: */
107: static PetscErrorCode PCSetUp_SupportGraph(PC pc)
108: {
109:   PC_SupportGraph *sg = (PC_SupportGraph*)pc->data;
110:   PetscBool       isSym;
111:   PetscErrorCode  ierr;
112:   /*
113:   Vec            diag;
114:   PetscInt       n,i;
115:   PetscScalar    *x;
116:   PetscBool      zeroflag = PETSC_FALSE;
117:   */

120:   if (!pc->setupcalled) {
121:     MatIsSymmetric(pc->pmat, 1.0e-9, &isSym);
122:     if (!isSym) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"matrix must be symmetric");
123:     /* note that maxCong is being updated */
124:     AugmentedLowStretchSpanningTree(pc->pmat, &sg->pre, sg->augment, sg->tol, sg->maxCong);
125:   }
126:   return(0);
127: }


130: /* -------------------------------------------------------------------------- */
131: /*
132:    PCApply_SupportGraph - Applies the SupportGraph preconditioner to a vector.

134:    Input Parameters:
135: .  pc - the preconditioner context
136: .  x - input vector

138:    Output Parameter:
139: .  y - output vector

141:    Application Interface Routine: PCApply()
142:  */
145: static PetscErrorCode PCApply_SupportGraph(PC pc,Vec x,Vec y)
146: {
147:   PC_SupportGraph *sg = (PC_SupportGraph*)pc->data;
148:   PetscErrorCode  ierr;

151:   MatSolve(sg->pre,x,y);
152:   return(0);
153: }
154: /* -------------------------------------------------------------------------- */
155: /*
156:    PCDestroy_SupportGraph - Destroys the private context for the SupportGraph preconditioner
157:    that was created with PCCreate_SupportGraph().

159:    Input Parameter:
160: .  pc - the preconditioner context

162:    Application Interface Routine: PCDestroy()
163: */
166: static PetscErrorCode PCDestroy_SupportGraph(PC pc)
167: {
168:   PC_SupportGraph *sg = (PC_SupportGraph*)pc->data;
169:   PetscErrorCode  ierr;

172:   MatDestroy(&sg->pre);
173:   /*
174:       Free the private data structure that was hanging off the PC
175:   */
176:   PetscFree(pc->data);
177:   return(0);
178: }

182: static PetscErrorCode PCSetFromOptions_SupportGraph(PC pc)
183: {
184:   PC_SupportGraph *sg = (PC_SupportGraph*)pc->data;
185:   PetscErrorCode  ierr;

188:   PetscOptionsHead("SupportGraph options");
189:   PetscOptionsBool("-pc_sg_augment","Max congestion","",sg->augment,&sg->augment,0);
190:   PetscOptionsReal("-pc_sg_cong","Max congestion","",sg->maxCong,&sg->maxCong,0);
191:   PetscOptionsReal("-pc_sg_tol","Smallest usable value","",sg->tol,&sg->tol,0);
192:   PetscOptionsTail();
193:   return(0);
194: }

196: /* -------------------------------------------------------------------------- */
197: /*
198:    PCCreate_SupportGraph - Creates a SupportGraph preconditioner context, PC_SupportGraph,
199:    and sets this as the private data within the generic preconditioning
200:    context, PC, that was created within PCCreate().

202:    Input Parameter:
203: .  pc - the preconditioner context

205:    Application Interface Routine: PCCreate()
206: */

208: /*MC
209:      PCSUPPORTGRAPH - SupportGraph (i.e. diagonal scaling preconditioning)

211:    Options Database Key:
212: .    -pc_supportgraph_augment - augment the spanning tree

214:    Level: beginner

216:   Concepts: SupportGraph, diagonal scaling, preconditioners

218:   Notes: Zero entries along the diagonal are replaced with the value 1.0

220: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
221: M*/

225: PETSC_EXTERN PetscErrorCode PCCreate_SupportGraph(PC pc)
226: {
227:   PC_SupportGraph *sg;
228:   PetscErrorCode  ierr;

231:   /*
232:      Creates the private data structure for this preconditioner and
233:      attach it to the PC object.
234:   */
235:   PetscNewLog(pc,PC_SupportGraph,&sg);
236:   pc->data = (void*)sg;

238:   sg->pre     = 0;
239:   sg->augment = PETSC_TRUE;
240:   sg->maxCong = 3.0;
241:   sg->tol     = 0;


244:   /*
245:       Set the pointers for the functions that are provided above.
246:       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
247:       are called, they will automatically call these functions.  Note we
248:       choose not to provide a couple of these functions since they are
249:       not needed.
250:   */
251:   pc->ops->apply               = PCApply_SupportGraph;
252:   pc->ops->applytranspose      = 0;
253:   pc->ops->setup               = PCSetUp_SupportGraph;
254:   pc->ops->destroy             = PCDestroy_SupportGraph;
255:   pc->ops->setfromoptions      = PCSetFromOptions_SupportGraph;
256:   pc->ops->view                = PCView_SupportGraph;
257:   pc->ops->applyrichardson     = 0;
258:   pc->ops->applysymmetricleft  = 0;
259:   pc->ops->applysymmetricright = 0;
260:   return(0);
261: }