1 2 /* 3 Provides utility routines for manipulating any type of PETSc object. 4 */ 5 #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 6 #include <petscviewer.h> 7 8 #if defined(PETSC_USE_LOG) 9 PetscObject *PetscObjects = 0; 10 PetscInt PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0; 11 PetscBool PetscObjectsLog = PETSC_FALSE; 12 #endif 13 14 extern PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*); 15 extern PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject); 16 extern PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*); 17 extern PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],void (*)(void)); 18 extern PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void)); 19 20 /* 21 PetscHeaderCreate_Private - Creates a base PETSc object header and fills 22 in the default values. Called by the macro PetscHeaderCreate(). 23 */ 24 PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[], 25 MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view) 26 { 27 static PetscInt idcnt = 1; 28 PetscErrorCode ierr; 29 #if defined(PETSC_USE_LOG) 30 PetscObject *newPetscObjects; 31 PetscInt newPetscObjectsMaxCounts,i; 32 #endif 33 34 PetscFunctionBegin; 35 h->classid = classid; 36 h->type = 0; 37 h->class_name = (char*)class_name; 38 h->description = (char*)descr; 39 h->mansec = (char*)mansec; 40 h->prefix = 0; 41 h->refct = 1; 42 #if defined(PETSC_HAVE_SAWS) 43 h->amsmem = PETSC_FALSE; 44 #endif 45 h->id = idcnt++; 46 h->parentid = 0; 47 h->qlist = 0; 48 h->olist = 0; 49 h->bops->destroy = destroy; 50 h->bops->view = view; 51 h->bops->getcomm = PetscObjectGetComm_Petsc; 52 h->bops->compose = PetscObjectCompose_Petsc; 53 h->bops->query = PetscObjectQuery_Petsc; 54 h->bops->composefunction = PetscObjectComposeFunction_Petsc; 55 h->bops->queryfunction = PetscObjectQueryFunction_Petsc; 56 57 ierr = PetscCommDuplicate(comm,&h->comm,&h->tag);CHKERRQ(ierr); 58 59 #if defined(PETSC_USE_LOG) 60 /* Keep a record of object created */ 61 if (PetscObjectsLog) { 62 PetscObjectsCounts++; 63 for (i=0; i<PetscObjectsMaxCounts; i++) { 64 if (!PetscObjects[i]) { 65 PetscObjects[i] = h; 66 PetscFunctionReturn(0); 67 } 68 } 69 /* Need to increase the space for storing PETSc objects */ 70 if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100; 71 else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts; 72 ierr = PetscMalloc1(newPetscObjectsMaxCounts,&newPetscObjects);CHKERRQ(ierr); 73 ierr = PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));CHKERRQ(ierr); 74 ierr = PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));CHKERRQ(ierr); 75 ierr = PetscFree(PetscObjects);CHKERRQ(ierr); 76 77 PetscObjects = newPetscObjects; 78 PetscObjects[PetscObjectsMaxCounts] = h; 79 PetscObjectsMaxCounts = newPetscObjectsMaxCounts; 80 } 81 #endif 82 PetscFunctionReturn(0); 83 } 84 85 extern PetscBool PetscMemoryCollectMaximumUsage; 86 extern PetscLogDouble PetscMemoryMaximumUsage; 87 88 /* 89 PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by 90 the macro PetscHeaderDestroy(). 91 */ 92 PetscErrorCode PetscHeaderDestroy_Private(PetscObject h) 93 { 94 PetscErrorCode ierr; 95 96 PetscFunctionBegin; 97 PetscValidHeader(h,1); 98 ierr = PetscLogObjectDestroy(h);CHKERRQ(ierr); 99 ierr = PetscComposedQuantitiesDestroy(h);CHKERRQ(ierr); 100 if (PetscMemoryCollectMaximumUsage) { 101 PetscLogDouble usage; 102 ierr = PetscMemoryGetCurrentUsage(&usage);CHKERRQ(ierr); 103 if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage; 104 } 105 /* first destroy things that could execute arbitrary code */ 106 if (h->python_destroy) { 107 void *python_context = h->python_context; 108 PetscErrorCode (*python_destroy)(void*) = h->python_destroy; 109 h->python_context = 0; 110 h->python_destroy = 0; 111 112 ierr = (*python_destroy)(python_context);CHKERRQ(ierr); 113 } 114 ierr = PetscObjectDestroyOptionsHandlers(h);CHKERRQ(ierr); 115 ierr = PetscObjectListDestroy(&h->olist);CHKERRQ(ierr); 116 ierr = PetscCommDestroy(&h->comm);CHKERRQ(ierr); 117 /* next destroy other things */ 118 h->classid = PETSCFREEDHEADER; 119 120 ierr = PetscFunctionListDestroy(&h->qlist);CHKERRQ(ierr); 121 ierr = PetscFree(h->type_name);CHKERRQ(ierr); 122 ierr = PetscFree(h->name);CHKERRQ(ierr); 123 ierr = PetscFree(h->prefix);CHKERRQ(ierr); 124 ierr = PetscFree(h->fortran_func_pointers);CHKERRQ(ierr); 125 ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);CHKERRQ(ierr); 126 ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);CHKERRQ(ierr); 127 128 #if defined(PETSC_USE_LOG) 129 if (PetscObjectsLog) { 130 PetscInt i; 131 /* Record object removal from list of all objects */ 132 for (i=0; i<PetscObjectsMaxCounts; i++) { 133 if (PetscObjects[i] == h) { 134 PetscObjects[i] = 0; 135 PetscObjectsCounts--; 136 break; 137 } 138 } 139 if (!PetscObjectsCounts) { 140 ierr = PetscFree(PetscObjects);CHKERRQ(ierr); 141 PetscObjectsMaxCounts = 0; 142 } 143 } 144 #endif 145 PetscFunctionReturn(0); 146 } 147 148 /*@C 149 PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object 150 151 Logically Collective on PetscObject 152 153 Input Parameter: 154 + src - source object 155 - dest - destination object 156 157 Level: developer 158 159 Note: 160 Both objects must have the same class. 161 @*/ 162 PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest) 163 { 164 PetscErrorCode ierr; 165 PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE]; 166 167 PetscFunctionBegin; 168 PetscValidHeader(src,1); 169 PetscValidHeader(dest,2); 170 if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class"); 171 172 ierr = PetscFree(dest->fortran_func_pointers);CHKERRQ(ierr); 173 ierr = PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);CHKERRQ(ierr); 174 ierr = PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));CHKERRQ(ierr); 175 176 dest->num_fortran_func_pointers = src->num_fortran_func_pointers; 177 178 ierr = PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);CHKERRQ(ierr); 179 for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) { 180 ierr = PetscFree(dest->fortrancallback[cbtype]);CHKERRQ(ierr); 181 ierr = PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);CHKERRQ(ierr); 182 ierr = PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));CHKERRQ(ierr); 183 } 184 PetscFunctionReturn(0); 185 } 186 187 /*@C 188 PetscObjectSetFortranCallback - set fortran callback function pointer and context 189 190 Logically Collective 191 192 Input Arguments: 193 + obj - object on which to set callback 194 . cbtype - callback type (class or subtype) 195 . cid - address of callback Id, updated if not yet initialized (zero) 196 . func - Fortran function 197 - ctx - Fortran context 198 199 Level: developer 200 201 .seealso: PetscObjectGetFortranCallback() 202 @*/ 203 PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx) 204 { 205 PetscErrorCode ierr; 206 const char *subtype = NULL; 207 208 PetscFunctionBegin; 209 PetscValidHeader(obj,1); 210 if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name; 211 if (!*cid) {ierr = PetscFortranCallbackRegister(obj->classid,subtype,cid);CHKERRQ(ierr);} 212 if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) { 213 PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum); 214 PetscFortranCallback *callback; 215 ierr = PetscMalloc1(newnum,&callback);CHKERRQ(ierr); 216 ierr = PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));CHKERRQ(ierr); 217 ierr = PetscFree(obj->fortrancallback[cbtype]);CHKERRQ(ierr); 218 219 obj->fortrancallback[cbtype] = callback; 220 obj->num_fortrancallback[cbtype] = newnum; 221 } 222 obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func; 223 obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx; 224 PetscFunctionReturn(0); 225 } 226 227 /*@C 228 PetscObjectGetFortranCallback - get fortran callback function pointer and context 229 230 Logically Collective 231 232 Input Arguments: 233 + obj - object on which to get callback 234 . cbtype - callback type 235 - cid - address of callback Id 236 237 Output Arguments: 238 + func - Fortran function (or NULL if not needed) 239 - ctx - Fortran context (or NULL if not needed) 240 241 Level: developer 242 243 .seealso: PetscObjectSetFortranCallback() 244 @*/ 245 PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx) 246 { 247 PetscFortranCallback *cb; 248 249 PetscFunctionBegin; 250 PetscValidHeader(obj,1); 251 if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid"); 252 if (PetscUnlikely(cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype])) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback not set on this object"); 253 cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK]; 254 if (func) *func = cb->func; 255 if (ctx) *ctx = cb->ctx; 256 PetscFunctionReturn(0); 257 } 258 259 #if defined(PETSC_USE_LOG) 260 /*@C 261 PetscObjectsDump - Prints the currently existing objects. 262 263 Logically Collective on PetscViewer 264 265 Input Parameter: 266 + fd - file pointer 267 - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects 268 269 Options Database: 270 . -objects_dump <all> 271 272 Level: advanced 273 274 Concepts: options database^printing 275 276 @*/ 277 PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all) 278 { 279 PetscErrorCode ierr; 280 PetscInt i; 281 #if defined(PETSC_USE_DEBUG) 282 PetscInt j,k=0; 283 #endif 284 PetscObject h; 285 286 PetscFunctionBegin; 287 if (PetscObjectsCounts) { 288 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");CHKERRQ(ierr); 289 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");CHKERRQ(ierr); 290 for (i=0; i<PetscObjectsMaxCounts; i++) { 291 if ((h = PetscObjects[i])) { 292 ierr = PetscObjectName(h);CHKERRQ(ierr); 293 { 294 #if defined(PETSC_USE_DEBUG) 295 PetscStack *stack = 0; 296 char *create,*rclass; 297 298 /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */ 299 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 300 if (stack) { 301 k = stack->currentsize-2; 302 if (!all) { 303 k = 0; 304 while (!stack->petscroutine[k]) k++; 305 ierr = PetscStrstr(stack->function[k],"Create",&create);CHKERRQ(ierr); 306 if (!create) { 307 ierr = PetscStrstr(stack->function[k],"Get",&create);CHKERRQ(ierr); 308 } 309 ierr = PetscStrstr(stack->function[k],h->class_name,&rclass);CHKERRQ(ierr); 310 if (!create) continue; 311 if (!rclass) continue; 312 } 313 } 314 #endif 315 316 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);CHKERRQ(ierr); 317 318 #if defined(PETSC_USE_DEBUG) 319 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 320 if (stack) { 321 for (j=k; j>=0; j--) { 322 fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]); 323 } 324 } 325 #endif 326 } 327 } 328 } 329 } 330 PetscFunctionReturn(0); 331 } 332 #endif 333 334 #if defined(PETSC_USE_LOG) 335 336 /*@C 337 PetscObjectsView - Prints the currently existing objects. 338 339 Logically Collective on PetscViewer 340 341 Input Parameter: 342 . viewer - must be an PETSCVIEWERASCII viewer 343 344 Level: advanced 345 346 Concepts: options database^printing 347 348 @*/ 349 PetscErrorCode PetscObjectsView(PetscViewer viewer) 350 { 351 PetscErrorCode ierr; 352 PetscBool isascii; 353 FILE *fd; 354 355 PetscFunctionBegin; 356 if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 357 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 358 if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer"); 359 ierr = PetscViewerASCIIGetPointer(viewer,&fd);CHKERRQ(ierr); 360 ierr = PetscObjectsDump(fd,PETSC_TRUE);CHKERRQ(ierr); 361 PetscFunctionReturn(0); 362 } 363 364 /*@C 365 PetscObjectsGetObject - Get a pointer to a named object 366 367 Not collective 368 369 Input Parameter: 370 . name - the name of an object 371 372 Output Parameter: 373 . obj - the object or null if there is no object 374 375 Level: advanced 376 377 Concepts: options database^printing 378 379 @*/ 380 PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname) 381 { 382 PetscErrorCode ierr; 383 PetscInt i; 384 PetscObject h; 385 PetscBool flg; 386 387 PetscFunctionBegin; 388 *obj = NULL; 389 for (i=0; i<PetscObjectsMaxCounts; i++) { 390 if ((h = PetscObjects[i])) { 391 ierr = PetscObjectName(h);CHKERRQ(ierr); 392 ierr = PetscStrcmp(h->name,name,&flg);CHKERRQ(ierr); 393 if (flg) { 394 *obj = h; 395 if (classname) *classname = h->class_name; 396 PetscFunctionReturn(0); 397 } 398 } 399 } 400 PetscFunctionReturn(0); 401 } 402 #endif 403 404 /*@C 405 PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called. 406 407 Not Collective 408 409 Input Parameter: 410 + obj - the PETSc object 411 . handle - function that checks for options 412 . destroy - function to destroy context if provided 413 - ctx - optional context for check function 414 415 Level: developer 416 417 418 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers() 419 420 @*/ 421 PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx) 422 { 423 PetscFunctionBegin; 424 PetscValidHeader(obj,1); 425 if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added"); 426 obj->optionhandler[obj->noptionhandler] = handle; 427 obj->optiondestroy[obj->noptionhandler] = destroy; 428 obj->optionctx[obj->noptionhandler++] = ctx; 429 PetscFunctionReturn(0); 430 } 431 432 /*@C 433 PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object 434 435 Not Collective 436 437 Input Parameter: 438 . obj - the PETSc object 439 440 Level: developer 441 442 443 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers() 444 445 @*/ 446 PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj) 447 { 448 PetscInt i; 449 PetscErrorCode ierr; 450 451 PetscFunctionBegin; 452 PetscValidHeader(obj,1); 453 for (i=0; i<obj->noptionhandler; i++) { 454 ierr = (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);CHKERRQ(ierr); 455 } 456 PetscFunctionReturn(0); 457 } 458 459 /*@C 460 PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object 461 462 Not Collective 463 464 Input Parameter: 465 . obj - the PETSc object 466 467 Level: developer 468 469 470 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers() 471 472 @*/ 473 PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj) 474 { 475 PetscInt i; 476 PetscErrorCode ierr; 477 478 PetscFunctionBegin; 479 PetscValidHeader(obj,1); 480 for (i=0; i<obj->noptionhandler; i++) { 481 if (obj->optiondestroy[i]) { 482 ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 483 } 484 } 485 obj->noptionhandler = 0; 486 PetscFunctionReturn(0); 487 } 488 489 490 /*@ 491 PetscObjectReference - Indicates to any PetscObject that it is being 492 referenced by another PetscObject. This increases the reference 493 count for that object by one. 494 495 Logically Collective on PetscObject 496 497 Input Parameter: 498 . obj - the PETSc object. This must be cast with (PetscObject), for example, 499 PetscObjectReference((PetscObject)mat); 500 501 Level: advanced 502 503 .seealso: PetscObjectCompose(), PetscObjectDereference() 504 @*/ 505 PetscErrorCode PetscObjectReference(PetscObject obj) 506 { 507 PetscFunctionBegin; 508 if (!obj) PetscFunctionReturn(0); 509 PetscValidHeader(obj,1); 510 obj->refct++; 511 PetscFunctionReturn(0); 512 } 513 514 /*@ 515 PetscObjectGetReference - Gets the current reference count for 516 any PETSc object. 517 518 Not Collective 519 520 Input Parameter: 521 . obj - the PETSc object; this must be cast with (PetscObject), for example, 522 PetscObjectGetReference((PetscObject)mat,&cnt); 523 524 Output Parameter: 525 . cnt - the reference count 526 527 Level: advanced 528 529 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference() 530 @*/ 531 PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt) 532 { 533 PetscFunctionBegin; 534 PetscValidHeader(obj,1); 535 PetscValidIntPointer(cnt,2); 536 *cnt = obj->refct; 537 PetscFunctionReturn(0); 538 } 539 540 /*@ 541 PetscObjectDereference - Indicates to any PetscObject that it is being 542 referenced by one less PetscObject. This decreases the reference 543 count for that object by one. 544 545 Collective on PetscObject if reference reaches 0 otherwise Logically Collective 546 547 Input Parameter: 548 . obj - the PETSc object; this must be cast with (PetscObject), for example, 549 PetscObjectDereference((PetscObject)mat); 550 551 Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not. 552 553 Level: advanced 554 555 .seealso: PetscObjectCompose(), PetscObjectReference() 556 @*/ 557 PetscErrorCode PetscObjectDereference(PetscObject obj) 558 { 559 PetscErrorCode ierr; 560 561 PetscFunctionBegin; 562 if (!obj) PetscFunctionReturn(0); 563 PetscValidHeader(obj,1); 564 if (obj->bops->destroy) { 565 ierr = (*obj->bops->destroy)(&obj);CHKERRQ(ierr); 566 } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine"); 567 PetscFunctionReturn(0); 568 } 569 570 /* ----------------------------------------------------------------------- */ 571 /* 572 The following routines are the versions private to the PETSc object 573 data structures. 574 */ 575 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm) 576 { 577 PetscFunctionBegin; 578 PetscValidHeader(obj,1); 579 *comm = obj->comm; 580 PetscFunctionReturn(0); 581 } 582 583 PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[]) 584 { 585 PetscErrorCode ierr; 586 587 PetscFunctionBegin; 588 PetscValidHeader(obj,1); 589 ierr = PetscObjectListRemoveReference(&obj->olist,name);CHKERRQ(ierr); 590 PetscFunctionReturn(0); 591 } 592 593 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr) 594 { 595 PetscErrorCode ierr; 596 char *tname; 597 PetscBool skipreference; 598 599 PetscFunctionBegin; 600 if (ptr) { 601 ierr = PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);CHKERRQ(ierr); 602 if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it"); 603 } 604 ierr = PetscObjectListAdd(&obj->olist,name,ptr);CHKERRQ(ierr); 605 PetscFunctionReturn(0); 606 } 607 608 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr) 609 { 610 PetscErrorCode ierr; 611 612 PetscFunctionBegin; 613 PetscValidHeader(obj,1); 614 ierr = PetscObjectListFind(obj->olist,name,ptr);CHKERRQ(ierr); 615 PetscFunctionReturn(0); 616 } 617 618 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void)) 619 { 620 PetscErrorCode ierr; 621 622 PetscFunctionBegin; 623 PetscValidHeader(obj,1); 624 ierr = PetscFunctionListAdd(&obj->qlist,name,ptr);CHKERRQ(ierr); 625 PetscFunctionReturn(0); 626 } 627 628 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void)) 629 { 630 PetscErrorCode ierr; 631 632 PetscFunctionBegin; 633 PetscValidHeader(obj,1); 634 ierr = PetscFunctionListFind(obj->qlist,name,ptr);CHKERRQ(ierr); 635 PetscFunctionReturn(0); 636 } 637 638 /*@C 639 PetscObjectCompose - Associates another PETSc object with a given PETSc object. 640 641 Not Collective 642 643 Input Parameters: 644 + obj - the PETSc object; this must be cast with (PetscObject), for example, 645 PetscObjectCompose((PetscObject)mat,...); 646 . name - name associated with the child object 647 - ptr - the other PETSc object to associate with the PETSc object; this must also be 648 cast with (PetscObject) 649 650 Level: advanced 651 652 Notes: 653 The second objects reference count is automatically increased by one when it is 654 composed. 655 656 Replaces any previous object that had the same name. 657 658 If ptr is null and name has previously been composed using an object, then that 659 entry is removed from the obj. 660 661 PetscObjectCompose() can be used with any PETSc object (such as 662 Mat, Vec, KSP, SNES, etc.) or any user-provided object. See 663 PetscContainerCreate() for info on how to create an object from a 664 user-provided pointer that may then be composed with PETSc objects. 665 666 Concepts: objects^composing 667 Concepts: composing objects 668 669 .seealso: PetscObjectQuery(), PetscContainerCreate() 670 @*/ 671 PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr) 672 { 673 PetscErrorCode ierr; 674 675 PetscFunctionBegin; 676 PetscValidHeader(obj,1); 677 PetscValidCharPointer(name,2); 678 if (ptr) PetscValidHeader(ptr,3); 679 ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr); 680 PetscFunctionReturn(0); 681 } 682 683 /*@C 684 PetscObjectQuery - Gets a PETSc object associated with a given object. 685 686 Not Collective 687 688 Input Parameters: 689 + obj - the PETSc object 690 Thus must be cast with a (PetscObject), for example, 691 PetscObjectCompose((PetscObject)mat,...); 692 . name - name associated with child object 693 - ptr - the other PETSc object associated with the PETSc object, this must be 694 cast with (PetscObject*) 695 696 Level: advanced 697 698 The reference count of neither object is increased in this call 699 700 Concepts: objects^composing 701 Concepts: composing objects 702 Concepts: objects^querying 703 Concepts: querying objects 704 705 .seealso: PetscObjectCompose() 706 @*/ 707 PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 708 { 709 PetscErrorCode ierr; 710 711 PetscFunctionBegin; 712 PetscValidHeader(obj,1); 713 PetscValidCharPointer(name,2); 714 PetscValidPointer(ptr,3); 715 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 716 PetscFunctionReturn(0); 717 } 718 719 /*MC 720 PetscObjectComposeFunction - Associates a function with a given PETSc object. 721 722 Synopsis: 723 #include <petscsys.h> 724 PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void)) 725 726 Logically Collective on PetscObject 727 728 Input Parameters: 729 + obj - the PETSc object; this must be cast with a (PetscObject), for example, 730 PetscObjectCompose((PetscObject)mat,...); 731 . name - name associated with the child function 732 . fname - name of the function 733 - fptr - function pointer 734 735 Level: advanced 736 737 Notes: 738 To remove a registered routine, pass in NULL for fptr(). 739 740 PetscObjectComposeFunction() can be used with any PETSc object (such as 741 Mat, Vec, KSP, SNES, etc.) or any user-provided object. 742 743 Concepts: objects^composing functions 744 Concepts: composing functions 745 Concepts: functions^querying 746 Concepts: objects^querying 747 Concepts: querying objects 748 749 .seealso: PetscObjectQueryFunction(), PetscContainerCreate() 750 M*/ 751 752 PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void)) 753 { 754 PetscErrorCode ierr; 755 756 PetscFunctionBegin; 757 PetscValidHeader(obj,1); 758 PetscValidCharPointer(name,2); 759 ierr = (*obj->bops->composefunction)(obj,name,fptr);CHKERRQ(ierr); 760 PetscFunctionReturn(0); 761 } 762 763 /*MC 764 PetscObjectQueryFunction - Gets a function associated with a given object. 765 766 Synopsis: 767 #include <petscsys.h> 768 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void)) 769 770 Logically Collective on PetscObject 771 772 Input Parameters: 773 + obj - the PETSc object; this must be cast with (PetscObject), for example, 774 PetscObjectQueryFunction((PetscObject)ksp,...); 775 - name - name associated with the child function 776 777 Output Parameter: 778 . fptr - function pointer 779 780 Level: advanced 781 782 Concepts: objects^composing functions 783 Concepts: composing functions 784 Concepts: functions^querying 785 Concepts: objects^querying 786 Concepts: querying objects 787 788 .seealso: PetscObjectComposeFunction(), PetscFunctionListFind() 789 M*/ 790 PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void)) 791 { 792 PetscErrorCode ierr; 793 794 PetscFunctionBegin; 795 PetscValidHeader(obj,1); 796 PetscValidCharPointer(name,2); 797 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 798 PetscFunctionReturn(0); 799 } 800 801 struct _p_PetscContainer { 802 PETSCHEADER(int); 803 void *ptr; 804 PetscErrorCode (*userdestroy)(void*); 805 }; 806 807 /*@C 808 PetscContainerGetPointer - Gets the pointer value contained in the container. 809 810 Not Collective 811 812 Input Parameter: 813 . obj - the object created with PetscContainerCreate() 814 815 Output Parameter: 816 . ptr - the pointer value 817 818 Level: advanced 819 820 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 821 PetscContainerSetPointer() 822 @*/ 823 PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr) 824 { 825 PetscFunctionBegin; 826 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 827 PetscValidPointer(ptr,2); 828 *ptr = obj->ptr; 829 PetscFunctionReturn(0); 830 } 831 832 833 /*@C 834 PetscContainerSetPointer - Sets the pointer value contained in the container. 835 836 Logically Collective on PetscContainer 837 838 Input Parameters: 839 + obj - the object created with PetscContainerCreate() 840 - ptr - the pointer value 841 842 Level: advanced 843 844 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 845 PetscContainerGetPointer() 846 @*/ 847 PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr) 848 { 849 PetscFunctionBegin; 850 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 851 if (ptr) PetscValidPointer(ptr,2); 852 obj->ptr = ptr; 853 PetscFunctionReturn(0); 854 } 855 856 /*@C 857 PetscContainerDestroy - Destroys a PETSc container object. 858 859 Collective on PetscContainer 860 861 Input Parameter: 862 . obj - an object that was created with PetscContainerCreate() 863 864 Level: advanced 865 866 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy() 867 @*/ 868 PetscErrorCode PetscContainerDestroy(PetscContainer *obj) 869 { 870 PetscErrorCode ierr; 871 872 PetscFunctionBegin; 873 if (!*obj) PetscFunctionReturn(0); 874 PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1); 875 if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);} 876 if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr); 877 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 878 PetscFunctionReturn(0); 879 } 880 881 /*@C 882 PetscContainerSetUserDestroy - Sets name of the user destroy function. 883 884 Logically Collective on PetscContainer 885 886 Input Parameter: 887 + obj - an object that was created with PetscContainerCreate() 888 - des - name of the user destroy function 889 890 Level: advanced 891 892 .seealso: PetscContainerDestroy() 893 @*/ 894 PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 895 { 896 PetscFunctionBegin; 897 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 898 obj->userdestroy = des; 899 PetscFunctionReturn(0); 900 } 901 902 PetscClassId PETSC_CONTAINER_CLASSID; 903 904 /*@C 905 PetscContainerCreate - Creates a PETSc object that has room to hold 906 a single pointer. This allows one to attach any type of data (accessible 907 through a pointer) with the PetscObjectCompose() function to a PetscObject. 908 The data item itself is attached by a call to PetscContainerSetPointer(). 909 910 Collective on MPI_Comm 911 912 Input Parameters: 913 . comm - MPI communicator that shares the object 914 915 Output Parameters: 916 . container - the container created 917 918 Level: advanced 919 920 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer() 921 @*/ 922 PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 923 { 924 PetscErrorCode ierr; 925 PetscContainer contain; 926 927 PetscFunctionBegin; 928 PetscValidPointer(container,2); 929 ierr = PetscSysInitializePackage();CHKERRQ(ierr); 930 ierr = PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);CHKERRQ(ierr); 931 *container = contain; 932 PetscFunctionReturn(0); 933 } 934 935 /*@ 936 PetscObjectSetFromOptions - Sets generic parameters from user options. 937 938 Collective on obj 939 940 Input Parameter: 941 . obj - the PetscObjcet 942 943 Options Database Keys: 944 945 Notes: 946 We have no generic options at present, so this does nothing 947 948 Level: beginner 949 950 .keywords: set, options, database 951 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 952 @*/ 953 PetscErrorCode PetscObjectSetFromOptions(PetscObject obj) 954 { 955 PetscFunctionBegin; 956 PetscValidHeader(obj,1); 957 PetscFunctionReturn(0); 958 } 959 960 /*@ 961 PetscObjectSetUp - Sets up the internal data structures for the later use. 962 963 Collective on PetscObject 964 965 Input Parameters: 966 . obj - the PetscObject 967 968 Notes: 969 This does nothing at present. 970 971 Level: advanced 972 973 .keywords: setup 974 .seealso: PetscObjectDestroy() 975 @*/ 976 PetscErrorCode PetscObjectSetUp(PetscObject obj) 977 { 978 PetscFunctionBegin; 979 PetscValidHeader(obj,1); 980 PetscFunctionReturn(0); 981 } 982