Actual source code: coarsen.c

petsc-3.12.5 2020-03-29
Report Typos and Errors

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

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

  7: PetscFunctionList MatCoarsenList              = 0;
  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: MatCoarsenRegisterDestroy(), MatCoarsenRegisterAll()
 32: @*/
 33: PetscErrorCode  MatCoarsenRegister(const char sname[],PetscErrorCode (*function)(MatCoarsen))
 34: {

 38:   MatInitializePackage();
 39:   PetscFunctionListAdd(&MatCoarsenList,sname,function);
 40:   return(0);
 41: }

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

 47:    Not collective

 49:    Input Parameter:
 50: .  coarsen - the coarsen context

 52:    Output Parameter:
 53: .  type - coarsener type

 55:    Level: advanced

 57:    Not Collective

 59: .seealso: MatCoarsenCreate(), MatCoarsenType, MatCoarsenSetType()
 60: @*/
 61: PetscErrorCode  MatCoarsenGetType(MatCoarsen coarsen,MatCoarsenType *type)
 62: {
 66:   *type = ((PetscObject)coarsen)->type_name;
 67:   return(0);
 68: }

 70: /*@
 71:    MatCoarsenApply - Gets a coarsen for a matrix.

 73:    Collective on MatCoarsen

 75:    Input Parameter:
 76: .   coarsen - the coarsen

 78:    Options Database Keys:
 79:    To specify the coarsen through the options database, use one of
 80:    the following
 81: $    -mat_coarsen_type mis
 82:    To see the coarsen result
 83: $    -mat_coarsen_view

 85:    Level: advanced

 87:    Notes:
 88:     Use MatCoarsenGetData() to access the results of the coarsening

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

 92: .seealso:  MatCoarsenRegister(), MatCoarsenCreate(),
 93:            MatCoarsenDestroy(), MatCoarsenSetAdjacency(), ISCoarsenToNumbering(),
 94:            ISCoarsenCount(), MatCoarsenGetData()
 95: @*/
 96: PetscErrorCode  MatCoarsenApply(MatCoarsen coarser)
 97: {

103:   if (!coarser->graph->assembled) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
104:   if (coarser->graph->factortype) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
105:   if (!coarser->ops->apply) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"Must set type with MatCoarsenSetFromOptions() or MatCoarsenSetType()");
106:   PetscLogEventBegin(MAT_Coarsen,coarser,0,0,0);
107:   (*coarser->ops->apply)(coarser);
108:   PetscLogEventEnd(MAT_Coarsen,coarser,0,0,0);
109:   return(0);
110: }

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

115:    Collective on MatCoarsen

117:    Input Parameters:
118: +  agg - the coarsen context
119: -  adj - the adjacency matrix

121:    Level: advanced

123: .seealso: MatCoarsenCreate(), MatCoarsenApply()
124: @*/
125: PetscErrorCode  MatCoarsenSetAdjacency(MatCoarsen agg, Mat adj)
126: {
130:   agg->graph = adj;
131:   return(0);
132: }

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

137:    Logically Collective on MatCoarsen

139:    Input Parameters:
140: +  agg - the coarsen context
141: -  str - PETSC_TRUE keep strict aggregates, PETSC_FALSE allow overlap
142:    Level: advanced

144: .seealso: MatCoarsenCreate()
145: @*/
146: PetscErrorCode MatCoarsenSetStrictAggs(MatCoarsen agg, PetscBool str)
147: {
150:   agg->strict_aggs = str;
151:   return(0);
152: }

154: /*@
155:    MatCoarsenDestroy - Destroys the coarsen context.

157:    Collective on MatCoarsen

159:    Input Parameters:
160: .  agg - the coarsen context

162:    Level: advanced

164: .seealso: MatCoarsenCreate()
165: @*/
166: PetscErrorCode  MatCoarsenDestroy(MatCoarsen *agg)
167: {

171:   if (!*agg) return(0);
173:   if (--((PetscObject)(*agg))->refct > 0) {*agg = 0; return(0);}

175:   if ((*agg)->ops->destroy) {
176:     (*(*agg)->ops->destroy)((*agg));
177:   }

179:   if ((*agg)->agg_lists) {
180:     PetscCDDestroy((*agg)->agg_lists);
181:   }

183:   PetscHeaderDestroy(agg);
184:   return(0);
185: }

187: /*@
188:    MatCoarsenCreate - Creates a coarsen context.

190:    Collective

192:    Input Parameter:
193: .   comm - MPI communicator

195:    Output Parameter:
196: .  newcrs - location to put the context

198:    Level: advanced

200: .seealso: MatCoarsenSetType(), MatCoarsenApply(), MatCoarsenDestroy(),
201:           MatCoarsenSetAdjacency(), MatCoarsenGetData()

203: @*/
204: PetscErrorCode  MatCoarsenCreate(MPI_Comm comm, MatCoarsen *newcrs)
205: {
206:   MatCoarsen     agg;

210:   *newcrs = 0;

212:   MatInitializePackage();
213:   PetscHeaderCreate(agg, MAT_COARSEN_CLASSID,"MatCoarsen","Matrix/graph coarsen", "MatCoarsen", comm, MatCoarsenDestroy, MatCoarsenView);

215:   *newcrs = agg;
216:   return(0);
217: }

219: /*@C
220:    MatCoarsenView - Prints the coarsen data structure.

222:    Collective on MatCoarsen

224:    Input Parameters:
225: +  agg - the coarsen context
226: -  viewer - optional visualization context

228:    Level: advanced

230:    Note:
231:    The available visualization contexts include
232: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
233: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
234:          output where only the first processor opens
235:          the file.  All other processors send their
236:          data to the first processor to print.

238:    The user can open alternative visualization contexts with
239: .     PetscViewerASCIIOpen() - output to a specified file

241: .seealso: PetscViewerASCIIOpen()
242: @*/
243: PetscErrorCode  MatCoarsenView(MatCoarsen agg,PetscViewer viewer)
244: {
246:   PetscBool      iascii;

250:   if (!viewer) {
251:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)agg),&viewer);
252:   }

256:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
257:   PetscObjectPrintClassNamePrefixType((PetscObject)agg,viewer);
258:   if (agg->ops->view) {
259:     PetscViewerASCIIPushTab(viewer);
260:     (*agg->ops->view)(agg,viewer);
261:     PetscViewerASCIIPopTab(viewer);
262:   }
263:   return(0);
264: }

266: /*@C
267:    MatCoarsenSetType - Sets the type of aggregator to use

269:    Collective on MatCoarsen

271:    Input Parameter:
272: +  coarser - the coarsen context.
273: -  type - a known coarsening method

275:    Options Database Command:
276: $  -mat_coarsen_type  <type>
277: $      Use -help for a list of available methods
278: $      (for instance, mis)

280:    Level: advanced

282: .seealso: MatCoarsenCreate(), MatCoarsenApply(), MatCoarsenType, MatCoarsenGetType()

284: @*/
285: PetscErrorCode  MatCoarsenSetType(MatCoarsen coarser, MatCoarsenType type)
286: {
287:   PetscErrorCode ierr,(*r)(MatCoarsen);
288:   PetscBool      match;


294:   PetscObjectTypeCompare((PetscObject)coarser,type,&match);
295:   if (match) return(0);

297:   if (coarser->setupcalled) {
298:      (*coarser->ops->destroy)(coarser);

300:     coarser->ops->destroy = NULL;
301:     coarser->subctx       = 0;
302:     coarser->setupcalled  = 0;
303:   }

305:    PetscFunctionListFind(MatCoarsenList,type,&r);

307:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown coarsen type %s",type);

309:   coarser->ops->destroy = (PetscErrorCode (*)(MatCoarsen)) 0;
310:   coarser->ops->view    = (PetscErrorCode (*)(MatCoarsen,PetscViewer)) 0;

312:   (*r)(coarser);

314:   PetscFree(((PetscObject)coarser)->type_name);
315:   PetscStrallocpy(type,&((PetscObject)coarser)->type_name);
316:   return(0);
317: }

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

322:    Logically Collective on Coarsen

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

328:    Level: advanced

330:    Notes:
331:       The IS weights is freed by PETSc, so user has given this to us

333: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
334: @*/
335: PetscErrorCode MatCoarsenSetGreedyOrdering(MatCoarsen coarser, const IS perm)
336: {
339:   coarser->perm = perm;
340:   return(0);
341: }

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

346:    Logically Collective on Coarsen

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

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

354:    Level: advanced

356: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
357: @*/
358: PetscErrorCode MatCoarsenGetData(MatCoarsen coarser, PetscCoarsenData **llist)
359: {
362:   if (!coarser->agg_lists) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"No linked list - generate it or call ApplyCoarsen");
363:   *llist             = coarser->agg_lists;
364:   coarser->agg_lists = 0; /* giving up ownership */
365:   return(0);
366: }

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

372:    Collective on MatCoarsen

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

377:    Options Database Command:
378: $  -mat_coarsen_type  <type>
379: $      Use -help for a list of available methods
380: $      (for instance, mis)

382:    Level: advanced

384: @*/
385: PetscErrorCode MatCoarsenSetFromOptions(MatCoarsen coarser)
386: {
388:   PetscBool      flag;
389:   char           type[256];
390:   const char     *def;

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

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

411:   if (coarser->ops->setfromoptions) {
412:     (*coarser->ops->setfromoptions)(PetscOptionsObject,coarser);
413:   }
414:   PetscOptionsEnd();
415:   MatCoarsenViewFromOptions(coarser,NULL,"-mat_coarsen_view");
416:   return(0);
417: }