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 { 10 PetscInt i; 11 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(0); 29 } 30 31 /*@ 32 PetscObjectDestroy - Destroys any `PetscObject`, regardless of the type. 33 34 Collective on obj 35 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); 40 41 Level: beginner 42 43 .seealso: `PetscObject` 44 @*/ 45 PetscErrorCode PetscObjectDestroy(PetscObject *obj) 46 { 47 PetscFunctionBegin; 48 if (!obj || !*obj) PetscFunctionReturn(0); 49 PetscValidHeader(*obj, 1); 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(0); 53 } 54 55 /*@C 56 PetscObjectView - Views any `PetscObject`, regardless of the type. 57 58 Collective on obj 59 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 65 66 Level: intermediate 67 68 .seealso: `PetscObject`, `PetscObjectViewFromOptions()` 69 @*/ 70 PetscErrorCode PetscObjectView(PetscObject obj, PetscViewer viewer) 71 { 72 PetscFunctionBegin; 73 PetscValidHeader(obj, 1); 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)); 76 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 77 78 PetscCall((*obj->bops->view)(obj, viewer)); 79 PetscFunctionReturn(0); 80 } 81 82 /*@C 83 PetscObjectViewFromOptions - Processes command line options to determine if/how a `PetscObject` is to be viewed. 84 85 Collective on obj 86 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 91 92 Options Database Key: 93 . -optionname_view [viewertype]:... - option name and values. In actual usage this would be something like -mat_coarse_view 94 95 Notes: 96 .vb 97 If no value is provided ascii:stdout is used 98 ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 99 for example ascii::ascii_info prints just the information about the object not all details 100 unless :append is given filename opens in write mode, overwriting what was already there 101 binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 102 draw[:drawtype[:filename]] for example, draw:tikz, draw:tikz:figure.tex or draw:x 103 socket[:port] defaults to the standard output port 104 saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 105 .ve 106 107 This is not called directly but is called by, for example, `MatCoarseViewFromOptions()` 108 109 Level: developer 110 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; 120 121 PetscFunctionBegin; 122 if (incall) PetscFunctionReturn(0); 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(0); 135 } 136 137 /*@C 138 PetscObjectTypeCompare - Determines whether a PETSc object is of a particular type. 139 140 Not Collective 141 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 147 148 Output Parameter: 149 . same - `PETSC_TRUE` if they are the same, else `PETSC_FALSE` 150 151 Level: intermediate 152 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; 158 PetscValidBoolPointer(same, 3); 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 { 163 PetscValidHeader(obj, 1); 164 PetscValidCharPointer(type_name, 2); 165 PetscCall(PetscStrcmp((char *)(obj->type_name), type_name, same)); 166 } 167 PetscFunctionReturn(0); 168 } 169 170 /*@C 171 PetscObjectObjectTypeCompare - Determines whether two PETSc objects are of the same type 172 173 Logically Collective 174 175 Input Parameters: 176 + obj1 - any PETSc object, for example a Vec, Mat or KSP. 177 - obj2 - anther PETSc object 178 179 Output Parameter: 180 . same - PETSC_TRUE if they are the same, else PETSC_FALSE 181 182 Level: intermediate 183 184 .seealso: `PetscObjectTypeCompare()`, `VecGetType()`, `KSPGetType()`, `PCGetType()`, `SNESGetType()`, `PetscObjectBaseTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()` 185 186 @*/ 187 PetscErrorCode PetscObjectObjectTypeCompare(PetscObject obj1, PetscObject obj2, PetscBool *same) 188 { 189 PetscFunctionBegin; 190 PetscValidBoolPointer(same, 3); 191 PetscValidHeader(obj1, 1); 192 PetscValidHeader(obj2, 2); 193 PetscCall(PetscStrcmp((char *)(obj1->type_name), (char *)(obj2->type_name), same)); 194 PetscFunctionReturn(0); 195 } 196 197 /*@C 198 PetscObjectBaseTypeCompare - Determines whether a `PetscObject` is of a given base type. For example the base type of `MATSEQAIJPERM` is `MATSEQAIJ` 199 200 Not Collective 201 202 Input Parameters: 203 + mat - the matrix 204 - type_name - string containing a type name 205 206 Output Parameter: 207 . same - `PETSC_TRUE` if it is of the same base type 208 209 Level: intermediate 210 211 .seealso: `PetscObject`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`, `PetscObjectBaseTypeCompareAny()` 212 @*/ 213 PetscErrorCode PetscObjectBaseTypeCompare(PetscObject obj, const char type_name[], PetscBool *same) 214 { 215 PetscFunctionBegin; 216 PetscValidBoolPointer(same, 3); 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 { 221 PetscValidHeader(obj, 1); 222 PetscValidCharPointer(type_name, 2); 223 PetscCall(PetscStrbeginswith((char *)(obj->type_name), type_name, same)); 224 } 225 PetscFunctionReturn(0); 226 } 227 228 /*@C 229 PetscObjectTypeCompareAny - Determines whether a PETSc object is of any of a list of types. 230 231 Not Collective 232 233 Input Parameters: 234 + obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. 235 This must be cast with a (`PetscObjec`t), for example, `PetscObjectTypeCompareAny`((`PetscObject`)mat,...); 236 - type_name - array of strings containing type names, pass the empty string "" to terminate the list 237 238 Output Parameter: 239 . match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE` 240 241 Level: intermediate 242 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; 248 249 PetscFunctionBegin; 250 PetscValidBoolPointer(match, 2); 251 *match = PETSC_FALSE; 252 if (!obj) PetscFunctionReturn(0); 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(0); 265 } 266 267 /*@C 268 PetscObjectBaseTypeCompareAny - Determines whether a PETSc object has the base type of any of a list of types. 269 270 Not Collective 271 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 276 277 Output Parameter: 278 . match - `PETSC_TRUE` if the type of obj matches any in the list, else `PETSC_FALSE` 279 280 Level: intermediate 281 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; 287 288 PetscFunctionBegin; 289 PetscValidBoolPointer(match, 2); 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(0); 303 } 304 305 #define MAXREGDESOBJS 256 306 static int PetscObjectRegisterDestroy_Count = 0; 307 static PetscObject PetscObjectRegisterDestroy_Objects[MAXREGDESOBJS]; 308 309 /*@C 310 PetscObjectRegisterDestroy - Registers a PETSc object to be destroyed when 311 `PetscFinalize()` is called. 312 313 Logically Collective on obj 314 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); 319 320 Level: developer 321 322 Note: 323 This is used by, for example, PETSC_VIEWER_XXX_() routines to free the viewer 324 when PETSc ends. 325 326 .seealso: `PetscObjectRegisterDestroyAll()` 327 @*/ 328 PetscErrorCode PetscObjectRegisterDestroy(PetscObject obj) 329 { 330 PetscFunctionBegin; 331 PetscValidHeader(obj, 1); 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(0); 335 } 336 337 /*@C 338 PetscObjectRegisterDestroyAll - Frees all the PETSc objects that have been registered 339 with `PetscObjectRegisterDestroy()`. Called by `PetscFinalize()` 340 341 Logically Collective on the individual `PetscObject`s that are being processed 342 343 Level: developer 344 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(0); 353 } 354 355 #define MAXREGFIN 256 356 static int PetscRegisterFinalize_Count = 0; 357 static PetscErrorCode (*PetscRegisterFinalize_Functions[MAXREGFIN])(void); 358 359 /*@C 360 PetscRegisterFinalize - Registers a function that is to be called in `PetscFinalize()` 361 362 Not Collective 363 364 Input Parameter: 365 . PetscErrorCode (*fun)(void) - 366 367 Level: developer 368 369 Note: 370 This is used by, for example, `DMInitializePackage()` to have `DMFinalizePackage()` called 371 372 .seealso: `PetscRegisterFinalizeAll()` 373 @*/ 374 PetscErrorCode PetscRegisterFinalize(PetscErrorCode (*f)(void)) 375 { 376 PetscFunctionBegin; 377 for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) { 378 if (f == PetscRegisterFinalize_Functions[i]) PetscFunctionReturn(0); 379 } 380 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__); 381 PetscRegisterFinalize_Functions[PetscRegisterFinalize_Count++] = f; 382 PetscFunctionReturn(0); 383 } 384 385 /*@C 386 PetscRegisterFinalizeAll - Runs all the finalize functions set with `PetscRegisterFinalize()` 387 388 Not Collective unless registered functions are collective 389 390 Level: developer 391 392 .seealso: `PetscRegisterFinalize()` 393 @*/ 394 PetscErrorCode PetscRegisterFinalizeAll(void) 395 { 396 PetscFunctionBegin; 397 for (PetscInt i = 0; i < PetscRegisterFinalize_Count; i++) PetscCall((*PetscRegisterFinalize_Functions[i])()); 398 PetscRegisterFinalize_Count = 0; 399 PetscFunctionReturn(0); 400 } 401