Actual source code: destroy.c


  2: /*
  3:      Provides utility routines for manulating any type of PETSc object.
  4: */
  5: #include <petsc/private/petscimpl.h>
  6: #include <petscviewer.h>

  8: PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj)
  9: {
 10:   PetscInt i;

 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(PETSC_SUCCESS);
 29: }

 31: /*@
 32:    PetscObjectDestroy - Destroys any `PetscObject`, regardless of the type.

 34:    Collective

 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);

 41:    Level: beginner

 43: .seealso: `PetscObject`
 44: @*/
 45: PetscErrorCode PetscObjectDestroy(PetscObject *obj)
 46: {
 47:   PetscFunctionBegin;
 48:   if (!obj || !*obj) PetscFunctionReturn(PETSC_SUCCESS);
 50:   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);
 51:   PetscCall((*(*obj)->bops->destroy)(obj));
 52:   PetscFunctionReturn(PETSC_SUCCESS);
 53: }

 55: /*@C
 56:    PetscObjectView - Views any `PetscObject`, regardless of the type.

 58:    Collective

 60:    Input Parameters:
 61: +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
 62:          This must be cast with a (`PetscObject`), for example,
 63:          `PetscObjectView`((`PetscObject`)mat,viewer);
 64: -  viewer - any PETSc viewer

 66:    Level: intermediate

 68: .seealso: `PetscObject`, `PetscObjectViewFromOptions()`
 69: @*/
 70: PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer)
 71: {
 72:   PetscFunctionBegin;
 74:   PetscCheck(obj->bops->view, PETSC_COMM_SELF, PETSC_ERR_SUP, "This PETSc object does not have a generic viewer routine");
 75:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(obj->comm, &viewer));

 78:   PetscCall((*obj->bops->view)(obj, viewer));
 79:   PetscFunctionReturn(PETSC_SUCCESS);
 80: }

 82: /*@C
 83:   PetscObjectViewFromOptions - Processes command line options to determine if/how a `PetscObject` is to be viewed.

 85:   Collective

 87:   Input Parameters:
 88: + obj   - the object
 89: . bobj  - optional other object that provides prefix (if `NULL` then the prefix in `obj` is used)
 90: - optionname - option string that is used to activate viewing

 92:   Options Database Key:
 93: .  -optionname_view [viewertype]:... - option name and values. In actual usage this would be something like `-mat_coarse_view`

 95:   Level: developer

 97:  Notes:
 98: .vb
 99:     If no value is provided ascii:stdout is used
100:        ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
101:                                                   for example ascii::ascii_info prints just the information about the object not all details
102:                                                   unless :append is given filename opens in write mode, overwriting what was already there
103:        binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
104:        draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
105:        socket[:port]                             defaults to the standard output port
106:        saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)
107: .ve

109:   This is not called directly but is called by, for example, `MatViewFromOptions()`

111: .seealso: `PetscObject`, `PetscObjectView()`, `PetscOptionsGetViewer()`
112: @*/
113: PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[])
114: {
115:   PetscViewer       viewer;
116:   PetscBool         flg;
117:   static PetscBool  incall = PETSC_FALSE;
118:   PetscViewerFormat format;
119:   const char       *prefix;

121:   PetscFunctionBegin;
122:   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
123:   incall = PETSC_TRUE;
124:   prefix = bobj ? bobj->prefix : obj->prefix;
125:   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg));
126:   if (flg) {
127:     PetscCall(PetscViewerPushFormat(viewer, format));
128:     PetscCall(PetscObjectView(obj, viewer));
129:     PetscCall(PetscViewerFlush(viewer));
130:     PetscCall(PetscViewerPopFormat(viewer));
131:     PetscCall(PetscViewerDestroy(&viewer));
132:   }
133:   incall = PETSC_FALSE;
134:   PetscFunctionReturn(PETSC_SUCCESS);
135: }

137: /*@C
138:    PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type.

140:    Not Collective

142:    Input Parameters:
143: +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
144:          This must be cast with a (`PetscObject`), for example,
145:          `PetscObjectTypeCompare`((`PetscObject`)mat);
146: -  type_name - string containing a type name

148:    Output Parameter:
149: .  same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE`

151:    Level: intermediate

153: .seealso: `PetscObject`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`, `PetscObjectObjectTypeCompare()`
154: @*/
155: PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same)
156: {
157:   PetscFunctionBegin;
159:   if (!obj) *same = PETSC_FALSE;
160:   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
161:   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
162:   else {
165:     PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same));
166:   }
167:   PetscFunctionReturn(PETSC_SUCCESS);
168: }

170: /*@C
171:    PetscObjectObjectTypeCompare - Determines whether two PETSc objects are of the same type

173:    Logically Collective

175:    Input Parameters:
176: +  obj1 - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
177: -  obj2 - another PETSc object

179:    Output Parameter:
180: .  same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE`

182:    Level: intermediate

184: .seealso: `PetscObjectTypeCompare()`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`

186: @*/
187: PetscErrorCode PetscObjectObjectTypeCompare(PetscObject obj1, PetscObject obj2, PetscBool *same)
188: {
189:   PetscFunctionBegin;
193:   PetscCall(PetscStrcmp((char *)(obj1->type_name), (char *)(obj2->type_name), same));
194:   PetscFunctionReturn(PETSC_SUCCESS);
195: }

197: /*@C
198:    PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ`

200:    Not Collective

202:    Input Parameters:
203: +  mat - the matrix
204: -  type_name - string containing a type name

206:    Output Parameter:
207: .  same - `PETSC_TRUE` if it is of the same base type

209:    Level: intermediate

211: .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`
212: @*/
213: PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same)
214: {
215:   PetscFunctionBegin;
217:   if (!obj) *same = PETSC_FALSE;
218:   else if (!type_name && !obj->type_name) *same = PETSC_TRUE;
219:   else if (!type_name || !obj->type_name) *same = PETSC_FALSE;
220:   else {
223:     PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same));
224:   }
225:   PetscFunctionReturn(PETSC_SUCCESS);
226: }

228: /*@C
229:    PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types.

231:    Not Collective

233:    Input Parameters:
234: +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
235:          This must be cast with a (`PetscObject`), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...);
236: -  type_name - array of strings containing type names, pass the empty string "" to terminate the list

238:    Output Parameter:
239: .  match - `PETSC_TRUE` if the type of `obj` matches any in the list, else `PETSC_FALSE`

241:    Level: intermediate

243: .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`
244: @*/
245: PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...)
246: {
247:   va_list Argp;

249:   PetscFunctionBegin;
251:   *match = PETSC_FALSE;
252:   if (!obj) PetscFunctionReturn(PETSC_SUCCESS);
253:   va_start(Argp, type_name);
254:   while (type_name && type_name[0]) {
255:     PetscBool found;
256:     PetscCall(PetscObjectTypeCompare(obj, type_name, &found));
257:     if (found) {
258:       *match = PETSC_TRUE;
259:       break;
260:     }
261:     type_name = va_arg(Argp, const char *);
262:   }
263:   va_end(Argp);
264:   PetscFunctionReturn(PETSC_SUCCESS);
265: }

267: /*@C
268:    PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types.

270:    Not Collective

272:    Input Parameters:
273: +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
274:          This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...);
275: -  type_name - array of strings containing type names, pass the empty string "" to terminate the list

277:    Output Parameter:
278: .  match - `PETSC_TRUE` if the type of `obj` matches any in the list, else `PETSC_FALSE`

280:    Level: intermediate

282: .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`
283: @*/
284: PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...)
285: {
286:   va_list Argp;

288:   PetscFunctionBegin;
290:   *match = PETSC_FALSE;
291:   va_start(Argp, type_name);
292:   while (type_name && type_name[0]) {
293:     PetscBool found;
294:     PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found));
295:     if (found) {
296:       *match = PETSC_TRUE;
297:       break;
298:     }
299:     type_name = va_arg(Argp, const char *);
300:   }
301:   va_end(Argp);
302:   PetscFunctionReturn(PETSC_SUCCESS);
303: }

305: #define MAXREGDESOBJS 256
306: static int         PetscObjectRegisterDestroy_Count = 0;
307: static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS];

309: /*@C
310:    PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when
311:      `PetscFinalize()` is called.

313:    Logically Collective

315:    Input Parameter:
316: .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`.
317:          This must be cast with a (`PetscObject`), for example,
318:          `PetscObjectRegisterDestroy`((`PetscObject`)mat);

320:    Level: developer

322:    Note:
323:       This is used by, for example, `PETSC_VIEWER_XXX_()` routines to free the viewer
324:     when PETSc ends.

326: .seealso: `PetscObjectRegisterDestroyAll()`
327: @*/
328: PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj)
329: {
330:   PetscFunctionBegin;
332:   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__);
333:   PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj;
334:   PetscFunctionReturn(PETSC_SUCCESS);
335: }

337: /*@C
338:    PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered
339:      with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()`

341:    Logically Collective on the individual `PetscObject`s that are being processed

343:    Level: developer

345: .seealso: `PetscObjectRegisterDestroy()`
346: @*/
347: PetscErrorCode PetscObjectRegisterDestroyAll(void)
348: {
349:   PetscFunctionBegin;
350:   for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i]));
351:   PetscObjectRegisterDestroy_Count = 0;
352:   PetscFunctionReturn(PETSC_SUCCESS);
353: }

355: #define MAXREGFIN 256
356: static int PetscRegisterFinalize_Count = 0;
357: static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void);

359: /*@C
360:    PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()`

362:    Not Collective

364:    Input Parameter:
365: .  PetscErrorCode (*fun)(void) - function to be called

367:    Level: developer

369:    Notes:
370:   This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called

372:   Use `PetscObjectRegisterDestroy()` to register the destruction of an object in `PetscFinalize()`

374: .seealso: `PetscRegisterFinalizeAll()`, `PetscObjectRegisterDestroy()`
375: @*/
376: PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void))
377: {
378:   PetscFunctionBegin;
379:   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) {
380:     if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(PETSC_SUCCESS);
381:   }
382:   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__);
383:   PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f;
384:   PetscFunctionReturn(PETSC_SUCCESS);
385: }

387: /*@C
388:    PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()`

390:    Not Collective unless registered functions are collective

392:    Level: developer

394: .seealso: `PetscRegisterFinalize()`, `PetscObjectRegisterDestroyAll()`
395: @*/
396: PetscErrorCode PetscRegisterFinalizeAll(void)
397: {
398:   PetscFunctionBegin;
399:   for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])());
400:   PetscRegisterFinalize_Count = 0;
401:   PetscFunctionReturn(PETSC_SUCCESS);
402: }