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 Options Database Key: 90 . -optionname_view [viewertype]:... - option name and values. In actual usage this would be something like -mat_coarse_view 91 92 Notes: 93 .vb 94 If no value is provided ascii:stdout is used 95 ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 96 for example ascii::ascii_info prints just the information about the object not all details 97 unless :append is given filename opens in write mode, overwriting what was already there 98 binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 99 draw[:drawtype[:filename]] for example, draw:tikz, draw:tikz:figure.tex or draw:x 100 socket[:port] defaults to the standard output port 101 saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 102 .ve 103 104 This is not called directly but is called by, for example, `MatCoarseViewFromOptions()` 105 106 Level: developer 107 108 .seealso: `PetscObject`, `PetscObjectView()`, `PetscOptionsGetViewer()` 109 @*/ 110 PetscErrorCode PetscObjectViewFromOptions(PetscObject obj, PetscObject bobj, const char optionname[]) { 111 PetscViewer viewer; 112 PetscBool flg; 113 static PetscBool incall = PETSC_FALSE; 114 PetscViewerFormat format; 115 const char *prefix; 116 117 PetscFunctionBegin; 118 if (incall) PetscFunctionReturn(0); 119 incall = PETSC_TRUE; 120 prefix = bobj ? bobj->prefix : obj->prefix; 121 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), obj->options, prefix, optionname, &viewer, &format, &flg)); 122 if (flg) { 123 PetscCall(PetscViewerPushFormat(viewer, format)); 124 PetscCall(PetscObjectView(obj, viewer)); 125 PetscCall(PetscViewerFlush(viewer)); 126 PetscCall(PetscViewerPopFormat(viewer)); 127 PetscCall(PetscViewerDestroy(&viewer)); 128 } 129 incall = PETSC_FALSE; 130 PetscFunctionReturn(0); 131 } 132 133 /*@C 134 PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type. 135 136 Not Collective 137 138 Input Parameters: 139 + obj - any PETSc object, for example a `Vec`, `Mat or `KSP`. 140 This must be cast with a (`PetscObject`), for example, 141 `PetscObjectTypeCompare`((`PetscObject`)mat); 142 - type_name - string containing a type name 143 144 Output Parameter: 145 . same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE` 146 147 Level: intermediate 148 149 .seealso: `PetscObject`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()`, `PetscObjectObjectTypeCompare()` 150 @*/ 151 PetscErrorCode PetscObjectTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) { 152 PetscFunctionBegin; 153 PetscValidBoolPointer(same, 3); 154 if (!obj) *same = PETSC_FALSE; 155 else if (!type_name && !obj->type_name) *same = PETSC_TRUE; 156 else if (!type_name || !obj->type_name) *same = PETSC_FALSE; 157 else { 158 PetscValidHeader(obj, 1); 159 PetscValidCharPointer(type_name, 2); 160 PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same)); 161 } 162 PetscFunctionReturn(0); 163 } 164 165 /*@C 166 PetscObjectObjectTypeCompare - Determines whether two PETSc objects are of the same type 167 168 Logically Collective 169 170 Input Parameters: 171 + obj1 - any PETSc object, for example a Vec, Mat or KSP. 172 - obj2 - anther PETSc object 173 174 Output Parameter: 175 . same - PETSC_TRUE if they are the same, else PETSC_FALSE 176 177 Level: intermediate 178 179 .seealso: `PetscObjectTypeCompare()`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()` 180 181 @*/ 182 PetscErrorCode PetscObjectObjectTypeCompare(PetscObject obj1, PetscObject obj2, PetscBool *same) { 183 PetscFunctionBegin; 184 PetscValidBoolPointer(same, 3); 185 PetscValidHeader(obj1, 1); 186 PetscValidHeader(obj2, 2); 187 PetscCall(PetscStrcmp((char *)(obj1->type_name), (char *)(obj2->type_name), same)); 188 PetscFunctionReturn(0); 189 } 190 191 /*@C 192 PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ` 193 194 Not Collective 195 196 Input Parameters: 197 + mat - the matrix 198 - type_name - string containing a type name 199 200 Output Parameter: 201 . same - `PETSC_TRUE` if it is of the same base type 202 203 Level: intermediate 204 205 .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()` 206 @*/ 207 PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) { 208 PetscFunctionBegin; 209 PetscValidBoolPointer(same, 3); 210 if (!obj) *same = PETSC_FALSE; 211 else if (!type_name && !obj->type_name) *same = PETSC_TRUE; 212 else if (!type_name || !obj->type_name) *same = PETSC_FALSE; 213 else { 214 PetscValidHeader(obj, 1); 215 PetscValidCharPointer(type_name, 2); 216 PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same)); 217 } 218 PetscFunctionReturn(0); 219 } 220 221 /*@C 222 PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types. 223 224 Not Collective 225 226 Input Parameters: 227 + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. 228 This must be cast with a (`PetscObjec`t), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...); 229 - type_name - array of strings containing type names, pass the empty string "" to terminate the list 230 231 Output Parameter: 232 . match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE` 233 234 Level: intermediate 235 236 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()` 237 @*/ 238 PetscErrorCode PetscObjectTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) { 239 va_list Argp; 240 241 PetscFunctionBegin; 242 PetscValidBoolPointer(match, 2); 243 *match = PETSC_FALSE; 244 if (!obj) PetscFunctionReturn(0); 245 va_start(Argp, type_name); 246 while (type_name && type_name[0]) { 247 PetscBool found; 248 PetscCall(PetscObjectTypeCompare(obj, type_name, &found)); 249 if (found) { 250 *match = PETSC_TRUE; 251 break; 252 } 253 type_name = va_arg(Argp, const char *); 254 } 255 va_end(Argp); 256 PetscFunctionReturn(0); 257 } 258 259 /*@C 260 PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types. 261 262 Not Collective 263 264 Input Parameters: 265 + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. 266 This must be cast with a (`PetscObject`), for example, `PetscObjectBaseTypeCompareAny`((`PetscObject`)mat,...); 267 - type_name - array of strings containing type names, pass the empty string "" to terminate the list 268 269 Output Parameter: 270 . match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE` 271 272 Level: intermediate 273 274 .seealso: `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectTypeCompare()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()` 275 @*/ 276 PetscErrorCode PetscObjectBaseTypeCompareAny(PetscObject obj, PetscBool *match, const char type_name[], ...) { 277 va_list Argp; 278 279 PetscFunctionBegin; 280 PetscValidBoolPointer(match, 2); 281 *match = PETSC_FALSE; 282 va_start(Argp, type_name); 283 while (type_name && type_name[0]) { 284 PetscBool found; 285 PetscCall(PetscObjectBaseTypeCompare(obj, type_name, &found)); 286 if (found) { 287 *match = PETSC_TRUE; 288 break; 289 } 290 type_name = va_arg(Argp, const char *); 291 } 292 va_end(Argp); 293 PetscFunctionReturn(0); 294 } 295 296 #define MAXREGDESOBJS 256 297 static int PetscObjectRegisterDestroy_Count = 0; 298 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS]; 299 300 /*@C 301 PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when 302 `PetscFinalize()` is called. 303 304 Logically Collective on obj 305 306 Input Parameter: 307 . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. 308 This must be cast with a (`PetscObject`), for example, 309 `PetscObjectRegisterDestroy`((`PetscObject`)mat); 310 311 Level: developer 312 313 Note: 314 This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer 315 when PETSc ends. 316 317 .seealso: `PetscObjectRegisterDestroyAll()` 318 @*/ 319 PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj) { 320 PetscFunctionBegin; 321 PetscValidHeader(obj, 1); 322 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__); 323 PetscObjectRegisterDestroy_Objects[PetscObjectRegisterDestroy_Count++] = obj; 324 PetscFunctionReturn(0); 325 } 326 327 /*@C 328 PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered 329 with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()` 330 331 Logically Collective on the individual `PetscObject`s that are being processed 332 333 Level: developer 334 335 .seealso: `PetscObjectRegisterDestroy()` 336 @*/ 337 PetscErrorCode PetscObjectRegisterDestroyAll(void) { 338 PetscFunctionBegin; 339 for (PetscInt i = 0; i < PetscObjectRegisterDestroy_Count; i++) PetscCall(PetscObjectDestroy(&PetscObjectRegisterDestroy_Objects[i])); 340 PetscObjectRegisterDestroy_Count = 0; 341 PetscFunctionReturn(0); 342 } 343 344 #define MAXREGFIN 256 345 static int PetscRegisterFinalize_Count = 0; 346 static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void); 347 348 /*@C 349 PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()` 350 351 Not Collective 352 353 Input Parameter: 354 . PetscErrorCode (*fun)(void) - 355 356 Level: developer 357 358 Note: 359 This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called 360 361 .seealso: `PetscRegisterFinalizeAll()` 362 @*/ 363 PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void)) { 364 PetscFunctionBegin; 365 for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) { 366 if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0); 367 } 368 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__); 369 PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f; 370 PetscFunctionReturn(0); 371 } 372 373 /*@C 374 PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()` 375 376 Not Collective unless registered functions are collective 377 378 Level: developer 379 380 .seealso: `PetscRegisterFinalize()` 381 @*/ 382 PetscErrorCode PetscRegisterFinalizeAll(void) { 383 PetscFunctionBegin; 384 for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])()); 385 PetscRegisterFinalize_Count = 0; 386 PetscFunctionReturn(0); 387 } 388