Actual source code: supportgraph.c

petsc-3.3-p7 2013-05-11
  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:   } else {
 86:     SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_SUP,"Viewer type %s not supported for PCSupportGraph",((PetscObject)viewer)->type_name);
 87:   }
 88:   return(0);
 89: }

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

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

 98:    Input Parameter:
 99: .  pc - the preconditioner context

101:    Application Interface Routine: PCSetUp()

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

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


132: /* -------------------------------------------------------------------------- */
133: /*
134:    PCApply_SupportGraph - Applies the SupportGraph preconditioner to a vector.

136:    Input Parameters:
137: .  pc - the preconditioner context
138: .  x - input vector

140:    Output Parameter:
141: .  y - output vector

143:    Application Interface Routine: PCApply()
144:  */
147: static PetscErrorCode PCApply_SupportGraph(PC pc,Vec x,Vec y)
148: {
149:   PC_SupportGraph      *sg = (PC_SupportGraph*)pc->data;

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

161:    Input Parameter:
162: .  pc - the preconditioner context

164:    Application Interface Routine: PCDestroy()
165: */
168: static PetscErrorCode PCDestroy_SupportGraph(PC pc)
169: {
170:   PC_SupportGraph *sg = (PC_SupportGraph*)pc->data;
171:   PetscErrorCode  ierr;

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

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

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

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

204:    Input Parameter:
205: .  pc - the preconditioner context

207:    Application Interface Routine: PCCreate()
208: */

210: /*MC
211:      PCSUPPORTGRAPH - SupportGraph (i.e. diagonal scaling preconditioning)

213:    Options Database Key:
214: .    -pc_supportgraph_augment - augment the spanning tree

216:    Level: beginner

218:   Concepts: SupportGraph, diagonal scaling, preconditioners

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

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

225: EXTERN_C_BEGIN
228: PetscErrorCode  PCCreate_SupportGraph(PC pc)
229: {
230:   PC_SupportGraph      *sg;

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

241:   sg->pre = 0;
242:   sg->augment = PETSC_TRUE;
243:   sg->maxCong = 3.0;
244:   sg->tol = 0;
245: 

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