Actual source code: coarsen.c
petsc-3.12.5 2020-03-29
2: #include <petsc/private/matimpl.h>
4: /* Logging support */
5: PetscClassId MAT_COARSEN_CLASSID;
7: PetscFunctionList MatCoarsenList = 0;
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(), ISCoarsenToNumbering(),
94: ISCoarsenCount(), 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 = 0; 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 = 0;
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: MatCoarsenView - Prints the coarsen data structure.
222: Collective on MatCoarsen
224: Input Parameters:
225: + agg - the coarsen context
226: - viewer - optional visualization context
228: Level: advanced
230: Note:
231: The available visualization contexts include
232: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
233: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
234: output where only the first processor opens
235: the file. All other processors send their
236: data to the first processor to print.
238: The user can open alternative visualization contexts with
239: . PetscViewerASCIIOpen() - output to a specified file
241: .seealso: PetscViewerASCIIOpen()
242: @*/
243: PetscErrorCode MatCoarsenView(MatCoarsen agg,PetscViewer viewer)
244: {
246: PetscBool iascii;
250: if (!viewer) {
251: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)agg),&viewer);
252: }
256: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
257: PetscObjectPrintClassNamePrefixType((PetscObject)agg,viewer);
258: if (agg->ops->view) {
259: PetscViewerASCIIPushTab(viewer);
260: (*agg->ops->view)(agg,viewer);
261: PetscViewerASCIIPopTab(viewer);
262: }
263: return(0);
264: }
266: /*@C
267: MatCoarsenSetType - Sets the type of aggregator to use
269: Collective on MatCoarsen
271: Input Parameter:
272: + coarser - the coarsen context.
273: - type - a known coarsening method
275: Options Database Command:
276: $ -mat_coarsen_type <type>
277: $ Use -help for a list of available methods
278: $ (for instance, mis)
280: Level: advanced
282: .seealso: MatCoarsenCreate(), MatCoarsenApply(), MatCoarsenType, MatCoarsenGetType()
284: @*/
285: PetscErrorCode MatCoarsenSetType(MatCoarsen coarser, MatCoarsenType type)
286: {
287: PetscErrorCode ierr,(*r)(MatCoarsen);
288: PetscBool match;
294: PetscObjectTypeCompare((PetscObject)coarser,type,&match);
295: if (match) return(0);
297: if (coarser->setupcalled) {
298: (*coarser->ops->destroy)(coarser);
300: coarser->ops->destroy = NULL;
301: coarser->subctx = 0;
302: coarser->setupcalled = 0;
303: }
305: PetscFunctionListFind(MatCoarsenList,type,&r);
307: if (!r) SETERRQ1(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown coarsen type %s",type);
309: coarser->ops->destroy = (PetscErrorCode (*)(MatCoarsen)) 0;
310: coarser->ops->view = (PetscErrorCode (*)(MatCoarsen,PetscViewer)) 0;
312: (*r)(coarser);
314: PetscFree(((PetscObject)coarser)->type_name);
315: PetscStrallocpy(type,&((PetscObject)coarser)->type_name);
316: return(0);
317: }
319: /*@C
320: MatCoarsenSetGreedyOrdering - Sets the ordering of the vertices to use with a greedy coarsening method
322: Logically Collective on Coarsen
324: Input Parameters:
325: + coarser - the coarsen context
326: - perm - vertex ordering of (greedy) algorithm
328: Level: advanced
330: Notes:
331: The IS weights is freed by PETSc, so user has given this to us
333: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
334: @*/
335: PetscErrorCode MatCoarsenSetGreedyOrdering(MatCoarsen coarser, const IS perm)
336: {
339: coarser->perm = perm;
340: return(0);
341: }
343: /*@C
344: MatCoarsenGetData - Gets the weights for vertices for a coarsen.
346: Logically Collective on Coarsen
348: Input Parameter:
349: . coarser - the coarsen context
351: Output Parameter:
352: . llist - linked list of aggregates
354: Level: advanced
356: .seealso: MatCoarsenCreate(), MatCoarsenSetType()
357: @*/
358: PetscErrorCode MatCoarsenGetData(MatCoarsen coarser, PetscCoarsenData **llist)
359: {
362: if (!coarser->agg_lists) SETERRQ(PetscObjectComm((PetscObject)coarser),PETSC_ERR_ARG_WRONGSTATE,"No linked list - generate it or call ApplyCoarsen");
363: *llist = coarser->agg_lists;
364: coarser->agg_lists = 0; /* giving up ownership */
365: return(0);
366: }
368: /*@
369: MatCoarsenSetFromOptions - Sets various coarsen options from the
370: options database.
372: Collective on MatCoarsen
374: Input Parameter:
375: . coarser - the coarsen context.
377: Options Database Command:
378: $ -mat_coarsen_type <type>
379: $ Use -help for a list of available methods
380: $ (for instance, mis)
382: Level: advanced
384: @*/
385: PetscErrorCode MatCoarsenSetFromOptions(MatCoarsen coarser)
386: {
388: PetscBool flag;
389: char type[256];
390: const char *def;
393: PetscObjectOptionsBegin((PetscObject)coarser);
394: if (!((PetscObject)coarser)->type_name) {
395: def = MATCOARSENMIS;
396: } else {
397: def = ((PetscObject)coarser)->type_name;
398: }
400: PetscOptionsFList("-mat_coarsen_type","Type of aggregator","MatCoarsenSetType",MatCoarsenList,def,type,256,&flag);
401: if (flag) {
402: MatCoarsenSetType(coarser,type);
403: }
404: /*
405: Set the type if it was never set.
406: */
407: if (!((PetscObject)coarser)->type_name) {
408: MatCoarsenSetType(coarser,def);
409: }
411: if (coarser->ops->setfromoptions) {
412: (*coarser->ops->setfromoptions)(PetscOptionsObject,coarser);
413: }
414: PetscOptionsEnd();
415: MatCoarsenViewFromOptions(coarser,NULL,"-mat_coarsen_view");
416: return(0);
417: }