xref: /petsc/src/sys/objects/destroy.c (revision 58d68138c660dfb4e9f5b03334792cd4f2ffd7cc)
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 PetscObject
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 @*/
43 PetscErrorCode PetscObjectDestroy(PetscObject *obj) {
44   PetscFunctionBegin;
45   if (!obj || !*obj) PetscFunctionReturn(0);
46   PetscValidHeader(*obj, 1);
47   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);
48   PetscCall((*(*obj)->bops->destroy)(obj));
49   PetscFunctionReturn(0);
50 }
51 
52 /*@C
53    PetscObjectView - Views any PetscObject, regardless of the type.
54 
55    Collective on PetscObject
56 
57    Input Parameters:
58 +  obj - any PETSc object, for example a Vec, Mat or KSP.
59          This must be cast with a (PetscObject), for example,
60          PetscObjectView((PetscObject)mat,viewer);
61 -  viewer - any PETSc viewer
62 
63    Level: intermediate
64 
65 @*/
66 PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer) {
67   PetscFunctionBegin;
68   PetscValidHeader(obj, 1);
69   PetscCheck(obj->bops->view, PETSC_COMM_SELF, PETSC_ERR_SUP, "This PETSc object does not have a generic viewer routine");
70   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(obj->comm, &viewer));
71   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
72 
73   PetscCall((*obj->bops->view)(obj, viewer));
74   PetscFunctionReturn(0);
75 }
76 
77 /*@C
78   PetscObjectViewFromOptions - Processes command line options to determine if/how a PetscObject is to be viewed.
79 
80   Collective on PetscObject
81 
82   Input Parameters:
83 + obj   - the object
84 . bobj  - optional other object that provides prefix (if NULL then the prefix in obj is used)
85 - optionname - option string that is used to activate viewing
86 
87   Level: intermediate
88 
89 @*/
90 PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[]) {
91   PetscViewer       viewer;
92   PetscBool         flg;
93   static PetscBool  incall = PETSC_FALSE;
94   PetscViewerFormat format;
95   const char       *prefix;
96 
97   PetscFunctionBegin;
98   if (incall) PetscFunctionReturn(0);
99   incall = PETSC_TRUE;
100   prefix = bobj ? bobj->prefix : obj->prefix;
101   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg));
102   if (flg) {
103     PetscCall(PetscViewerPushFormat(viewer, format));
104     PetscCall(PetscObjectView(obj, viewer));
105     PetscCall(PetscViewerFlush(viewer));
106     PetscCall(PetscViewerPopFormat(viewer));
107     PetscCall(PetscViewerDestroy(&viewer));
108   }
109   incall = PETSC_FALSE;
110   PetscFunctionReturn(0);
111 }
112 
113 /*@C
114    PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type.
115 
116    Not Collective
117 
118    Input Parameters:
119 +  obj - any PETSc object, for example a Vec, Mat or KSP.
120          This must be cast with a (PetscObject), for example,
121          PetscObjectTypeCompare((PetscObject)mat);
122 -  type_name - string containing a type name
123 
124    Output Parameter:
125 .  same - PETSC_TRUE if they are the same, else PETSC_FALSE
126 
127    Level: intermediate
128 
129 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
130 
131 @*/
132 PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) {
133   PetscFunctionBegin;
134   PetscValidBoolPointer(same, 3);
135   if (!obj) *same = PETSC_FALSE;
136   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
137   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
138   else {
139     PetscValidHeader(obj, 1);
140     PetscValidCharPointer(type_name, 2);
141     PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same));
142   }
143   PetscFunctionReturn(0);
144 }
145 
146 /*@C
147    PetscObjectBaseTypeCompare - Determines whether a PetscObject is of a given base type. For example the base type of MATSEQAIJPERM is MATSEQAIJ
148 
149    Not Collective
150 
151    Input Parameters:
152 +  mat - the matrix
153 -  type_name - string containing a type name
154 
155    Output Parameter:
156 .  same - PETSC_TRUE if it is of the same base type
157 
158    Level: intermediate
159 
160 .seealso: `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
161 
162 @*/
163 PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) {
164   PetscFunctionBegin;
165   PetscValidBoolPointer(same, 3);
166   if (!obj) *same = PETSC_FALSE;
167   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
168   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
169   else {
170     PetscValidHeader(obj, 1);
171     PetscValidCharPointer(type_name, 2);
172     PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same));
173   }
174   PetscFunctionReturn(0);
175 }
176 
177 /*@C
178    PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.
179 
180    Not Collective
181 
182    Input Parameters:
183 +  obj - any PETSc object, for example a Vec, Mat or KSP.
184          This must be cast with a (PetscObject), for example, PetscObjectTypeCompareAny((PetscObject)mat,...);
185 -  type_name - string containing a type name, pass the empty string "" to terminate the list
186 
187    Output Parameter:
188 .  match - PETSC_TRUE if the type of obj matches any in the list, else PETSC_FALSE
189 
190    Level: intermediate
191 
192 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`
193 
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 - string containing a type name, 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 @*/
234 PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) {
235   va_list Argp;
236 
237   PetscFunctionBegin;
238   PetscValidBoolPointer(match, 2);
239   *match = PETSC_FALSE;
240   va_start(Argp, type_name);
241   while (type_name && type_name[0]) {
242     PetscBool found;
243     PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found));
244     if (found) {
245       *match = PETSC_TRUE;
246       break;
247     }
248     type_name = va_arg(Argp, const char *);
249   }
250   va_end(Argp);
251   PetscFunctionReturn(0);
252 }
253 
254 #define MAXREGDESOBJS 256
255 static int         PetscObjectRegisterDestroy_Count = 0;
256 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
257 
258 /*@C
259    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
260      PetscFinalize() is called.
261 
262    Logically Collective on PetscObject
263 
264    Input Parameter:
265 .  obj - any PETSc object, for example a Vec, Mat or KSP.
266          This must be cast with a (PetscObject), for example,
267          PetscObjectRegisterDestroy((PetscObject)mat);
268 
269    Level: developer
270 
271    Notes:
272       This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer
273     when PETSc ends.
274 
275 .seealso: `PetscObjectRegisterDestroyAll()`
276 @*/
277 PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj) {
278   PetscFunctionBegin;
279   PetscValidHeader(obj, 1);
280   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__);
281   PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
282   PetscFunctionReturn(0);
283 }
284 
285 /*@C
286    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
287      with PetscObjectRegisterDestroy(). Called by PetscFinalize()
288 
289    Logically Collective on individual PetscObjects
290 
291    Level: developer
292 
293 .seealso: `PetscObjectRegisterDestroy()`
294 @*/
295 PetscErrorCode PetscObjectRegisterDestroyAll(void) {
296   PetscFunctionBegin;
297   for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i]));
298   PetscObjectRegisterDestroy_Count = 0;
299   PetscFunctionReturn(0);
300 }
301 
302 #define MAXREGFIN 256
303 static int PetscRegisterFinalize_Count = 0;
304 static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);
305 
306 /*@C
307    PetscRegisterFinalize - Registers a function that is to be called in PetscFinalize()
308 
309    Not Collective
310 
311    Input Parameter:
312 .  PetscErrorCode (*fun)(void) -
313 
314    Level: developer
315 
316    Notes:
317       This is used by, for example, DMInitializePackage() to have DMFinalizePackage() called
318 
319 .seealso: `PetscRegisterFinalizeAll()`
320 @*/
321 PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void)) {
322   PetscFunctionBegin;
323   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
324     if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0);
325   }
326   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__);
327   PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
328   PetscFunctionReturn(0);
329 }
330 
331 /*@C
332    PetscRegisterFinalizeAll - Runs all the finalize functions set with PetscRegisterFinalize()
333 
334    Not Collective unless registered functions are collective
335 
336    Level: developer
337 
338 .seealso: `PetscRegisterFinalize()`
339 @*/
340 PetscErrorCode PetscRegisterFinalizeAll(void) {
341   PetscFunctionBegin;
342   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
343   PetscRegisterFinalize_Count = 0;
344   PetscFunctionReturn(0);
345 }
346