Actual source code: coarsen.c

petsc-3.3-p7 2013-05-11
  2: #include <petsc-private/matimpl.h>               /*I "petscmat.h" I*/

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

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

 12: PetscErrorCode  MatCoarsenRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(MatCoarsen))
 13: {
 15:   char fullname[PETSC_MAX_PATH_LEN];

 18:   PetscFListConcat(path,name,fullname);
 19:   PetscFListAdd(&MatCoarsenList,sname,fullname,(void (*)(void))function);
 20:   return(0);
 21: }

 25: /*@C
 26:    MatCoarsenRegisterDestroy - Frees the list of coarsen routines.

 28:   Not Collective

 30:   Level: developer

 32: .keywords: matrix, register, destroy

 34: .seealso: MatCoarsenRegisterDynamic(), MatCoarsenRegisterAll()
 35: @*/
 36: PetscErrorCode  MatCoarsenRegisterDestroy(void)
 37: {

 41:   MatCoarsenRegisterAllCalled = PETSC_FALSE;
 42:   PetscFListDestroy(&MatCoarsenList);
 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,const 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 MatCoarsenRegisterDynamic().

100: .keywords: matrix, get, coarsen

102: .seealso:  MatCoarsenRegisterDynamic(), 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(((PetscObject)coarser)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
115:   if (coarser->graph->factortype) SETERRQ(((PetscObject)coarser)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
116:   if (!coarser->ops->apply) SETERRQ(((PetscObject)coarser)->comm,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(PETSC_NULL,"-mat_coarsen_view",&flag,PETSC_NULL);
122:   if (flag) {
123:     PetscViewer viewer;
124:     PetscViewerASCIIGetStdout(((PetscObject)coarser)->comm,&viewer);
125:     MatCoarsenView(coarser,viewer);
126:     /* ISView(coarser->mis,viewer); */
127:   }
128:   return(0);
129: }
130: 
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;
269:   PetscErrorCode  ierr;

272:   *newcrs = 0;

274: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
275:   MatInitializePackage(PETSC_NULL);
276: #endif
277:   PetscHeaderCreate( agg, _p_MatCoarsen, struct _MatCoarsenOps, MAT_COARSEN_CLASSID,-1,"MatCoarsen","Matrix/graph coarsen",
278:                            "MatCoarsen", comm, MatCoarsenDestroy, MatCoarsenView );
279: 

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

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

290:    Collective on MatCoarsen

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

296:    Level: intermediate

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

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

309: .keywords: Coarsen, view

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

320:   if (!viewer) {
321:     PetscViewerASCIIGetStdout(((PetscObject)agg)->comm,&viewer);
322:   }

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

333:   if (agg->ops->view) {
334:     PetscViewerASCIIPushTab(viewer);
335:     (*agg->ops->view)(agg,viewer);
336:     PetscViewerASCIIPopTab(viewer);
337:   }

339:   return(0);
340: }

344: /*@C
345:    MatCoarsenSetType - Sets the type of aggregator to use

347:    Collective on MatCoarsen

349:    Input Parameter:
350: .  coarser - the coarsen context.
351: .  type - a known method

353:    Options Database Command:
354: $  -mat_coarsen_type  <type>
355: $      Use -help for a list of available methods
356: $      (for instance, mis)

358:    Level: intermediate

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

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

364: @*/
365: PetscErrorCode  MatCoarsenSetType( MatCoarsen coarser, const MatCoarsenType type )
366: {
367:   PetscErrorCode ierr,(*r)(MatCoarsen);
368:   PetscBool  match;


374:   PetscObjectTypeCompare((PetscObject)coarser,type,&match);
375:   if (match) return(0);

377:   if (coarser->setupcalled) {
378:      (*coarser->ops->destroy)(coarser);
379:     coarser->ops->destroy = PETSC_NULL;
380:     coarser->subctx       = 0;
381:     coarser->setupcalled = 0;
382:   }

384:    PetscFListFind(MatCoarsenList,((PetscObject)coarser)->comm,type,PETSC_TRUE,(void (**)(void)) &r);

386:   if (!r) SETERRQ1(((PetscObject)coarser)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown coarsen type %s",type);

388:   coarser->ops->destroy      = (PetscErrorCode (*)(MatCoarsen)) 0;
389:   coarser->ops->view         = (PetscErrorCode (*)(MatCoarsen,PetscViewer)) 0;
390:   (*r)(coarser);

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

399: /*@C
400:    MatCoarsenSetGreedyOrdering - Sets the weights for vertices for a coarsen.

402:    Logically Collective on Coarsen

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

408:    Level: beginner

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

413: .keywords: Coarsen

415: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
416: @*/
417: PetscErrorCode MatCoarsenSetGreedyOrdering( MatCoarsen coarser, const IS perm )
418: {
421:   coarser->perm = perm;
422:   return(0);
423: }

427: /*@C
428:    MatCoarsenGetData - Sets the weights for vertices for a coarsen.

430:    Logically Collective on Coarsen

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

437:    Level: beginner

439:    Notes:

441: .keywords: Coarsen

443: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
444: @*/
445: PetscErrorCode MatCoarsenGetData( MatCoarsen coarser, PetscCoarsenData **llist )
446: {

450:   if( !coarser->agg_lists ) {
451:     SETERRQ(((PetscObject)coarser)->comm,PETSC_ERR_ARG_WRONGSTATE,"No linked list - generate it or call ApplyCoarsen");
452:   }
453:   *llist = coarser->agg_lists;
454:   coarser->agg_lists = 0; /* giving up ownership */
455: 
456:   return(0);
457: }

461: /*@
462:    MatCoarsenSetFromOptions - Sets various coarsen options from the 
463:         options database.

465:    Collective on MatCoarsen

467:    Input Parameter:
468: .  coarser - the coarsen context.

470:    Options Database Command:
471: $  -mat_coarsen_type  <type>
472: $      Use -help for a list of available methods
473: $      (for instance, mis)

475:    Level: beginner

477: .keywords: coarsen, set, method, type
478: @*/
479: PetscErrorCode MatCoarsenSetFromOptions( MatCoarsen coarser )
480: {
482:   PetscBool  flag;
483:   char       type[256];
484:   const char *def;

487:   PetscObjectOptionsBegin((PetscObject)coarser);
488:   if (!((PetscObject)coarser)->type_name) {
489:     def = MATCOARSENMIS;
490:   } else {
491:     def = ((PetscObject)coarser)->type_name;
492:   }

494:   PetscOptionsList("-mat_coarsen_type","Type of aggregator","MatCoarsenSetType",MatCoarsenList,def,type,256,&flag);
495: 

497:   if (flag) {
498:     MatCoarsenSetType(coarser,type);
499:   }
500:   /*
501:    Set the type if it was never set.
502:    */
503:   if (!((PetscObject)coarser)->type_name) {
504:     MatCoarsenSetType(coarser,def);
505:   }
506: 
507:   if (coarser->ops->setfromoptions) {
508:     (*coarser->ops->setfromoptions)(coarser);
509:   }
510:   PetscOptionsEnd();
511:   return(0);
512: }