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