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: +    -mat_coarsen_type mis|hem|misk - set the coarsening type
 76: -    -mat_coarsen_view - view the coarsening object

 78:    Level: advanced

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

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

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

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

105:    Collective

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

111:    Level: advanced

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

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

127:    Logically Collective

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

133:    Level: advanced

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

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

148:    Collective

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

153:    Level: advanced

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

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

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

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

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

178:    Collective

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

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

186:    Level: advanced

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

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

196:   PetscFunctionBegin;
197:   *newcrs = NULL;

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

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

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

209:    Collective

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

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

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

231:    Level: intermediate

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

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

246:    Collective

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

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

254:    Level: advanced

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

262:   PetscFunctionBegin;
264:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)agg), &viewer));
266:   PetscCheckSameComm(agg, 1, viewer, 2);

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

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

281:    Collective

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

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

290:    Level: advanced

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

299:   PetscFunctionBegin;

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

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

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

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

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

322:    Logically Collective

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

328:    Level: advanced

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

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

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

346:    Logically Collective

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

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

354:    Level: advanced

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

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

371:    Collective

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

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

379:    Level: advanced

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

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

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

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

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

410:   PetscFunctionReturn(PETSC_SUCCESS);
411: }