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