Actual source code: coarsen.c

  1: #include <petsc/private/matimpl.h>

  3: /* Logging support */
  4: PetscClassId MAT_COARSEN_CLASSID;

  6: PetscFunctionList MatCoarsenList              = NULL;
  7: PetscBool         MatCoarsenRegisterAllCalled = PETSC_FALSE;

  9: /*@C
 10:   MatCoarsenRegister - Adds a new sparse matrix coarsening algorithm to the matrix package.

 12:   Logically Collective

 14:   Input Parameters:
 15: + sname    - name of coarsen (for example `MATCOARSENMIS`)
 16: - function - function pointer that creates the coarsen type

 18:   Level: developer

 20:   Example Usage:
 21: .vb
 22:    MatCoarsenRegister("my_agg", MyAggCreate);
 23: .ve

 25:   Then, your aggregator can be chosen with the procedural interface via
 26: $     MatCoarsenSetType(agg, "my_agg")
 27:   or at runtime via the option
 28: $     -mat_coarsen_type my_agg

 30: .seealso: `MatCoarsen`, `MatCoarsenType`, `MatCoarsenSetType()`, `MatCoarsenCreate()`, `MatCoarsenRegisterDestroy()`, `MatCoarsenRegisterAll()`
 31: @*/
 32: PetscErrorCode MatCoarsenRegister(const char sname[], PetscErrorCode (*function)(MatCoarsen))
 33: {
 34:   PetscFunctionBegin;
 35:   PetscCall(MatInitializePackage());
 36:   PetscCall(PetscFunctionListAdd(&MatCoarsenList, sname, function));
 37:   PetscFunctionReturn(PETSC_SUCCESS);
 38: }

 40: /*@C
 41:   MatCoarsenGetType - Gets the Coarsen method type and name (as a string)
 42:   from the coarsen context.

 44:   Not Collective

 46:   Input Parameter:
 47: . coarsen - the coarsen context

 49:   Output Parameter:
 50: . type - coarsener type

 52:   Level: advanced

 54: .seealso: `MatCoarsen`, `MatCoarsenCreate()`, `MatCoarsenType`, `MatCoarsenSetType()`, `MatCoarsenRegister()`
 55: @*/
 56: PetscErrorCode MatCoarsenGetType(MatCoarsen coarsen, MatCoarsenType *type)
 57: {
 58:   PetscFunctionBegin;
 60:   PetscAssertPointer(type, 2);
 61:   *type = ((PetscObject)coarsen)->type_name;
 62:   PetscFunctionReturn(PETSC_SUCCESS);
 63: }

 65: /*@
 66:   MatCoarsenApply - Gets a coarsen for a matrix.

 68:   Collective

 70:   Input Parameter:
 71: . coarser - the coarsen

 73:   Options Database Keys:
 74: + -mat_coarsen_type mis|hem|misk - set the coarsening type
 75: - -mat_coarsen_view              - view the coarsening object

 77:   Level: advanced

 79:   Notes:
 80:   Use `MatCoarsenGetData()` to access the results of the coarsening

 82:   The user can define additional coarsens; see `MatCoarsenRegister()`.

 84: .seealso: `MatCoarsen`, `MatCoarseSetFromOptions()`, `MatCoarsenSetType()`, `MatCoarsenRegister()`, `MatCoarsenCreate()`,
 85:           `MatCoarsenDestroy()`, `MatCoarsenSetAdjacency()`
 86:           `MatCoarsenGetData()`
 87: @*/
 88: PetscErrorCode MatCoarsenApply(MatCoarsen coarser)
 89: {
 90:   PetscFunctionBegin;
 92:   PetscAssertPointer(coarser, 1);
 93:   PetscCheck(coarser->graph->assembled, PetscObjectComm((PetscObject)coarser), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
 94:   PetscCheck(!coarser->graph->factortype, PetscObjectComm((PetscObject)coarser), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
 95:   PetscCall(PetscLogEventBegin(MAT_Coarsen, coarser, 0, 0, 0));
 96:   PetscUseTypeMethod(coarser, apply);
 97:   PetscCall(PetscLogEventEnd(MAT_Coarsen, coarser, 0, 0, 0));
 98:   PetscFunctionReturn(PETSC_SUCCESS);
 99: }

101: /*@
102:   MatCoarsenSetAdjacency - Sets the adjacency graph (matrix) of the thing to be coarsened.

104:   Collective

106:   Input Parameters:
107: + agg - the coarsen context
108: - adj - the adjacency matrix

110:   Level: advanced

112: .seealso: `MatCoarsen`, `MatCoarsenSetFromOptions()`, `Mat`, `MatCoarsenCreate()`, `MatCoarsenApply()`
113: @*/
114: PetscErrorCode MatCoarsenSetAdjacency(MatCoarsen agg, Mat adj)
115: {
116:   PetscFunctionBegin;
119:   agg->graph = adj;
120:   PetscFunctionReturn(PETSC_SUCCESS);
121: }

123: /*@
124:   MatCoarsenSetStrictAggs - Set whether to keep strict (non overlapping) aggregates in the linked list of aggregates for a coarsen context

126:   Logically Collective

128:   Input Parameters:
129: + agg - the coarsen context
130: - str - `PETSC_TRUE` keep strict aggregates, `PETSC_FALSE` allow overlap

132:   Level: advanced

134: .seealso: `MatCoarsen`, `MatCoarsenCreate()`, `MatCoarsenSetFromOptions()`
135: @*/
136: PetscErrorCode MatCoarsenSetStrictAggs(MatCoarsen agg, PetscBool str)
137: {
138:   PetscFunctionBegin;
140:   agg->strict_aggs = str;
141:   PetscFunctionReturn(PETSC_SUCCESS);
142: }

144: /*@
145:   MatCoarsenDestroy - Destroys the coarsen context.

147:   Collective

149:   Input Parameter:
150: . agg - the coarsen context

152:   Level: advanced

154: .seealso: `MatCoarsen`, `MatCoarsenCreate()`
155: @*/
156: PetscErrorCode MatCoarsenDestroy(MatCoarsen *agg)
157: {
158:   PetscFunctionBegin;
159:   if (!*agg) PetscFunctionReturn(PETSC_SUCCESS);
161:   if (--((PetscObject)(*agg))->refct > 0) {
162:     *agg = NULL;
163:     PetscFunctionReturn(PETSC_SUCCESS);
164:   }

166:   if ((*agg)->ops->destroy) PetscCall((*(*agg)->ops->destroy)((*agg)));

168:   if ((*agg)->agg_lists) PetscCall(PetscCDDestroy((*agg)->agg_lists));

170:   PetscCall(PetscHeaderDestroy(agg));
171:   PetscFunctionReturn(PETSC_SUCCESS);
172: }

174: /*@
175:   MatCoarsenCreate - Creates a coarsen context.

177:   Collective

179:   Input Parameter:
180: . comm - MPI communicator

182:   Output Parameter:
183: . newcrs - location to put the context

185:   Level: advanced

187: .seealso: `MatCoarsen`, `MatCoarsenSetType()`, `MatCoarsenApply()`, `MatCoarsenDestroy()`,
188:           `MatCoarsenSetAdjacency()`, `MatCoarsenGetData()`

190: @*/
191: PetscErrorCode MatCoarsenCreate(MPI_Comm comm, MatCoarsen *newcrs)
192: {
193:   MatCoarsen agg;

195:   PetscFunctionBegin;
196:   *newcrs = NULL;

198:   PetscCall(MatInitializePackage());
199:   PetscCall(PetscHeaderCreate(agg, MAT_COARSEN_CLASSID, "MatCoarsen", "Matrix/graph coarsen", "MatCoarsen", comm, MatCoarsenDestroy, MatCoarsenView));

201:   *newcrs = agg;
202:   PetscFunctionReturn(PETSC_SUCCESS);
203: }

205: /*@C
206:   MatCoarsenViewFromOptions - View the coarsener from the options database

208:   Collective

210:   Input Parameters:
211: + A    - the coarsen context
212: . obj  - Optional object that provides the prefix for the option name
213: - name - command line option (usually `-mat_coarsen_view`)

215:   Options Database Key:
216: . -mat_coarsen_view [viewertype]:... - the viewer and its options

218:   Note:
219: .vb
220:     If no value is provided ascii:stdout is used
221:        ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
222:                                                   for example ascii::ascii_info prints just the information about the object not all details
223:                                                   unless :append is given filename opens in write mode, overwriting what was already there
224:        binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
225:        draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
226:        socket[:port]                             defaults to the standard output port
227:        saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)
228: .ve

230:   Level: intermediate

232: .seealso: `MatCoarsen`, `MatCoarsenView`, `PetscObjectViewFromOptions()`, `MatCoarsenCreate()`
233: @*/
234: PetscErrorCode MatCoarsenViewFromOptions(MatCoarsen A, PetscObject obj, const char name[])
235: {
236:   PetscFunctionBegin;
238:   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
239:   PetscFunctionReturn(PETSC_SUCCESS);
240: }

242: /*@C
243:   MatCoarsenView - Prints the coarsen data structure.

245:   Collective

247:   Input Parameters:
248: + agg    - the coarsen context
249: - viewer - optional visualization context

251:    For viewing the options database see `MatCoarsenViewFromOptions()`

253:   Level: advanced

255: .seealso: `MatCoarsen`, `PetscViewer`, `PetscViewerASCIIOpen()`, `MatCoarsenViewFromOptions`
256: @*/
257: PetscErrorCode MatCoarsenView(MatCoarsen agg, PetscViewer viewer)
258: {
259:   PetscBool iascii;

261:   PetscFunctionBegin;
263:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)agg), &viewer));
265:   PetscCheckSameComm(agg, 1, viewer, 2);

267:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
268:   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)agg, viewer));
269:   if (agg->ops->view) {
270:     PetscCall(PetscViewerASCIIPushTab(viewer));
271:     PetscUseTypeMethod(agg, view, viewer);
272:     PetscCall(PetscViewerASCIIPopTab(viewer));
273:   }
274:   PetscFunctionReturn(PETSC_SUCCESS);
275: }

277: /*@C
278:   MatCoarsenSetType - Sets the type of aggregator to use

280:   Collective

282:   Input Parameters:
283: + coarser - the coarsen context.
284: - type    - a known coarsening method

286:   Options Database Key:
287: . -mat_coarsen_type  <type> - (for instance, misk), use -help for a list of available methods

289:   Level: advanced

291: .seealso: `MatCoarsen`, `MatCoarsenCreate()`, `MatCoarsenApply()`, `MatCoarsenType`, `MatCoarsenGetType()`
292: @*/
293: PetscErrorCode MatCoarsenSetType(MatCoarsen coarser, MatCoarsenType type)
294: {
295:   PetscBool match;
296:   PetscErrorCode (*r)(MatCoarsen);

298:   PetscFunctionBegin;
300:   PetscAssertPointer(type, 2);

302:   PetscCall(PetscObjectTypeCompare((PetscObject)coarser, type, &match));
303:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

305:   PetscTryTypeMethod(coarser, destroy);
306:   coarser->ops->destroy = NULL;
307:   PetscCall(PetscMemzero(coarser->ops, sizeof(struct _MatCoarsenOps)));

309:   PetscCall(PetscFunctionListFind(MatCoarsenList, type, &r));
310:   PetscCheck(r, PetscObjectComm((PetscObject)coarser), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown coarsen type %s", type);
311:   PetscCall((*r)(coarser));

313:   PetscCall(PetscFree(((PetscObject)coarser)->type_name));
314:   PetscCall(PetscStrallocpy(type, &((PetscObject)coarser)->type_name));
315:   PetscFunctionReturn(PETSC_SUCCESS);
316: }

318: /*@C
319:   MatCoarsenSetGreedyOrdering - Sets the ordering of the vertices to use with a greedy coarsening method

321:   Logically Collective

323:   Input Parameters:
324: + coarser - the coarsen context
325: - perm    - vertex ordering of (greedy) algorithm

327:   Level: advanced

329:   Note:
330:   The `IS` weights is freed by PETSc, the user should not destroy it or change it after this call

332: .seealso: `MatCoarsen`, `MatCoarsenType`, `MatCoarsenCreate()`, `MatCoarsenSetType()`
333: @*/
334: PetscErrorCode MatCoarsenSetGreedyOrdering(MatCoarsen coarser, const IS perm)
335: {
336:   PetscFunctionBegin;
338:   coarser->perm = perm;
339:   PetscFunctionReturn(PETSC_SUCCESS);
340: }

342: /*@C
343:   MatCoarsenGetData - Gets the weights for vertices for a coarsener.

345:   Logically Collective

347:   Input Parameter:
348: . coarser - the coarsen context

350:   Output Parameter:
351: . llist - linked list of aggregates

353:   Level: advanced

355: .seealso: `MatCoarsen`, `MatCoarsenApply()`, `MatCoarsenCreate()`, `MatCoarsenSetType()`
356: @*/
357: PetscErrorCode MatCoarsenGetData(MatCoarsen coarser, PetscCoarsenData **llist)
358: {
359:   PetscFunctionBegin;
361:   PetscCheck(coarser->agg_lists, PetscObjectComm((PetscObject)coarser), PETSC_ERR_ARG_WRONGSTATE, "No linked list - generate it or call ApplyCoarsen");
362:   *llist             = coarser->agg_lists;
363:   coarser->agg_lists = NULL; /* giving up ownership */
364:   PetscFunctionReturn(PETSC_SUCCESS);
365: }

367: /*@
368:   MatCoarsenSetFromOptions - Sets various coarsen options from the options database.

370:   Collective

372:   Input Parameter:
373: . coarser - the coarsen context.

375:   Options Database Key:
376: . -mat_coarsen_type  <type> - (for instance, mis), use -help for a list of available methods

378:   Level: advanced

380:   Note:
381:   Sets the `MatCoarsenType` to `MATCOARSENMISK` if has not been set previously

383: .seealso: `MatCoarsen`, `MatCoarsenType`, `MatCoarsenApply()`, `MatCoarsenCreate()`, `MatCoarsenSetType()`
384: @*/
385: PetscErrorCode MatCoarsenSetFromOptions(MatCoarsen coarser)
386: {
387:   PetscBool   flag;
388:   char        type[256];
389:   const char *def;

391:   PetscFunctionBegin;
392:   PetscObjectOptionsBegin((PetscObject)coarser);
393:   if (!((PetscObject)coarser)->type_name) {
394:     def = MATCOARSENMISK;
395:   } else {
396:     def = ((PetscObject)coarser)->type_name;
397:   }

399:   PetscCall(PetscOptionsFList("-mat_coarsen_type", "Type of aggregator", "MatCoarsenSetType", MatCoarsenList, def, type, 256, &flag));
400:   if (flag) PetscCall(MatCoarsenSetType(coarser, type));
401:   /*
402:    Set the type if it was never set.
403:    */
404:   if (!((PetscObject)coarser)->type_name) PetscCall(MatCoarsenSetType(coarser, def));

406:   PetscTryTypeMethod(coarser, setfromoptions, PetscOptionsObject);
407:   PetscOptionsEnd();

409:   PetscFunctionReturn(PETSC_SUCCESS);
410: }