xref: /petsc/src/sys/objects/destroy.c (revision 66c9fbdd036b1e887ebf0d2bef6dbdcafd086d45)
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 {
10   PetscInt i;
11 
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(0);
29 }
30 
31 /*@
32    PetscObjectDestroy - Destroys any `PetscObject`, regardless of the type.
33 
34    Collective
35 
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);
40 
41    Level: beginner
42 
43 .seealso: `PetscObject`
44 @*/
45 PetscErrorCode PetscObjectDestroy(PetscObject *obj)
46 {
47   PetscFunctionBegin;
48   if (!obj || !*obj) PetscFunctionReturn(0);
49   PetscValidHeader(*obj, 1);
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(0);
53 }
54 
55 /*@C
56    PetscObjectView - Views any `PetscObject`, regardless of the type.
57 
58    Collective
59 
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
65 
66    Level: intermediate
67 
68 .seealso: `PetscObject`, `PetscObjectViewFromOptions()`
69 @*/
70 PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer)
71 {
72   PetscFunctionBegin;
73   PetscValidHeader(obj, 1);
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));
76   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
77 
78   PetscCall((*obj->bops->view)(obj, viewer));
79   PetscFunctionReturn(0);
80 }
81 
82 /*@C
83   PetscObjectViewFromOptions - Processes command line options to determine if/how a `PetscObject` is to be viewed.
84 
85   Collective
86 
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
91 
92   Options Database Key:
93 .  -optionname_view [viewertype]:... - option name and values. In actual usage this would be something like -mat_coarse_view
94 
95   Notes:
96 .vb
97     If no value is provided ascii:stdout is used
98        ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
99                                                   for example ascii::ascii_info prints just the information about the object not all details
100                                                   unless :append is given filename opens in write mode, overwriting what was already there
101        binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
102        draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
103        socket[:port]                             defaults to the standard output port
104        saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)
105 .ve
106 
107   This is not called directly but is called by, for example, `MatCoarseViewFromOptions()`
108 
109   Level: developer
110 
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;
120 
121   PetscFunctionBegin;
122   if (incall) PetscFunctionReturn(0);
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(0);
135 }
136 
137 /*@C
138    PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type.
139 
140    Not Collective
141 
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
147 
148    Output Parameter:
149 .  same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE`
150 
151    Level: intermediate
152 
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;
158   PetscValidBoolPointer(same, 3);
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 {
163     PetscValidHeader(obj, 1);
164     PetscValidCharPointer(type_name, 2);
165     PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same));
166   }
167   PetscFunctionReturn(0);
168 }
169 
170 /*@C
171    PetscObjectObjectTypeCompare - Determines whether two PETSc objects are of the same type
172 
173    Logically Collective
174 
175    Input Parameters:
176 +  obj1 - any PETSc object, for example a Vec, Mat or KSP.
177 -  obj2 - anther PETSc object
178 
179    Output Parameter:
180 .  same - PETSC_TRUE if they are the same, else PETSC_FALSE
181 
182    Level: intermediate
183 
184 .seealso: `PetscObjectTypeCompare()`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
185 
186 @*/
187 PetscErrorCode PetscObjectObjectTypeCompare(PetscObject obj1, PetscObject obj2, PetscBool *same)
188 {
189   PetscFunctionBegin;
190   PetscValidBoolPointer(same, 3);
191   PetscValidHeader(obj1, 1);
192   PetscValidHeader(obj2, 2);
193   PetscCall(PetscStrcmp((char *)(obj1->type_name), (char *)(obj2->type_name), same));
194   PetscFunctionReturn(0);
195 }
196 
197 /*@C
198    PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ`
199 
200    Not Collective
201 
202    Input Parameters:
203 +  mat - the matrix
204 -  type_name - string containing a type name
205 
206    Output Parameter:
207 .  same - `PETSC_TRUE` if it is of the same base type
208 
209    Level: intermediate
210 
211 .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
212 @*/
213 PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same)
214 {
215   PetscFunctionBegin;
216   PetscValidBoolPointer(same, 3);
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 {
221     PetscValidHeader(obj, 1);
222     PetscValidCharPointer(type_name, 2);
223     PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same));
224   }
225   PetscFunctionReturn(0);
226 }
227 
228 /*@C
229    PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.
230 
231    Not Collective
232 
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
237 
238    Output Parameter:
239 .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
240 
241    Level: intermediate
242 
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;
248 
249   PetscFunctionBegin;
250   PetscValidBoolPointer(match, 2);
251   *match = PETSC_FALSE;
252   if (!obj) PetscFunctionReturn(0);
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(0);
265 }
266 
267 /*@C
268    PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types.
269 
270    Not Collective
271 
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
276 
277    Output Parameter:
278 .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
279 
280    Level: intermediate
281 
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;
287 
288   PetscFunctionBegin;
289   PetscValidBoolPointer(match, 2);
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(0);
303 }
304 
305 #define MAXREGDESOBJS 256
306 static int         PetscObjectRegisterDestroy_Count = 0;
307 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
308 
309 /*@C
310    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
311      `PetscFinalize()` is called.
312 
313    Logically Collective
314 
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);
319 
320    Level: developer
321 
322    Note:
323       This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer
324     when PETSc ends.
325 
326 .seealso: `PetscObjectRegisterDestroyAll()`
327 @*/
328 PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj)
329 {
330   PetscFunctionBegin;
331   PetscValidHeader(obj, 1);
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(0);
335 }
336 
337 /*@C
338    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
339      with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()`
340 
341    Logically Collective on the individual `PetscObject`s that are being processed
342 
343    Level: developer
344 
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(0);
353 }
354 
355 #define MAXREGFIN 256
356 static int PetscRegisterFinalize_Count = 0;
357 static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);
358 
359 /*@C
360    PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()`
361 
362    Not Collective
363 
364    Input Parameter:
365 .  PetscErrorCode (*fun)(void) -
366 
367    Level: developer
368 
369    Note:
370       This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called
371 
372 .seealso: `PetscRegisterFinalizeAll()`
373 @*/
374 PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void))
375 {
376   PetscFunctionBegin;
377   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
378     if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0);
379   }
380   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__);
381   PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
382   PetscFunctionReturn(0);
383 }
384 
385 /*@C
386    PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()`
387 
388    Not Collective unless registered functions are collective
389 
390    Level: developer
391 
392 .seealso: `PetscRegisterFinalize()`
393 @*/
394 PetscErrorCode PetscRegisterFinalizeAll(void)
395 {
396   PetscFunctionBegin;
397   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
398   PetscRegisterFinalize_Count = 0;
399   PetscFunctionReturn(0);
400 }
401