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