xref: /petsc/src/sys/objects/destroy.c (revision c3339decea92175325d9368fa13196bcd0e0e58b)
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 
8d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj)
9d71ae5a4SJacob Faibussowitsch {
10d42688cbSBarry Smith   PetscInt i;
11d42688cbSBarry Smith 
12b436f76fSVictor Eijkhout   PetscFunctionBegin;
13b436f76fSVictor Eijkhout   if (obj->intstar_idmax > 0) {
149566063dSJacob Faibussowitsch     for (i = 0; i < obj->intstar_idmax; i++) PetscCall(PetscFree(obj->intstarcomposeddata[i]));
159566063dSJacob Faibussowitsch     PetscCall(PetscFree2(obj->intstarcomposeddata, obj->intstarcomposedstate));
16b436f76fSVictor Eijkhout   }
17b436f76fSVictor Eijkhout   if (obj->realstar_idmax > 0) {
189566063dSJacob Faibussowitsch     for (i = 0; i < obj->realstar_idmax; i++) PetscCall(PetscFree(obj->realstarcomposeddata[i]));
199566063dSJacob Faibussowitsch     PetscCall(PetscFree2(obj->realstarcomposeddata, obj->realstarcomposedstate));
20b436f76fSVictor Eijkhout   }
21b436f76fSVictor Eijkhout   if (obj->scalarstar_idmax > 0) {
229566063dSJacob Faibussowitsch     for (i = 0; i < obj->scalarstar_idmax; i++) PetscCall(PetscFree(obj->scalarstarcomposeddata[i]));
239566063dSJacob Faibussowitsch     PetscCall(PetscFree2(obj->scalarstarcomposeddata, obj->scalarstarcomposedstate));
24b436f76fSVictor Eijkhout   }
259566063dSJacob Faibussowitsch   PetscCall(PetscFree2(obj->intcomposeddata, obj->intcomposedstate));
269566063dSJacob Faibussowitsch   PetscCall(PetscFree2(obj->realcomposeddata, obj->realcomposedstate));
279566063dSJacob Faibussowitsch   PetscCall(PetscFree2(obj->scalarcomposeddata, obj->scalarcomposedstate));
28b436f76fSVictor Eijkhout   PetscFunctionReturn(0);
29b436f76fSVictor Eijkhout }
30b436f76fSVictor Eijkhout 
31e30d2299SSatish Balay /*@
32811af0c4SBarry Smith    PetscObjectDestroy - Destroys any `PetscObject`, regardless of the type.
33e5c89e4eSSatish Balay 
34*c3339decSBarry Smith    Collective
35e5c89e4eSSatish Balay 
36e5c89e4eSSatish Balay    Input Parameter:
37811af0c4SBarry Smith .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
38811af0c4SBarry Smith          This must be cast with a (`PetscObject`*), for example,
39811af0c4SBarry Smith          `PetscObjectDestroy`((`PetscObject`*)&mat);
40e5c89e4eSSatish Balay 
41e5c89e4eSSatish Balay    Level: beginner
42e5c89e4eSSatish Balay 
43811af0c4SBarry Smith .seealso: `PetscObject`
44e5c89e4eSSatish Balay @*/
45d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectDestroy(PetscObject *obj)
46d71ae5a4SJacob Faibussowitsch {
47e5c89e4eSSatish Balay   PetscFunctionBegin;
485f80ce2aSJacob Faibussowitsch   if (!obj || !*obj) PetscFunctionReturn(0);
496bf464f9SBarry Smith   PetscValidHeader(*obj, 1);
505f80ce2aSJacob 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);
519566063dSJacob Faibussowitsch   PetscCall((*(*obj)->bops->destroy)(obj));
52e5c89e4eSSatish Balay   PetscFunctionReturn(0);
53e5c89e4eSSatish Balay }
54e5c89e4eSSatish Balay 
55e5c89e4eSSatish Balay /*@C
56811af0c4SBarry Smith    PetscObjectView - Views any `PetscObject`, regardless of the type.
57e5c89e4eSSatish Balay 
58*c3339decSBarry Smith    Collective
59e5c89e4eSSatish Balay 
60e5c89e4eSSatish Balay    Input Parameters:
61811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
62811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example,
63811af0c4SBarry Smith          `PetscObjectView`((`PetscObject`)mat,viewer);
64e5c89e4eSSatish Balay -  viewer - any PETSc viewer
65e5c89e4eSSatish Balay 
66e5c89e4eSSatish Balay    Level: intermediate
67e5c89e4eSSatish Balay 
68811af0c4SBarry Smith .seealso: `PetscObject`, `PetscObjectViewFromOptions()`
69e5c89e4eSSatish Balay @*/
70d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer)
71d71ae5a4SJacob Faibussowitsch {
72e5c89e4eSSatish Balay   PetscFunctionBegin;
73e5c89e4eSSatish Balay   PetscValidHeader(obj, 1);
745f80ce2aSJacob Faibussowitsch   PetscCheck(obj->bops->view, PETSC_COMM_SELF, PETSC_ERR_SUP, "This PETSc object does not have a generic viewer routine");
759566063dSJacob Faibussowitsch   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(obj->comm, &viewer));
760700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
77e5c89e4eSSatish Balay 
789566063dSJacob Faibussowitsch   PetscCall((*obj->bops->view)(obj, viewer));
79e5c89e4eSSatish Balay   PetscFunctionReturn(0);
80e5c89e4eSSatish Balay }
81e5c89e4eSSatish Balay 
822d747510SLisandro Dalcin /*@C
83811af0c4SBarry Smith   PetscObjectViewFromOptions - Processes command line options to determine if/how a `PetscObject` is to be viewed.
842d747510SLisandro Dalcin 
85*c3339decSBarry Smith   Collective
862d747510SLisandro Dalcin 
872d747510SLisandro Dalcin   Input Parameters:
882d747510SLisandro Dalcin + obj   - the object
892d747510SLisandro Dalcin . bobj  - optional other object that provides prefix (if NULL then the prefix in obj is used)
90bb7acecfSBarry Smith - optionname - option string that is used to activate viewing
912d747510SLisandro Dalcin 
9211a5261eSBarry Smith   Options Database Key:
9311a5261eSBarry Smith .  -optionname_view [viewertype]:... - option name and values. In actual usage this would be something like -mat_coarse_view
942d747510SLisandro Dalcin 
9511a5261eSBarry Smith   Notes:
9611a5261eSBarry Smith .vb
9711a5261eSBarry Smith     If no value is provided ascii:stdout is used
9811a5261eSBarry Smith        ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
9911a5261eSBarry Smith                                                   for example ascii::ascii_info prints just the information about the object not all details
10011a5261eSBarry Smith                                                   unless :append is given filename opens in write mode, overwriting what was already there
10111a5261eSBarry Smith        binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
10211a5261eSBarry Smith        draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
10311a5261eSBarry Smith        socket[:port]                             defaults to the standard output port
10411a5261eSBarry Smith        saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)
10511a5261eSBarry Smith .ve
10611a5261eSBarry Smith 
10711a5261eSBarry Smith   This is not called directly but is called by, for example, `MatCoarseViewFromOptions()`
10811a5261eSBarry Smith 
10911a5261eSBarry Smith   Level: developer
11011a5261eSBarry Smith 
11111a5261eSBarry Smith .seealso: `PetscObject`, `PetscObjectView()`, `PetscOptionsGetViewer()`
1122d747510SLisandro Dalcin @*/
113d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[])
114d71ae5a4SJacob Faibussowitsch {
1152d747510SLisandro Dalcin   PetscViewer       viewer;
1162d747510SLisandro Dalcin   PetscBool         flg;
1172d747510SLisandro Dalcin   static PetscBool  incall = PETSC_FALSE;
1182d747510SLisandro Dalcin   PetscViewerFormat format;
1192d747510SLisandro Dalcin   const char       *prefix;
1202d747510SLisandro Dalcin 
1212d747510SLisandro Dalcin   PetscFunctionBegin;
1222d747510SLisandro Dalcin   if (incall) PetscFunctionReturn(0);
1232d747510SLisandro Dalcin   incall = PETSC_TRUE;
1242d747510SLisandro Dalcin   prefix = bobj ? bobj->prefix : obj->prefix;
1259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg));
1262d747510SLisandro Dalcin   if (flg) {
1279566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, format));
1289566063dSJacob Faibussowitsch     PetscCall(PetscObjectView(obj, viewer));
1299566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
1309566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
1319566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
1322d747510SLisandro Dalcin   }
1332d747510SLisandro Dalcin   incall = PETSC_FALSE;
1342d747510SLisandro Dalcin   PetscFunctionReturn(0);
1352d747510SLisandro Dalcin }
1362d747510SLisandro Dalcin 
137e5c89e4eSSatish Balay /*@C
138251f4c67SDmitry Karpeev    PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type.
139e5c89e4eSSatish Balay 
140e5c89e4eSSatish Balay    Not Collective
141e5c89e4eSSatish Balay 
142e5c89e4eSSatish Balay    Input Parameters:
143811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat or `KSP`.
144811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example,
145811af0c4SBarry Smith          `PetscObjectTypeCompare`((`PetscObject`)mat);
146e5c89e4eSSatish Balay -  type_name - string containing a type name
147e5c89e4eSSatish Balay 
148e5c89e4eSSatish Balay    Output Parameter:
149811af0c4SBarry Smith .  same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE`
150e5c89e4eSSatish Balay 
151e5c89e4eSSatish Balay    Level: intermediate
152e5c89e4eSSatish Balay 
153013e2dc7SBarry Smith .seealso: `PetscObject`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`, `PetscObjectObjectTypeCompare()`
154e5c89e4eSSatish Balay @*/
155d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same)
156d71ae5a4SJacob Faibussowitsch {
157e5c89e4eSSatish Balay   PetscFunctionBegin;
1585f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(same, 3);
159a297a907SKarl Rupp   if (!obj) *same = PETSC_FALSE;
160a297a907SKarl Rupp   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
161a297a907SKarl Rupp   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
162a297a907SKarl Rupp   else {
163e5c89e4eSSatish Balay     PetscValidHeader(obj, 1);
164e5c89e4eSSatish Balay     PetscValidCharPointer(type_name, 2);
1659566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same));
166e5c89e4eSSatish Balay   }
167e5c89e4eSSatish Balay   PetscFunctionReturn(0);
168e5c89e4eSSatish Balay }
169e5c89e4eSSatish Balay 
1702b12f010SJed Brown /*@C
171013e2dc7SBarry Smith    PetscObjectObjectTypeCompare - Determines whether two PETSc objects are of the same type
172013e2dc7SBarry Smith 
173013e2dc7SBarry Smith    Logically Collective
174013e2dc7SBarry Smith 
175013e2dc7SBarry Smith    Input Parameters:
176013e2dc7SBarry Smith +  obj1 - any PETSc object, for example a Vec, Mat or KSP.
177013e2dc7SBarry Smith -  obj2 - anther PETSc object
178013e2dc7SBarry Smith 
179013e2dc7SBarry Smith    Output Parameter:
180013e2dc7SBarry Smith .  same - PETSC_TRUE if they are the same, else PETSC_FALSE
181013e2dc7SBarry Smith 
182013e2dc7SBarry Smith    Level: intermediate
183013e2dc7SBarry Smith 
184013e2dc7SBarry Smith .seealso: `PetscObjectTypeCompare()`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
185013e2dc7SBarry Smith 
186013e2dc7SBarry Smith @*/
187d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectObjectTypeCompare(PetscObject obj1, PetscObject obj2, PetscBool *same)
188d71ae5a4SJacob Faibussowitsch {
189013e2dc7SBarry Smith   PetscFunctionBegin;
190013e2dc7SBarry Smith   PetscValidBoolPointer(same, 3);
191013e2dc7SBarry Smith   PetscValidHeader(obj1, 1);
192013e2dc7SBarry Smith   PetscValidHeader(obj2, 2);
193013e2dc7SBarry Smith   PetscCall(PetscStrcmp((char *)(obj1->type_name), (char *)(obj2->type_name), same));
194013e2dc7SBarry Smith   PetscFunctionReturn(0);
195013e2dc7SBarry Smith }
196013e2dc7SBarry Smith 
197013e2dc7SBarry Smith /*@C
198811af0c4SBarry Smith    PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ`
1994099cc6bSBarry Smith 
2004099cc6bSBarry Smith    Not Collective
2014099cc6bSBarry Smith 
2024099cc6bSBarry Smith    Input Parameters:
2034099cc6bSBarry Smith +  mat - the matrix
2044099cc6bSBarry Smith -  type_name - string containing a type name
2054099cc6bSBarry Smith 
2064099cc6bSBarry Smith    Output Parameter:
207811af0c4SBarry Smith .  same - `PETSC_TRUE` if it is of the same base type
2084099cc6bSBarry Smith 
2094099cc6bSBarry Smith    Level: intermediate
2104099cc6bSBarry Smith 
211811af0c4SBarry Smith .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
2124099cc6bSBarry Smith @*/
213d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same)
214d71ae5a4SJacob Faibussowitsch {
2154099cc6bSBarry Smith   PetscFunctionBegin;
2165f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(same, 3);
2174099cc6bSBarry Smith   if (!obj) *same = PETSC_FALSE;
2184099cc6bSBarry Smith   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
2194099cc6bSBarry Smith   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
2204099cc6bSBarry Smith   else {
2214099cc6bSBarry Smith     PetscValidHeader(obj, 1);
2224099cc6bSBarry Smith     PetscValidCharPointer(type_name, 2);
2239566063dSJacob Faibussowitsch     PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same));
2244099cc6bSBarry Smith   }
2254099cc6bSBarry Smith   PetscFunctionReturn(0);
2264099cc6bSBarry Smith }
2274099cc6bSBarry Smith 
2284099cc6bSBarry Smith /*@C
229251f4c67SDmitry Karpeev    PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.
2302b12f010SJed Brown 
2312b12f010SJed Brown    Not Collective
2322b12f010SJed Brown 
2332b12f010SJed Brown    Input Parameters:
234811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
235811af0c4SBarry Smith          This must be cast with a (`PetscObjec`t), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...);
236811af0c4SBarry Smith -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
2372b12f010SJed Brown 
2382b12f010SJed Brown    Output Parameter:
239811af0c4SBarry Smith .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
2402b12f010SJed Brown 
2412b12f010SJed Brown    Level: intermediate
2422b12f010SJed Brown 
243dee2f2dbSPierre Jolivet .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`
2442b12f010SJed Brown @*/
245d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...)
246d71ae5a4SJacob Faibussowitsch {
2472b12f010SJed Brown   va_list Argp;
2482b12f010SJed Brown 
2492b12f010SJed Brown   PetscFunctionBegin;
2505f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(match, 2);
2512b12f010SJed Brown   *match = PETSC_FALSE;
252f73a99e8SStefano Zampini   if (!obj) PetscFunctionReturn(0);
2532b12f010SJed Brown   va_start(Argp, type_name);
2542b12f010SJed Brown   while (type_name && type_name[0]) {
2552b12f010SJed Brown     PetscBool found;
2569566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare(obj, type_name, &found));
2572b12f010SJed Brown     if (found) {
2582b12f010SJed Brown       *match = PETSC_TRUE;
2592b12f010SJed Brown       break;
2602b12f010SJed Brown     }
2612b12f010SJed Brown     type_name = va_arg(Argp, const char *);
2622b12f010SJed Brown   }
2632b12f010SJed Brown   va_end(Argp);
2642b12f010SJed Brown   PetscFunctionReturn(0);
2652b12f010SJed Brown }
2662b12f010SJed Brown 
267b9e7e5c1SBarry Smith /*@C
268b9e7e5c1SBarry Smith    PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types.
269b9e7e5c1SBarry Smith 
270b9e7e5c1SBarry Smith    Not Collective
271b9e7e5c1SBarry Smith 
272b9e7e5c1SBarry Smith    Input Parameters:
273811af0c4SBarry Smith +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
274811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...);
275811af0c4SBarry Smith -  type_name - array of strings containing type names, pass the empty string "" to terminate the list
276b9e7e5c1SBarry Smith 
277b9e7e5c1SBarry Smith    Output Parameter:
278811af0c4SBarry Smith .  match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE`
279b9e7e5c1SBarry Smith 
280b9e7e5c1SBarry Smith    Level: intermediate
281b9e7e5c1SBarry Smith 
282db781477SPatrick Sanan .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`
283b9e7e5c1SBarry Smith @*/
284d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...)
285d71ae5a4SJacob Faibussowitsch {
286b9e7e5c1SBarry Smith   va_list Argp;
287b9e7e5c1SBarry Smith 
288b9e7e5c1SBarry Smith   PetscFunctionBegin;
2895f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(match, 2);
290b9e7e5c1SBarry Smith   *match = PETSC_FALSE;
291b9e7e5c1SBarry Smith   va_start(Argp, type_name);
292b9e7e5c1SBarry Smith   while (type_name && type_name[0]) {
293b9e7e5c1SBarry Smith     PetscBool found;
2949566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found));
295b9e7e5c1SBarry Smith     if (found) {
296b9e7e5c1SBarry Smith       *match = PETSC_TRUE;
297b9e7e5c1SBarry Smith       break;
298b9e7e5c1SBarry Smith     }
299b9e7e5c1SBarry Smith     type_name = va_arg(Argp, const char *);
300b9e7e5c1SBarry Smith   }
301b9e7e5c1SBarry Smith   va_end(Argp);
302b9e7e5c1SBarry Smith   PetscFunctionReturn(0);
303b9e7e5c1SBarry Smith }
304b9e7e5c1SBarry Smith 
3053cfa8680SLisandro Dalcin #define MAXREGDESOBJS 256
306e5c89e4eSSatish Balay static int         PetscObjectRegisterDestroy_Count = 0;
3073cfa8680SLisandro Dalcin static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];
308e5c89e4eSSatish Balay 
309e5c89e4eSSatish Balay /*@C
310e5c89e4eSSatish Balay    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
311811af0c4SBarry Smith      `PetscFinalize()` is called.
312e5c89e4eSSatish Balay 
313*c3339decSBarry Smith    Logically Collective
314e5c89e4eSSatish Balay 
315e5c89e4eSSatish Balay    Input Parameter:
316811af0c4SBarry Smith .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
317811af0c4SBarry Smith          This must be cast with a (`PetscObject`), for example,
318811af0c4SBarry Smith          `PetscObjectRegisterDestroy`((`PetscObject`)mat);
319e5c89e4eSSatish Balay 
320e5c89e4eSSatish Balay    Level: developer
321e5c89e4eSSatish Balay 
322811af0c4SBarry Smith    Note:
323e5c89e4eSSatish Balay       This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer
324e5c89e4eSSatish Balay     when PETSc ends.
325e5c89e4eSSatish Balay 
326db781477SPatrick Sanan .seealso: `PetscObjectRegisterDestroyAll()`
327e5c89e4eSSatish Balay @*/
328d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj)
329d71ae5a4SJacob Faibussowitsch {
330e5c89e4eSSatish Balay   PetscFunctionBegin;
331e5c89e4eSSatish Balay   PetscValidHeader(obj, 1);
3320e6b6b59SJacob 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__);
3335f80ce2aSJacob Faibussowitsch   PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
334e5c89e4eSSatish Balay   PetscFunctionReturn(0);
335e5c89e4eSSatish Balay }
336e5c89e4eSSatish Balay 
337e5c89e4eSSatish Balay /*@C
338e5c89e4eSSatish Balay    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
339811af0c4SBarry Smith      with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()`
340e5c89e4eSSatish Balay 
341811af0c4SBarry Smith    Logically Collective on the individual `PetscObject`s that are being processed
342e5c89e4eSSatish Balay 
343e5c89e4eSSatish Balay    Level: developer
344e5c89e4eSSatish Balay 
345db781477SPatrick Sanan .seealso: `PetscObjectRegisterDestroy()`
346e5c89e4eSSatish Balay @*/
347d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectRegisterDestroyAll(void)
348d71ae5a4SJacob Faibussowitsch {
349e5c89e4eSSatish Balay   PetscFunctionBegin;
3509566063dSJacob Faibussowitsch   for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i]));
3513cfa8680SLisandro Dalcin   PetscObjectRegisterDestroy_Count = 0;
352e5c89e4eSSatish Balay   PetscFunctionReturn(0);
353e5c89e4eSSatish Balay }
354e5c89e4eSSatish Balay 
355eb8be38cSBarry Smith #define MAXREGFIN 256
356eb8be38cSBarry Smith static int PetscRegisterFinalize_Count = 0;
35700a402e0SLisandro Dalcin static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);
358eb8be38cSBarry Smith 
359eb8be38cSBarry Smith /*@C
360811af0c4SBarry Smith    PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()`
361eb8be38cSBarry Smith 
362eb8be38cSBarry Smith    Not Collective
363eb8be38cSBarry Smith 
364eb8be38cSBarry Smith    Input Parameter:
365eb8be38cSBarry Smith .  PetscErrorCode (*fun)(void) -
366eb8be38cSBarry Smith 
367eb8be38cSBarry Smith    Level: developer
368eb8be38cSBarry Smith 
369811af0c4SBarry Smith    Note:
370811af0c4SBarry Smith       This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called
371eb8be38cSBarry Smith 
372db781477SPatrick Sanan .seealso: `PetscRegisterFinalizeAll()`
373eb8be38cSBarry Smith @*/
374d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void))
375d71ae5a4SJacob Faibussowitsch {
376f4aac215SBarry Smith   PetscFunctionBegin;
3775f80ce2aSJacob Faibussowitsch   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
378aee23540SBarry Smith     if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0);
379f4aac215SBarry Smith   }
3800e6b6b59SJacob 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__);
3815f80ce2aSJacob Faibussowitsch   PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
382eb8be38cSBarry Smith   PetscFunctionReturn(0);
383eb8be38cSBarry Smith }
384eb8be38cSBarry Smith 
385eb8be38cSBarry Smith /*@C
386811af0c4SBarry Smith    PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()`
387eb8be38cSBarry Smith 
388eb8be38cSBarry Smith    Not Collective unless registered functions are collective
389eb8be38cSBarry Smith 
390eb8be38cSBarry Smith    Level: developer
391eb8be38cSBarry Smith 
392db781477SPatrick Sanan .seealso: `PetscRegisterFinalize()`
393eb8be38cSBarry Smith @*/
394d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRegisterFinalizeAll(void)
395d71ae5a4SJacob Faibussowitsch {
396eb8be38cSBarry Smith   PetscFunctionBegin;
3979566063dSJacob Faibussowitsch   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
398eb8be38cSBarry Smith   PetscRegisterFinalize_Count = 0;
399eb8be38cSBarry Smith   PetscFunctionReturn(0);
400eb8be38cSBarry Smith }
401