xref: /petsc/src/sys/objects/destroy.c (revision 811af0c4b09a35de4306c442f88bd09fdc09897d)
1 
2 /*
3      Provides utility routines for manulating any type of PETSc object.
4 */
5 #include <petsc/private/petscimpl.h> /*I   "petscsys.h"    I*/
6 #include <petscviewer.h>
7 
8 PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj) {
9   PetscInt i;
10 
11   PetscFunctionBegin;
12   if (obj->intstar_idmax > 0) {
13     for (i = 0; i < obj->intstar_idmax; i++) PetscCall(PetscFree(obj->intstarcomposeddata[i]));
14     PetscCall(PetscFree2(obj->intstarcomposeddata, obj->intstarcomposedstate));
15   }
16   if (obj->realstar_idmax > 0) {
17     for (i = 0; i < obj->realstar_idmax; i++) PetscCall(PetscFree(obj->realstarcomposeddata[i]));
18     PetscCall(PetscFree2(obj->realstarcomposeddata, obj->realstarcomposedstate));
19   }
20   if (obj->scalarstar_idmax > 0) {
21     for (i = 0; i < obj->scalarstar_idmax; i++) PetscCall(PetscFree(obj->scalarstarcomposeddata[i]));
22     PetscCall(PetscFree2(obj->scalarstarcomposeddata, obj->scalarstarcomposedstate));
23   }
24   PetscCall(PetscFree2(obj->intcomposeddata, obj->intcomposedstate));
25   PetscCall(PetscFree2(obj->realcomposeddata, obj->realcomposedstate));
26   PetscCall(PetscFree2(obj->scalarcomposeddata, obj->scalarcomposedstate));
27   PetscFunctionReturn(0);
28 }
29 
30 /*@
31    PetscObjectDestroy - Destroys any `PetscObject`, regardless of the type.
32 
33    Collective on obj
34 
35    Input Parameter:
36 .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
37          This must be cast with a (`PetscObject`*), for example,
38          `PetscObjectDestroy`((`PetscObject`*)&mat);
39 
40    Level: beginner
41 
42 .seealso: `PetscObject`
43 @*/
44 PetscErrorCode PetscObjectDestroy(PetscObject *obj) {
45   PetscFunctionBegin;
46   if (!obj || !*obj) PetscFunctionReturn(0);
47   PetscValidHeader(*obj, 1);
48   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);
49   PetscCall((*(*obj)->bops->destroy)(obj));
50   PetscFunctionReturn(0);
51 }
52 
53 /*@C
54    PetscObjectView - Views any `PetscObject`, regardless of the type.
55 
56    Collective on obj
57 
58    Input Parameters:
59 +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
60          This must be cast with a (`PetscObject`), for example,
61          `PetscObjectView`((`PetscObject`)mat,viewer);
62 -  viewer - any PETSc viewer
63 
64    Level: intermediate
65 
66 .seealso: `PetscObject`, `PetscObjectViewFromOptions()`
67 @*/
68 PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer) {
69   PetscFunctionBegin;
70   PetscValidHeader(obj, 1);
71   PetscCheck(obj->bops->view, PETSC_COMM_SELF, PETSC_ERR_SUP, "This PETSc object does not have a generic viewer routine");
72   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(obj->comm, &viewer));
73   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
74 
75   PetscCall((*obj->bops->view)(obj, viewer));
76   PetscFunctionReturn(0);
77 }
78 
79 /*@C
80   PetscObjectViewFromOptions - Processes command line options to determine if/how a `PetscObject` is to be viewed.
81 
82   Collective on obj
83 
84   Input Parameters:
85 + obj   - the object
86 . bobj  - optional other object that provides prefix (if NULL then the prefix in obj is used)
87 - optionname - option string that is used to activate viewing
88 
89   Level: intermediate
90 
91 .seealso: `PetscObject`, `PetscObjectView()`
92 @*/
93 PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[]) {
94   PetscViewer       viewer;
95   PetscBool         flg;
96   static PetscBool  incall = PETSC_FALSE;
97   PetscViewerFormat format;
98   const char       *prefix;
99 
100   PetscFunctionBegin;
101   if (incall) PetscFunctionReturn(0);
102   incall = PETSC_TRUE;
103   prefix = bobj ? bobj->prefix : obj->prefix;
104   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg));
105   if (flg) {
106     PetscCall(PetscViewerPushFormat(viewer, format));
107     PetscCall(PetscObjectView(obj, viewer));
108     PetscCall(PetscViewerFlush(viewer));
109     PetscCall(PetscViewerPopFormat(viewer));
110     PetscCall(PetscViewerDestroy(&viewer));
111   }
112   incall = PETSC_FALSE;
113   PetscFunctionReturn(0);
114 }
115 
116 /*@C
117    PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type.
118 
119    Not Collective
120 
121    Input Parameters:
122 +  obj - any PETSc object, for example a `Vec`, `Mat or `KSP`.
123          This must be cast with a (`PetscObject`), for example,
124          `PetscObjectTypeCompare`((`PetscObject`)mat);
125 -  type_name - string containing a type name
126 
127    Output Parameter:
128 .  same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE`
129 
130    Level: intermediate
131 
132 .seealso: `PetscObject`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
133 @*/
134 PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) {
135   PetscFunctionBegin;
136   PetscValidBoolPointer(same, 3);
137   if (!obj) *same = PETSC_FALSE;
138   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
139   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
140   else {
141     PetscValidHeader(obj, 1);
142     PetscValidCharPointer(type_name, 2);
143     PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same));
144   }
145   PetscFunctionReturn(0);
146 }
147 
148 /*@C
149    PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ`
150 
151    Not Collective
152 
153    Input Parameters:
154 +  mat - the matrix
155 -  type_name - string containing a type name
156 
157    Output Parameter:
158 .  same - `PETSC_TRUE` if it is of the same base type
159 
160    Level: intermediate
161 
162 .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
163 @*/
164 PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) {
165   PetscFunctionBegin;
166   PetscValidBoolPointer(same, 3);
167   if (!obj) *same = PETSC_FALSE;
168   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
169   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
170   else {
171     PetscValidHeader(obj, 1);
172     PetscValidCharPointer(type_name, 2);
173     PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same));
174   }
175   PetscFunctionReturn(0);
176 }
177 
178 /*@C
179    PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.
180 
181    Not Collective
182 
183    Input Parameters:
184 +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
185          This must be cast with a (`PetscObjec`t), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...);
186 -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
187 
188    Output Parameter:
189 .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
190 
191    Level: intermediate
192 
193 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`
194 @*/
195 PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) {
196   va_list Argp;
197 
198   PetscFunctionBegin;
199   PetscValidBoolPointer(match, 2);
200   *match = PETSC_FALSE;
201   if (!obj) PetscFunctionReturn(0);
202   va_start(Argp, type_name);
203   while (type_name && type_name[0]) {
204     PetscBool found;
205     PetscCall(PetscObjectTypeCompare(obj, type_name, &found));
206     if (found) {
207       *match = PETSC_TRUE;
208       break;
209     }
210     type_name = va_arg(Argp, const char *);
211   }
212   va_end(Argp);
213   PetscFunctionReturn(0);
214 }
215 
216 /*@C
217    PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types.
218 
219    Not Collective
220 
221    Input Parameters:
222 +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
223          This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...);
224 -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
225 
226    Output Parameter:
227 .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
228 
229    Level: intermediate
230 
231 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`
232 @*/
233 PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) {
234   va_list Argp;
235 
236   PetscFunctionBegin;
237   PetscValidBoolPointer(match, 2);
238   *match = PETSC_FALSE;
239   va_start(Argp, type_name);
240   while (type_name && type_name[0]) {
241     PetscBool found;
242     PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found));
243     if (found) {
244       *match = PETSC_TRUE;
245       break;
246     }
247     type_name = va_arg(Argp, const char *);
248   }
249   va_end(Argp);
250   PetscFunctionReturn(0);
251 }
252 
253 #define MAXREGDESOBJS 256
254 static int         PetscObjectRegisterDestroy_Count = 0;
255 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
256 
257 /*@C
258    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
259      `PetscFinalize()` is called.
260 
261    Logically Collective on obj
262 
263    Input Parameter:
264 .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
265          This must be cast with a (`PetscObject`), for example,
266          `PetscObjectRegisterDestroy`((`PetscObject`)mat);
267 
268    Level: developer
269 
270    Note:
271       This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer
272     when PETSc ends.
273 
274 .seealso: `PetscObjectRegisterDestroyAll()`
275 @*/
276 PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj) {
277   PetscFunctionBegin;
278   PetscValidHeader(obj, 1);
279   PetscCheck(PetscObjectRegisterDestroy_Count < MAXREGDESOBJS, PETSC_COMM_SELF, PETSC_ERR_PLIB, "No more room in array, limit %d \n recompile %s with larger value for " PetscStringize_(MAXREGDESOBJS), MAXREGDESOBJS, __FILE__);
280   PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
281   PetscFunctionReturn(0);
282 }
283 
284 /*@C
285    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
286      with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()`
287 
288    Logically Collective on the individual `PetscObject`s that are being processed
289 
290    Level: developer
291 
292 .seealso: `PetscObjectRegisterDestroy()`
293 @*/
294 PetscErrorCode PetscObjectRegisterDestroyAll(void) {
295   PetscFunctionBegin;
296   for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i]));
297   PetscObjectRegisterDestroy_Count = 0;
298   PetscFunctionReturn(0);
299 }
300 
301 #define MAXREGFIN 256
302 static int PetscRegisterFinalize_Count = 0;
303 static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);
304 
305 /*@C
306    PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()`
307 
308    Not Collective
309 
310    Input Parameter:
311 .  PetscErrorCode (*fun)(void) -
312 
313    Level: developer
314 
315    Note:
316       This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called
317 
318 .seealso: `PetscRegisterFinalizeAll()`
319 @*/
320 PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void)) {
321   PetscFunctionBegin;
322   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
323     if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0);
324   }
325   PetscCheck(PetscRegisterFinalize_Count < MAXREGFIN, PETSC_COMM_SELF, PETSC_ERR_PLIB, "No more room in array, limit %d \n recompile %s with larger value for " PetscStringize_(MAXREGFIN), MAXREGFIN, __FILE__);
326   PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
327   PetscFunctionReturn(0);
328 }
329 
330 /*@C
331    PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()`
332 
333    Not Collective unless registered functions are collective
334 
335    Level: developer
336 
337 .seealso: `PetscRegisterFinalize()`
338 @*/
339 PetscErrorCode PetscRegisterFinalizeAll(void) {
340   PetscFunctionBegin;
341   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
342   PetscRegisterFinalize_Count = 0;
343   PetscFunctionReturn(0);
344 }
345