xref: /petsc/src/sys/objects/destroy.c (revision 7fe062437cfdcfbe55b16ad09a00625b08c14a7b)
1 #define PETSC_DLL
2 /*
3      Provides utility routines for manulating any type of PETSc object.
4 */
5 #include "petsc.h"  /*I   "petsc.h"    I*/
6 
7 typedef struct _p_GenericObject* GenericObject;
8 
9 struct _p_GenericObject {
10   PETSCHEADER(int);
11 };
12 
13 PetscErrorCode PetscObjectDestroy_GenericObject(GenericObject obj)
14 {
15   PetscErrorCode ierr;
16   PetscFunctionBegin;
17   PetscValidHeader(obj,1);
18   if (--((PetscObject)obj)->refct > 0) PetscFunctionReturn(0);
19   ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr);
20   PetscFunctionReturn(0);
21 }
22 
23 #undef __FUNCT__
24 #define __FUNCT__ "PetscObjectCreate"
25 /*@C
26    PetscObjectCreate - Creates a PetscObject
27 
28    Collective on PetscObject
29 
30    Input Parameter:
31 .  comm - An MPI communicator
32 
33    Output Parameter:
34 .  obj - The object
35 
36    Level: developer
37 
38    Notes: This is a template intended as a starting point to cut and paste with PetscObjectDestroy_GenericObject()
39           to make new object classes.
40 
41     Concepts: destroying object
42     Concepts: freeing object
43     Concepts: deleting object
44 
45 @*/
46 PetscErrorCode PETSC_DLLEXPORT PetscObjectCreate(MPI_Comm comm, PetscObject *obj)
47 {
48   GenericObject  o;
49   PetscErrorCode ierr;
50 
51   PetscFunctionBegin;
52   PetscValidPointer(obj,2);
53 #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
54   ierr = PetscInitializePackage(PETSC_NULL);CHKERRQ(ierr);
55 #endif
56   ierr = PetscHeaderCreate(o,_p_GenericObject,-1,PETSC_OBJECT_COOKIE,0,"PetscObject",comm,PetscObjectDestroy_GenericObject,0);CHKERRQ(ierr);
57   /* records not yet defined in PetscObject
58   o->data        = 0;
59   o->setupcalled = 0;
60   */
61   *obj = (PetscObject)o;
62   PetscFunctionReturn(0);
63 }
64 
65 #undef __FUNCT__
66 #define __FUNCT__ "PetscObjectCreateGeneric"
67 /*@C
68    PetscObjectCreateGeneric - Creates a PetscObject
69 
70    Collective on PetscObject
71 
72    Input Parameter:
73 +  comm - An MPI communicator
74 .  cookie - The class cookie
75 -  name - The class name
76 
77    Output Parameter:
78 .  obj - The object
79 
80    Level: developer
81 
82    Notes: This is a template intended as a starting point to cut and paste with PetscObjectDestroy_GenericObject()
83           to make new object classes.
84 
85     Concepts: destroying object
86     Concepts: freeing object
87     Concepts: deleting object
88 
89 @*/
90 PetscErrorCode PETSC_DLLEXPORT PetscObjectCreateGeneric(MPI_Comm comm, PetscCookie cookie, const char name[], PetscObject *obj)
91 {
92   GenericObject  o;
93   PetscErrorCode ierr;
94 
95   PetscFunctionBegin;
96   PetscValidPointer(obj,2);
97 #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
98   ierr = PetscInitializePackage(PETSC_NULL);CHKERRQ(ierr);
99 #endif
100   ierr = PetscHeaderCreate(o,_p_GenericObject,-1,cookie,0,name,comm,PetscObjectDestroy_GenericObject,0);CHKERRQ(ierr);
101   /* records not yet defined in PetscObject
102   o->data        = 0;
103   o->setupcalled = 0;
104   */
105   *obj = (PetscObject)o;
106   PetscFunctionReturn(0);
107 }
108 
109 #undef __FUNCT__
110 #define __FUNCT__ "PetscObjectDestroy"
111 /*@
112    PetscObjectDestroy - Destroys any PetscObject, regardless of the type.
113 
114    Collective on PetscObject
115 
116    Input Parameter:
117 .  obj - any PETSc object, for example a Vec, Mat or KSP.
118          This must be cast with a (PetscObject), for example,
119          PetscObjectDestroy((PetscObject)mat);
120 
121    Level: beginner
122 
123     Concepts: destroying object
124     Concepts: freeing object
125     Concepts: deleting object
126 
127 @*/
128 PetscErrorCode PETSC_DLLEXPORT PetscObjectDestroy(PetscObject obj)
129 {
130   PetscErrorCode ierr;
131 
132   PetscFunctionBegin;
133   PetscValidHeader(obj,1);
134   if (obj->bops->destroy) {
135     ierr = (*obj->bops->destroy)(obj);CHKERRQ(ierr);
136   } else {
137     SETERRQ1(PETSC_ERR_PLIB,"This PETSc object of class %s does not have a generic destroy routine",obj->class_name);
138   }
139   PetscFunctionReturn(0);
140 }
141 
142 #undef __FUNCT__
143 #define __FUNCT__ "PetscObjectView"
144 /*@C
145    PetscObjectView - Views any PetscObject, regardless of the type.
146 
147    Collective on PetscObject
148 
149    Input Parameters:
150 +  obj - any PETSc object, for example a Vec, Mat or KSP.
151          This must be cast with a (PetscObject), for example,
152          PetscObjectView((PetscObject)mat,viewer);
153 -  viewer - any PETSc viewer
154 
155    Level: intermediate
156 
157 @*/
158 PetscErrorCode PETSC_DLLEXPORT PetscObjectView(PetscObject obj,PetscViewer viewer)
159 {
160   PetscErrorCode ierr;
161 
162   PetscFunctionBegin;
163   PetscValidHeader(obj,1);
164   if (!viewer) {
165     ierr = PetscViewerASCIIGetStdout(obj->comm,&viewer);CHKERRQ(ierr);
166   }
167   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2);
168 
169   if (obj->bops->view) {
170     ierr = (*obj->bops->view)(obj,viewer);CHKERRQ(ierr);
171   } else {
172     SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic viewer routine");
173   }
174   PetscFunctionReturn(0);
175 }
176 
177 #undef __FUNCT__
178 #define __FUNCT__ "PetscTypeCompare"
179 /*@C
180    PetscTypeCompare - Determines whether a PETSc object is of a particular type.
181 
182    Not Collective
183 
184    Input Parameters:
185 +  obj - any PETSc object, for example a Vec, Mat or KSP.
186          This must be cast with a (PetscObject), for example,
187          PetscObjectDestroy((PetscObject)mat);
188 -  type_name - string containing a type name
189 
190    Output Parameter:
191 .  same - PETSC_TRUE if they are the same, else PETSC_FALSE
192 
193    Level: intermediate
194 
195 .seealso: VecGetType(), KSPGetType(), PCGetType(), SNESGetType()
196 
197    Concepts: comparing^object types
198    Concepts: types^comparing
199    Concepts: object type^comparing
200 
201 @*/
202 PetscErrorCode PETSC_DLLEXPORT PetscTypeCompare(PetscObject obj,const char type_name[],PetscTruth *same)
203 {
204   PetscErrorCode ierr;
205 
206   PetscFunctionBegin;
207   if (!obj) {
208     *same = PETSC_FALSE;
209   } else if (!type_name && !obj->type_name) {
210     *same = PETSC_TRUE;
211   } else if (!type_name || !obj->type_name) {
212     *same = PETSC_FALSE;
213   } else {
214     PetscValidHeader(obj,1);
215     PetscValidCharPointer(type_name,2);
216     PetscValidPointer(same,3);
217     ierr = PetscStrcmp((char*)(obj->type_name),type_name,same);CHKERRQ(ierr);
218   }
219   PetscFunctionReturn(0);
220 }
221 
222 #define MAXREGDESOBJS 256
223 static int         PetscObjectRegisterDestroy_Count = 0;
224 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
225 
226 #undef __FUNCT__
227 #define __FUNCT__ "PetscObjectRegisterDestroy"
228 /*@C
229    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
230      PetscFinalize() is called.
231 
232    Collective on PetscObject
233 
234    Input Parameter:
235 .  obj - any PETSc object, for example a Vec, Mat or KSP.
236          This must be cast with a (PetscObject), for example,
237          PetscObjectRegisterDestroy((PetscObject)mat);
238 
239    Level: developer
240 
241    Notes:
242       This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer
243     when PETSc ends.
244 
245 .seealso: PetscObjectRegisterDestroyAll()
246 @*/
247 PetscErrorCode PETSC_DLLEXPORT PetscObjectRegisterDestroy(PetscObject obj)
248 {
249   PetscFunctionBegin;
250   PetscValidHeader(obj,1);
251   if (PetscObjectRegisterDestroy_Count < MAXREGDESOBJS) {
252     PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
253   } else {
254     SETERRQ1(PETSC_ERR_PLIB,"No more room in array, limit %d \n recompile src/sys/objects/destroy.c with larger value for MAXREGDESOBJS\n",MAXREGDESOBJS);
255 
256   }
257   PetscFunctionReturn(0);
258 }
259 
260 #undef __FUNCT__
261 #define __FUNCT__ "PetscObjectRegisterDestroyAll"
262 /*@C
263    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
264      with PetscObjectRegisterDestroy(). Called by PetscFinalize()
265 
266    Collective on individual PetscObjects
267 
268    Level: developer
269 
270 .seealso: PetscObjectRegisterDestroy()
271 @*/
272 PetscErrorCode PETSC_DLLEXPORT PetscObjectRegisterDestroyAll(void)
273 {
274   PetscErrorCode ierr;
275   int i;
276 
277   PetscFunctionBegin;
278   for (i=0; i<PetscObjectRegisterDestroy_Count; i++) {
279     ierr = PetscObjectDestroy(PetscObjectRegisterDestroy_Objects[i]);CHKERRQ(ierr);
280   }
281   PetscObjectRegisterDestroy_Count = 0;
282   PetscFunctionReturn(0);
283 }
284 
285 
286 #define MAXREGFIN 256
287 static int         PetscRegisterFinalize_Count = 0;
288 static PetscErrorCode ((*PetscRegisterFinalize_Functions[MAXREGFIN])(void));
289 
290 #undef __FUNCT__
291 #define __FUNCT__ "PetscRegisterFinalize"
292 /*@C
293    PetscRegisterFinalize - Registers a function that is to be called in PetscFinalize()
294 
295    Not Collective
296 
297    Input Parameter:
298 .  PetscErrorCode (*fun)(void) -
299 
300    Level: developer
301 
302    Notes:
303       This is used by, for example, DMPackageInitialize() to have DMPackageFinalize() called
304 
305 .seealso: PetscRegisterFinalizeAll()
306 @*/
307 PetscErrorCode PETSC_DLLEXPORT PetscRegisterFinalize(PetscErrorCode (*f)(void))
308 {
309   PetscFunctionBegin;
310 
311   if (PetscRegisterFinalize_Count < MAXREGFIN) {
312     PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
313   } else {
314     SETERRQ1(PETSC_ERR_PLIB,"No more room in array, limit %d \n recompile src/sys/objects/destroy.c with larger value for MAXREGFIN\n",MAXREGFIN);
315 
316   }
317   PetscFunctionReturn(0);
318 }
319 
320 #undef __FUNCT__
321 #define __FUNCT__ "PetsRegisterFinalizeAll"
322 /*@C
323    PetscRegisterFinalizeAll - Runs all the finalize functions set with PetscRegisterFinalize()
324 
325    Not Collective unless registered functions are collective
326 
327    Level: developer
328 
329 .seealso: PetscRegisterFinalize()
330 @*/
331 PetscErrorCode PETSC_DLLEXPORT PetscRegisterFinalizeAll(void)
332 {
333   PetscErrorCode ierr;
334   int i;
335 
336   PetscFunctionBegin;
337   for (i=0; i<PetscRegisterFinalize_Count; i++) {
338     ierr = (*PetscRegisterFinalize_Functions[i])();CHKERRQ(ierr);
339   }
340   PetscRegisterFinalize_Count = 0;
341   PetscFunctionReturn(0);
342 }
343