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 PetscObject 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 @*/ 43 PetscErrorCode PetscObjectDestroy(PetscObject *obj) { 44 PetscFunctionBegin; 45 if (!obj || !*obj) PetscFunctionReturn(0); 46 PetscValidHeader(*obj, 1); 47 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); 48 PetscCall((*(*obj)->bops->destroy)(obj)); 49 PetscFunctionReturn(0); 50 } 51 52 /*@C 53 PetscObjectView - Views any PetscObject, regardless of the type. 54 55 Collective on PetscObject 56 57 Input Parameters: 58 + obj - any PETSc object, for example a Vec, Mat or KSP. 59 This must be cast with a (PetscObject), for example, 60 PetscObjectView((PetscObject)mat,viewer); 61 - viewer - any PETSc viewer 62 63 Level: intermediate 64 65 @*/ 66 PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer) { 67 PetscFunctionBegin; 68 PetscValidHeader(obj, 1); 69 PetscCheck(obj->bops->view, PETSC_COMM_SELF, PETSC_ERR_SUP, "This PETSc object does not have a generic viewer routine"); 70 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(obj->comm, &viewer)); 71 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 72 73 PetscCall((*obj->bops->view)(obj, viewer)); 74 PetscFunctionReturn(0); 75 } 76 77 /*@C 78 PetscObjectViewFromOptions - Processes command line options to determine if/how a PetscObject is to be viewed. 79 80 Collective on PetscObject 81 82 Input Parameters: 83 + obj - the object 84 . bobj - optional other object that provides prefix (if NULL then the prefix in obj is used) 85 - optionname - option string that is used to activate viewing 86 87 Level: intermediate 88 89 @*/ 90 PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[]) { 91 PetscViewer viewer; 92 PetscBool flg; 93 static PetscBool incall = PETSC_FALSE; 94 PetscViewerFormat format; 95 const char *prefix; 96 97 PetscFunctionBegin; 98 if (incall) PetscFunctionReturn(0); 99 incall = PETSC_TRUE; 100 prefix = bobj ? bobj->prefix : obj->prefix; 101 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg)); 102 if (flg) { 103 PetscCall(PetscViewerPushFormat(viewer, format)); 104 PetscCall(PetscObjectView(obj, viewer)); 105 PetscCall(PetscViewerFlush(viewer)); 106 PetscCall(PetscViewerPopFormat(viewer)); 107 PetscCall(PetscViewerDestroy(&viewer)); 108 } 109 incall = PETSC_FALSE; 110 PetscFunctionReturn(0); 111 } 112 113 /*@C 114 PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type. 115 116 Not Collective 117 118 Input Parameters: 119 + obj - any PETSc object, for example a Vec, Mat or KSP. 120 This must be cast with a (PetscObject), for example, 121 PetscObjectTypeCompare((PetscObject)mat); 122 - type_name - string containing a type name 123 124 Output Parameter: 125 . same - PETSC_TRUE if they are the same, else PETSC_FALSE 126 127 Level: intermediate 128 129 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()` 130 131 @*/ 132 PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) { 133 PetscFunctionBegin; 134 PetscValidBoolPointer(same, 3); 135 if (!obj) *same = PETSC_FALSE; 136 else if (!type_name && !obj->type_name) *same = PETSC_TRUE; 137 else if (!type_name || !obj->type_name) *same = PETSC_FALSE; 138 else { 139 PetscValidHeader(obj, 1); 140 PetscValidCharPointer(type_name, 2); 141 PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same)); 142 } 143 PetscFunctionReturn(0); 144 } 145 146 /*@C 147 PetscObjectBaseTypeCompare - Determines whether a PetscObject is of a given base type. For example the base type of MATSEQAIJPERM is MATSEQAIJ 148 149 Not Collective 150 151 Input Parameters: 152 + mat - the matrix 153 - type_name - string containing a type name 154 155 Output Parameter: 156 . same - PETSC_TRUE if it is of the same base type 157 158 Level: intermediate 159 160 .seealso: `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()` 161 162 @*/ 163 PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) { 164 PetscFunctionBegin; 165 PetscValidBoolPointer(same, 3); 166 if (!obj) *same = PETSC_FALSE; 167 else if (!type_name && !obj->type_name) *same = PETSC_TRUE; 168 else if (!type_name || !obj->type_name) *same = PETSC_FALSE; 169 else { 170 PetscValidHeader(obj, 1); 171 PetscValidCharPointer(type_name, 2); 172 PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same)); 173 } 174 PetscFunctionReturn(0); 175 } 176 177 /*@C 178 PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types. 179 180 Not Collective 181 182 Input Parameters: 183 + obj - any PETSc object, for example a Vec, Mat or KSP. 184 This must be cast with a (PetscObject), for example, PetscObjectTypeCompareAny((PetscObject)mat,...); 185 - type_name - string containing a type name, pass the empty string "" to terminate the list 186 187 Output Parameter: 188 . match - PETSC_TRUE if the type of obj matches any in the list, else PETSC_FALSE 189 190 Level: intermediate 191 192 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()` 193 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 - string containing a type name, 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 @*/ 234 PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) { 235 va_list Argp; 236 237 PetscFunctionBegin; 238 PetscValidBoolPointer(match, 2); 239 *match = PETSC_FALSE; 240 va_start(Argp, type_name); 241 while (type_name && type_name[0]) { 242 PetscBool found; 243 PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found)); 244 if (found) { 245 *match = PETSC_TRUE; 246 break; 247 } 248 type_name = va_arg(Argp, const char *); 249 } 250 va_end(Argp); 251 PetscFunctionReturn(0); 252 } 253 254 #define MAXREGDESOBJS 256 255 static int PetscObjectRegisterDestroy_Count = 0; 256 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS]; 257 258 /*@C 259 PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when 260 PetscFinalize() is called. 261 262 Logically Collective on PetscObject 263 264 Input Parameter: 265 . obj - any PETSc object, for example a Vec, Mat or KSP. 266 This must be cast with a (PetscObject), for example, 267 PetscObjectRegisterDestroy((PetscObject)mat); 268 269 Level: developer 270 271 Notes: 272 This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer 273 when PETSc ends. 274 275 .seealso: `PetscObjectRegisterDestroyAll()` 276 @*/ 277 PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj) { 278 PetscFunctionBegin; 279 PetscValidHeader(obj, 1); 280 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__); 281 PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj; 282 PetscFunctionReturn(0); 283 } 284 285 /*@C 286 PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered 287 with PetscObjectRegisterDestroy(). Called by PetscFinalize() 288 289 Logically Collective on individual PetscObjects 290 291 Level: developer 292 293 .seealso: `PetscObjectRegisterDestroy()` 294 @*/ 295 PetscErrorCode PetscObjectRegisterDestroyAll(void) { 296 PetscFunctionBegin; 297 for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i])); 298 PetscObjectRegisterDestroy_Count = 0; 299 PetscFunctionReturn(0); 300 } 301 302 #define MAXREGFIN 256 303 static int PetscRegisterFinalize_Count = 0; 304 static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void); 305 306 /*@C 307 PetscRegisterFinalize - Registers a function that is to be called in PetscFinalize() 308 309 Not Collective 310 311 Input Parameter: 312 . PetscErrorCode (*fun)(void) - 313 314 Level: developer 315 316 Notes: 317 This is used by, for example, DMInitializePackage() to have DMFinalizePackage() called 318 319 .seealso: `PetscRegisterFinalizeAll()` 320 @*/ 321 PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void)) { 322 PetscFunctionBegin; 323 for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) { 324 if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0); 325 } 326 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__); 327 PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f; 328 PetscFunctionReturn(0); 329 } 330 331 /*@C 332 PetscRegisterFinalizeAll - Runs all the finalize functions set with PetscRegisterFinalize() 333 334 Not Collective unless registered functions are collective 335 336 Level: developer 337 338 .seealso: `PetscRegisterFinalize()` 339 @*/ 340 PetscErrorCode PetscRegisterFinalizeAll(void) { 341 PetscFunctionBegin; 342 for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])()); 343 PetscRegisterFinalize_Count = 0; 344 PetscFunctionReturn(0); 345 } 346