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: 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()
     94:            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 = NULL; 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 = NULL;

    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:    MatCoarsenViewFromOptions - View from Options

    222:    Collective on MatCoarsen

    224:    Input Parameters:
    225: +  A - the coarsen context
    226: .  obj - Optional object
    227: -  name - command line option

    229:    Level: intermediate
    230: .seealso:  MatCoarsen, MatCoarsenView, PetscObjectViewFromOptions(), MatCoarsenCreate()
    231: @*/
    232: PetscErrorCode  MatCoarsenViewFromOptions(MatCoarsen A,PetscObject obj,const char name[])
    233: {

    238:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
    239:   return(0);
    240: }

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

    245:    Collective on MatCoarsen

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

    251:    Level: advanced

    253:    Note:
    254:    The available visualization contexts include
    255: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    256: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    257:          output where only the first processor opens
    258:          the file.  All other processors send their
    259:          data to the first processor to print.

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

    264: .seealso: PetscViewerASCIIOpen()
    265: @*/
    266: PetscErrorCode  MatCoarsenView(MatCoarsen agg,PetscViewer viewer)
    267: {
    269:   PetscBool      iascii;

    273:   if (!viewer) {
    274:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)agg),&viewer);
    275:   }

    279:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    280:   PetscObjectPrintClassNamePrefixType((PetscObject)agg,viewer);
    281:   if (agg->ops->view) {
    282:     PetscViewerASCIIPushTab(viewer);
    283:     (*agg->ops->view)(agg,viewer);
    284:     PetscViewerASCIIPopTab(viewer);
    285:   }
    286:   return(0);
    287: }

    289: /*@C
    290:    MatCoarsenSetType - Sets the type of aggregator to use

    292:    Collective on MatCoarsen

    294:    Input Parameter:
    295: +  coarser - the coarsen context.
    296: -  type - a known coarsening method

    298:    Options Database Command:
    299: $  -mat_coarsen_type  <type>
    300: $      Use -help for a list of available methods
    301: $      (for instance, mis)

    303:    Level: advanced

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

    307: @*/
    308: PetscErrorCode  MatCoarsenSetType(MatCoarsen coarser, MatCoarsenType type)
    309: {
    310:   PetscErrorCode ierr,(*r)(MatCoarsen);
    311:   PetscBool      match;

    317:   PetscObjectTypeCompare((PetscObject)coarser,type,&match);
    318:   if (match) return(0);

    320:   if (coarser->ops->destroy) {
    321:     (*coarser->ops->destroy)(coarser);
    322:     coarser->ops->destroy = NULL;
    323:   }
    324:   PetscMemzero(coarser->ops,sizeof(struct _MatCoarsenOps));

    326:   PetscFunctionListFind(MatCoarsenList,type,&r);
    327:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown coarsen type %s",type);
    328:   (*r)(coarser);

    330:   PetscFree(((PetscObject)coarser)->type_name);
    331:   PetscStrallocpy(type,&((PetscObject)coarser)->type_name);
    332:   return(0);
    333: }

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

    338:    Logically Collective on Coarsen

    340:    Input Parameters:
    341: +  coarser - the coarsen context
    342: -  perm - vertex ordering of (greedy) algorithm

    344:    Level: advanced

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

    349: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
    350: @*/
    351: PetscErrorCode MatCoarsenSetGreedyOrdering(MatCoarsen coarser, const IS perm)
    352: {
    355:   coarser->perm = perm;
    356:   return(0);
    357: }

    359: /*@C
    360:    MatCoarsenGetData - Gets the weights for vertices for a coarsen.

    362:    Logically Collective on Coarsen

    364:    Input Parameter:
    365: .  coarser - the coarsen context

    367:    Output Parameter:
    368: .  llist - linked list of aggregates

    370:    Level: advanced

    372: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
    373: @*/
    374: PetscErrorCode MatCoarsenGetData(MatCoarsen coarser, PetscCoarsenData **llist)
    375: {
    378:   if (!coarser->agg_lists) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"No linked list - generate it or call ApplyCoarsen");
    379:   *llist             = coarser->agg_lists;
    380:   coarser->agg_lists = NULL; /* giving up ownership */
    381:   return(0);
    382: }

    384: /*@
    385:    MatCoarsenSetFromOptions - Sets various coarsen options from the
    386:         options database.

    388:    Collective on MatCoarsen

    390:    Input Parameter:
    391: .  coarser - the coarsen context.

    393:    Options Database Command:
    394: $  -mat_coarsen_type  <type>
    395: $      Use -help for a list of available methods
    396: $      (for instance, mis)

    398:    Level: advanced

    400: @*/
    401: PetscErrorCode MatCoarsenSetFromOptions(MatCoarsen coarser)
    402: {
    404:   PetscBool      flag;
    405:   char           type[256];
    406:   const char     *def;

    409:   PetscObjectOptionsBegin((PetscObject)coarser);
    410:   if (!((PetscObject)coarser)->type_name) {
    411:     def = MATCOARSENMIS;
    412:   } else {
    413:     def = ((PetscObject)coarser)->type_name;
    414:   }

    416:   PetscOptionsFList("-mat_coarsen_type","Type of aggregator","MatCoarsenSetType",MatCoarsenList,def,type,256,&flag);
    417:   if (flag) {
    418:     MatCoarsenSetType(coarser,type);
    419:   }
    420:   /*
    421:    Set the type if it was never set.
    422:    */
    423:   if (!((PetscObject)coarser)->type_name) {
    424:     MatCoarsenSetType(coarser,def);
    425:   }

    427:   if (coarser->ops->setfromoptions) {
    428:     (*coarser->ops->setfromoptions)(PetscOptionsObject,coarser);
    429:   }
    430:   PetscOptionsEnd();
    431:   MatCoarsenViewFromOptions(coarser,NULL,"-mat_coarsen_view");
    432:   return(0);
    433: }