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 PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE]; 171 172 PetscFunctionBegin; 173 PetscValidHeader(src,1); 174 PetscValidHeader(dest,2); 175 if (src->classid != dest->classid) SETERRQ(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 PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum); 220 PetscFortranCallback *callback; 221 ierr = PetscMalloc1(newnum,&callback);CHKERRQ(ierr); 222 ierr = PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));CHKERRQ(ierr); 223 ierr = PetscFree(obj->fortrancallback[cbtype]);CHKERRQ(ierr); 224 225 obj->fortrancallback[cbtype] = callback; 226 obj->num_fortrancallback[cbtype] = newnum; 227 } 228 obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func; 229 obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx; 230 PetscFunctionReturn(0); 231 } 232 233 /*@C 234 PetscObjectGetFortranCallback - get fortran callback function pointer and context 235 236 Logically Collective 237 238 Input Parameters: 239 + obj - object on which to get callback 240 . cbtype - callback type 241 - cid - address of callback Id 242 243 Output Parameters: 244 + func - Fortran function (or NULL if not needed) 245 - ctx - Fortran context (or NULL if not needed) 246 247 Level: developer 248 249 .seealso: PetscObjectSetFortranCallback() 250 @*/ 251 PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx) 252 { 253 PetscFortranCallback *cb; 254 255 PetscFunctionBegin; 256 PetscValidHeader(obj,1); 257 if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid"); 258 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"); 259 cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK]; 260 if (func) *func = cb->func; 261 if (ctx) *ctx = cb->ctx; 262 PetscFunctionReturn(0); 263 } 264 265 #if defined(PETSC_USE_LOG) 266 /*@C 267 PetscObjectsDump - Prints the currently existing objects. 268 269 Logically Collective on PetscViewer 270 271 Input Parameters: 272 + fd - file pointer 273 - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects 274 275 Options Database: 276 . -objects_dump <all> - print information about all the objects that exist at the end of the programs run 277 278 Level: advanced 279 280 @*/ 281 PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all) 282 { 283 PetscErrorCode ierr; 284 PetscInt i; 285 #if defined(PETSC_USE_DEBUG) 286 PetscInt j,k=0; 287 #endif 288 PetscObject h; 289 290 PetscFunctionBegin; 291 if (PetscObjectsCounts) { 292 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");CHKERRQ(ierr); 293 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");CHKERRQ(ierr); 294 for (i=0; i<PetscObjectsMaxCounts; i++) { 295 if ((h = PetscObjects[i])) { 296 ierr = PetscObjectName(h);CHKERRQ(ierr); 297 { 298 #if defined(PETSC_USE_DEBUG) 299 PetscStack *stack = NULL; 300 char *create,*rclass; 301 302 /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */ 303 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 304 if (stack) { 305 k = stack->currentsize-2; 306 if (!all) { 307 k = 0; 308 while (!stack->petscroutine[k]) k++; 309 ierr = PetscStrstr(stack->function[k],"Create",&create);CHKERRQ(ierr); 310 if (!create) { 311 ierr = PetscStrstr(stack->function[k],"Get",&create);CHKERRQ(ierr); 312 } 313 ierr = PetscStrstr(stack->function[k],h->class_name,&rclass);CHKERRQ(ierr); 314 if (!create) continue; 315 if (!rclass) continue; 316 } 317 } 318 #endif 319 320 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);CHKERRQ(ierr); 321 322 #if defined(PETSC_USE_DEBUG) 323 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 324 if (stack) { 325 for (j=k; j>=0; j--) { 326 fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]); 327 } 328 } 329 #endif 330 } 331 } 332 } 333 } 334 PetscFunctionReturn(0); 335 } 336 #endif 337 338 #if defined(PETSC_USE_LOG) 339 340 /*@C 341 PetscObjectsView - Prints the currently existing objects. 342 343 Logically Collective on PetscViewer 344 345 Input Parameter: 346 . viewer - must be an PETSCVIEWERASCII viewer 347 348 Level: advanced 349 350 @*/ 351 PetscErrorCode PetscObjectsView(PetscViewer viewer) 352 { 353 PetscErrorCode ierr; 354 PetscBool isascii; 355 FILE *fd; 356 357 PetscFunctionBegin; 358 if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 359 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 360 if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer"); 361 ierr = PetscViewerASCIIGetPointer(viewer,&fd);CHKERRQ(ierr); 362 ierr = PetscObjectsDump(fd,PETSC_TRUE);CHKERRQ(ierr); 363 PetscFunctionReturn(0); 364 } 365 366 /*@C 367 PetscObjectsGetObject - Get a pointer to a named object 368 369 Not collective 370 371 Input Parameter: 372 . name - the name of an object 373 374 Output Parameters: 375 + obj - the object or null if there is no object 376 - classname - the name of the class 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);CHKERRMPI(ierr); 450 ierr = MPI_Comm_size(obj->comm,&size);CHKERRMPI(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 Parameters: 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 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers() 469 470 @*/ 471 PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx) 472 { 473 PetscFunctionBegin; 474 PetscValidHeader(obj,1); 475 if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added"); 476 obj->optionhandler[obj->noptionhandler] = handle; 477 obj->optiondestroy[obj->noptionhandler] = destroy; 478 obj->optionctx[obj->noptionhandler++] = ctx; 479 PetscFunctionReturn(0); 480 } 481 482 /*@C 483 PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object 484 485 Not Collective 486 487 Input Parameter: 488 . obj - the PETSc object 489 490 Level: developer 491 492 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers() 493 494 @*/ 495 PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj) 496 { 497 PetscInt i; 498 PetscErrorCode ierr; 499 500 PetscFunctionBegin; 501 PetscValidHeader(obj,2); 502 for (i=0; i<obj->noptionhandler; i++) { 503 ierr = (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);CHKERRQ(ierr); 504 } 505 PetscFunctionReturn(0); 506 } 507 508 /*@C 509 PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object 510 511 Not Collective 512 513 Input Parameter: 514 . obj - the PETSc object 515 516 Level: developer 517 518 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers() 519 520 @*/ 521 PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj) 522 { 523 PetscInt i; 524 PetscErrorCode ierr; 525 526 PetscFunctionBegin; 527 PetscValidHeader(obj,1); 528 for (i=0; i<obj->noptionhandler; i++) { 529 if (obj->optiondestroy[i]) { 530 ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 531 } 532 } 533 obj->noptionhandler = 0; 534 PetscFunctionReturn(0); 535 } 536 537 /*@C 538 PetscObjectReference - Indicates to any PetscObject that it is being 539 referenced by another PetscObject. This increases the reference 540 count for that object by one. 541 542 Logically Collective on PetscObject 543 544 Input Parameter: 545 . obj - the PETSc object. This must be cast with (PetscObject), for example, 546 PetscObjectReference((PetscObject)mat); 547 548 Level: advanced 549 550 .seealso: PetscObjectCompose(), PetscObjectDereference() 551 @*/ 552 PetscErrorCode PetscObjectReference(PetscObject obj) 553 { 554 PetscFunctionBegin; 555 if (!obj) PetscFunctionReturn(0); 556 PetscValidHeader(obj,1); 557 obj->refct++; 558 PetscFunctionReturn(0); 559 } 560 561 /*@C 562 PetscObjectGetReference - Gets the current reference count for 563 any PETSc object. 564 565 Not Collective 566 567 Input Parameter: 568 . obj - the PETSc object; this must be cast with (PetscObject), for example, 569 PetscObjectGetReference((PetscObject)mat,&cnt); 570 571 Output Parameter: 572 . cnt - the reference count 573 574 Level: advanced 575 576 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference() 577 @*/ 578 PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt) 579 { 580 PetscFunctionBegin; 581 PetscValidHeader(obj,1); 582 PetscValidIntPointer(cnt,2); 583 *cnt = obj->refct; 584 PetscFunctionReturn(0); 585 } 586 587 /*@C 588 PetscObjectDereference - Indicates to any PetscObject that it is being 589 referenced by one less PetscObject. This decreases the reference 590 count for that object by one. 591 592 Collective on PetscObject if reference reaches 0 otherwise Logically Collective 593 594 Input Parameter: 595 . obj - the PETSc object; this must be cast with (PetscObject), for example, 596 PetscObjectDereference((PetscObject)mat); 597 598 Notes: 599 PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not. 600 601 Level: advanced 602 603 .seealso: PetscObjectCompose(), PetscObjectReference() 604 @*/ 605 PetscErrorCode PetscObjectDereference(PetscObject obj) 606 { 607 PetscErrorCode ierr; 608 609 PetscFunctionBegin; 610 if (!obj) PetscFunctionReturn(0); 611 PetscValidHeader(obj,1); 612 if (obj->bops->destroy) { 613 ierr = (*obj->bops->destroy)(&obj);CHKERRQ(ierr); 614 } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine"); 615 PetscFunctionReturn(0); 616 } 617 618 /* ----------------------------------------------------------------------- */ 619 /* 620 The following routines are the versions private to the PETSc object 621 data structures. 622 */ 623 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm) 624 { 625 PetscFunctionBegin; 626 PetscValidHeader(obj,1); 627 *comm = obj->comm; 628 PetscFunctionReturn(0); 629 } 630 631 PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[]) 632 { 633 PetscErrorCode ierr; 634 635 PetscFunctionBegin; 636 PetscValidHeader(obj,1); 637 ierr = PetscObjectListRemoveReference(&obj->olist,name);CHKERRQ(ierr); 638 PetscFunctionReturn(0); 639 } 640 641 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr) 642 { 643 PetscErrorCode ierr; 644 char *tname; 645 PetscBool skipreference; 646 647 PetscFunctionBegin; 648 if (ptr) { 649 ierr = PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);CHKERRQ(ierr); 650 if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it"); 651 } 652 ierr = PetscObjectListAdd(&obj->olist,name,ptr);CHKERRQ(ierr); 653 PetscFunctionReturn(0); 654 } 655 656 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr) 657 { 658 PetscErrorCode ierr; 659 660 PetscFunctionBegin; 661 PetscValidHeader(obj,1); 662 ierr = PetscObjectListFind(obj->olist,name,ptr);CHKERRQ(ierr); 663 PetscFunctionReturn(0); 664 } 665 666 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void)) 667 { 668 PetscErrorCode ierr; 669 670 PetscFunctionBegin; 671 PetscValidHeader(obj,1); 672 ierr = PetscFunctionListAdd(&obj->qlist,name,ptr);CHKERRQ(ierr); 673 PetscFunctionReturn(0); 674 } 675 676 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void)) 677 { 678 PetscErrorCode ierr; 679 680 PetscFunctionBegin; 681 PetscValidHeader(obj,1); 682 ierr = PetscFunctionListFind(obj->qlist,name,ptr);CHKERRQ(ierr); 683 PetscFunctionReturn(0); 684 } 685 686 /*@C 687 PetscObjectCompose - Associates another PETSc object with a given PETSc object. 688 689 Not Collective 690 691 Input Parameters: 692 + obj - the PETSc object; this must be cast with (PetscObject), for example, 693 PetscObjectCompose((PetscObject)mat,...); 694 . name - name associated with the child object 695 - ptr - the other PETSc object to associate with the PETSc object; this must also be 696 cast with (PetscObject) 697 698 Level: advanced 699 700 Notes: 701 The second objects reference count is automatically increased by one when it is 702 composed. 703 704 Replaces any previous object that had the same name. 705 706 If ptr is null and name has previously been composed using an object, then that 707 entry is removed from the obj. 708 709 PetscObjectCompose() can be used with any PETSc object (such as 710 Mat, Vec, KSP, SNES, etc.) or any user-provided object. See 711 PetscContainerCreate() for info on how to create an object from a 712 user-provided pointer that may then be composed with PETSc objects. 713 714 .seealso: PetscObjectQuery(), PetscContainerCreate(), PetscObjectComposeFunction(), PetscObjectQueryFunction() 715 @*/ 716 PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr) 717 { 718 PetscErrorCode ierr; 719 720 PetscFunctionBegin; 721 PetscValidHeader(obj,1); 722 PetscValidCharPointer(name,2); 723 if (ptr) PetscValidHeader(ptr,3); 724 if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself"); 725 ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr); 726 PetscFunctionReturn(0); 727 } 728 729 /*@C 730 PetscObjectQuery - Gets a PETSc object associated with a given object. 731 732 Not Collective 733 734 Input Parameters: 735 + obj - the PETSc object 736 Thus must be cast with a (PetscObject), for example, 737 PetscObjectCompose((PetscObject)mat,...); 738 . name - name associated with child object 739 - ptr - the other PETSc object associated with the PETSc object, this must be 740 cast with (PetscObject*) 741 742 Level: advanced 743 744 The reference count of neither object is increased in this call 745 746 .seealso: PetscObjectCompose(), PetscObjectComposeFunction(), PetscObjectQueryFunction() 747 @*/ 748 PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 749 { 750 PetscErrorCode ierr; 751 752 PetscFunctionBegin; 753 PetscValidHeader(obj,1); 754 PetscValidCharPointer(name,2); 755 PetscValidPointer(ptr,3); 756 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 757 PetscFunctionReturn(0); 758 } 759 760 /*MC 761 PetscObjectComposeFunction - Associates a function with a given PETSc object. 762 763 Synopsis: 764 #include <petscsys.h> 765 PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void)) 766 767 Logically Collective on PetscObject 768 769 Input Parameters: 770 + obj - the PETSc object; this must be cast with a (PetscObject), for example, 771 PetscObjectCompose((PetscObject)mat,...); 772 . name - name associated with the child function 773 . fname - name of the function 774 - fptr - function pointer 775 776 Level: advanced 777 778 Notes: 779 To remove a registered routine, pass in NULL for fptr(). 780 781 PetscObjectComposeFunction() can be used with any PETSc object (such as 782 Mat, Vec, KSP, SNES, etc.) or any user-provided object. 783 784 .seealso: PetscObjectQueryFunction(), PetscContainerCreate() PetscObjectCompose(), PetscObjectQuery() 785 M*/ 786 787 PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void)) 788 { 789 PetscErrorCode ierr; 790 791 PetscFunctionBegin; 792 PetscValidHeader(obj,1); 793 PetscValidCharPointer(name,2); 794 ierr = (*obj->bops->composefunction)(obj,name,fptr);CHKERRQ(ierr); 795 PetscFunctionReturn(0); 796 } 797 798 /*MC 799 PetscObjectQueryFunction - Gets a function associated with a given object. 800 801 Synopsis: 802 #include <petscsys.h> 803 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void)) 804 805 Logically Collective on PetscObject 806 807 Input Parameters: 808 + obj - the PETSc object; this must be cast with (PetscObject), for example, 809 PetscObjectQueryFunction((PetscObject)ksp,...); 810 - name - name associated with the child function 811 812 Output Parameter: 813 . fptr - function pointer 814 815 Level: advanced 816 817 .seealso: PetscObjectComposeFunction(), PetscFunctionListFind(), PetscObjectCompose(), PetscObjectQuery() 818 M*/ 819 PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void)) 820 { 821 PetscErrorCode ierr; 822 823 PetscFunctionBegin; 824 PetscValidHeader(obj,1); 825 PetscValidCharPointer(name,2); 826 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 827 PetscFunctionReturn(0); 828 } 829 830 struct _p_PetscContainer { 831 PETSCHEADER(int); 832 void *ptr; 833 PetscErrorCode (*userdestroy)(void*); 834 }; 835 836 /*@C 837 PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree(). 838 839 Logically Collective on PetscContainer 840 841 Input Parameter: 842 . ctx - pointer to user-provided data 843 844 Level: advanced 845 846 .seealso: PetscContainerDestroy(), PetscContainerSetUserDestroy() 847 @*/ 848 PetscErrorCode PetscContainerUserDestroyDefault(void* ctx) 849 { 850 PetscErrorCode ierr; 851 852 PetscFunctionBegin; 853 ierr = PetscFree(ctx);CHKERRQ(ierr); 854 PetscFunctionReturn(0); 855 } 856 857 /*@C 858 PetscContainerGetPointer - Gets the pointer value contained in the container. 859 860 Not Collective 861 862 Input Parameter: 863 . obj - the object created with PetscContainerCreate() 864 865 Output Parameter: 866 . ptr - the pointer value 867 868 Level: advanced 869 870 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 871 PetscContainerSetPointer() 872 @*/ 873 PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr) 874 { 875 PetscFunctionBegin; 876 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 877 PetscValidPointer(ptr,2); 878 *ptr = obj->ptr; 879 PetscFunctionReturn(0); 880 } 881 882 /*@C 883 PetscContainerSetPointer - Sets the pointer value contained in the container. 884 885 Logically Collective on PetscContainer 886 887 Input Parameters: 888 + obj - the object created with PetscContainerCreate() 889 - ptr - the pointer value 890 891 Level: advanced 892 893 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 894 PetscContainerGetPointer() 895 @*/ 896 PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr) 897 { 898 PetscFunctionBegin; 899 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 900 if (ptr) PetscValidPointer(ptr,2); 901 obj->ptr = ptr; 902 PetscFunctionReturn(0); 903 } 904 905 /*@C 906 PetscContainerDestroy - Destroys a PETSc container object. 907 908 Collective on PetscContainer 909 910 Input Parameter: 911 . obj - an object that was created with PetscContainerCreate() 912 913 Level: advanced 914 915 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy() 916 @*/ 917 PetscErrorCode PetscContainerDestroy(PetscContainer *obj) 918 { 919 PetscErrorCode ierr; 920 921 PetscFunctionBegin; 922 if (!*obj) PetscFunctionReturn(0); 923 PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1); 924 if (--((PetscObject)(*obj))->refct > 0) {*obj = NULL; PetscFunctionReturn(0);} 925 if ((*obj)->userdestroy) { ierr = (*(*obj)->userdestroy)((*obj)->ptr);CHKERRQ(ierr); } 926 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 927 PetscFunctionReturn(0); 928 } 929 930 /*@C 931 PetscContainerSetUserDestroy - Sets name of the user destroy function. 932 933 Logically Collective on PetscContainer 934 935 Input Parameters: 936 + obj - an object that was created with PetscContainerCreate() 937 - des - name of the user destroy function 938 939 Notes: 940 Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation. 941 942 Level: advanced 943 944 .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1() 945 @*/ 946 PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 947 { 948 PetscFunctionBegin; 949 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 950 obj->userdestroy = des; 951 PetscFunctionReturn(0); 952 } 953 954 PetscClassId PETSC_CONTAINER_CLASSID; 955 956 /*@C 957 PetscContainerCreate - Creates a PETSc object that has room to hold 958 a single pointer. This allows one to attach any type of data (accessible 959 through a pointer) with the PetscObjectCompose() function to a PetscObject. 960 The data item itself is attached by a call to PetscContainerSetPointer(). 961 962 Collective 963 964 Input Parameters: 965 . comm - MPI communicator that shares the object 966 967 Output Parameters: 968 . container - the container created 969 970 Level: advanced 971 972 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer(), PetscObjectCompose(), PetscObjectQuery() 973 @*/ 974 PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 975 { 976 PetscErrorCode ierr; 977 PetscContainer contain; 978 979 PetscFunctionBegin; 980 PetscValidPointer(container,2); 981 ierr = PetscSysInitializePackage();CHKERRQ(ierr); 982 ierr = PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);CHKERRQ(ierr); 983 *container = contain; 984 PetscFunctionReturn(0); 985 } 986 987 /*@ 988 PetscObjectSetFromOptions - Sets generic parameters from user options. 989 990 Collective on obj 991 992 Input Parameter: 993 . obj - the PetscObjcet 994 995 Options Database Keys: 996 997 Notes: 998 We have no generic options at present, so this does nothing 999 1000 Level: beginner 1001 1002 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 1003 @*/ 1004 PetscErrorCode PetscObjectSetFromOptions(PetscObject obj) 1005 { 1006 PetscFunctionBegin; 1007 PetscValidHeader(obj,1); 1008 PetscFunctionReturn(0); 1009 } 1010 1011 /*@ 1012 PetscObjectSetUp - Sets up the internal data structures for the later use. 1013 1014 Collective on PetscObject 1015 1016 Input Parameters: 1017 . obj - the PetscObject 1018 1019 Notes: 1020 This does nothing at present. 1021 1022 Level: advanced 1023 1024 .seealso: PetscObjectDestroy() 1025 @*/ 1026 PetscErrorCode PetscObjectSetUp(PetscObject obj) 1027 { 1028 PetscFunctionBegin; 1029 PetscValidHeader(obj,1); 1030 PetscFunctionReturn(0); 1031 } 1032