1 #define PETSC_DLL 2 /* 3 Provides utility routines for manipulating any type of PETSc object. 4 */ 5 #include "petsc.h" /*I "petsc.h" I*/ 6 #include "petscsys.h" 7 8 EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm *); 9 EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject); 10 EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject *); 11 EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],const char[],void (*)(void)); 12 EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void)); 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "PetscHeaderCreate_Private" 16 /* 17 PetscHeaderCreate_Private - Creates a base PETSc object header and fills 18 in the default values. Called by the macro PetscHeaderCreate(). 19 */ 20 PetscErrorCode PETSC_DLLEXPORT PetscHeaderCreate_Private(PetscObject h,PetscCookie cookie,PetscInt type,const char class_name[],MPI_Comm comm, 21 PetscErrorCode (*des)(PetscObject),PetscErrorCode (*vie)(PetscObject,PetscViewer)) 22 { 23 static PetscInt idcnt = 1; 24 PetscErrorCode ierr; 25 26 PetscFunctionBegin; 27 h->cookie = cookie; 28 h->type = type; 29 h->class_name = (char*)class_name; 30 h->prefix = 0; 31 h->refct = 1; 32 h->amem = -1; 33 h->id = idcnt++; 34 h->parentid = 0; 35 h->qlist = 0; 36 h->olist = 0; 37 h->bops->destroy = des; 38 h->bops->view = vie; 39 h->bops->getcomm = PetscObjectGetComm_Petsc; 40 h->bops->compose = PetscObjectCompose_Petsc; 41 h->bops->query = PetscObjectQuery_Petsc; 42 h->bops->composefunction = PetscObjectComposeFunction_Petsc; 43 h->bops->queryfunction = PetscObjectQueryFunction_Petsc; 44 ierr = PetscCommDuplicate(comm,&h->comm,&h->tag);CHKERRQ(ierr); 45 PetscFunctionReturn(0); 46 } 47 48 extern PetscTruth PetscMemoryCollectMaximumUsage; 49 extern PetscLogDouble PetscMemoryMaximumUsage; 50 51 #undef __FUNCT__ 52 #define __FUNCT__ "PetscHeaderDestroy_Private" 53 /* 54 PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by 55 the macro PetscHeaderDestroy(). 56 */ 57 PetscErrorCode PETSC_DLLEXPORT PetscHeaderDestroy_Private(PetscObject h) 58 { 59 PetscErrorCode ierr; 60 61 PetscFunctionBegin; 62 if (PetscMemoryCollectMaximumUsage) { 63 PetscLogDouble usage; 64 ierr = PetscMemoryGetCurrentUsage(&usage);CHKERRQ(ierr); 65 if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage; 66 } 67 ierr = PetscCommDestroy(&h->comm);CHKERRQ(ierr); 68 ierr = PetscFree(h->bops);CHKERRQ(ierr); 69 ierr = PetscFree(h->ops);CHKERRQ(ierr); 70 ierr = PetscOListDestroy(&h->olist);CHKERRQ(ierr); 71 ierr = PetscFListDestroy(&h->qlist);CHKERRQ(ierr); 72 ierr = PetscStrfree(h->type_name);CHKERRQ(ierr); 73 ierr = PetscStrfree(h->name);CHKERRQ(ierr); 74 h->cookie = PETSCFREEDHEADER; 75 ierr = PetscStrfree(h->prefix);CHKERRQ(ierr); 76 ierr = PetscFree(h->fortran_func_pointers);CHKERRQ(ierr); 77 ierr = PetscFree(h->intcomposeddata);CHKERRQ(ierr); 78 ierr = PetscFree(h->intcomposedstate);CHKERRQ(ierr); 79 ierr = PetscFree(h->realcomposeddata);CHKERRQ(ierr); 80 ierr = PetscFree(h->realcomposedstate);CHKERRQ(ierr); 81 ierr = PetscFree(h->scalarcomposeddata);CHKERRQ(ierr); 82 ierr = PetscFree(h->scalarcomposedstate);CHKERRQ(ierr); 83 PetscFunctionReturn(0); 84 } 85 86 #undef __FUNCT__ 87 #define __FUNCT__ "PetscObjectReference" 88 /*@C 89 PetscObjectReference - Indicates to any PetscObject that it is being 90 referenced by another PetscObject. This increases the reference 91 count for that object by one. 92 93 Collective on PetscObject 94 95 Input Parameter: 96 . obj - the PETSc object. This must be cast with (PetscObject), for example, 97 PetscObjectReference((PetscObject)mat); 98 99 Level: advanced 100 101 .seealso: PetscObjectCompose(), PetscObjectDereference() 102 @*/ 103 PetscErrorCode PETSC_DLLEXPORT PetscObjectReference(PetscObject obj) 104 { 105 PetscFunctionBegin; 106 PetscValidHeader(obj,1); 107 obj->refct++; 108 PetscFunctionReturn(0); 109 } 110 111 #undef __FUNCT__ 112 #define __FUNCT__ "PetscObjectGetReference" 113 /*@C 114 PetscObjectGetReference - Gets the current reference count for 115 any PETSc object. 116 117 Not Collective 118 119 Input Parameter: 120 . obj - the PETSc object; this must be cast with (PetscObject), for example, 121 PetscObjectGetReference((PetscObject)mat,&cnt); 122 123 Output Parameter: 124 . cnt - the reference count 125 126 Level: advanced 127 128 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference() 129 @*/ 130 PetscErrorCode PETSC_DLLEXPORT PetscObjectGetReference(PetscObject obj,PetscInt *cnt) 131 { 132 PetscFunctionBegin; 133 PetscValidHeader(obj,1); 134 PetscValidIntPointer(cnt,2); 135 *cnt = obj->refct; 136 PetscFunctionReturn(0); 137 } 138 139 #undef __FUNCT__ 140 #define __FUNCT__ "PetscObjectDereference" 141 /*@ 142 PetscObjectDereference - Indicates to any PetscObject that it is being 143 referenced by one less PetscObject. This decreases the reference 144 count for that object by one. 145 146 Collective on PetscObject 147 148 Input Parameter: 149 . obj - the PETSc object; this must be cast with (PetscObject), for example, 150 PetscObjectDereference((PetscObject)mat); 151 152 Level: advanced 153 154 .seealso: PetscObjectCompose(), PetscObjectReference() 155 @*/ 156 PetscErrorCode PETSC_DLLEXPORT PetscObjectDereference(PetscObject obj) 157 { 158 PetscErrorCode ierr; 159 160 PetscFunctionBegin; 161 PetscValidHeader(obj,1); 162 if (obj->bops->destroy) { 163 ierr = (*obj->bops->destroy)(obj);CHKERRQ(ierr); 164 } else if (!--obj->refct) { 165 SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine"); 166 } 167 PetscFunctionReturn(0); 168 } 169 170 /* ----------------------------------------------------------------------- */ 171 /* 172 The following routines are the versions private to the PETSc object 173 data structures. 174 */ 175 #undef __FUNCT__ 176 #define __FUNCT__ "PetscObjectGetComm_Petsc" 177 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm) 178 { 179 PetscFunctionBegin; 180 *comm = obj->comm; 181 PetscFunctionReturn(0); 182 } 183 184 #undef __FUNCT__ 185 #define __FUNCT__ "PetscObjectCompose_Petsc" 186 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr) 187 { 188 PetscErrorCode ierr; 189 char *tname; 190 191 PetscFunctionBegin; 192 if (ptr) { 193 ierr = PetscOListReverseFind(ptr->olist,obj,&tname);CHKERRQ(ierr); 194 if (tname){ 195 SETERRQ(PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it"); 196 } 197 } 198 ierr = PetscOListAdd(&obj->olist,name,ptr);CHKERRQ(ierr); 199 PetscFunctionReturn(0); 200 } 201 202 #undef __FUNCT__ 203 #define __FUNCT__ "PetscObjectQuery_Petsc" 204 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr) 205 { 206 PetscErrorCode ierr; 207 208 PetscFunctionBegin; 209 ierr = PetscOListFind(obj->olist,name,ptr);CHKERRQ(ierr); 210 PetscFunctionReturn(0); 211 } 212 213 #undef __FUNCT__ 214 #define __FUNCT__ "PetscObjectComposeFunction_Petsc" 215 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void)) 216 { 217 PetscErrorCode ierr; 218 219 PetscFunctionBegin; 220 ierr = PetscFListAdd(&obj->qlist,name,fname,ptr);CHKERRQ(ierr); 221 PetscFunctionReturn(0); 222 } 223 224 #undef __FUNCT__ 225 #define __FUNCT__ "PetscObjectQueryFunction_Petsc" 226 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void)) 227 { 228 PetscErrorCode ierr; 229 230 PetscFunctionBegin; 231 ierr = PetscFListFind(obj->comm,obj->qlist,name,ptr);CHKERRQ(ierr); 232 PetscFunctionReturn(0); 233 } 234 235 /* 236 These are the versions that are usable to any CCA compliant objects 237 */ 238 #undef __FUNCT__ 239 #define __FUNCT__ "PetscObjectCompose" 240 /*@C 241 PetscObjectCompose - Associates another PETSc object with a given PETSc object. 242 243 Not Collective 244 245 Input Parameters: 246 + obj - the PETSc object; this must be cast with (PetscObject), for example, 247 PetscObjectCompose((PetscObject)mat,...); 248 . name - name associated with the child object 249 - ptr - the other PETSc object to associate with the PETSc object; this must also be 250 cast with (PetscObject) 251 252 Level: advanced 253 254 Notes: 255 The second objects reference count is automatically increased by one when it is 256 composed. 257 258 Replaces any previous object that had the same name. 259 260 If ptr is null and name has previously been composed using an object, then that 261 entry is removed from the obj. 262 263 PetscObjectCompose() can be used with any PETSc object (such as 264 Mat, Vec, KSP, SNES, etc.) or any user-provided object. See 265 PetscObjectContainerCreate() for info on how to create an object from a 266 user-provided pointer that may then be composed with PETSc objects. 267 268 Concepts: objects^composing 269 Concepts: composing objects 270 271 .seealso: PetscObjectQuery(), PetscObjectContainerCreate() 272 @*/ 273 PetscErrorCode PETSC_DLLEXPORT PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr) 274 { 275 PetscErrorCode ierr; 276 277 PetscFunctionBegin; 278 ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr); 279 PetscFunctionReturn(0); 280 } 281 282 #undef __FUNCT__ 283 #define __FUNCT__ "PetscObjectQuery" 284 /*@C 285 PetscObjectQuery - Gets a PETSc object associated with a given object. 286 287 Not Collective 288 289 Input Parameters: 290 + obj - the PETSc object 291 Thus must be cast with a (PetscObject), for example, 292 PetscObjectCompose((PetscObject)mat,...); 293 . name - name associated with child object 294 - ptr - the other PETSc object associated with the PETSc object, this must also be 295 cast with (PetscObject) 296 297 Level: advanced 298 299 Concepts: objects^composing 300 Concepts: composing objects 301 Concepts: objects^querying 302 Concepts: querying objects 303 304 .seealso: PetscObjectQuery() 305 @*/ 306 PetscErrorCode PETSC_DLLEXPORT PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 307 { 308 PetscErrorCode ierr; 309 310 PetscFunctionBegin; 311 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 312 PetscFunctionReturn(0); 313 } 314 315 #undef __FUNCT__ 316 #define __FUNCT__ "PetscObjectComposeFunction" 317 PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void)) 318 { 319 PetscErrorCode ierr; 320 321 PetscFunctionBegin; 322 ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr); 323 PetscFunctionReturn(0); 324 } 325 326 #undef __FUNCT__ 327 #define __FUNCT__ "PetscObjectQueryFunction" 328 /*@C 329 PetscObjectQueryFunction - Gets a function associated with a given object. 330 331 Collective on PetscObject 332 333 Input Parameters: 334 + obj - the PETSc object; this must be cast with (PetscObject), for example, 335 PetscObjectQueryFunction((PetscObject)ksp,...); 336 - name - name associated with the child function 337 338 Output Parameter: 339 . ptr - function pointer 340 341 Level: advanced 342 343 Concepts: objects^composing functions 344 Concepts: composing functions 345 Concepts: functions^querying 346 Concepts: objects^querying 347 Concepts: querying objects 348 349 .seealso: PetscObjectComposeFunctionDynamic() 350 @*/ 351 PetscErrorCode PETSC_DLLEXPORT PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void)) 352 { 353 PetscErrorCode ierr; 354 355 PetscFunctionBegin; 356 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 357 PetscFunctionReturn(0); 358 } 359 360 struct _p_PetscObjectContainer { 361 PETSCHEADER(int); 362 void *ptr; 363 PetscErrorCode (*userdestroy)(void*); 364 }; 365 366 #undef __FUNCT__ 367 #define __FUNCT__ "PetscObjectContainerGetPointer" 368 /*@C 369 PetscObjectContainerGetPointer - Gets the pointer value contained in the container. 370 371 Collective on PetscObjectContainer 372 373 Input Parameter: 374 . obj - the object created with PetscObjectContainerCreate() 375 376 Output Parameter: 377 . ptr - the pointer value 378 379 Level: advanced 380 381 .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(), 382 PetscObjectContainerSetPointer() 383 @*/ 384 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerGetPointer(PetscObjectContainer obj,void **ptr) 385 { 386 PetscFunctionBegin; 387 *ptr = obj->ptr; 388 PetscFunctionReturn(0); 389 } 390 391 392 #undef __FUNCT__ 393 #define __FUNCT__ "PetscObjectContainerSetPointer" 394 /*@C 395 PetscObjectContainerSetPointer - Sets the pointer value contained in the container. 396 397 Collective on PetscObjectContainer 398 399 Input Parameters: 400 + obj - the object created with PetscObjectContainerCreate() 401 - ptr - the pointer value 402 403 Level: advanced 404 405 .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(), 406 PetscObjectContainerGetPointer() 407 @*/ 408 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetPointer(PetscObjectContainer obj,void *ptr) 409 { 410 PetscFunctionBegin; 411 obj->ptr = ptr; 412 PetscFunctionReturn(0); 413 } 414 415 #undef __FUNCT__ 416 #define __FUNCT__ "PetscObjectContainerDestroy" 417 /*@C 418 PetscObjectContainerDestroy - Destroys a PETSc container object. 419 420 Collective on PetscObjectContainer 421 422 Input Parameter: 423 . obj - an object that was created with PetscObjectContainerCreate() 424 425 Level: advanced 426 427 .seealso: PetscObjectContainerCreate() 428 @*/ 429 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerDestroy(PetscObjectContainer obj) 430 { 431 PetscErrorCode ierr; 432 PetscFunctionBegin; 433 if (--obj->refct > 0) PetscFunctionReturn(0); 434 if (obj->userdestroy) (*obj->userdestroy)(obj->ptr); 435 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 436 PetscFunctionReturn(0); 437 } 438 439 #undef __FUNCT__ 440 #define __FUNCT__ "PetscObjectContainerSetUserDestroy" 441 /*@C 442 PetscObjectContainerSetUserDestroy - Sets name of the user destroy function. 443 444 Collective on PetscObjectContainer 445 446 Input Parameter: 447 + obj - an object that was created with PetscObjectContainerCreate() 448 - des - name of the user destroy function 449 450 Level: advanced 451 452 .seealso: PetscObjectContainerDestroy() 453 @*/ 454 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetUserDestroy(PetscObjectContainer obj, PetscErrorCode (*des)(void*)) 455 { 456 PetscFunctionBegin; 457 obj->userdestroy = des; 458 PetscFunctionReturn(0); 459 } 460 461 PetscCookie PETSC_DLLEXPORT CONTAINER_COOKIE = 0; 462 463 #undef __FUNCT__ 464 #define __FUNCT__ "PetscObjectContainerCreate" 465 /*@C 466 PetscObjectContainerCreate - Creates a PETSc object that has room to hold 467 a single pointer. This allows one to attach any type of data (accessible 468 through a pointer) with the PetscObjectCompose() function to a PetscObject. 469 The data item itself is attached by a call to PetscObjectContainerSetPointer. 470 471 Collective on MPI_Comm 472 473 Input Parameters: 474 . comm - MPI communicator that shares the object 475 476 Output Parameters: 477 . container - the container created 478 479 Level: advanced 480 481 .seealso: PetscObjectContainerDestroy(), PetscObjectContainerSetPointer(), PetscObjectContainerGetPointer() 482 @*/ 483 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerCreate(MPI_Comm comm,PetscObjectContainer *container) 484 { 485 PetscErrorCode ierr; 486 PetscObjectContainer contain; 487 488 PetscFunctionBegin; 489 if (!CONTAINER_COOKIE) { 490 ierr = PetscLogClassRegister(&CONTAINER_COOKIE, "Container");CHKERRQ(ierr); 491 } 492 ierr = PetscHeaderCreate(contain,_p_PetscObjectContainer,PetscInt,CONTAINER_COOKIE,0,"container",comm,PetscObjectContainerDestroy,0);CHKERRQ(ierr); 493 *container = contain; 494 PetscFunctionReturn(0); 495 } 496 497 #undef __FUNCT__ 498 #define __FUNCT__ "PetscObjectSetFromOptions" 499 /*@ 500 PetscObjectSetFromOptions - Sets generic parameters from user options. 501 502 Collective on obj 503 504 Input Parameter: 505 . obj - the PetscObjcet 506 507 Options Database Keys: 508 509 Notes: 510 We have no generic options at present, so this does nothing 511 512 Level: beginner 513 514 .keywords: set, options, database 515 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 516 @*/ 517 PetscErrorCode PETSC_DLLEXPORT PetscObjectSetFromOptions(PetscObject obj) 518 { 519 PetscFunctionBegin; 520 if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object"); 521 PetscFunctionReturn(0); 522 } 523 524 #undef __FUNCT__ 525 #define __FUNCT__ "PetscObjectSetUp" 526 /*@ 527 PetscObjectSetUp - Sets up the internal data structures for the later use. 528 529 Collective on PetscObject 530 531 Input Parameters: 532 . obj - the PetscObject 533 534 Notes: 535 This does nothing at present. 536 537 Level: advanced 538 539 .keywords: setup 540 .seealso: PetscObjectDestroy() 541 @*/ 542 PetscErrorCode PETSC_DLLEXPORT PetscObjectSetUp(PetscObject obj) 543 { 544 PetscFunctionBegin; 545 if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object"); 546 PetscFunctionReturn(0); 547 } 548