xref: /petsc/src/sys/objects/destroy.c (revision 11a5261e40035b7c793f2783a2ba6c7cd4f3b077)
17d0a6c19SBarry Smith 
2e5c89e4eSSatish Balay /*
3e5c89e4eSSatish Balay      Provides utility routines for manulating any type of PETSc object.
4e5c89e4eSSatish Balay */
5af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I   "petscsys.h"    I*/
6665c2dedSJed Brown #include <petscviewer.h>
7e5c89e4eSSatish Balay 
89371c9d4SSatish Balay PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj) {
9d42688cbSBarry Smith   PetscInt i;
10d42688cbSBarry Smith 
11b436f76fSVictor Eijkhout   PetscFunctionBegin;
12b436f76fSVictor Eijkhout   if (obj->intstar_idmax > 0) {
139566063dSJacob Faibussowitsch     for (i = 0; i < obj->intstar_idmax; i++) PetscCall(PetscFree(obj->intstarcomposeddata[i]));
149566063dSJacob Faibussowitsch     PetscCall(PetscFree2(obj->intstarcomposeddata, obj->intstarcomposedstate));
15b436f76fSVictor Eijkhout   }
16b436f76fSVictor Eijkhout   if (obj->realstar_idmax > 0) {
179566063dSJacob Faibussowitsch     for (i = 0; i < obj->realstar_idmax; i++) PetscCall(PetscFree(obj->realstarcomposeddata[i]));
189566063dSJacob Faibussowitsch     PetscCall(PetscFree2(obj->realstarcomposeddata, obj->realstarcomposedstate));
19b436f76fSVictor Eijkhout   }
20b436f76fSVictor Eijkhout   if (obj->scalarstar_idmax > 0) {
219566063dSJacob Faibussowitsch     for (i = 0; i < obj->scalarstar_idmax; i++) PetscCall(PetscFree(obj->scalarstarcomposeddata[i]));
229566063dSJacob Faibussowitsch     PetscCall(PetscFree2(obj->scalarstarcomposeddata, obj->scalarstarcomposedstate));
23b436f76fSVictor Eijkhout   }
249566063dSJacob Faibussowitsch   PetscCall(PetscFree2(obj->intcomposeddata, obj->intcomposedstate));
259566063dSJacob Faibussowitsch   PetscCall(PetscFree2(obj->realcomposeddata, obj->realcomposedstate));
269566063dSJacob Faibussowitsch   PetscCall(PetscFree2(obj->scalarcomposeddata, obj->scalarcomposedstate));
27b436f76fSVictor Eijkhout   PetscFunctionReturn(0);
28b436f76fSVictor Eijkhout }
29b436f76fSVictor Eijkhout 
30e30d2299SSatish Balay /*@
31811af0c4SBarry Smith    PetscObjectDestroy - Destroys any `PetscObject`, regardless of the type.
32e5c89e4eSSatish Balay 
33811af0c4SBarry Smith    Collective on obj
34e5c89e4eSSatish Balay 
35e5c89e4eSSatish Balay    Input Parameter:
36811af0c4SBarry Smith .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
37811af0c4SBarry Smith          This must be cast with a (`PetscObject`*), for example,
38811af0c4SBarry Smith          `PetscObjectDestroy`((`PetscObject`*)&mat);
39e5c89e4eSSatish Balay 
40e5c89e4eSSatish Balay    Level: beginner
41e5c89e4eSSatish Balay 
42811af0c4SBarry Smith .seealso: `PetscObject`
43e5c89e4eSSatish Balay @*/
449371c9d4SSatish Balay PetscErrorCode PetscObjectDestroy(PetscObject *obj) {
45e5c89e4eSSatish Balay   PetscFunctionBegin;
465f80ce2aSJacob Faibussowitsch   if (!obj || !*obj) PetscFunctionReturn(0);
476bf464f9SBarry Smith   PetscValidHeader(*obj, 1);
485f80ce2aSJacob Faibussowitsch   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);
499566063dSJacob Faibussowitsch   PetscCall((*(*obj)->bops->destroy)(obj));
50e5c89e4eSSatish Balay   PetscFunctionReturn(0);
51e5c89e4eSSatish Balay }
52e5c89e4eSSatish Balay 
53e5c89e4eSSatish Balay /*@C
54811af0c4SBarry Smith    PetscObjectView - Views any `PetscObject`, regardless of the type.
55e5c89e4eSSatish Balay 
56811af0c4SBarry Smith    Collective on obj
57e5c89e4eSSatish Balay 
58e5c89e4eSSatish Balay    Input Parameters:
59811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
60811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example,
61811af0c4SBarry Smith          `PetscObjectView`((`PetscObject`)mat,viewer);
62e5c89e4eSSatish Balay -  viewer - any PETSc viewer
63e5c89e4eSSatish Balay 
64e5c89e4eSSatish Balay    Level: intermediate
65e5c89e4eSSatish Balay 
66811af0c4SBarry Smith .seealso: `PetscObject`, `PetscObjectViewFromOptions()`
67e5c89e4eSSatish Balay @*/
689371c9d4SSatish Balay PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer) {
69e5c89e4eSSatish Balay   PetscFunctionBegin;
70e5c89e4eSSatish Balay   PetscValidHeader(obj, 1);
715f80ce2aSJacob Faibussowitsch   PetscCheck(obj->bops->view, PETSC_COMM_SELF, PETSC_ERR_SUP, "This PETSc object does not have a generic viewer routine");
729566063dSJacob Faibussowitsch   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(obj->comm, &viewer));
730700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
74e5c89e4eSSatish Balay 
759566063dSJacob Faibussowitsch   PetscCall((*obj->bops->view)(obj, viewer));
76e5c89e4eSSatish Balay   PetscFunctionReturn(0);
77e5c89e4eSSatish Balay }
78e5c89e4eSSatish Balay 
792d747510SLisandro Dalcin /*@C
80811af0c4SBarry Smith   PetscObjectViewFromOptions - Processes command line options to determine if/how a `PetscObject` is to be viewed.
812d747510SLisandro Dalcin 
82811af0c4SBarry Smith   Collective on obj
832d747510SLisandro Dalcin 
842d747510SLisandro Dalcin   Input Parameters:
852d747510SLisandro Dalcin + obj   - the object
862d747510SLisandro Dalcin . bobj  - optional other object that provides prefix (if NULL then the prefix in obj is used)
87bb7acecfSBarry Smith - optionname - option string that is used to activate viewing
882d747510SLisandro Dalcin 
89*11a5261eSBarry Smith   Options Database Key:
90*11a5261eSBarry Smith .  -optionname_view [viewertype]:... - option name and values. In actual usage this would be something like -mat_coarse_view
912d747510SLisandro Dalcin 
92*11a5261eSBarry Smith   Notes:
93*11a5261eSBarry Smith .vb
94*11a5261eSBarry Smith     If no value is provided ascii:stdout is used
95*11a5261eSBarry Smith        ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
96*11a5261eSBarry Smith                                                   for example ascii::ascii_info prints just the information about the object not all details
97*11a5261eSBarry Smith                                                   unless :append is given filename opens in write mode, overwriting what was already there
98*11a5261eSBarry Smith        binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
99*11a5261eSBarry Smith        draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
100*11a5261eSBarry Smith        socket[:port]                             defaults to the standard output port
101*11a5261eSBarry Smith        saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)
102*11a5261eSBarry Smith .ve
103*11a5261eSBarry Smith 
104*11a5261eSBarry Smith   This is not called directly but is called by, for example, `MatCoarseViewFromOptions()`
105*11a5261eSBarry Smith 
106*11a5261eSBarry Smith   Level: developer
107*11a5261eSBarry Smith 
108*11a5261eSBarry Smith .seealso: `PetscObject`, `PetscObjectView()`, `PetscOptionsGetViewer()`
1092d747510SLisandro Dalcin @*/
1109371c9d4SSatish Balay PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[]) {
1112d747510SLisandro Dalcin   PetscViewer       viewer;
1122d747510SLisandro Dalcin   PetscBool         flg;
1132d747510SLisandro Dalcin   static PetscBool  incall = PETSC_FALSE;
1142d747510SLisandro Dalcin   PetscViewerFormat format;
1152d747510SLisandro Dalcin   const char       *prefix;
1162d747510SLisandro Dalcin 
1172d747510SLisandro Dalcin   PetscFunctionBegin;
1182d747510SLisandro Dalcin   if (incall) PetscFunctionReturn(0);
1192d747510SLisandro Dalcin   incall = PETSC_TRUE;
1202d747510SLisandro Dalcin   prefix = bobj ? bobj->prefix : obj->prefix;
1219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg));
1222d747510SLisandro Dalcin   if (flg) {
1239566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, format));
1249566063dSJacob Faibussowitsch     PetscCall(PetscObjectView(obj, viewer));
1259566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
1269566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
1279566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
1282d747510SLisandro Dalcin   }
1292d747510SLisandro Dalcin   incall = PETSC_FALSE;
1302d747510SLisandro Dalcin   PetscFunctionReturn(0);
1312d747510SLisandro Dalcin }
1322d747510SLisandro Dalcin 
133e5c89e4eSSatish Balay /*@C
134251f4c67SDmitry Karpeev    PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type.
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Not Collective
137e5c89e4eSSatish Balay 
138e5c89e4eSSatish Balay    Input Parameters:
139811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat or `KSP`.
140811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example,
141811af0c4SBarry Smith          `PetscObjectTypeCompare`((`PetscObject`)mat);
142e5c89e4eSSatish Balay -  type_name - string containing a type name
143e5c89e4eSSatish Balay 
144e5c89e4eSSatish Balay    Output Parameter:
145811af0c4SBarry Smith .  same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE`
146e5c89e4eSSatish Balay 
147e5c89e4eSSatish Balay    Level: intermediate
148e5c89e4eSSatish Balay 
149811af0c4SBarry Smith .seealso: `PetscObject`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
150e5c89e4eSSatish Balay @*/
1519371c9d4SSatish Balay PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) {
152e5c89e4eSSatish Balay   PetscFunctionBegin;
1535f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(same, 3);
154a297a907SKarl Rupp   if (!obj) *same = PETSC_FALSE;
155a297a907SKarl Rupp   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
156a297a907SKarl Rupp   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
157a297a907SKarl Rupp   else {
158e5c89e4eSSatish Balay     PetscValidHeader(obj, 1);
159e5c89e4eSSatish Balay     PetscValidCharPointer(type_name, 2);
1609566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same));
161e5c89e4eSSatish Balay   }
162e5c89e4eSSatish Balay   PetscFunctionReturn(0);
163e5c89e4eSSatish Balay }
164e5c89e4eSSatish Balay 
1652b12f010SJed Brown /*@C
166811af0c4SBarry Smith    PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ`
1674099cc6bSBarry Smith 
1684099cc6bSBarry Smith    Not Collective
1694099cc6bSBarry Smith 
1704099cc6bSBarry Smith    Input Parameters:
1714099cc6bSBarry Smith +  mat - the matrix
1724099cc6bSBarry Smith -  type_name - string containing a type name
1734099cc6bSBarry Smith 
1744099cc6bSBarry Smith    Output Parameter:
175811af0c4SBarry Smith .  same - `PETSC_TRUE` if it is of the same base type
1764099cc6bSBarry Smith 
1774099cc6bSBarry Smith    Level: intermediate
1784099cc6bSBarry Smith 
179811af0c4SBarry Smith .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
1804099cc6bSBarry Smith @*/
1819371c9d4SSatish Balay PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) {
1824099cc6bSBarry Smith   PetscFunctionBegin;
1835f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(same, 3);
1844099cc6bSBarry Smith   if (!obj) *same = PETSC_FALSE;
1854099cc6bSBarry Smith   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
1864099cc6bSBarry Smith   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
1874099cc6bSBarry Smith   else {
1884099cc6bSBarry Smith     PetscValidHeader(obj, 1);
1894099cc6bSBarry Smith     PetscValidCharPointer(type_name, 2);
1909566063dSJacob Faibussowitsch     PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same));
1914099cc6bSBarry Smith   }
1924099cc6bSBarry Smith   PetscFunctionReturn(0);
1934099cc6bSBarry Smith }
1944099cc6bSBarry Smith 
1954099cc6bSBarry Smith /*@C
196251f4c67SDmitry Karpeev    PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.
1972b12f010SJed Brown 
1982b12f010SJed Brown    Not Collective
1992b12f010SJed Brown 
2002b12f010SJed Brown    Input Parameters:
201811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
202811af0c4SBarry Smith          This must be cast with a (`PetscObjec`t), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...);
203811af0c4SBarry Smith -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
2042b12f010SJed Brown 
2052b12f010SJed Brown    Output Parameter:
206811af0c4SBarry Smith .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
2072b12f010SJed Brown 
2082b12f010SJed Brown    Level: intermediate
2092b12f010SJed Brown 
210dee2f2dbSPierre Jolivet .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`
2112b12f010SJed Brown @*/
2129371c9d4SSatish Balay PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) {
2132b12f010SJed Brown   va_list Argp;
2142b12f010SJed Brown 
2152b12f010SJed Brown   PetscFunctionBegin;
2165f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(match, 2);
2172b12f010SJed Brown   *match = PETSC_FALSE;
218f73a99e8SStefano Zampini   if (!obj) PetscFunctionReturn(0);
2192b12f010SJed Brown   va_start(Argp, type_name);
2202b12f010SJed Brown   while (type_name && type_name[0]) {
2212b12f010SJed Brown     PetscBool found;
2229566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare(obj, type_name, &found));
2232b12f010SJed Brown     if (found) {
2242b12f010SJed Brown       *match = PETSC_TRUE;
2252b12f010SJed Brown       break;
2262b12f010SJed Brown     }
2272b12f010SJed Brown     type_name = va_arg(Argp, const char *);
2282b12f010SJed Brown   }
2292b12f010SJed Brown   va_end(Argp);
2302b12f010SJed Brown   PetscFunctionReturn(0);
2312b12f010SJed Brown }
2322b12f010SJed Brown 
233b9e7e5c1SBarry Smith /*@C
234b9e7e5c1SBarry Smith    PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types.
235b9e7e5c1SBarry Smith 
236b9e7e5c1SBarry Smith    Not Collective
237b9e7e5c1SBarry Smith 
238b9e7e5c1SBarry Smith    Input Parameters:
239811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
240811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...);
241811af0c4SBarry Smith -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
242b9e7e5c1SBarry Smith 
243b9e7e5c1SBarry Smith    Output Parameter:
244811af0c4SBarry Smith .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
245b9e7e5c1SBarry Smith 
246b9e7e5c1SBarry Smith    Level: intermediate
247b9e7e5c1SBarry Smith 
248db781477SPatrick Sanan .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`
249b9e7e5c1SBarry Smith @*/
2509371c9d4SSatish Balay PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) {
251b9e7e5c1SBarry Smith   va_list Argp;
252b9e7e5c1SBarry Smith 
253b9e7e5c1SBarry Smith   PetscFunctionBegin;
2545f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(match, 2);
255b9e7e5c1SBarry Smith   *match = PETSC_FALSE;
256b9e7e5c1SBarry Smith   va_start(Argp, type_name);
257b9e7e5c1SBarry Smith   while (type_name && type_name[0]) {
258b9e7e5c1SBarry Smith     PetscBool found;
2599566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found));
260b9e7e5c1SBarry Smith     if (found) {
261b9e7e5c1SBarry Smith       *match = PETSC_TRUE;
262b9e7e5c1SBarry Smith       break;
263b9e7e5c1SBarry Smith     }
264b9e7e5c1SBarry Smith     type_name = va_arg(Argp, const char *);
265b9e7e5c1SBarry Smith   }
266b9e7e5c1SBarry Smith   va_end(Argp);
267b9e7e5c1SBarry Smith   PetscFunctionReturn(0);
268b9e7e5c1SBarry Smith }
269b9e7e5c1SBarry Smith 
2703cfa8680SLisandro Dalcin #define MAXREGDESOBJS 256
271e5c89e4eSSatish Balay static int         PetscObjectRegisterDestroy_Count = 0;
2723cfa8680SLisandro Dalcin static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
273e5c89e4eSSatish Balay 
274e5c89e4eSSatish Balay /*@C
275e5c89e4eSSatish Balay    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
276811af0c4SBarry Smith      `PetscFinalize()` is called.
277e5c89e4eSSatish Balay 
278811af0c4SBarry Smith    Logically Collective on obj
279e5c89e4eSSatish Balay 
280e5c89e4eSSatish Balay    Input Parameter:
281811af0c4SBarry Smith .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
282811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example,
283811af0c4SBarry Smith          `PetscObjectRegisterDestroy`((`PetscObject`)mat);
284e5c89e4eSSatish Balay 
285e5c89e4eSSatish Balay    Level: developer
286e5c89e4eSSatish Balay 
287811af0c4SBarry Smith    Note:
288e5c89e4eSSatish Balay       This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer
289e5c89e4eSSatish Balay     when PETSc ends.
290e5c89e4eSSatish Balay 
291db781477SPatrick Sanan .seealso: `PetscObjectRegisterDestroyAll()`
292e5c89e4eSSatish Balay @*/
2939371c9d4SSatish Balay PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj) {
294e5c89e4eSSatish Balay   PetscFunctionBegin;
295e5c89e4eSSatish Balay   PetscValidHeader(obj, 1);
2965f80ce2aSJacob Faibussowitsch   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__);
2975f80ce2aSJacob Faibussowitsch   PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
298e5c89e4eSSatish Balay   PetscFunctionReturn(0);
299e5c89e4eSSatish Balay }
300e5c89e4eSSatish Balay 
301e5c89e4eSSatish Balay /*@C
302e5c89e4eSSatish Balay    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
303811af0c4SBarry Smith      with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()`
304e5c89e4eSSatish Balay 
305811af0c4SBarry Smith    Logically Collective on the individual `PetscObject`s that are being processed
306e5c89e4eSSatish Balay 
307e5c89e4eSSatish Balay    Level: developer
308e5c89e4eSSatish Balay 
309db781477SPatrick Sanan .seealso: `PetscObjectRegisterDestroy()`
310e5c89e4eSSatish Balay @*/
3119371c9d4SSatish Balay PetscErrorCode PetscObjectRegisterDestroyAll(void) {
312e5c89e4eSSatish Balay   PetscFunctionBegin;
3139566063dSJacob Faibussowitsch   for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i]));
3143cfa8680SLisandro Dalcin   PetscObjectRegisterDestroy_Count = 0;
315e5c89e4eSSatish Balay   PetscFunctionReturn(0);
316e5c89e4eSSatish Balay }
317e5c89e4eSSatish Balay 
318eb8be38cSBarry Smith #define MAXREGFIN 256
319eb8be38cSBarry Smith static int PetscRegisterFinalize_Count = 0;
32000a402e0SLisandro Dalcin static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);
321eb8be38cSBarry Smith 
322eb8be38cSBarry Smith /*@C
323811af0c4SBarry Smith    PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()`
324eb8be38cSBarry Smith 
325eb8be38cSBarry Smith    Not Collective
326eb8be38cSBarry Smith 
327eb8be38cSBarry Smith    Input Parameter:
328eb8be38cSBarry Smith .  PetscErrorCode (*fun)(void) -
329eb8be38cSBarry Smith 
330eb8be38cSBarry Smith    Level: developer
331eb8be38cSBarry Smith 
332811af0c4SBarry Smith    Note:
333811af0c4SBarry Smith       This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called
334eb8be38cSBarry Smith 
335db781477SPatrick Sanan .seealso: `PetscRegisterFinalizeAll()`
336eb8be38cSBarry Smith @*/
3379371c9d4SSatish Balay PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void)) {
338f4aac215SBarry Smith   PetscFunctionBegin;
3395f80ce2aSJacob Faibussowitsch   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
340aee23540SBarry Smith     if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0);
341f4aac215SBarry Smith   }
3425f80ce2aSJacob Faibussowitsch   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__);
3435f80ce2aSJacob Faibussowitsch   PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
344eb8be38cSBarry Smith   PetscFunctionReturn(0);
345eb8be38cSBarry Smith }
346eb8be38cSBarry Smith 
347eb8be38cSBarry Smith /*@C
348811af0c4SBarry Smith    PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()`
349eb8be38cSBarry Smith 
350eb8be38cSBarry Smith    Not Collective unless registered functions are collective
351eb8be38cSBarry Smith 
352eb8be38cSBarry Smith    Level: developer
353eb8be38cSBarry Smith 
354db781477SPatrick Sanan .seealso: `PetscRegisterFinalize()`
355eb8be38cSBarry Smith @*/
3569371c9d4SSatish Balay PetscErrorCode PetscRegisterFinalizeAll(void) {
357eb8be38cSBarry Smith   PetscFunctionBegin;
3589566063dSJacob Faibussowitsch   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
359eb8be38cSBarry Smith   PetscRegisterFinalize_Count = 0;
360eb8be38cSBarry Smith   PetscFunctionReturn(0);
361eb8be38cSBarry Smith }
362