Actual source code: coarsen.c

petsc-3.4.4 2014-03-13
  2: #include <petsc-private/matimpl.h>               /*I "petscmat.h" I*/

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

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

 12: /*@C
 13:    MatCoarsenRegister - Adds a new sparse matrix coarsen to the  matrix package.

 15:    Not Collective

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

 21:    Level: developer

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

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

 33: .keywords: matrix, coarsen, register

 35: .seealso: MatCoarsenRegisterDestroy(), MatCoarsenRegisterAll()
 36: @*/
 37: PetscErrorCode  MatCoarsenRegister(const char sname[],PetscErrorCode (*function)(MatCoarsen))
 38: {

 42:   PetscFunctionListAdd(&MatCoarsenList,sname,function);
 43:   return(0);
 44: }

 48: /*@C
 49:    MatCoarsenGetType - Gets the Coarsen method type and name (as a string)
 50:         from the coarsen context.

 52:    Not collective

 54:    Input Parameter:
 55: .  coarsen - the coarsen context

 57:    Output Parameter:
 58: .  type - aggregator type

 60:    Level: intermediate

 62:    Not Collective

 64: .keywords: Coarsen, get, method, name, type
 65: @*/
 66: PetscErrorCode  MatCoarsenGetType(MatCoarsen coarsen,MatCoarsenType *type)
 67: {
 71:   *type = ((PetscObject)coarsen)->type_name;
 72:   return(0);
 73: }

 77: /*@
 78:    MatCoarsenApply - Gets a coarsen for a matrix.

 80:    Collective on Mat

 82:    Input Parameters:
 83: .  matp - the matrix coarsen object

 85:    Output Parameters:
 86: .   coarsen - the coarsen. For each local node this tells the aggregate
 87:                    number that that node is assigned to.

 89:    Options Database Keys:
 90:    To specify the coarsen through the options database, use one of
 91:    the following
 92: $    -mat_coarsen_type mis
 93:    To see the coarsen result
 94: $    -mat_coarsen_view

 96:    Level: beginner

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

100: .keywords: matrix, get, coarsen

102: .seealso:  MatCoarsenRegister(), MatCoarsenCreate(),
103:            MatCoarsenDestroy(), MatCoarsenSetAdjacency(), ISCoarsenToNumbering(),
104:            ISCoarsenCount()
105: @*/
106: PetscErrorCode  MatCoarsenApply(MatCoarsen coarser)
107: {
109:   PetscBool      flag = PETSC_FALSE;

114:   if (!coarser->graph->assembled) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
115:   if (coarser->graph->factortype) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
116:   if (!coarser->ops->apply) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"Must set type with MatCoarsenSetFromOptions() or MatCoarsenSetType()");
117:   PetscLogEventBegin(MAT_Coarsen,coarser,0,0,0);
118:   (*coarser->ops->apply)(coarser);
119:   PetscLogEventEnd(MAT_Coarsen,coarser,0,0,0);

121:   PetscOptionsGetBool(NULL,"-mat_coarsen_view",&flag,NULL);
122:   if (flag) {
123:     PetscViewer viewer;
124:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)coarser),&viewer);
125:     MatCoarsenView(coarser,viewer);
126:     /* ISView(coarser->mis,viewer); */
127:   }
128:   return(0);
129: }

133: /*@
134:    MatCoarsenSetAdjacency - Sets the adjacency graph (matrix) of the thing to be
135:       partitioned.

137:    Collective on MatCoarsen and Mat

139:    Input Parameters:
140: +  agg - the coarsen context
141: -  adj - the adjacency matrix

143:    Level: beginner

145: .keywords: Coarsen, adjacency

147: .seealso: MatCoarsenCreate()
148: @*/
149: PetscErrorCode  MatCoarsenSetAdjacency(MatCoarsen agg, Mat adj)
150: {
154:   agg->graph = adj;
155:   return(0);
156: }

160: /*@
161:    MatCoarsenSetStrictAggs -

163:    Not Collective on MatCoarsen and Mat

165:    Input Parameters:
166: +  agg - the coarsen context
167: -  str - the adjacency matrix

169:    Level: beginner

171: .keywords: Coarsen, adjacency

173: .seealso: MatCoarsenCreate()
174: @*/
175: PetscErrorCode MatCoarsenSetStrictAggs(MatCoarsen agg, PetscBool str)
176: {
179:   agg->strict_aggs = str;
180:   return(0);
181: }

185: /*@
186:    MatCoarsenSetVerbose -

188:    Not Collective on MatCoarsen and Mat

190:    Input Parameters:
191: +  agg - the coarsen context
192: -  str - the adjacency matrix

194:    Level: beginner

196: .keywords: Coarsen, adjacency

198: .seealso: MatCoarsenCreate()
199: @*/
200: PetscErrorCode MatCoarsenSetVerbose(MatCoarsen agg, PetscInt vv)
201: {
204:   agg->verbose = vv;
205:   return(0);
206: }

210: /*@
211:    MatCoarsenDestroy - Destroys the coarsen context.

213:    Collective on Coarsen

215:    Input Parameters:
216: .  agg - the coarsen context

218:    Level: beginner

220: .keywords: Coarsen, destroy, context

222: .seealso: MatCoarsenCreate()
223: @*/
224: PetscErrorCode  MatCoarsenDestroy(MatCoarsen *agg)
225: {

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

233:   if ((*agg)->ops->destroy) {
234:     (*(*agg)->ops->destroy)((*agg));
235:   }

237:   if ((*agg)->agg_lists) {
238:     PetscCDDestroy((*agg)->agg_lists);
239:   }

241:   PetscHeaderDestroy(agg);
242:   return(0);
243: }

247: /*@
248:    MatCoarsenCreate - Creates a coarsen context.

250:    Collective on MPI_Comm

252:    Input Parameter:
253: .   comm - MPI communicator

255:    Output Parameter:
256: .  newcrs - location to put the context

258:    Level: beginner

260: .keywords: Coarsen, create, context

262: .seealso: MatCoarsenSetType(), MatCoarsenApply(), MatCoarsenDestroy(),
263:           MatCoarsenSetAdjacency()

265: @*/
266: PetscErrorCode  MatCoarsenCreate(MPI_Comm comm, MatCoarsen *newcrs)
267: {
268:   MatCoarsen     agg;

272:   *newcrs = 0;

274: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
275:   MatInitializePackage();
276: #endif
277:   PetscHeaderCreate(agg, _p_MatCoarsen, struct _MatCoarsenOps, MAT_COARSEN_CLASSID,"MatCoarsen","Matrix/graph coarsen",
278:                            "MatCoarsen", comm, MatCoarsenDestroy, MatCoarsenView);

280:   *newcrs = agg;
281:   return(0);
282: }

286: /*@C
287:    MatCoarsenView - Prints the coarsen data structure.

289:    Collective on MatCoarsen

291:    Input Parameters:
292: .  agg - the coarsen context
293: .  viewer - optional visualization context

295:    Level: intermediate

297:    Note:
298:    The available visualization contexts include
299: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
300: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
301:          output where only the first processor opens
302:          the file.  All other processors send their
303:          data to the first processor to print.

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

308: .keywords: Coarsen, view

310: .seealso: PetscViewerASCIIOpen()
311: @*/
312: PetscErrorCode  MatCoarsenView(MatCoarsen agg,PetscViewer viewer)
313: {
315:   PetscBool      iascii;

319:   if (!viewer) {
320:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)agg),&viewer);
321:   }

325:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
326:   if (iascii) {
327:     PetscObjectPrintClassNamePrefixType((PetscObject)agg,viewer,"MatCoarsen Object");
328:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for this MatCoarsen",((PetscObject)viewer)->type_name);

330:   if (agg->ops->view) {
331:     PetscViewerASCIIPushTab(viewer);
332:     (*agg->ops->view)(agg,viewer);
333:     PetscViewerASCIIPopTab(viewer);
334:   }
335:   return(0);
336: }

340: /*@C
341:    MatCoarsenSetType - Sets the type of aggregator to use

343:    Collective on MatCoarsen

345:    Input Parameter:
346: .  coarser - the coarsen context.
347: .  type - a known method

349:    Options Database Command:
350: $  -mat_coarsen_type  <type>
351: $      Use -help for a list of available methods
352: $      (for instance, mis)

354:    Level: intermediate

356: .keywords: coarsen, set, method, type

358: .seealso: MatCoarsenCreate(), MatCoarsenApply(), MatCoarsenType

360: @*/
361: PetscErrorCode  MatCoarsenSetType(MatCoarsen coarser, MatCoarsenType type)
362: {
363:   PetscErrorCode ierr,(*r)(MatCoarsen);
364:   PetscBool      match;


370:   PetscObjectTypeCompare((PetscObject)coarser,type,&match);
371:   if (match) return(0);

373:   if (coarser->setupcalled) {
374:      (*coarser->ops->destroy)(coarser);

376:     coarser->ops->destroy = NULL;
377:     coarser->subctx       = 0;
378:     coarser->setupcalled  = 0;
379:   }

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

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

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

388:   (*r)(coarser);

390:   PetscFree(((PetscObject)coarser)->type_name);
391:   PetscStrallocpy(type,&((PetscObject)coarser)->type_name);
392:   return(0);
393: }

397: /*@C
398:    MatCoarsenSetGreedyOrdering - Sets the weights for vertices for a coarsen.

400:    Logically Collective on Coarsen

402:    Input Parameters:
403: +  coarser - the coarsen context
404: -  perm - vertex ordering of (greedy) algorithm

406:    Level: beginner

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

411: .keywords: Coarsen

413: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
414: @*/
415: PetscErrorCode MatCoarsenSetGreedyOrdering(MatCoarsen coarser, const IS perm)
416: {
419:   coarser->perm = perm;
420:   return(0);
421: }

425: /*@C
426:    MatCoarsenGetData - Sets the weights for vertices for a coarsen.

428:    Logically Collective on Coarsen

430:    Input Parameters:
431: +  coarser - the coarsen context
432: -  mis - pointer into 'llist'
433: -  llist - linked list of aggregates

435:    Level: beginner

437:    Notes:

439: .keywords: Coarsen

441: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
442: @*/
443: PetscErrorCode MatCoarsenGetData(MatCoarsen coarser, PetscCoarsenData **llist)
444: {
447:   if (!coarser->agg_lists) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"No linked list - generate it or call ApplyCoarsen");
448:   *llist             = coarser->agg_lists;
449:   coarser->agg_lists = 0; /* giving up ownership */
450:   return(0);
451: }

455: /*@
456:    MatCoarsenSetFromOptions - Sets various coarsen options from the
457:         options database.

459:    Collective on MatCoarsen

461:    Input Parameter:
462: .  coarser - the coarsen context.

464:    Options Database Command:
465: $  -mat_coarsen_type  <type>
466: $      Use -help for a list of available methods
467: $      (for instance, mis)

469:    Level: beginner

471: .keywords: coarsen, set, method, type
472: @*/
473: PetscErrorCode MatCoarsenSetFromOptions(MatCoarsen coarser)
474: {
476:   PetscBool      flag;
477:   char           type[256];
478:   const char     *def;

481:   PetscObjectOptionsBegin((PetscObject)coarser);
482:   if (!((PetscObject)coarser)->type_name) {
483:     def = MATCOARSENMIS;
484:   } else {
485:     def = ((PetscObject)coarser)->type_name;
486:   }

488:   PetscOptionsList("-mat_coarsen_type","Type of aggregator","MatCoarsenSetType",MatCoarsenList,def,type,256,&flag);
489:   if (flag) {
490:     MatCoarsenSetType(coarser,type);
491:   }
492:   /*
493:    Set the type if it was never set.
494:    */
495:   if (!((PetscObject)coarser)->type_name) {
496:     MatCoarsenSetType(coarser,def);
497:   }

499:   if (coarser->ops->setfromoptions) {
500:     (*coarser->ops->setfromoptions)(coarser);
501:   }
502:   PetscOptionsEnd();
503:   return(0);
504: }