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