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