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 PC177: */
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), PC223: 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