1 2 /* 3 Provides utility routines for manulating any type of PETSc object. 4 */ 5 #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 6 #include <petscviewer.h> 7 8 PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj) { 9 PetscInt i; 10 11 PetscFunctionBegin; 12 if (obj->intstar_idmax > 0) { 13 for (i = 0; i < obj->intstar_idmax; i++) PetscCall(PetscFree(obj->intstarcomposeddata[i])); 14 PetscCall(PetscFree2(obj->intstarcomposeddata, obj->intstarcomposedstate)); 15 } 16 if (obj->realstar_idmax > 0) { 17 for (i = 0; i < obj->realstar_idmax; i++) PetscCall(PetscFree(obj->realstarcomposeddata[i])); 18 PetscCall(PetscFree2(obj->realstarcomposeddata, obj->realstarcomposedstate)); 19 } 20 if (obj->scalarstar_idmax > 0) { 21 for (i = 0; i < obj->scalarstar_idmax; i++) PetscCall(PetscFree(obj->scalarstarcomposeddata[i])); 22 PetscCall(PetscFree2(obj->scalarstarcomposeddata, obj->scalarstarcomposedstate)); 23 } 24 PetscCall(PetscFree2(obj->intcomposeddata, obj->intcomposedstate)); 25 PetscCall(PetscFree2(obj->realcomposeddata, obj->realcomposedstate)); 26 PetscCall(PetscFree2(obj->scalarcomposeddata, obj->scalarcomposedstate)); 27 PetscFunctionReturn(0); 28 } 29 30 /*@ 31 PetscObjectDestroy - Destroys any `PetscObject`, regardless of the type. 32 33 Collective on obj 34 35 Input Parameter: 36 . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. 37 This must be cast with a (`PetscObject`*), for example, 38 `PetscObjectDestroy`((`PetscObject`*)&mat); 39 40 Level: beginner 41 42 .seealso: `PetscObject` 43 @*/ 44 PetscErrorCode PetscObjectDestroy(PetscObject *obj) { 45 PetscFunctionBegin; 46 if (!obj || !*obj) PetscFunctionReturn(0); 47 PetscValidHeader(*obj, 1); 48 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); 49 PetscCall((*(*obj)->bops->destroy)(obj)); 50 PetscFunctionReturn(0); 51 } 52 53 /*@C 54 PetscObjectView - Views any `PetscObject`, regardless of the type. 55 56 Collective on obj 57 58 Input Parameters: 59 + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. 60 This must be cast with a (`PetscObject`), for example, 61 `PetscObjectView`((`PetscObject`)mat,viewer); 62 - viewer - any PETSc viewer 63 64 Level: intermediate 65 66 .seealso: `PetscObject`, `PetscObjectViewFromOptions()` 67 @*/ 68 PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer) { 69 PetscFunctionBegin; 70 PetscValidHeader(obj, 1); 71 PetscCheck(obj->bops->view, PETSC_COMM_SELF, PETSC_ERR_SUP, "This PETSc object does not have a generic viewer routine"); 72 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(obj->comm, &viewer)); 73 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 74 75 PetscCall((*obj->bops->view)(obj, viewer)); 76 PetscFunctionReturn(0); 77 } 78 79 /*@C 80 PetscObjectViewFromOptions - Processes command line options to determine if/how a `PetscObject` is to be viewed. 81 82 Collective on obj 83 84 Input Parameters: 85 + obj - the object 86 . bobj - optional other object that provides prefix (if NULL then the prefix in obj is used) 87 - optionname - option string that is used to activate viewing 88 89 Level: intermediate 90 91 .seealso: `PetscObject`, `PetscObjectView()` 92 @*/ 93 PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[]) { 94 PetscViewer viewer; 95 PetscBool flg; 96 static PetscBool incall = PETSC_FALSE; 97 PetscViewerFormat format; 98 const char *prefix; 99 100 PetscFunctionBegin; 101 if (incall) PetscFunctionReturn(0); 102 incall = PETSC_TRUE; 103 prefix = bobj ? bobj->prefix : obj->prefix; 104 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg)); 105 if (flg) { 106 PetscCall(PetscViewerPushFormat(viewer, format)); 107 PetscCall(PetscObjectView(obj, viewer)); 108 PetscCall(PetscViewerFlush(viewer)); 109 PetscCall(PetscViewerPopFormat(viewer)); 110 PetscCall(PetscViewerDestroy(&viewer)); 111 } 112 incall = PETSC_FALSE; 113 PetscFunctionReturn(0); 114 } 115 116 /*@C 117 PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type. 118 119 Not Collective 120 121 Input Parameters: 122 + obj - any PETSc object, for example a `Vec`, `Mat or `KSP`. 123 This must be cast with a (`PetscObject`), for example, 124 `PetscObjectTypeCompare`((`PetscObject`)mat); 125 - type_name - string containing a type name 126 127 Output Parameter: 128 . same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE` 129 130 Level: intermediate 131 132 .seealso: `PetscObject`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()` 133 @*/ 134 PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) { 135 PetscFunctionBegin; 136 PetscValidBoolPointer(same, 3); 137 if (!obj) *same = PETSC_FALSE; 138 else if (!type_name && !obj->type_name) *same = PETSC_TRUE; 139 else if (!type_name || !obj->type_name) *same = PETSC_FALSE; 140 else { 141 PetscValidHeader(obj, 1); 142 PetscValidCharPointer(type_name, 2); 143 PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same)); 144 } 145 PetscFunctionReturn(0); 146 } 147 148 /*@C 149 PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ` 150 151 Not Collective 152 153 Input Parameters: 154 + mat - the matrix 155 - type_name - string containing a type name 156 157 Output Parameter: 158 . same - `PETSC_TRUE` if it is of the same base type 159 160 Level: intermediate 161 162 .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()` 163 @*/ 164 PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) { 165 PetscFunctionBegin; 166 PetscValidBoolPointer(same, 3); 167 if (!obj) *same = PETSC_FALSE; 168 else if (!type_name && !obj->type_name) *same = PETSC_TRUE; 169 else if (!type_name || !obj->type_name) *same = PETSC_FALSE; 170 else { 171 PetscValidHeader(obj, 1); 172 PetscValidCharPointer(type_name, 2); 173 PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same)); 174 } 175 PetscFunctionReturn(0); 176 } 177 178 /*@C 179 PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types. 180 181 Not Collective 182 183 Input Parameters: 184 + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. 185 This must be cast with a (`PetscObjec`t), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...); 186 - type_name - array of strings containing type names, pass the empty string "" to terminate the list 187 188 Output Parameter: 189 . match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE` 190 191 Level: intermediate 192 193 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()` 194 @*/ 195 PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) { 196 va_list Argp; 197 198 PetscFunctionBegin; 199 PetscValidBoolPointer(match, 2); 200 *match = PETSC_FALSE; 201 if (!obj) PetscFunctionReturn(0); 202 va_start(Argp, type_name); 203 while (type_name && type_name[0]) { 204 PetscBool found; 205 PetscCall(PetscObjectTypeCompare(obj, type_name, &found)); 206 if (found) { 207 *match = PETSC_TRUE; 208 break; 209 } 210 type_name = va_arg(Argp, const char *); 211 } 212 va_end(Argp); 213 PetscFunctionReturn(0); 214 } 215 216 /*@C 217 PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types. 218 219 Not Collective 220 221 Input Parameters: 222 + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. 223 This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...); 224 - type_name - array of strings containing type names, pass the empty string "" to terminate the list 225 226 Output Parameter: 227 . match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE` 228 229 Level: intermediate 230 231 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()` 232 @*/ 233 PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) { 234 va_list Argp; 235 236 PetscFunctionBegin; 237 PetscValidBoolPointer(match, 2); 238 *match = PETSC_FALSE; 239 va_start(Argp, type_name); 240 while (type_name && type_name[0]) { 241 PetscBool found; 242 PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found)); 243 if (found) { 244 *match = PETSC_TRUE; 245 break; 246 } 247 type_name = va_arg(Argp, const char *); 248 } 249 va_end(Argp); 250 PetscFunctionReturn(0); 251 } 252 253 #define MAXREGDESOBJS 256 254 static int PetscObjectRegisterDestroy_Count = 0; 255 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS]; 256 257 /*@C 258 PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when 259 `PetscFinalize()` is called. 260 261 Logically Collective on obj 262 263 Input Parameter: 264 . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. 265 This must be cast with a (`PetscObject`), for example, 266 `PetscObjectRegisterDestroy`((`PetscObject`)mat); 267 268 Level: developer 269 270 Note: 271 This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer 272 when PETSc ends. 273 274 .seealso: `PetscObjectRegisterDestroyAll()` 275 @*/ 276 PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj) { 277 PetscFunctionBegin; 278 PetscValidHeader(obj, 1); 279 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__); 280 PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj; 281 PetscFunctionReturn(0); 282 } 283 284 /*@C 285 PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered 286 with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()` 287 288 Logically Collective on the individual `PetscObject`s that are being processed 289 290 Level: developer 291 292 .seealso: `PetscObjectRegisterDestroy()` 293 @*/ 294 PetscErrorCode PetscObjectRegisterDestroyAll(void) { 295 PetscFunctionBegin; 296 for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i])); 297 PetscObjectRegisterDestroy_Count = 0; 298 PetscFunctionReturn(0); 299 } 300 301 #define MAXREGFIN 256 302 static int PetscRegisterFinalize_Count = 0; 303 static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void); 304 305 /*@C 306 PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()` 307 308 Not Collective 309 310 Input Parameter: 311 . PetscErrorCode (*fun)(void) - 312 313 Level: developer 314 315 Note: 316 This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called 317 318 .seealso: `PetscRegisterFinalizeAll()` 319 @*/ 320 PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void)) { 321 PetscFunctionBegin; 322 for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) { 323 if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0); 324 } 325 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__); 326 PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f; 327 PetscFunctionReturn(0); 328 } 329 330 /*@C 331 PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()` 332 333 Not Collective unless registered functions are collective 334 335 Level: developer 336 337 .seealso: `PetscRegisterFinalize()` 338 @*/ 339 PetscErrorCode PetscRegisterFinalizeAll(void) { 340 PetscFunctionBegin; 341 for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])()); 342 PetscRegisterFinalize_Count = 0; 343 PetscFunctionReturn(0); 344 } 345