xref: /petsc/src/sys/objects/destroy.c (revision 11a5261e40035b7c793f2783a2ba6c7cd4f3b077)
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   Options Database Key:
90 .  -optionname_view [viewertype]:... - option name and values. In actual usage this would be something like -mat_coarse_view
91 
92   Notes:
93 .vb
94     If no value is provided ascii:stdout is used
95        ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
96                                                   for example ascii::ascii_info prints just the information about the object not all details
97                                                   unless :append is given filename opens in write mode, overwriting what was already there
98        binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
99        draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
100        socket[:port]                             defaults to the standard output port
101        saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)
102 .ve
103 
104   This is not called directly but is called by, for example, `MatCoarseViewFromOptions()`
105 
106   Level: developer
107 
108 .seealso: `PetscObject`, `PetscObjectView()`, `PetscOptionsGetViewer()`
109 @*/
110 PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[]) {
111   PetscViewer       viewer;
112   PetscBool         flg;
113   static PetscBool  incall = PETSC_FALSE;
114   PetscViewerFormat format;
115   const char       *prefix;
116 
117   PetscFunctionBegin;
118   if (incall) PetscFunctionReturn(0);
119   incall = PETSC_TRUE;
120   prefix = bobj ? bobj->prefix : obj->prefix;
121   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg));
122   if (flg) {
123     PetscCall(PetscViewerPushFormat(viewer, format));
124     PetscCall(PetscObjectView(obj, viewer));
125     PetscCall(PetscViewerFlush(viewer));
126     PetscCall(PetscViewerPopFormat(viewer));
127     PetscCall(PetscViewerDestroy(&viewer));
128   }
129   incall = PETSC_FALSE;
130   PetscFunctionReturn(0);
131 }
132 
133 /*@C
134    PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type.
135 
136    Not Collective
137 
138    Input Parameters:
139 +  obj - any PETSc object, for example a `Vec`, `Mat or `KSP`.
140          This must be cast with a (`PetscObject`), for example,
141          `PetscObjectTypeCompare`((`PetscObject`)mat);
142 -  type_name - string containing a type name
143 
144    Output Parameter:
145 .  same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE`
146 
147    Level: intermediate
148 
149 .seealso: `PetscObject`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
150 @*/
151 PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) {
152   PetscFunctionBegin;
153   PetscValidBoolPointer(same, 3);
154   if (!obj) *same = PETSC_FALSE;
155   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
156   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
157   else {
158     PetscValidHeader(obj, 1);
159     PetscValidCharPointer(type_name, 2);
160     PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same));
161   }
162   PetscFunctionReturn(0);
163 }
164 
165 /*@C
166    PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ`
167 
168    Not Collective
169 
170    Input Parameters:
171 +  mat - the matrix
172 -  type_name - string containing a type name
173 
174    Output Parameter:
175 .  same - `PETSC_TRUE` if it is of the same base type
176 
177    Level: intermediate
178 
179 .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
180 @*/
181 PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) {
182   PetscFunctionBegin;
183   PetscValidBoolPointer(same, 3);
184   if (!obj) *same = PETSC_FALSE;
185   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
186   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
187   else {
188     PetscValidHeader(obj, 1);
189     PetscValidCharPointer(type_name, 2);
190     PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same));
191   }
192   PetscFunctionReturn(0);
193 }
194 
195 /*@C
196    PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.
197 
198    Not Collective
199 
200    Input Parameters:
201 +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
202          This must be cast with a (`PetscObjec`t), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...);
203 -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
204 
205    Output Parameter:
206 .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
207 
208    Level: intermediate
209 
210 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`
211 @*/
212 PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) {
213   va_list Argp;
214 
215   PetscFunctionBegin;
216   PetscValidBoolPointer(match, 2);
217   *match = PETSC_FALSE;
218   if (!obj) PetscFunctionReturn(0);
219   va_start(Argp, type_name);
220   while (type_name && type_name[0]) {
221     PetscBool found;
222     PetscCall(PetscObjectTypeCompare(obj, type_name, &found));
223     if (found) {
224       *match = PETSC_TRUE;
225       break;
226     }
227     type_name = va_arg(Argp, const char *);
228   }
229   va_end(Argp);
230   PetscFunctionReturn(0);
231 }
232 
233 /*@C
234    PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types.
235 
236    Not Collective
237 
238    Input Parameters:
239 +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
240          This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...);
241 -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
242 
243    Output Parameter:
244 .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
245 
246    Level: intermediate
247 
248 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`
249 @*/
250 PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) {
251   va_list Argp;
252 
253   PetscFunctionBegin;
254   PetscValidBoolPointer(match, 2);
255   *match = PETSC_FALSE;
256   va_start(Argp, type_name);
257   while (type_name && type_name[0]) {
258     PetscBool found;
259     PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found));
260     if (found) {
261       *match = PETSC_TRUE;
262       break;
263     }
264     type_name = va_arg(Argp, const char *);
265   }
266   va_end(Argp);
267   PetscFunctionReturn(0);
268 }
269 
270 #define MAXREGDESOBJS 256
271 static int         PetscObjectRegisterDestroy_Count = 0;
272 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
273 
274 /*@C
275    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
276      `PetscFinalize()` is called.
277 
278    Logically Collective on obj
279 
280    Input Parameter:
281 .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
282          This must be cast with a (`PetscObject`), for example,
283          `PetscObjectRegisterDestroy`((`PetscObject`)mat);
284 
285    Level: developer
286 
287    Note:
288       This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer
289     when PETSc ends.
290 
291 .seealso: `PetscObjectRegisterDestroyAll()`
292 @*/
293 PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj) {
294   PetscFunctionBegin;
295   PetscValidHeader(obj, 1);
296   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__);
297   PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
298   PetscFunctionReturn(0);
299 }
300 
301 /*@C
302    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
303      with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()`
304 
305    Logically Collective on the individual `PetscObject`s that are being processed
306 
307    Level: developer
308 
309 .seealso: `PetscObjectRegisterDestroy()`
310 @*/
311 PetscErrorCode PetscObjectRegisterDestroyAll(void) {
312   PetscFunctionBegin;
313   for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i]));
314   PetscObjectRegisterDestroy_Count = 0;
315   PetscFunctionReturn(0);
316 }
317 
318 #define MAXREGFIN 256
319 static int PetscRegisterFinalize_Count = 0;
320 static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);
321 
322 /*@C
323    PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()`
324 
325    Not Collective
326 
327    Input Parameter:
328 .  PetscErrorCode (*fun)(void) -
329 
330    Level: developer
331 
332    Note:
333       This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called
334 
335 .seealso: `PetscRegisterFinalizeAll()`
336 @*/
337 PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void)) {
338   PetscFunctionBegin;
339   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
340     if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0);
341   }
342   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__);
343   PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
344   PetscFunctionReturn(0);
345 }
346 
347 /*@C
348    PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()`
349 
350    Not Collective unless registered functions are collective
351 
352    Level: developer
353 
354 .seealso: `PetscRegisterFinalize()`
355 @*/
356 PetscErrorCode PetscRegisterFinalizeAll(void) {
357   PetscFunctionBegin;
358   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
359   PetscRegisterFinalize_Count = 0;
360   PetscFunctionReturn(0);
361 }
362