Actual source code: coarsen.c


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

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

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

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

 13:    Logically Collective

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

 19:    Level: developer

 21:    Sample usage:
 22: .vb
 23:    MatCoarsenRegister("my_agg",MyAggCreate);
 24: .ve

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

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

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

 45:    Not Collective

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

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

 53:    Level: advanced

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

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

 69:    Collective

 71:    Input Parameter:
 72: .   coarsen - the coarsen

 74:    Options Database Keys:
 75:    To specify the coarsen through the options database, use one of
 76:    the following
 77: $    -mat_coarsen_type mis|hem|misk
 78:    To see the coarsen result
 79: $    -mat_coarsen_view

 81:    Level: advanced

 83:    Notes:
 84:     Use `MatCoarsenGetData()` to access the results of the coarsening

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

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

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

108:    Collective

110:    Input Parameters:
111: +  agg - the coarsen context
112: -  adj - the adjacency matrix

114:    Level: advanced

116: .seealso: `MatCoarsen`, `MatCoarsenSetFromOptions()`, `Mat`, `MatCoarsenCreate()`, `MatCoarsenApply()`
117: @*/
118: PetscErrorCode MatCoarsenSetAdjacency(MatCoarsen agg, Mat adj)
119: {
120:   PetscFunctionBegin;
123:   agg->graph = adj;
124:   PetscFunctionReturn(PETSC_SUCCESS);
125: }

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

130:    Logically Collective

132:    Input Parameters:
133: +  agg - the coarsen context
134: -  str - `PETSC_TRUE` keep strict aggregates, `PETSC_FALSE` allow overlap

136:    Level: advanced

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

148: /*@
149:    MatCoarsenDestroy - Destroys the coarsen context.

151:    Collective

153:    Input Parameter:
154: .  agg - the coarsen context

156:    Level: advanced

158: .seealso: `MatCoarsen`, `MatCoarsenCreate()`
159: @*/
160: PetscErrorCode MatCoarsenDestroy(MatCoarsen *agg)
161: {
162:   PetscFunctionBegin;
163:   if (!*agg) PetscFunctionReturn(PETSC_SUCCESS);
165:   if (--((PetscObject)(*agg))->refct > 0) {
166:     *agg = NULL;
167:     PetscFunctionReturn(PETSC_SUCCESS);
168:   }

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

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

174:   PetscCall(PetscHeaderDestroy(agg));
175:   PetscFunctionReturn(PETSC_SUCCESS);
176: }

178: /*@
179:    MatCoarsenCreate - Creates a coarsen context.

181:    Collective

183:    Input Parameter:
184: .   comm - MPI communicator

186:    Output Parameter:
187: .  newcrs - location to put the context

189:    Level: advanced

191: .seealso: `MatCoarsen`, `MatCoarsenSetType()`, `MatCoarsenApply()`, `MatCoarsenDestroy()`,
192:           `MatCoarsenSetAdjacency()`, `MatCoarsenGetData()`

194: @*/
195: PetscErrorCode MatCoarsenCreate(MPI_Comm comm, MatCoarsen *newcrs)
196: {
197:   MatCoarsen agg;

199:   PetscFunctionBegin;
200:   *newcrs = NULL;

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

205:   *newcrs = agg;
206:   PetscFunctionReturn(PETSC_SUCCESS);
207: }

209: /*@C
210:    MatCoarsenViewFromOptions - View the coarsener from the options database

212:    Collective

214:    Input Parameters:
215: +  A - the coarsen context
216: .  obj - Optional object that provides the prefix for the option name
217: -  name - command line option (usually `-mat_coarsen_view`)

219:   Options Database Key:
220: .  -mat_coarsen_view [viewertype]:... - the viewer and its options

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

234:    Level: intermediate

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

246: /*@C
247:    MatCoarsenView - Prints the coarsen data structure.

249:    Collective

251:    Input Parameters:
252: +  agg - the coarsen context
253: -  viewer - optional visualization context

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

257:    Level: advanced

259: .seealso: `MatCoarsen`, `PetscViewer`, `PetscViewerASCIIOpen()`, `MatCoarsenViewFromOptions`
260: @*/
261: PetscErrorCode MatCoarsenView(MatCoarsen agg, PetscViewer viewer)
262: {
263:   PetscBool iascii;

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

271:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
272:   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)agg, viewer));
273:   if (agg->ops->view) {
274:     PetscCall(PetscViewerASCIIPushTab(viewer));
275:     PetscUseTypeMethod(agg, view, viewer);
276:     PetscCall(PetscViewerASCIIPopTab(viewer));
277:   }
278:   PetscFunctionReturn(PETSC_SUCCESS);
279: }

281: /*@C
282:    MatCoarsenSetType - Sets the type of aggregator to use

284:    Collective

286:    Input Parameters:
287: +  coarser - the coarsen context.
288: -  type - a known coarsening method

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

293:    Level: advanced

295: .seealso: `MatCoarsen`, `MatCoarsenCreate()`, `MatCoarsenApply()`, `MatCoarsenType`, `MatCoarsenGetType()`
296: @*/
297: PetscErrorCode MatCoarsenSetType(MatCoarsen coarser, MatCoarsenType type)
298: {
299:   PetscBool match;
300:   PetscErrorCode (*r)(MatCoarsen);

302:   PetscFunctionBegin;

306:   PetscCall(PetscObjectTypeCompare((PetscObject)coarser, type, &match));
307:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

309:   PetscTryTypeMethod(coarser, destroy);
310:   coarser->ops->destroy = NULL;
311:   PetscCall(PetscMemzero(coarser->ops, sizeof(struct _MatCoarsenOps)));

313:   PetscCall(PetscFunctionListFind(MatCoarsenList, type, &r));
314:   PetscCheck(r, PetscObjectComm((PetscObject)coarser), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown coarsen type %s", type);
315:   PetscCall((*r)(coarser));

317:   PetscCall(PetscFree(((PetscObject)coarser)->type_name));
318:   PetscCall(PetscStrallocpy(type, &((PetscObject)coarser)->type_name));
319:   PetscFunctionReturn(PETSC_SUCCESS);
320: }

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

325:    Logically Collective

327:    Input Parameters:
328: +  coarser - the coarsen context
329: -  perm - vertex ordering of (greedy) algorithm

331:    Level: advanced

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

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

346: /*@C
347:    MatCoarsenGetData - Gets the weights for vertices for a coarsener.

349:    Logically Collective

351:    Input Parameter:
352: .  coarser - the coarsen context

354:    Output Parameter:
355: .  llist - linked list of aggregates

357:    Level: advanced

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

371: /*@
372:    MatCoarsenSetFromOptions - Sets various coarsen options from the options database.

374:    Collective

376:    Input Parameter:
377: .  coarser - the coarsen context.

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

382:    Level: advanced

384:    Note:
385:    Sets the `MatCoarsenType` to `MATCOARSENMISK` if has not been set previously

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

395:   PetscFunctionBegin;
396:   PetscObjectOptionsBegin((PetscObject)coarser);
397:   if (!((PetscObject)coarser)->type_name) {
398:     def = MATCOARSENMISK;
399:   } else {
400:     def = ((PetscObject)coarser)->type_name;
401:   }

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

410:   PetscTryTypeMethod(coarser, setfromoptions, PetscOptionsObject);
411:   PetscOptionsEnd();

413:   PetscFunctionReturn(PETSC_SUCCESS);
414: }