xref: /petsc/src/mat/graphops/coarsen/interface/coarsen.c (revision a77d671b1191ed14ce34133f22d77229bbb91e89)
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