Actual source code: destroy.c
2: /*
3: Provides utility routines for manulating any type of PETSc object.
4: */
5: #include <petsc/private/petscimpl.h>
6: #include <petscviewer.h>
8: PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj)
9: {
10: PetscInt i;
12: PetscFunctionBegin;
13: if (obj->intstar_idmax > 0) {
14: for (i = 0; i < obj->intstar_idmax; i++) PetscCall(PetscFree(obj->intstarcomposeddata[i]));
15: PetscCall(PetscFree2(obj->intstarcomposeddata, obj->intstarcomposedstate));
16: }
17: if (obj->realstar_idmax > 0) {
18: for (i = 0; i < obj->realstar_idmax; i++) PetscCall(PetscFree(obj->realstarcomposeddata[i]));
19: PetscCall(PetscFree2(obj->realstarcomposeddata, obj->realstarcomposedstate));
20: }
21: if (obj->scalarstar_idmax > 0) {
22: for (i = 0; i < obj->scalarstar_idmax; i++) PetscCall(PetscFree(obj->scalarstarcomposeddata[i]));
23: PetscCall(PetscFree2(obj->scalarstarcomposeddata, obj->scalarstarcomposedstate));
24: }
25: PetscCall(PetscFree2(obj->intcomposeddata, obj->intcomposedstate));
26: PetscCall(PetscFree2(obj->realcomposeddata, obj->realcomposedstate));
27: PetscCall(PetscFree2(obj->scalarcomposeddata, obj->scalarcomposedstate));
28: PetscFunctionReturn(PETSC_SUCCESS);
29: }
31: /*@
32: PetscObjectDestroy - Destroys any `PetscObject`, regardless of the type.
34: Collective
36: Input Parameter:
37: . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
38: This must be cast with a (`PetscObject`*), for example,
39: `PetscObjectDestroy`((`PetscObject`*)&mat);
41: Level: beginner
43: .seealso: `PetscObject`
44: @*/
45: PetscErrorCode PetscObjectDestroy(PetscObject *obj)
46: {
47: PetscFunctionBegin;
48: if (!obj || !*obj) PetscFunctionReturn(PETSC_SUCCESS);
50: PetscCheck((*obj)->bops->destroy, PETSC_COMM_SELF, PETSC_ERR_PLIB, "This PETSc object of class %s does not have a generic destroy routine", (*obj)->class_name);
51: PetscCall((*(*obj)->bops->destroy)(obj));
52: PetscFunctionReturn(PETSC_SUCCESS);
53: }
55: /*@C
56: PetscObjectView - Views any `PetscObject`, regardless of the type.
58: Collective
60: Input Parameters:
61: + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
62: This must be cast with a (`PetscObject`), for example,
63: `PetscObjectView`((`PetscObject`)mat,viewer);
64: - viewer - any PETSc viewer
66: Level: intermediate
68: .seealso: `PetscObject`, `PetscObjectViewFromOptions()`
69: @*/
70: PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer)
71: {
72: PetscFunctionBegin;
74: PetscCheck(obj->bops->view, PETSC_COMM_SELF, PETSC_ERR_SUP, "This PETSc object does not have a generic viewer routine");
75: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(obj->comm, &viewer));
78: PetscCall((*obj->bops->view)(obj, viewer));
79: PetscFunctionReturn(PETSC_SUCCESS);
80: }
82: /*@C
83: PetscObjectViewFromOptions - Processes command line options to determine if/how a `PetscObject` is to be viewed.
85: Collective
87: Input Parameters:
88: + obj - the object
89: . bobj - optional other object that provides prefix (if `NULL` then the prefix in `obj` is used)
90: - optionname - option string that is used to activate viewing
92: Options Database Key:
93: . -optionname_view [viewertype]:... - option name and values. In actual usage this would be something like `-mat_coarse_view`
95: Level: developer
97: Notes:
98: .vb
99: If no value is provided ascii:stdout is used
100: ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
101: for example ascii::ascii_info prints just the information about the object not all details
102: unless :append is given filename opens in write mode, overwriting what was already there
103: binary[:[filename][:[format][:append]]] defaults to the file binaryoutput
104: draw[:drawtype[:filename]] for example, draw:tikz, draw:tikz:figure.tex or draw:x
105: socket[:port] defaults to the standard output port
106: saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs)
107: .ve
109: This is not called directly but is called by, for example, `MatViewFromOptions()`
111: .seealso: `PetscObject`, `PetscObjectView()`, `PetscOptionsGetViewer()`
112: @*/
113: PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[])
114: {
115: PetscViewer viewer;
116: PetscBool flg;
117: static PetscBool incall = PETSC_FALSE;
118: PetscViewerFormat format;
119: const char *prefix;
121: PetscFunctionBegin;
122: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
123: incall = PETSC_TRUE;
124: prefix = bobj ? bobj->prefix : obj->prefix;
125: PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg));
126: if (flg) {
127: PetscCall(PetscViewerPushFormat(viewer, format));
128: PetscCall(PetscObjectView(obj, viewer));
129: PetscCall(PetscViewerFlush(viewer));
130: PetscCall(PetscViewerPopFormat(viewer));
131: PetscCall(PetscViewerDestroy(&viewer));
132: }
133: incall = PETSC_FALSE;
134: PetscFunctionReturn(PETSC_SUCCESS);
135: }
137: /*@C
138: PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type.
140: Not Collective
142: Input Parameters:
143: + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
144: This must be cast with a (`PetscObject`), for example,
145: `PetscObjectTypeCompare`((`PetscObject`)mat);
146: - type_name - string containing a type name
148: Output Parameter:
149: . same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE`
151: Level: intermediate
153: .seealso: `PetscObject`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`, `PetscObjectObjectTypeCompare()`
154: @*/
155: PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same)
156: {
157: PetscFunctionBegin;
159: if (!obj) *same = PETSC_FALSE;
160: else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
161: else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
162: else {
165: PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same));
166: }
167: PetscFunctionReturn(PETSC_SUCCESS);
168: }
170: /*@C
171: PetscObjectObjectTypeCompare - Determines whether two PETSc objects are of the same type
173: Logically Collective
175: Input Parameters:
176: + obj1 - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
177: - obj2 - another PETSc object
179: Output Parameter:
180: . same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE`
182: Level: intermediate
184: .seealso: `PetscObjectTypeCompare()`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
186: @*/
187: PetscErrorCode PetscObjectObjectTypeCompare(PetscObject obj1, PetscObject obj2, PetscBool *same)
188: {
189: PetscFunctionBegin;
193: PetscCall(PetscStrcmp((char *)(obj1->type_name), (char *)(obj2->type_name), same));
194: PetscFunctionReturn(PETSC_SUCCESS);
195: }
197: /*@C
198: PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ`
200: Not Collective
202: Input Parameters:
203: + mat - the matrix
204: - type_name - string containing a type name
206: Output Parameter:
207: . same - `PETSC_TRUE` if it is of the same base type
209: Level: intermediate
211: .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
212: @*/
213: PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same)
214: {
215: PetscFunctionBegin;
217: if (!obj) *same = PETSC_FALSE;
218: else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
219: else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
220: else {
223: PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same));
224: }
225: PetscFunctionReturn(PETSC_SUCCESS);
226: }
228: /*@C
229: PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.
231: Not Collective
233: Input Parameters:
234: + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
235: This must be cast with a (`PetscObject`), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...);
236: - type_name - array of strings containing type names, pass the empty string "" to terminate the list
238: Output Parameter:
239: . match - `PETSC_TRUE` if the type of `obj` matches any in the list, else `PETSC_FALSE`
241: Level: intermediate
243: .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`
244: @*/
245: PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...)
246: {
247: va_list Argp;
249: PetscFunctionBegin;
251: *match = PETSC_FALSE;
252: if (!obj) PetscFunctionReturn(PETSC_SUCCESS);
253: va_start(Argp, type_name);
254: while (type_name && type_name[0]) {
255: PetscBool found;
256: PetscCall(PetscObjectTypeCompare(obj, type_name, &found));
257: if (found) {
258: *match = PETSC_TRUE;
259: break;
260: }
261: type_name = va_arg(Argp, const char *);
262: }
263: va_end(Argp);
264: PetscFunctionReturn(PETSC_SUCCESS);
265: }
267: /*@C
268: PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types.
270: Not Collective
272: Input Parameters:
273: + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
274: This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...);
275: - type_name - array of strings containing type names, pass the empty string "" to terminate the list
277: Output Parameter:
278: . match - `PETSC_TRUE` if the type of `obj` matches any in the list, else `PETSC_FALSE`
280: Level: intermediate
282: .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`
283: @*/
284: PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...)
285: {
286: va_list Argp;
288: PetscFunctionBegin;
290: *match = PETSC_FALSE;
291: va_start(Argp, type_name);
292: while (type_name && type_name[0]) {
293: PetscBool found;
294: PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found));
295: if (found) {
296: *match = PETSC_TRUE;
297: break;
298: }
299: type_name = va_arg(Argp, const char *);
300: }
301: va_end(Argp);
302: PetscFunctionReturn(PETSC_SUCCESS);
303: }
305: #define MAXREGDESOBJS 256
306: static int PetscObjectRegisterDestroy_Count = 0;
307: static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
309: /*@C
310: PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
311: `PetscFinalize()` is called.
313: Logically Collective
315: Input Parameter:
316: . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
317: This must be cast with a (`PetscObject`), for example,
318: `PetscObjectRegisterDestroy`((`PetscObject`)mat);
320: Level: developer
322: Note:
323: This is used by, for example, `PETSC_VIEWER_XXX_()` routines to free the viewer
324: when PETSc ends.
326: .seealso: `PetscObjectRegisterDestroyAll()`
327: @*/
328: PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj)
329: {
330: PetscFunctionBegin;
332: PetscCheck(PetscObjectRegisterDestroy_Count < (int)PETSC_STATIC_ARRAY_LENGTH(PetscObjectRegisterDestroy_Objects), PETSC_COMM_SELF, PETSC_ERR_PLIB, "No more room in array, limit %zu \n recompile %s with larger value for " PetscStringize_(MAXREGDESOBJS), PETSC_STATIC_ARRAY_LENGTH(PetscObjectRegisterDestroy_Objects), __FILE__);
333: PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
334: PetscFunctionReturn(PETSC_SUCCESS);
335: }
337: /*@C
338: PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
339: with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()`
341: Logically Collective on the individual `PetscObject`s that are being processed
343: Level: developer
345: .seealso: `PetscObjectRegisterDestroy()`
346: @*/
347: PetscErrorCode PetscObjectRegisterDestroyAll(void)
348: {
349: PetscFunctionBegin;
350: for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i]));
351: PetscObjectRegisterDestroy_Count = 0;
352: PetscFunctionReturn(PETSC_SUCCESS);
353: }
355: #define MAXREGFIN 256
356: static int PetscRegisterFinalize_Count = 0;
357: static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);
359: /*@C
360: PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()`
362: Not Collective
364: Input Parameter:
365: . PetscErrorCode (*fun)(void) - function to be called
367: Level: developer
369: Notes:
370: This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called
372: Use `PetscObjectRegisterDestroy()` to register the destruction of an object in `PetscFinalize()`
374: .seealso: `PetscRegisterFinalizeAll()`, `PetscObjectRegisterDestroy()`
375: @*/
376: PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void))
377: {
378: PetscFunctionBegin;
379: for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
380: if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(PETSC_SUCCESS);
381: }
382: PetscCheck(PetscRegisterFinalize_Count < (int)PETSC_STATIC_ARRAY_LENGTH(PetscRegisterFinalize_Functions), PETSC_COMM_SELF, PETSC_ERR_PLIB, "No more room in array, limit %zu \n recompile %s with larger value for " PetscStringize_(MAXREGFIN), PETSC_STATIC_ARRAY_LENGTH(PetscRegisterFinalize_Functions), __FILE__);
383: PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
384: PetscFunctionReturn(PETSC_SUCCESS);
385: }
387: /*@C
388: PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()`
390: Not Collective unless registered functions are collective
392: Level: developer
394: .seealso: `PetscRegisterFinalize()`, `PetscObjectRegisterDestroyAll()`
395: @*/
396: PetscErrorCode PetscRegisterFinalizeAll(void)
397: {
398: PetscFunctionBegin;
399: for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
400: PetscRegisterFinalize_Count = 0;
401: PetscFunctionReturn(PETSC_SUCCESS);
402: }