1*a77d671bSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 2*a77d671bSBarry Smith 3*a77d671bSBarry Smith /* Logging support */ 4*a77d671bSBarry Smith PetscClassId MAT_COARSEN_CLASSID; 5*a77d671bSBarry Smith 6*a77d671bSBarry Smith PetscFunctionList MatCoarsenList = NULL; 7*a77d671bSBarry Smith PetscBool MatCoarsenRegisterAllCalled = PETSC_FALSE; 8*a77d671bSBarry Smith 9*a77d671bSBarry Smith /*@C 10*a77d671bSBarry Smith MatCoarsenRegister - Adds a new sparse matrix coarsening algorithm to the matrix package. 11*a77d671bSBarry Smith 12*a77d671bSBarry Smith Logically Collective, No Fortran Support 13*a77d671bSBarry Smith 14*a77d671bSBarry Smith Input Parameters: 15*a77d671bSBarry Smith + sname - name of coarsen (for example `MATCOARSENMIS`) 16*a77d671bSBarry Smith - function - function pointer that creates the coarsen type 17*a77d671bSBarry Smith 18*a77d671bSBarry Smith Level: developer 19*a77d671bSBarry Smith 20*a77d671bSBarry Smith Example Usage: 21*a77d671bSBarry Smith .vb 22*a77d671bSBarry Smith MatCoarsenRegister("my_agg", MyAggCreate); 23*a77d671bSBarry Smith .ve 24*a77d671bSBarry Smith 25*a77d671bSBarry Smith Then, your aggregator can be chosen with the procedural interface via `MatCoarsenSetType(agg, "my_agg")` or at runtime via the option `-mat_coarsen_type my_agg` 26*a77d671bSBarry Smith 27*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenType`, `MatCoarsenSetType()`, `MatCoarsenCreate()`, `MatCoarsenRegisterDestroy()`, `MatCoarsenRegisterAll()` 28*a77d671bSBarry Smith @*/ 29*a77d671bSBarry Smith PetscErrorCode MatCoarsenRegister(const char sname[], PetscErrorCode (*function)(MatCoarsen)) 30*a77d671bSBarry Smith { 31*a77d671bSBarry Smith PetscFunctionBegin; 32*a77d671bSBarry Smith PetscCall(MatInitializePackage()); 33*a77d671bSBarry Smith PetscCall(PetscFunctionListAdd(&MatCoarsenList, sname, function)); 34*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 35*a77d671bSBarry Smith } 36*a77d671bSBarry Smith 37*a77d671bSBarry Smith /*@ 38*a77d671bSBarry Smith MatCoarsenGetType - Gets the Coarsen method type and name (as a string) 39*a77d671bSBarry Smith from the coarsen context. 40*a77d671bSBarry Smith 41*a77d671bSBarry Smith Not Collective 42*a77d671bSBarry Smith 43*a77d671bSBarry Smith Input Parameter: 44*a77d671bSBarry Smith . coarsen - the coarsen context 45*a77d671bSBarry Smith 46*a77d671bSBarry Smith Output Parameter: 47*a77d671bSBarry Smith . type - coarsener type 48*a77d671bSBarry Smith 49*a77d671bSBarry Smith Level: advanced 50*a77d671bSBarry Smith 51*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenCreate()`, `MatCoarsenType`, `MatCoarsenSetType()`, `MatCoarsenRegister()` 52*a77d671bSBarry Smith @*/ 53*a77d671bSBarry Smith PetscErrorCode MatCoarsenGetType(MatCoarsen coarsen, MatCoarsenType *type) 54*a77d671bSBarry Smith { 55*a77d671bSBarry Smith PetscFunctionBegin; 56*a77d671bSBarry Smith PetscValidHeaderSpecific(coarsen, MAT_COARSEN_CLASSID, 1); 57*a77d671bSBarry Smith PetscAssertPointer(type, 2); 58*a77d671bSBarry Smith *type = ((PetscObject)coarsen)->type_name; 59*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 60*a77d671bSBarry Smith } 61*a77d671bSBarry Smith 62*a77d671bSBarry Smith /*@ 63*a77d671bSBarry Smith MatCoarsenApply - Gets a coarsen for a matrix. 64*a77d671bSBarry Smith 65*a77d671bSBarry Smith Collective 66*a77d671bSBarry Smith 67*a77d671bSBarry Smith Input Parameter: 68*a77d671bSBarry Smith . coarser - the coarsen 69*a77d671bSBarry Smith 70*a77d671bSBarry Smith Options Database Keys: 71*a77d671bSBarry Smith + -mat_coarsen_type mis|hem|misk - mis: maximal independent set based; misk: distance k MIS; hem: heavy edge matching 72*a77d671bSBarry Smith - -mat_coarsen_view - view the coarsening object 73*a77d671bSBarry Smith 74*a77d671bSBarry Smith Level: advanced 75*a77d671bSBarry Smith 76*a77d671bSBarry Smith Notes: 77*a77d671bSBarry Smith When the coarsening is used inside `PCGAMG` then the options database keys are prefixed with `-pc_gamg_` 78*a77d671bSBarry Smith 79*a77d671bSBarry Smith Use `MatCoarsenGetData()` to access the results of the coarsening 80*a77d671bSBarry Smith 81*a77d671bSBarry Smith The user can define additional coarsens; see `MatCoarsenRegister()`. 82*a77d671bSBarry Smith 83*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarseSetFromOptions()`, `MatCoarsenSetType()`, `MatCoarsenRegister()`, `MatCoarsenCreate()`, 84*a77d671bSBarry Smith `MatCoarsenDestroy()`, `MatCoarsenSetAdjacency()` 85*a77d671bSBarry Smith `MatCoarsenGetData()` 86*a77d671bSBarry Smith @*/ 87*a77d671bSBarry Smith PetscErrorCode MatCoarsenApply(MatCoarsen coarser) 88*a77d671bSBarry Smith { 89*a77d671bSBarry Smith PetscFunctionBegin; 90*a77d671bSBarry Smith PetscValidHeaderSpecific(coarser, MAT_COARSEN_CLASSID, 1); 91*a77d671bSBarry Smith PetscAssertPointer(coarser, 1); 92*a77d671bSBarry Smith PetscCheck(coarser->graph->assembled, PetscObjectComm((PetscObject)coarser), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 93*a77d671bSBarry Smith PetscCheck(!coarser->graph->factortype, PetscObjectComm((PetscObject)coarser), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 94*a77d671bSBarry Smith PetscCall(PetscLogEventBegin(MAT_Coarsen, coarser, 0, 0, 0)); 95*a77d671bSBarry Smith PetscUseTypeMethod(coarser, apply); 96*a77d671bSBarry Smith PetscCall(PetscLogEventEnd(MAT_Coarsen, coarser, 0, 0, 0)); 97*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 98*a77d671bSBarry Smith } 99*a77d671bSBarry Smith 100*a77d671bSBarry Smith /*@ 101*a77d671bSBarry Smith MatCoarsenSetAdjacency - Sets the adjacency graph (matrix) of the thing to be coarsened. 102*a77d671bSBarry Smith 103*a77d671bSBarry Smith Collective 104*a77d671bSBarry Smith 105*a77d671bSBarry Smith Input Parameters: 106*a77d671bSBarry Smith + agg - the coarsen context 107*a77d671bSBarry Smith - adj - the adjacency matrix 108*a77d671bSBarry Smith 109*a77d671bSBarry Smith Level: advanced 110*a77d671bSBarry Smith 111*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenSetFromOptions()`, `Mat`, `MatCoarsenCreate()`, `MatCoarsenApply()` 112*a77d671bSBarry Smith @*/ 113*a77d671bSBarry Smith PetscErrorCode MatCoarsenSetAdjacency(MatCoarsen agg, Mat adj) 114*a77d671bSBarry Smith { 115*a77d671bSBarry Smith PetscFunctionBegin; 116*a77d671bSBarry Smith PetscValidHeaderSpecific(agg, MAT_COARSEN_CLASSID, 1); 117*a77d671bSBarry Smith PetscValidHeaderSpecific(adj, MAT_CLASSID, 2); 118*a77d671bSBarry Smith agg->graph = adj; 119*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 120*a77d671bSBarry Smith } 121*a77d671bSBarry Smith 122*a77d671bSBarry Smith /*@ 123*a77d671bSBarry Smith MatCoarsenSetStrictAggs - Set whether to keep strict (non overlapping) aggregates in the linked list of aggregates for a coarsen context 124*a77d671bSBarry Smith 125*a77d671bSBarry Smith Logically Collective 126*a77d671bSBarry Smith 127*a77d671bSBarry Smith Input Parameters: 128*a77d671bSBarry Smith + agg - the coarsen context 129*a77d671bSBarry Smith - str - `PETSC_TRUE` keep strict aggregates, `PETSC_FALSE` allow overlap 130*a77d671bSBarry Smith 131*a77d671bSBarry Smith Level: advanced 132*a77d671bSBarry Smith 133*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenCreate()`, `MatCoarsenSetFromOptions()` 134*a77d671bSBarry Smith @*/ 135*a77d671bSBarry Smith PetscErrorCode MatCoarsenSetStrictAggs(MatCoarsen agg, PetscBool str) 136*a77d671bSBarry Smith { 137*a77d671bSBarry Smith PetscFunctionBegin; 138*a77d671bSBarry Smith PetscValidHeaderSpecific(agg, MAT_COARSEN_CLASSID, 1); 139*a77d671bSBarry Smith agg->strict_aggs = str; 140*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 141*a77d671bSBarry Smith } 142*a77d671bSBarry Smith 143*a77d671bSBarry Smith /*@ 144*a77d671bSBarry Smith MatCoarsenDestroy - Destroys the coarsen context. 145*a77d671bSBarry Smith 146*a77d671bSBarry Smith Collective 147*a77d671bSBarry Smith 148*a77d671bSBarry Smith Input Parameter: 149*a77d671bSBarry Smith . agg - the coarsen context 150*a77d671bSBarry Smith 151*a77d671bSBarry Smith Level: advanced 152*a77d671bSBarry Smith 153*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenCreate()` 154*a77d671bSBarry Smith @*/ 155*a77d671bSBarry Smith PetscErrorCode MatCoarsenDestroy(MatCoarsen *agg) 156*a77d671bSBarry Smith { 157*a77d671bSBarry Smith PetscFunctionBegin; 158*a77d671bSBarry Smith if (!*agg) PetscFunctionReturn(PETSC_SUCCESS); 159*a77d671bSBarry Smith PetscValidHeaderSpecific(*agg, MAT_COARSEN_CLASSID, 1); 160*a77d671bSBarry Smith if (--((PetscObject)*agg)->refct > 0) { 161*a77d671bSBarry Smith *agg = NULL; 162*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 163*a77d671bSBarry Smith } 164*a77d671bSBarry Smith 165*a77d671bSBarry Smith PetscTryTypeMethod(*agg, destroy); 166*a77d671bSBarry Smith if ((*agg)->agg_lists) PetscCall(PetscCDDestroy((*agg)->agg_lists)); 167*a77d671bSBarry Smith PetscCall(PetscObjectComposeFunction((PetscObject)*agg, "MatCoarsenSetMaximumIterations_C", NULL)); 168*a77d671bSBarry Smith PetscCall(PetscObjectComposeFunction((PetscObject)*agg, "MatCoarsenSetThreshold_C", NULL)); 169*a77d671bSBarry Smith PetscCall(PetscObjectComposeFunction((PetscObject)*agg, "MatCoarsenSetStrengthIndex_C", NULL)); 170*a77d671bSBarry Smith 171*a77d671bSBarry Smith PetscCall(PetscHeaderDestroy(agg)); 172*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 173*a77d671bSBarry Smith } 174*a77d671bSBarry Smith 175*a77d671bSBarry Smith /*@ 176*a77d671bSBarry Smith MatCoarsenViewFromOptions - View the coarsener from the options database 177*a77d671bSBarry Smith 178*a77d671bSBarry Smith Collective 179*a77d671bSBarry Smith 180*a77d671bSBarry Smith Input Parameters: 181*a77d671bSBarry Smith + A - the coarsen context 182*a77d671bSBarry Smith . obj - Optional object that provides the prefix for the option name 183*a77d671bSBarry Smith - name - command line option (usually `-mat_coarsen_view`) 184*a77d671bSBarry Smith 185*a77d671bSBarry Smith Options Database Key: 186*a77d671bSBarry Smith . -mat_coarsen_view [viewertype]:... - the viewer and its options 187*a77d671bSBarry Smith 188*a77d671bSBarry Smith Note: 189*a77d671bSBarry Smith .vb 190*a77d671bSBarry Smith If no value is provided ascii:stdout is used 191*a77d671bSBarry Smith ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 192*a77d671bSBarry Smith for example ascii::ascii_info prints just the information about the object not all details 193*a77d671bSBarry Smith unless :append is given filename opens in write mode, overwriting what was already there 194*a77d671bSBarry Smith binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 195*a77d671bSBarry Smith draw[:drawtype[:filename]] for example, draw:tikz, draw:tikz:figure.tex or draw:x 196*a77d671bSBarry Smith socket[:port] defaults to the standard output port 197*a77d671bSBarry Smith saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 198*a77d671bSBarry Smith .ve 199*a77d671bSBarry Smith 200*a77d671bSBarry Smith Level: intermediate 201*a77d671bSBarry Smith 202*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenView`, `PetscObjectViewFromOptions()`, `MatCoarsenCreate()` 203*a77d671bSBarry Smith @*/ 204*a77d671bSBarry Smith PetscErrorCode MatCoarsenViewFromOptions(MatCoarsen A, PetscObject obj, const char name[]) 205*a77d671bSBarry Smith { 206*a77d671bSBarry Smith PetscFunctionBegin; 207*a77d671bSBarry Smith PetscValidHeaderSpecific(A, MAT_COARSEN_CLASSID, 1); 208*a77d671bSBarry Smith PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 209*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 210*a77d671bSBarry Smith } 211*a77d671bSBarry Smith 212*a77d671bSBarry Smith /*@ 213*a77d671bSBarry Smith MatCoarsenView - Prints the coarsen data structure. 214*a77d671bSBarry Smith 215*a77d671bSBarry Smith Collective 216*a77d671bSBarry Smith 217*a77d671bSBarry Smith Input Parameters: 218*a77d671bSBarry Smith + agg - the coarsen context 219*a77d671bSBarry Smith - viewer - optional visualization context 220*a77d671bSBarry Smith 221*a77d671bSBarry Smith For viewing the options database see `MatCoarsenViewFromOptions()` 222*a77d671bSBarry Smith 223*a77d671bSBarry Smith Level: advanced 224*a77d671bSBarry Smith 225*a77d671bSBarry Smith .seealso: `MatCoarsen`, `PetscViewer`, `PetscViewerASCIIOpen()`, `MatCoarsenViewFromOptions` 226*a77d671bSBarry Smith @*/ 227*a77d671bSBarry Smith PetscErrorCode MatCoarsenView(MatCoarsen agg, PetscViewer viewer) 228*a77d671bSBarry Smith { 229*a77d671bSBarry Smith PetscBool iascii; 230*a77d671bSBarry Smith 231*a77d671bSBarry Smith PetscFunctionBegin; 232*a77d671bSBarry Smith PetscValidHeaderSpecific(agg, MAT_COARSEN_CLASSID, 1); 233*a77d671bSBarry Smith if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)agg), &viewer)); 234*a77d671bSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 235*a77d671bSBarry Smith PetscCheckSameComm(agg, 1, viewer, 2); 236*a77d671bSBarry Smith 237*a77d671bSBarry Smith PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 238*a77d671bSBarry Smith PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)agg, viewer)); 239*a77d671bSBarry Smith if (agg->ops->view) { 240*a77d671bSBarry Smith PetscCall(PetscViewerASCIIPushTab(viewer)); 241*a77d671bSBarry Smith PetscUseTypeMethod(agg, view, viewer); 242*a77d671bSBarry Smith PetscCall(PetscViewerASCIIPopTab(viewer)); 243*a77d671bSBarry Smith } 244*a77d671bSBarry Smith if (agg->strength_index_size > 0) PetscCall(PetscViewerASCIIPrintf(viewer, " Using scalar strength-of-connection index index[%d] = {%d, ..}\n", (int)agg->strength_index_size, (int)agg->strength_index[0])); 245*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 246*a77d671bSBarry Smith } 247*a77d671bSBarry Smith 248*a77d671bSBarry Smith /*@ 249*a77d671bSBarry Smith MatCoarsenSetType - Sets the type of aggregator to use 250*a77d671bSBarry Smith 251*a77d671bSBarry Smith Collective 252*a77d671bSBarry Smith 253*a77d671bSBarry Smith Input Parameters: 254*a77d671bSBarry Smith + coarser - the coarsen context. 255*a77d671bSBarry Smith - type - a known coarsening method 256*a77d671bSBarry Smith 257*a77d671bSBarry Smith Options Database Key: 258*a77d671bSBarry Smith . -mat_coarsen_type <type> - maximal independent set based; distance k MIS; heavy edge matching 259*a77d671bSBarry Smith 260*a77d671bSBarry Smith Level: advanced 261*a77d671bSBarry Smith 262*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenCreate()`, `MatCoarsenApply()`, `MatCoarsenType`, `MatCoarsenGetType()` 263*a77d671bSBarry Smith @*/ 264*a77d671bSBarry Smith PetscErrorCode MatCoarsenSetType(MatCoarsen coarser, MatCoarsenType type) 265*a77d671bSBarry Smith { 266*a77d671bSBarry Smith PetscBool match; 267*a77d671bSBarry Smith PetscErrorCode (*r)(MatCoarsen); 268*a77d671bSBarry Smith 269*a77d671bSBarry Smith PetscFunctionBegin; 270*a77d671bSBarry Smith PetscValidHeaderSpecific(coarser, MAT_COARSEN_CLASSID, 1); 271*a77d671bSBarry Smith PetscAssertPointer(type, 2); 272*a77d671bSBarry Smith 273*a77d671bSBarry Smith PetscCall(PetscObjectTypeCompare((PetscObject)coarser, type, &match)); 274*a77d671bSBarry Smith if (match) PetscFunctionReturn(PETSC_SUCCESS); 275*a77d671bSBarry Smith 276*a77d671bSBarry Smith PetscTryTypeMethod(coarser, destroy); 277*a77d671bSBarry Smith coarser->ops->destroy = NULL; 278*a77d671bSBarry Smith PetscCall(PetscMemzero(coarser->ops, sizeof(struct _MatCoarsenOps))); 279*a77d671bSBarry Smith 280*a77d671bSBarry Smith PetscCall(PetscFunctionListFind(MatCoarsenList, type, &r)); 281*a77d671bSBarry Smith PetscCheck(r, PetscObjectComm((PetscObject)coarser), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown coarsen type %s", type); 282*a77d671bSBarry Smith PetscCall((*r)(coarser)); 283*a77d671bSBarry Smith 284*a77d671bSBarry Smith PetscCall(PetscFree(((PetscObject)coarser)->type_name)); 285*a77d671bSBarry Smith PetscCall(PetscStrallocpy(type, &((PetscObject)coarser)->type_name)); 286*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 287*a77d671bSBarry Smith } 288*a77d671bSBarry Smith 289*a77d671bSBarry Smith /*@ 290*a77d671bSBarry Smith MatCoarsenSetGreedyOrdering - Sets the ordering of the vertices to use with a greedy coarsening method 291*a77d671bSBarry Smith 292*a77d671bSBarry Smith Logically Collective 293*a77d671bSBarry Smith 294*a77d671bSBarry Smith Input Parameters: 295*a77d671bSBarry Smith + coarser - the coarsen context 296*a77d671bSBarry Smith - perm - vertex ordering of (greedy) algorithm 297*a77d671bSBarry Smith 298*a77d671bSBarry Smith Level: advanced 299*a77d671bSBarry Smith 300*a77d671bSBarry Smith Note: 301*a77d671bSBarry Smith The `IS` weights is freed by PETSc, the user should not destroy it or change it after this call 302*a77d671bSBarry Smith 303*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenType`, `MatCoarsenCreate()`, `MatCoarsenSetType()` 304*a77d671bSBarry Smith @*/ 305*a77d671bSBarry Smith PetscErrorCode MatCoarsenSetGreedyOrdering(MatCoarsen coarser, const IS perm) 306*a77d671bSBarry Smith { 307*a77d671bSBarry Smith PetscFunctionBegin; 308*a77d671bSBarry Smith PetscValidHeaderSpecific(coarser, MAT_COARSEN_CLASSID, 1); 309*a77d671bSBarry Smith coarser->perm = perm; 310*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 311*a77d671bSBarry Smith } 312*a77d671bSBarry Smith 313*a77d671bSBarry Smith /*@C 314*a77d671bSBarry Smith MatCoarsenGetData - Gets the weights for vertices for a coarsener. 315*a77d671bSBarry Smith 316*a77d671bSBarry Smith Logically Collective, No Fortran Support 317*a77d671bSBarry Smith 318*a77d671bSBarry Smith Input Parameter: 319*a77d671bSBarry Smith . coarser - the coarsen context 320*a77d671bSBarry Smith 321*a77d671bSBarry Smith Output Parameter: 322*a77d671bSBarry Smith . llist - linked list of aggregates 323*a77d671bSBarry Smith 324*a77d671bSBarry Smith Level: advanced 325*a77d671bSBarry Smith 326*a77d671bSBarry Smith Note: 327*a77d671bSBarry Smith This passes ownership to the caller and nullifies the value of weights (`PetscCoarsenData`) within the `MatCoarsen` 328*a77d671bSBarry Smith 329*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenApply()`, `MatCoarsenCreate()`, `MatCoarsenSetType()`, `PetscCoarsenData` 330*a77d671bSBarry Smith @*/ 331*a77d671bSBarry Smith PetscErrorCode MatCoarsenGetData(MatCoarsen coarser, PetscCoarsenData **llist) 332*a77d671bSBarry Smith { 333*a77d671bSBarry Smith PetscFunctionBegin; 334*a77d671bSBarry Smith PetscValidHeaderSpecific(coarser, MAT_COARSEN_CLASSID, 1); 335*a77d671bSBarry Smith PetscCheck(coarser->agg_lists, PetscObjectComm((PetscObject)coarser), PETSC_ERR_ARG_WRONGSTATE, "No linked list - generate it or call ApplyCoarsen"); 336*a77d671bSBarry Smith *llist = coarser->agg_lists; 337*a77d671bSBarry Smith coarser->agg_lists = NULL; /* giving up ownership */ 338*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 339*a77d671bSBarry Smith } 340*a77d671bSBarry Smith 341*a77d671bSBarry Smith /*@ 342*a77d671bSBarry Smith MatCoarsenSetFromOptions - Sets various coarsen options from the options database. 343*a77d671bSBarry Smith 344*a77d671bSBarry Smith Collective 345*a77d671bSBarry Smith 346*a77d671bSBarry Smith Input Parameter: 347*a77d671bSBarry Smith . coarser - the coarsen context. 348*a77d671bSBarry Smith 349*a77d671bSBarry Smith Options Database Key: 350*a77d671bSBarry Smith + -mat_coarsen_type <type> - mis: maximal independent set based; misk: distance k MIS; hem: heavy edge matching 351*a77d671bSBarry Smith - -mat_coarsen_max_it <its> number of iterations to use in the coarsening process - see `MatCoarsenSetMaximumIterations()` 352*a77d671bSBarry Smith 353*a77d671bSBarry Smith Level: advanced 354*a77d671bSBarry Smith 355*a77d671bSBarry Smith Notes: 356*a77d671bSBarry Smith When the coarsening is used inside `PCGAMG` then the options database keys are prefixed with `-pc_gamg_` 357*a77d671bSBarry Smith 358*a77d671bSBarry Smith Sets the `MatCoarsenType` to `MATCOARSENMISK` if has not been set previously 359*a77d671bSBarry Smith 360*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenType`, `MatCoarsenApply()`, `MatCoarsenCreate()`, `MatCoarsenSetType()`, 361*a77d671bSBarry Smith `MatCoarsenSetMaximumIterations()` 362*a77d671bSBarry Smith @*/ 363*a77d671bSBarry Smith PetscErrorCode MatCoarsenSetFromOptions(MatCoarsen coarser) 364*a77d671bSBarry Smith { 365*a77d671bSBarry Smith PetscBool flag; 366*a77d671bSBarry Smith char type[256]; 367*a77d671bSBarry Smith const char *def; 368*a77d671bSBarry Smith 369*a77d671bSBarry Smith PetscFunctionBegin; 370*a77d671bSBarry Smith PetscObjectOptionsBegin((PetscObject)coarser); 371*a77d671bSBarry Smith if (!((PetscObject)coarser)->type_name) { 372*a77d671bSBarry Smith def = MATCOARSENMISK; 373*a77d671bSBarry Smith } else { 374*a77d671bSBarry Smith def = ((PetscObject)coarser)->type_name; 375*a77d671bSBarry Smith } 376*a77d671bSBarry Smith PetscCall(PetscOptionsFList("-mat_coarsen_type", "Type of aggregator", "MatCoarsenSetType", MatCoarsenList, def, type, 256, &flag)); 377*a77d671bSBarry Smith if (flag) PetscCall(MatCoarsenSetType(coarser, type)); 378*a77d671bSBarry Smith 379*a77d671bSBarry Smith PetscCall(PetscOptionsInt("-mat_coarsen_max_it", "Number of iterations (for HEM)", "MatCoarsenSetMaximumIterations", coarser->max_it, &coarser->max_it, NULL)); 380*a77d671bSBarry Smith PetscCall(PetscOptionsInt("-mat_coarsen_threshold", "Threshold (for HEM)", "MatCoarsenSetThreshold", coarser->max_it, &coarser->max_it, NULL)); 381*a77d671bSBarry Smith coarser->strength_index_size = MAT_COARSEN_STRENGTH_INDEX_SIZE; 382*a77d671bSBarry Smith PetscCall(PetscOptionsIntArray("-mat_coarsen_strength_index", "Array of indices to use strength of connection measure (default is all indices)", "MatCoarsenSetStrengthIndex", coarser->strength_index, &coarser->strength_index_size, NULL)); 383*a77d671bSBarry Smith /* 384*a77d671bSBarry Smith Set the type if it was never set. 385*a77d671bSBarry Smith */ 386*a77d671bSBarry Smith if (!((PetscObject)coarser)->type_name) PetscCall(MatCoarsenSetType(coarser, def)); 387*a77d671bSBarry Smith 388*a77d671bSBarry Smith PetscTryTypeMethod(coarser, setfromoptions, PetscOptionsObject); 389*a77d671bSBarry Smith PetscOptionsEnd(); 390*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 391*a77d671bSBarry Smith } 392*a77d671bSBarry Smith 393*a77d671bSBarry Smith /*@ 394*a77d671bSBarry Smith MatCoarsenSetMaximumIterations - Maximum `MATCOARSENHEM` iterations to use 395*a77d671bSBarry Smith 396*a77d671bSBarry Smith Logically Collective 397*a77d671bSBarry Smith 398*a77d671bSBarry Smith Input Parameters: 399*a77d671bSBarry Smith + coarse - the coarsen context 400*a77d671bSBarry Smith - n - number of HEM iterations 401*a77d671bSBarry Smith 402*a77d671bSBarry Smith Options Database Key: 403*a77d671bSBarry Smith . -mat_coarsen_max_it <default=4> - Maximum `MATCOARSENHEM` iterations to use 404*a77d671bSBarry Smith 405*a77d671bSBarry Smith Level: intermediate 406*a77d671bSBarry Smith 407*a77d671bSBarry Smith Note: 408*a77d671bSBarry Smith When the coarsening is used inside `PCGAMG` then the options database keys are prefixed with `-pc_gamg_` 409*a77d671bSBarry Smith 410*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenType`, `MatCoarsenApply()`, `MatCoarsenCreate()`, `MatCoarsenSetType()` 411*a77d671bSBarry Smith @*/ 412*a77d671bSBarry Smith PetscErrorCode MatCoarsenSetMaximumIterations(MatCoarsen coarse, PetscInt n) 413*a77d671bSBarry Smith { 414*a77d671bSBarry Smith PetscFunctionBegin; 415*a77d671bSBarry Smith PetscValidHeaderSpecific(coarse, MAT_COARSEN_CLASSID, 1); 416*a77d671bSBarry Smith PetscValidLogicalCollectiveInt(coarse, n, 2); 417*a77d671bSBarry Smith PetscTryMethod(coarse, "MatCoarsenSetMaximumIterations_C", (MatCoarsen, PetscInt), (coarse, n)); 418*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 419*a77d671bSBarry Smith } 420*a77d671bSBarry Smith 421*a77d671bSBarry Smith static PetscErrorCode MatCoarsenSetMaximumIterations_MATCOARSEN(MatCoarsen coarse, PetscInt b) 422*a77d671bSBarry Smith { 423*a77d671bSBarry Smith PetscFunctionBegin; 424*a77d671bSBarry Smith coarse->max_it = b; 425*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 426*a77d671bSBarry Smith } 427*a77d671bSBarry Smith 428*a77d671bSBarry Smith /*@ 429*a77d671bSBarry Smith MatCoarsenSetStrengthIndex - Index array to use for index to use for strength of connection 430*a77d671bSBarry Smith 431*a77d671bSBarry Smith Logically Collective 432*a77d671bSBarry Smith 433*a77d671bSBarry Smith Input Parameters: 434*a77d671bSBarry Smith + coarse - the coarsen context 435*a77d671bSBarry Smith . n - number of indices 436*a77d671bSBarry Smith - idx - array of indices 437*a77d671bSBarry Smith 438*a77d671bSBarry Smith Options Database Key: 439*a77d671bSBarry Smith . -mat_coarsen_strength_index - array of subset of variables per vertex to use for strength norm, -1 for using all (default) 440*a77d671bSBarry Smith 441*a77d671bSBarry Smith Level: intermediate 442*a77d671bSBarry Smith 443*a77d671bSBarry Smith Note: 444*a77d671bSBarry Smith When the coarsening is used inside `PCGAMG` then the options database keys are prefixed with `-pc_gamg_` 445*a77d671bSBarry Smith 446*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenType`, `MatCoarsenApply()`, `MatCoarsenCreate()`, `MatCoarsenSetType()` 447*a77d671bSBarry Smith @*/ 448*a77d671bSBarry Smith PetscErrorCode MatCoarsenSetStrengthIndex(MatCoarsen coarse, PetscInt n, PetscInt idx[]) 449*a77d671bSBarry Smith { 450*a77d671bSBarry Smith PetscFunctionBegin; 451*a77d671bSBarry Smith PetscValidHeaderSpecific(coarse, MAT_COARSEN_CLASSID, 1); 452*a77d671bSBarry Smith PetscValidLogicalCollectiveInt(coarse, n, 2); 453*a77d671bSBarry Smith PetscTryMethod(coarse, "MatCoarsenSetStrengthIndex_C", (MatCoarsen, PetscInt, PetscInt[]), (coarse, n, idx)); 454*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 455*a77d671bSBarry Smith } 456*a77d671bSBarry Smith 457*a77d671bSBarry Smith static PetscErrorCode MatCoarsenSetStrengthIndex_MATCOARSEN(MatCoarsen coarse, PetscInt n, PetscInt idx[]) 458*a77d671bSBarry Smith { 459*a77d671bSBarry Smith PetscFunctionBegin; 460*a77d671bSBarry Smith coarse->strength_index_size = n; 461*a77d671bSBarry Smith for (int iii = 0; iii < n; iii++) coarse->strength_index[iii] = idx[iii]; 462*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 463*a77d671bSBarry Smith } 464*a77d671bSBarry Smith 465*a77d671bSBarry Smith /*@ 466*a77d671bSBarry Smith MatCoarsenSetThreshold - Set the threshold for HEM 467*a77d671bSBarry Smith 468*a77d671bSBarry Smith Logically Collective 469*a77d671bSBarry Smith 470*a77d671bSBarry Smith Input Parameters: 471*a77d671bSBarry Smith + coarse - the coarsen context 472*a77d671bSBarry Smith - b - threshold value 473*a77d671bSBarry Smith 474*a77d671bSBarry Smith Options Database Key: 475*a77d671bSBarry Smith . -mat_coarsen_threshold <-1> - threshold 476*a77d671bSBarry Smith 477*a77d671bSBarry Smith Level: intermediate 478*a77d671bSBarry Smith 479*a77d671bSBarry Smith Note: 480*a77d671bSBarry Smith When the coarsening is used inside `PCGAMG` then the options database keys are prefixed with `-pc_gamg_` 481*a77d671bSBarry Smith 482*a77d671bSBarry Smith Developer Note: 483*a77d671bSBarry Smith It is not documented how this threshold is used 484*a77d671bSBarry Smith 485*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenType`, `MatCoarsenApply()`, `MatCoarsenCreate()`, `MatCoarsenSetType()` 486*a77d671bSBarry Smith @*/ 487*a77d671bSBarry Smith PetscErrorCode MatCoarsenSetThreshold(MatCoarsen coarse, PetscReal b) 488*a77d671bSBarry Smith { 489*a77d671bSBarry Smith PetscFunctionBegin; 490*a77d671bSBarry Smith PetscValidHeaderSpecific(coarse, MAT_COARSEN_CLASSID, 1); 491*a77d671bSBarry Smith PetscValidLogicalCollectiveReal(coarse, b, 2); 492*a77d671bSBarry Smith PetscTryMethod(coarse, "MatCoarsenSetThreshold_C", (MatCoarsen, PetscReal), (coarse, b)); 493*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 494*a77d671bSBarry Smith } 495*a77d671bSBarry Smith 496*a77d671bSBarry Smith static PetscErrorCode MatCoarsenSetThreshold_MATCOARSEN(MatCoarsen coarse, PetscReal b) 497*a77d671bSBarry Smith { 498*a77d671bSBarry Smith PetscFunctionBegin; 499*a77d671bSBarry Smith coarse->threshold = b; 500*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 501*a77d671bSBarry Smith } 502*a77d671bSBarry Smith 503*a77d671bSBarry Smith /*@ 504*a77d671bSBarry Smith MatCoarsenCreate - Creates a coarsen context. 505*a77d671bSBarry Smith 506*a77d671bSBarry Smith Collective 507*a77d671bSBarry Smith 508*a77d671bSBarry Smith Input Parameter: 509*a77d671bSBarry Smith . comm - MPI communicator 510*a77d671bSBarry Smith 511*a77d671bSBarry Smith Output Parameter: 512*a77d671bSBarry Smith . newcrs - location to put the context 513*a77d671bSBarry Smith 514*a77d671bSBarry Smith Level: advanced 515*a77d671bSBarry Smith 516*a77d671bSBarry Smith .seealso: `MatCoarsen`, `MatCoarsenSetType()`, `MatCoarsenApply()`, `MatCoarsenDestroy()`, 517*a77d671bSBarry Smith `MatCoarsenSetAdjacency()`, `MatCoarsenGetData()` 518*a77d671bSBarry Smith @*/ 519*a77d671bSBarry Smith PetscErrorCode MatCoarsenCreate(MPI_Comm comm, MatCoarsen *newcrs) 520*a77d671bSBarry Smith { 521*a77d671bSBarry Smith MatCoarsen agg; 522*a77d671bSBarry Smith 523*a77d671bSBarry Smith PetscFunctionBegin; 524*a77d671bSBarry Smith *newcrs = NULL; 525*a77d671bSBarry Smith 526*a77d671bSBarry Smith PetscCall(MatInitializePackage()); 527*a77d671bSBarry Smith PetscCall(PetscHeaderCreate(agg, MAT_COARSEN_CLASSID, "MatCoarsen", "Matrix/graph coarsen", "MatCoarsen", comm, MatCoarsenDestroy, MatCoarsenView)); 528*a77d671bSBarry Smith PetscCall(PetscObjectComposeFunction((PetscObject)agg, "MatCoarsenSetMaximumIterations_C", MatCoarsenSetMaximumIterations_MATCOARSEN)); 529*a77d671bSBarry Smith PetscCall(PetscObjectComposeFunction((PetscObject)agg, "MatCoarsenSetThreshold_C", MatCoarsenSetThreshold_MATCOARSEN)); 530*a77d671bSBarry Smith PetscCall(PetscObjectComposeFunction((PetscObject)agg, "MatCoarsenSetStrengthIndex_C", MatCoarsenSetStrengthIndex_MATCOARSEN)); 531*a77d671bSBarry Smith 532*a77d671bSBarry Smith agg->strength_index_size = 0; 533*a77d671bSBarry Smith 534*a77d671bSBarry Smith *newcrs = agg; 535*a77d671bSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 536*a77d671bSBarry Smith } 537