xref: /petsc/src/sys/objects/destroy.c (revision 6524c165f7ddaf30fd7457737f668f984c8ababf)
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()`, `PetscObjectObjectTypeCompare()`
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    PetscObjectObjectTypeCompare - Determines whether two PETSc objects are of the same type
167 
168    Logically Collective
169 
170    Input Parameters:
171 +  obj1 - any PETSc object, for example a Vec, Mat or KSP.
172 -  obj2 - anther PETSc object
173 
174    Output Parameter:
175 .  same - PETSC_TRUE if they are the same, else PETSC_FALSE
176 
177    Level: intermediate
178 
179 .seealso: `PetscObjectTypeCompare()`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
180 
181 @*/
182 PetscErrorCode PetscObjectObjectTypeCompare(PetscObject obj1, PetscObject obj2, PetscBool *same) {
183   PetscFunctionBegin;
184   PetscValidBoolPointer(same, 3);
185   PetscValidHeader(obj1, 1);
186   PetscValidHeader(obj2, 2);
187   PetscCall(PetscStrcmp((char *)(obj1->type_name), (char *)(obj2->type_name), same));
188   PetscFunctionReturn(0);
189 }
190 
191 /*@C
192    PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ`
193 
194    Not Collective
195 
196    Input Parameters:
197 +  mat - the matrix
198 -  type_name - string containing a type name
199 
200    Output Parameter:
201 .  same - `PETSC_TRUE` if it is of the same base type
202 
203    Level: intermediate
204 
205 .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
206 @*/
207 PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) {
208   PetscFunctionBegin;
209   PetscValidBoolPointer(same, 3);
210   if (!obj) *same = PETSC_FALSE;
211   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
212   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
213   else {
214     PetscValidHeader(obj, 1);
215     PetscValidCharPointer(type_name, 2);
216     PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same));
217   }
218   PetscFunctionReturn(0);
219 }
220 
221 /*@C
222    PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.
223 
224    Not Collective
225 
226    Input Parameters:
227 +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
228          This must be cast with a (`PetscObjec`t), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...);
229 -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
230 
231    Output Parameter:
232 .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
233 
234    Level: intermediate
235 
236 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`
237 @*/
238 PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) {
239   va_list Argp;
240 
241   PetscFunctionBegin;
242   PetscValidBoolPointer(match, 2);
243   *match = PETSC_FALSE;
244   if (!obj) PetscFunctionReturn(0);
245   va_start(Argp, type_name);
246   while (type_name && type_name[0]) {
247     PetscBool found;
248     PetscCall(PetscObjectTypeCompare(obj, type_name, &found));
249     if (found) {
250       *match = PETSC_TRUE;
251       break;
252     }
253     type_name = va_arg(Argp, const char *);
254   }
255   va_end(Argp);
256   PetscFunctionReturn(0);
257 }
258 
259 /*@C
260    PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types.
261 
262    Not Collective
263 
264    Input Parameters:
265 +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
266          This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...);
267 -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
268 
269    Output Parameter:
270 .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
271 
272    Level: intermediate
273 
274 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`
275 @*/
276 PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) {
277   va_list Argp;
278 
279   PetscFunctionBegin;
280   PetscValidBoolPointer(match, 2);
281   *match = PETSC_FALSE;
282   va_start(Argp, type_name);
283   while (type_name && type_name[0]) {
284     PetscBool found;
285     PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found));
286     if (found) {
287       *match = PETSC_TRUE;
288       break;
289     }
290     type_name = va_arg(Argp, const char *);
291   }
292   va_end(Argp);
293   PetscFunctionReturn(0);
294 }
295 
296 #define MAXREGDESOBJS 256
297 static int         PetscObjectRegisterDestroy_Count = 0;
298 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
299 
300 /*@C
301    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
302      `PetscFinalize()` is called.
303 
304    Logically Collective on obj
305 
306    Input Parameter:
307 .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
308          This must be cast with a (`PetscObject`), for example,
309          `PetscObjectRegisterDestroy`((`PetscObject`)mat);
310 
311    Level: developer
312 
313    Note:
314       This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer
315     when PETSc ends.
316 
317 .seealso: `PetscObjectRegisterDestroyAll()`
318 @*/
319 PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj) {
320   PetscFunctionBegin;
321   PetscValidHeader(obj, 1);
322   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__);
323   PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
324   PetscFunctionReturn(0);
325 }
326 
327 /*@C
328    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
329      with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()`
330 
331    Logically Collective on the individual `PetscObject`s that are being processed
332 
333    Level: developer
334 
335 .seealso: `PetscObjectRegisterDestroy()`
336 @*/
337 PetscErrorCode PetscObjectRegisterDestroyAll(void) {
338   PetscFunctionBegin;
339   for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i]));
340   PetscObjectRegisterDestroy_Count = 0;
341   PetscFunctionReturn(0);
342 }
343 
344 #define MAXREGFIN 256
345 static int PetscRegisterFinalize_Count = 0;
346 static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);
347 
348 /*@C
349    PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()`
350 
351    Not Collective
352 
353    Input Parameter:
354 .  PetscErrorCode (*fun)(void) -
355 
356    Level: developer
357 
358    Note:
359       This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called
360 
361 .seealso: `PetscRegisterFinalizeAll()`
362 @*/
363 PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void)) {
364   PetscFunctionBegin;
365   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
366     if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0);
367   }
368   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__);
369   PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
370   PetscFunctionReturn(0);
371 }
372 
373 /*@C
374    PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()`
375 
376    Not Collective unless registered functions are collective
377 
378    Level: developer
379 
380 .seealso: `PetscRegisterFinalize()`
381 @*/
382 PetscErrorCode PetscRegisterFinalizeAll(void) {
383   PetscFunctionBegin;
384   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
385   PetscRegisterFinalize_Count = 0;
386   PetscFunctionReturn(0);
387 }
388