xref: /petsc/src/sys/objects/destroy.c (revision 9cd7b5a2df946e93e6c311ef47bb251ab0c81a71)
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 
8*9cd7b5a2SJacob Faibussowitsch static PetscErrorCode DestroyComposedData(void ***composed_star, PetscObjectState **state_star, PetscInt *count_star, void **composed, PetscObjectState **state)
9d71ae5a4SJacob Faibussowitsch {
10*9cd7b5a2SJacob Faibussowitsch   void **tmp_star = *composed_star;
11d42688cbSBarry Smith 
12b436f76fSVictor Eijkhout   PetscFunctionBegin;
13*9cd7b5a2SJacob Faibussowitsch   for (PetscInt i = 0, imax = *count_star; i < imax; ++i) PetscCall(PetscFree(tmp_star[i]));
14*9cd7b5a2SJacob Faibussowitsch   PetscCall(PetscFree2(*composed_star, *state_star));
15*9cd7b5a2SJacob Faibussowitsch   PetscCall(PetscFree2(*composed, *state));
16*9cd7b5a2SJacob Faibussowitsch   *count_star = 0;
17*9cd7b5a2SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18*9cd7b5a2SJacob Faibussowitsch }
19*9cd7b5a2SJacob Faibussowitsch 
20*9cd7b5a2SJacob Faibussowitsch PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj)
21*9cd7b5a2SJacob Faibussowitsch {
22*9cd7b5a2SJacob Faibussowitsch   PetscFunctionBegin;
23b843b480SStefano Zampini   PetscValidHeader(obj, 1);
24*9cd7b5a2SJacob Faibussowitsch   PetscCall(DestroyComposedData((void ***)&obj->intstarcomposeddata, &obj->intstarcomposedstate, &obj->intstar_idmax, (void **)&obj->intcomposeddata, &obj->intcomposedstate));
25*9cd7b5a2SJacob Faibussowitsch   PetscCall(DestroyComposedData((void ***)&obj->realstarcomposeddata, &obj->realstarcomposedstate, &obj->realstar_idmax, (void **)&obj->realcomposeddata, &obj->realcomposedstate));
26*9cd7b5a2SJacob Faibussowitsch #if PetscDefined(USE_COMPLEX)
27*9cd7b5a2SJacob Faibussowitsch   PetscCall(DestroyComposedData((void ***)&obj->scalarstarcomposeddata, &obj->scalarstarcomposedstate, &obj->scalarstar_idmax, (void **)&obj->scalarcomposeddata, &obj->scalarcomposedstate));
28*9cd7b5a2SJacob Faibussowitsch #endif
293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30b436f76fSVictor Eijkhout }
31b436f76fSVictor Eijkhout 
32e30d2299SSatish Balay /*@
33811af0c4SBarry Smith    PetscObjectDestroy - Destroys any `PetscObject`, regardless of the type.
34e5c89e4eSSatish Balay 
35c3339decSBarry Smith    Collective
36e5c89e4eSSatish Balay 
37e5c89e4eSSatish Balay    Input Parameter:
38811af0c4SBarry Smith .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
39811af0c4SBarry Smith          This must be cast with a (`PetscObject`*), for example,
40811af0c4SBarry Smith          `PetscObjectDestroy`((`PetscObject`*)&mat);
41e5c89e4eSSatish Balay 
42e5c89e4eSSatish Balay    Level: beginner
43e5c89e4eSSatish Balay 
44811af0c4SBarry Smith .seealso: `PetscObject`
45e5c89e4eSSatish Balay @*/
46d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectDestroy(PetscObject *obj)
47d71ae5a4SJacob Faibussowitsch {
48e5c89e4eSSatish Balay   PetscFunctionBegin;
493ba16761SJacob Faibussowitsch   if (!obj || !*obj) PetscFunctionReturn(PETSC_SUCCESS);
506bf464f9SBarry Smith   PetscValidHeader(*obj, 1);
515f80ce2aSJacob 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);
529566063dSJacob Faibussowitsch   PetscCall((*(*obj)->bops->destroy)(obj));
533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
54e5c89e4eSSatish Balay }
55e5c89e4eSSatish Balay 
56e5c89e4eSSatish Balay /*@C
57811af0c4SBarry Smith    PetscObjectView - Views any `PetscObject`, regardless of the type.
58e5c89e4eSSatish Balay 
59c3339decSBarry Smith    Collective
60e5c89e4eSSatish Balay 
61e5c89e4eSSatish Balay    Input Parameters:
62811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
63811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example,
64811af0c4SBarry Smith          `PetscObjectView`((`PetscObject`)mat,viewer);
65e5c89e4eSSatish Balay -  viewer - any PETSc viewer
66e5c89e4eSSatish Balay 
67e5c89e4eSSatish Balay    Level: intermediate
68e5c89e4eSSatish Balay 
69811af0c4SBarry Smith .seealso: `PetscObject`, `PetscObjectViewFromOptions()`
70e5c89e4eSSatish Balay @*/
71d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer)
72d71ae5a4SJacob Faibussowitsch {
73e5c89e4eSSatish Balay   PetscFunctionBegin;
74e5c89e4eSSatish Balay   PetscValidHeader(obj, 1);
755f80ce2aSJacob Faibussowitsch   PetscCheck(obj->bops->view, PETSC_COMM_SELF, PETSC_ERR_SUP, "This PETSc object does not have a generic viewer routine");
769566063dSJacob Faibussowitsch   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(obj->comm, &viewer));
770700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
78e5c89e4eSSatish Balay 
799566063dSJacob Faibussowitsch   PetscCall((*obj->bops->view)(obj, viewer));
803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
81e5c89e4eSSatish Balay }
82e5c89e4eSSatish Balay 
832d747510SLisandro Dalcin /*@C
84811af0c4SBarry Smith   PetscObjectViewFromOptions - Processes command line options to determine if/how a `PetscObject` is to be viewed.
852d747510SLisandro Dalcin 
86c3339decSBarry Smith   Collective
872d747510SLisandro Dalcin 
882d747510SLisandro Dalcin   Input Parameters:
892d747510SLisandro Dalcin + obj   - the object
9021532e8aSBarry Smith . bobj  - optional other object that provides prefix (if `NULL` then the prefix in `obj` is used)
91bb7acecfSBarry Smith - optionname - option string that is used to activate viewing
922d747510SLisandro Dalcin 
9311a5261eSBarry Smith   Options Database Key:
9421532e8aSBarry Smith .  -optionname_view [viewertype]:... - option name and values. In actual usage this would be something like `-mat_coarse_view`
9521532e8aSBarry Smith 
9621532e8aSBarry Smith   Level: developer
972d747510SLisandro Dalcin 
9811a5261eSBarry Smith  Notes:
9911a5261eSBarry Smith .vb
10011a5261eSBarry Smith     If no value is provided ascii:stdout is used
10111a5261eSBarry Smith        ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
10211a5261eSBarry Smith                                                   for example ascii::ascii_info prints just the information about the object not all details
10311a5261eSBarry Smith                                                   unless :append is given filename opens in write mode, overwriting what was already there
10411a5261eSBarry Smith        binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
10511a5261eSBarry Smith        draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
10611a5261eSBarry Smith        socket[:port]                             defaults to the standard output port
10711a5261eSBarry Smith        saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)
10811a5261eSBarry Smith .ve
10911a5261eSBarry Smith 
11021532e8aSBarry Smith   This is not called directly but is called by, for example, `MatViewFromOptions()`
11111a5261eSBarry Smith 
11211a5261eSBarry Smith .seealso: `PetscObject`, `PetscObjectView()`, `PetscOptionsGetViewer()`
1132d747510SLisandro Dalcin @*/
114d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[])
115d71ae5a4SJacob Faibussowitsch {
1162d747510SLisandro Dalcin   PetscViewer       viewer;
1172d747510SLisandro Dalcin   PetscBool         flg;
1182d747510SLisandro Dalcin   static PetscBool  incall = PETSC_FALSE;
1192d747510SLisandro Dalcin   PetscViewerFormat format;
1202d747510SLisandro Dalcin   const char       *prefix;
1212d747510SLisandro Dalcin 
1222d747510SLisandro Dalcin   PetscFunctionBegin;
123b843b480SStefano Zampini   PetscValidHeader(obj, 1);
124b843b480SStefano Zampini   if (bobj) PetscValidHeader(bobj, 2);
1253ba16761SJacob Faibussowitsch   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
1262d747510SLisandro Dalcin   incall = PETSC_TRUE;
1272d747510SLisandro Dalcin   prefix = bobj ? bobj->prefix : obj->prefix;
1289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg));
1292d747510SLisandro Dalcin   if (flg) {
1309566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, format));
1319566063dSJacob Faibussowitsch     PetscCall(PetscObjectView(obj, viewer));
1329566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
1339566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
1349566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
1352d747510SLisandro Dalcin   }
1362d747510SLisandro Dalcin   incall = PETSC_FALSE;
1373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1382d747510SLisandro Dalcin }
1392d747510SLisandro Dalcin 
140e5c89e4eSSatish Balay /*@C
141251f4c67SDmitry Karpeev    PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type.
142e5c89e4eSSatish Balay 
143e5c89e4eSSatish Balay    Not Collective
144e5c89e4eSSatish Balay 
145e5c89e4eSSatish Balay    Input Parameters:
146aa624791SPierre Jolivet +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
147811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example,
148811af0c4SBarry Smith          `PetscObjectTypeCompare`((`PetscObject`)mat);
149e5c89e4eSSatish Balay -  type_name - string containing a type name
150e5c89e4eSSatish Balay 
151e5c89e4eSSatish Balay    Output Parameter:
152b843b480SStefano Zampini .  same - `PETSC_TRUE` if the type of `obj` and `type_name` are the same or both `NULL`, else `PETSC_FALSE`
153e5c89e4eSSatish Balay 
154e5c89e4eSSatish Balay    Level: intermediate
155e5c89e4eSSatish Balay 
156013e2dc7SBarry Smith .seealso: `PetscObject`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`, `PetscObjectObjectTypeCompare()`
157e5c89e4eSSatish Balay @*/
158d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same)
159d71ae5a4SJacob Faibussowitsch {
160e5c89e4eSSatish Balay   PetscFunctionBegin;
1615f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(same, 3);
162b843b480SStefano Zampini   if (!obj) *same = (PetscBool)!type_name;
163a297a907SKarl Rupp   else {
164e5c89e4eSSatish Balay     PetscValidHeader(obj, 1);
165b843b480SStefano Zampini     if (!type_name || !obj->type_name) *same = (PetscBool)(!obj->type_name == !type_name);
166b843b480SStefano Zampini     else {
167e5c89e4eSSatish Balay       PetscValidCharPointer(type_name, 2);
168b843b480SStefano Zampini       PetscCall(PetscStrcmp(obj->type_name, type_name, same));
169b843b480SStefano Zampini     }
170e5c89e4eSSatish Balay   }
1713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
172e5c89e4eSSatish Balay }
173e5c89e4eSSatish Balay 
1742b12f010SJed Brown /*@C
175013e2dc7SBarry Smith    PetscObjectObjectTypeCompare - Determines whether two PETSc objects are of the same type
176013e2dc7SBarry Smith 
177013e2dc7SBarry Smith    Logically Collective
178013e2dc7SBarry Smith 
179013e2dc7SBarry Smith    Input Parameters:
18021532e8aSBarry Smith +  obj1 - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
181da81f932SPierre Jolivet -  obj2 - another PETSc object
182013e2dc7SBarry Smith 
183013e2dc7SBarry Smith    Output Parameter:
184b843b480SStefano Zampini .  same - `PETSC_TRUE` if they are the same or both unset, else `PETSC_FALSE`
185013e2dc7SBarry Smith 
186013e2dc7SBarry Smith    Level: intermediate
187013e2dc7SBarry Smith 
188013e2dc7SBarry Smith .seealso: `PetscObjectTypeCompare()`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
189013e2dc7SBarry Smith 
190013e2dc7SBarry Smith @*/
191d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectObjectTypeCompare(PetscObject obj1, PetscObject obj2, PetscBool *same)
192d71ae5a4SJacob Faibussowitsch {
193013e2dc7SBarry Smith   PetscFunctionBegin;
194013e2dc7SBarry Smith   PetscValidHeader(obj1, 1);
195013e2dc7SBarry Smith   PetscValidHeader(obj2, 2);
196b843b480SStefano Zampini   PetscValidBoolPointer(same, 3);
197b843b480SStefano Zampini   PetscCall(PetscStrcmp(obj1->type_name, obj2->type_name, same));
1983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
199013e2dc7SBarry Smith }
200013e2dc7SBarry Smith 
201013e2dc7SBarry Smith /*@C
202811af0c4SBarry Smith    PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ`
2034099cc6bSBarry Smith 
2044099cc6bSBarry Smith    Not Collective
2054099cc6bSBarry Smith 
2064099cc6bSBarry Smith    Input Parameters:
2074099cc6bSBarry Smith +  mat - the matrix
2084099cc6bSBarry Smith -  type_name - string containing a type name
2094099cc6bSBarry Smith 
2104099cc6bSBarry Smith    Output Parameter:
211b843b480SStefano Zampini .  same - `PETSC_TRUE` if the object is of the same base type identified by `type_name` or both `NULL`, `PETSC_FALSE` otherwise
2124099cc6bSBarry Smith 
2134099cc6bSBarry Smith    Level: intermediate
2144099cc6bSBarry Smith 
215811af0c4SBarry Smith .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
2164099cc6bSBarry Smith @*/
217d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same)
218d71ae5a4SJacob Faibussowitsch {
2194099cc6bSBarry Smith   PetscFunctionBegin;
2205f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(same, 3);
221b843b480SStefano Zampini   if (!obj) *same = (PetscBool)!type_name;
2224099cc6bSBarry Smith   else {
2234099cc6bSBarry Smith     PetscValidHeader(obj, 1);
224b843b480SStefano Zampini     if (!type_name || !obj->type_name) *same = (PetscBool)(!obj->type_name == !type_name);
225b843b480SStefano Zampini     else {
2264099cc6bSBarry Smith       PetscValidCharPointer(type_name, 2);
227b843b480SStefano Zampini       PetscCall(PetscStrbeginswith(obj->type_name, type_name, same));
228b843b480SStefano Zampini     }
2294099cc6bSBarry Smith   }
2303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2314099cc6bSBarry Smith }
2324099cc6bSBarry Smith 
2334099cc6bSBarry Smith /*@C
234251f4c67SDmitry Karpeev    PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.
2352b12f010SJed Brown 
2362b12f010SJed Brown    Not Collective
2372b12f010SJed Brown 
2382b12f010SJed Brown    Input Parameters:
239811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
2401a9a975bSPierre Jolivet          This must be cast with a (`PetscObject`), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...);
241811af0c4SBarry Smith -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
2422b12f010SJed Brown 
2432b12f010SJed Brown    Output Parameter:
24421532e8aSBarry Smith .  match - `PETSC_TRUE` if the type of `obj` matches any in the list, else `PETSC_FALSE`
2452b12f010SJed Brown 
2462b12f010SJed Brown    Level: intermediate
2472b12f010SJed Brown 
248dee2f2dbSPierre Jolivet .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`
2492b12f010SJed Brown @*/
250d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...)
251d71ae5a4SJacob Faibussowitsch {
2522b12f010SJed Brown   va_list Argp;
2532b12f010SJed Brown 
2542b12f010SJed Brown   PetscFunctionBegin;
2555f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(match, 2);
2562b12f010SJed Brown   *match = PETSC_FALSE;
2573ba16761SJacob Faibussowitsch   if (!obj) PetscFunctionReturn(PETSC_SUCCESS);
2582b12f010SJed Brown   va_start(Argp, type_name);
2592b12f010SJed Brown   while (type_name && type_name[0]) {
2602b12f010SJed Brown     PetscBool found;
2619566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare(obj, type_name, &found));
2622b12f010SJed Brown     if (found) {
2632b12f010SJed Brown       *match = PETSC_TRUE;
2642b12f010SJed Brown       break;
2652b12f010SJed Brown     }
2662b12f010SJed Brown     type_name = va_arg(Argp, const char *);
2672b12f010SJed Brown   }
2682b12f010SJed Brown   va_end(Argp);
2693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2702b12f010SJed Brown }
2712b12f010SJed Brown 
272b9e7e5c1SBarry Smith /*@C
273b9e7e5c1SBarry Smith    PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types.
274b9e7e5c1SBarry Smith 
275b9e7e5c1SBarry Smith    Not Collective
276b9e7e5c1SBarry Smith 
277b9e7e5c1SBarry Smith    Input Parameters:
278811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
279811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...);
280811af0c4SBarry Smith -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
281b9e7e5c1SBarry Smith 
282b9e7e5c1SBarry Smith    Output Parameter:
28321532e8aSBarry Smith .  match - `PETSC_TRUE` if the type of `obj` matches any in the list, else `PETSC_FALSE`
284b9e7e5c1SBarry Smith 
285b9e7e5c1SBarry Smith    Level: intermediate
286b9e7e5c1SBarry Smith 
287db781477SPatrick Sanan .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`
288b9e7e5c1SBarry Smith @*/
289d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...)
290d71ae5a4SJacob Faibussowitsch {
291b9e7e5c1SBarry Smith   va_list Argp;
292b9e7e5c1SBarry Smith 
293b9e7e5c1SBarry Smith   PetscFunctionBegin;
2945f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(match, 2);
295b9e7e5c1SBarry Smith   *match = PETSC_FALSE;
296b9e7e5c1SBarry Smith   va_start(Argp, type_name);
297b9e7e5c1SBarry Smith   while (type_name && type_name[0]) {
298b9e7e5c1SBarry Smith     PetscBool found;
2999566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found));
300b9e7e5c1SBarry Smith     if (found) {
301b9e7e5c1SBarry Smith       *match = PETSC_TRUE;
302b9e7e5c1SBarry Smith       break;
303b9e7e5c1SBarry Smith     }
304b9e7e5c1SBarry Smith     type_name = va_arg(Argp, const char *);
305b9e7e5c1SBarry Smith   }
306b9e7e5c1SBarry Smith   va_end(Argp);
3073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
308b9e7e5c1SBarry Smith }
309b9e7e5c1SBarry Smith 
3103cfa8680SLisandro Dalcin #define MAXREGDESOBJS 256
311e5c89e4eSSatish Balay static int         PetscObjectRegisterDestroy_Count = 0;
3123cfa8680SLisandro Dalcin static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
313e5c89e4eSSatish Balay 
314e5c89e4eSSatish Balay /*@C
315e5c89e4eSSatish Balay    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
316811af0c4SBarry Smith      `PetscFinalize()` is called.
317e5c89e4eSSatish Balay 
318c3339decSBarry Smith    Logically Collective
319e5c89e4eSSatish Balay 
320e5c89e4eSSatish Balay    Input Parameter:
321811af0c4SBarry Smith .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
322811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example,
323811af0c4SBarry Smith          `PetscObjectRegisterDestroy`((`PetscObject`)mat);
324e5c89e4eSSatish Balay 
325e5c89e4eSSatish Balay    Level: developer
326e5c89e4eSSatish Balay 
327811af0c4SBarry Smith    Note:
32821532e8aSBarry Smith       This is used by, for example, `PETSC_VIEWER_XXX_()` routines to free the viewer
329e5c89e4eSSatish Balay     when PETSc ends.
330e5c89e4eSSatish Balay 
331db781477SPatrick Sanan .seealso: `PetscObjectRegisterDestroyAll()`
332e5c89e4eSSatish Balay @*/
333d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj)
334d71ae5a4SJacob Faibussowitsch {
335e5c89e4eSSatish Balay   PetscFunctionBegin;
336e5c89e4eSSatish Balay   PetscValidHeader(obj, 1);
3370e6b6b59SJacob Faibussowitsch   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__);
3385f80ce2aSJacob Faibussowitsch   PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
3393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
340e5c89e4eSSatish Balay }
341e5c89e4eSSatish Balay 
342e5c89e4eSSatish Balay /*@C
343e5c89e4eSSatish Balay    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
344811af0c4SBarry Smith      with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()`
345e5c89e4eSSatish Balay 
346811af0c4SBarry Smith    Logically Collective on the individual `PetscObject`s that are being processed
347e5c89e4eSSatish Balay 
348e5c89e4eSSatish Balay    Level: developer
349e5c89e4eSSatish Balay 
350db781477SPatrick Sanan .seealso: `PetscObjectRegisterDestroy()`
351e5c89e4eSSatish Balay @*/
352d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectRegisterDestroyAll(void)
353d71ae5a4SJacob Faibussowitsch {
354e5c89e4eSSatish Balay   PetscFunctionBegin;
3559566063dSJacob Faibussowitsch   for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i]));
3563cfa8680SLisandro Dalcin   PetscObjectRegisterDestroy_Count = 0;
3573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
358e5c89e4eSSatish Balay }
359e5c89e4eSSatish Balay 
360eb8be38cSBarry Smith #define MAXREGFIN 256
361eb8be38cSBarry Smith static int PetscRegisterFinalize_Count = 0;
36200a402e0SLisandro Dalcin static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);
363eb8be38cSBarry Smith 
364eb8be38cSBarry Smith /*@C
365811af0c4SBarry Smith    PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()`
366eb8be38cSBarry Smith 
367eb8be38cSBarry Smith    Not Collective
368eb8be38cSBarry Smith 
369eb8be38cSBarry Smith    Input Parameter:
37021532e8aSBarry Smith .  PetscErrorCode (*fun)(void) - function to be called
371eb8be38cSBarry Smith 
372eb8be38cSBarry Smith    Level: developer
373eb8be38cSBarry Smith 
37421532e8aSBarry Smith    Notes:
375811af0c4SBarry Smith   This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called
376eb8be38cSBarry Smith 
37721532e8aSBarry Smith   Use `PetscObjectRegisterDestroy()` to register the destruction of an object in `PetscFinalize()`
37821532e8aSBarry Smith 
37921532e8aSBarry Smith .seealso: `PetscRegisterFinalizeAll()`, `PetscObjectRegisterDestroy()`
380eb8be38cSBarry Smith @*/
381d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void))
382d71ae5a4SJacob Faibussowitsch {
383f4aac215SBarry Smith   PetscFunctionBegin;
3845f80ce2aSJacob Faibussowitsch   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
3853ba16761SJacob Faibussowitsch     if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(PETSC_SUCCESS);
386f4aac215SBarry Smith   }
3870e6b6b59SJacob Faibussowitsch   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__);
3885f80ce2aSJacob Faibussowitsch   PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
3893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
390eb8be38cSBarry Smith }
391eb8be38cSBarry Smith 
392eb8be38cSBarry Smith /*@C
393811af0c4SBarry Smith    PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()`
394eb8be38cSBarry Smith 
395eb8be38cSBarry Smith    Not Collective unless registered functions are collective
396eb8be38cSBarry Smith 
397eb8be38cSBarry Smith    Level: developer
398eb8be38cSBarry Smith 
39921532e8aSBarry Smith .seealso: `PetscRegisterFinalize()`, `PetscObjectRegisterDestroyAll()`
400eb8be38cSBarry Smith @*/
401d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRegisterFinalizeAll(void)
402d71ae5a4SJacob Faibussowitsch {
403eb8be38cSBarry Smith   PetscFunctionBegin;
4049566063dSJacob Faibussowitsch   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
405eb8be38cSBarry Smith   PetscRegisterFinalize_Count = 0;
4063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
407eb8be38cSBarry Smith }
408