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 Parameter: 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 Arguments: 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 Arguments: 239 + obj - object on which to get callback 240 . cbtype - callback type 241 - cid - address of callback Id 242 243 Output Arguments: 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 Parameter: 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 Parameter: 375 . obj - the object or null if there is no object 376 377 Level: advanced 378 379 @*/ 380 PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname) 381 { 382 PetscErrorCode ierr; 383 PetscInt i; 384 PetscObject h; 385 PetscBool flg; 386 387 PetscFunctionBegin; 388 *obj = NULL; 389 for (i=0; i<PetscObjectsMaxCounts; i++) { 390 if ((h = PetscObjects[i])) { 391 ierr = PetscObjectName(h);CHKERRQ(ierr); 392 ierr = PetscStrcmp(h->name,name,&flg);CHKERRQ(ierr); 393 if (flg) { 394 *obj = h; 395 if (classname) *classname = h->class_name; 396 PetscFunctionReturn(0); 397 } 398 } 399 } 400 PetscFunctionReturn(0); 401 } 402 #endif 403 404 /*@ 405 PetscObjectSetPrintedOptions - indicate to an object that it should behave as if it has already printed the help for its options 406 407 Input Parameters: 408 . obj - the PetscObject 409 410 Level: developer 411 412 Developer Notes: 413 This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by 414 PCBJACOBI from all printing the same help messages to the screen 415 416 .seealso: PetscOptionsInsert() 417 @*/ 418 PetscErrorCode PetscObjectSetPrintedOptions(PetscObject obj) 419 { 420 PetscFunctionBegin; 421 obj->optionsprinted = PETSC_TRUE; 422 PetscFunctionReturn(0); 423 } 424 425 /*@ 426 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. 427 428 Input Parameters: 429 + pobj - the parent object 430 - obj - the PetscObject 431 432 Level: developer 433 434 Developer Notes: 435 This is used, for example to prevent sequential objects that are created from a parallel object; such as the KSP created by 436 PCBJACOBI from all printing the same help messages to the screen 437 438 This will not handle more complicated situations like with GASM where children may live on any subset of the parent's processes and overlap 439 440 .seealso: PetscOptionsInsert(), PetscObjectSetPrintedOptions() 441 @*/ 442 PetscErrorCode PetscObjectInheritPrintedOptions(PetscObject pobj,PetscObject obj) 443 { 444 PetscErrorCode ierr; 445 PetscMPIInt prank,size; 446 447 PetscFunctionBegin; 448 ierr = MPI_Comm_rank(pobj->comm,&prank);CHKERRMPI(ierr); 449 ierr = MPI_Comm_size(obj->comm,&size);CHKERRMPI(ierr); 450 if (size == 1 && prank > 0) obj->optionsprinted = PETSC_TRUE; 451 PetscFunctionReturn(0); 452 } 453 454 /*@C 455 PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called. 456 457 Not Collective 458 459 Input Parameter: 460 + obj - the PETSc object 461 . handle - function that checks for options 462 . destroy - function to destroy context if provided 463 - ctx - optional context for check function 464 465 Level: developer 466 467 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers() 468 469 @*/ 470 PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscOptionItems*,PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx) 471 { 472 PetscFunctionBegin; 473 PetscValidHeader(obj,1); 474 if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added"); 475 obj->optionhandler[obj->noptionhandler] = handle; 476 obj->optiondestroy[obj->noptionhandler] = destroy; 477 obj->optionctx[obj->noptionhandler++] = ctx; 478 PetscFunctionReturn(0); 479 } 480 481 /*@C 482 PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object 483 484 Not Collective 485 486 Input Parameter: 487 . obj - the PETSc object 488 489 Level: developer 490 491 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers() 492 493 @*/ 494 PetscErrorCode PetscObjectProcessOptionsHandlers(PetscOptionItems *PetscOptionsObject,PetscObject obj) 495 { 496 PetscInt i; 497 PetscErrorCode ierr; 498 499 PetscFunctionBegin; 500 PetscValidHeader(obj,2); 501 for (i=0; i<obj->noptionhandler; i++) { 502 ierr = (*obj->optionhandler[i])(PetscOptionsObject,obj,obj->optionctx[i]);CHKERRQ(ierr); 503 } 504 PetscFunctionReturn(0); 505 } 506 507 /*@C 508 PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object 509 510 Not Collective 511 512 Input Parameter: 513 . obj - the PETSc object 514 515 Level: developer 516 517 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers() 518 519 @*/ 520 PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj) 521 { 522 PetscInt i; 523 PetscErrorCode ierr; 524 525 PetscFunctionBegin; 526 PetscValidHeader(obj,1); 527 for (i=0; i<obj->noptionhandler; i++) { 528 if (obj->optiondestroy[i]) { 529 ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 530 } 531 } 532 obj->noptionhandler = 0; 533 PetscFunctionReturn(0); 534 } 535 536 /*@C 537 PetscObjectReference - Indicates to any PetscObject that it is being 538 referenced by another PetscObject. This increases the reference 539 count for that object by one. 540 541 Logically Collective on PetscObject 542 543 Input Parameter: 544 . obj - the PETSc object. This must be cast with (PetscObject), for example, 545 PetscObjectReference((PetscObject)mat); 546 547 Level: advanced 548 549 .seealso: PetscObjectCompose(), PetscObjectDereference() 550 @*/ 551 PetscErrorCode PetscObjectReference(PetscObject obj) 552 { 553 PetscFunctionBegin; 554 if (!obj) PetscFunctionReturn(0); 555 PetscValidHeader(obj,1); 556 obj->refct++; 557 PetscFunctionReturn(0); 558 } 559 560 /*@C 561 PetscObjectGetReference - Gets the current reference count for 562 any PETSc object. 563 564 Not Collective 565 566 Input Parameter: 567 . obj - the PETSc object; this must be cast with (PetscObject), for example, 568 PetscObjectGetReference((PetscObject)mat,&cnt); 569 570 Output Parameter: 571 . cnt - the reference count 572 573 Level: advanced 574 575 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference() 576 @*/ 577 PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt) 578 { 579 PetscFunctionBegin; 580 PetscValidHeader(obj,1); 581 PetscValidIntPointer(cnt,2); 582 *cnt = obj->refct; 583 PetscFunctionReturn(0); 584 } 585 586 /*@C 587 PetscObjectDereference - Indicates to any PetscObject that it is being 588 referenced by one less PetscObject. This decreases the reference 589 count for that object by one. 590 591 Collective on PetscObject if reference reaches 0 otherwise Logically Collective 592 593 Input Parameter: 594 . obj - the PETSc object; this must be cast with (PetscObject), for example, 595 PetscObjectDereference((PetscObject)mat); 596 597 Notes: 598 PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not. 599 600 Level: advanced 601 602 .seealso: PetscObjectCompose(), PetscObjectReference() 603 @*/ 604 PetscErrorCode PetscObjectDereference(PetscObject obj) 605 { 606 PetscErrorCode ierr; 607 608 PetscFunctionBegin; 609 if (!obj) PetscFunctionReturn(0); 610 PetscValidHeader(obj,1); 611 if (obj->bops->destroy) { 612 ierr = (*obj->bops->destroy)(&obj);CHKERRQ(ierr); 613 } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine"); 614 PetscFunctionReturn(0); 615 } 616 617 /* ----------------------------------------------------------------------- */ 618 /* 619 The following routines are the versions private to the PETSc object 620 data structures. 621 */ 622 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm) 623 { 624 PetscFunctionBegin; 625 PetscValidHeader(obj,1); 626 *comm = obj->comm; 627 PetscFunctionReturn(0); 628 } 629 630 PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[]) 631 { 632 PetscErrorCode ierr; 633 634 PetscFunctionBegin; 635 PetscValidHeader(obj,1); 636 ierr = PetscObjectListRemoveReference(&obj->olist,name);CHKERRQ(ierr); 637 PetscFunctionReturn(0); 638 } 639 640 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr) 641 { 642 PetscErrorCode ierr; 643 char *tname; 644 PetscBool skipreference; 645 646 PetscFunctionBegin; 647 if (ptr) { 648 ierr = PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);CHKERRQ(ierr); 649 if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it"); 650 } 651 ierr = PetscObjectListAdd(&obj->olist,name,ptr);CHKERRQ(ierr); 652 PetscFunctionReturn(0); 653 } 654 655 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr) 656 { 657 PetscErrorCode ierr; 658 659 PetscFunctionBegin; 660 PetscValidHeader(obj,1); 661 ierr = PetscObjectListFind(obj->olist,name,ptr);CHKERRQ(ierr); 662 PetscFunctionReturn(0); 663 } 664 665 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void)) 666 { 667 PetscErrorCode ierr; 668 669 PetscFunctionBegin; 670 PetscValidHeader(obj,1); 671 ierr = PetscFunctionListAdd(&obj->qlist,name,ptr);CHKERRQ(ierr); 672 PetscFunctionReturn(0); 673 } 674 675 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void)) 676 { 677 PetscErrorCode ierr; 678 679 PetscFunctionBegin; 680 PetscValidHeader(obj,1); 681 ierr = PetscFunctionListFind(obj->qlist,name,ptr);CHKERRQ(ierr); 682 PetscFunctionReturn(0); 683 } 684 685 /*@C 686 PetscObjectCompose - Associates another PETSc object with a given PETSc object. 687 688 Not Collective 689 690 Input Parameters: 691 + obj - the PETSc object; this must be cast with (PetscObject), for example, 692 PetscObjectCompose((PetscObject)mat,...); 693 . name - name associated with the child object 694 - ptr - the other PETSc object to associate with the PETSc object; this must also be 695 cast with (PetscObject) 696 697 Level: advanced 698 699 Notes: 700 The second objects reference count is automatically increased by one when it is 701 composed. 702 703 Replaces any previous object that had the same name. 704 705 If ptr is null and name has previously been composed using an object, then that 706 entry is removed from the obj. 707 708 PetscObjectCompose() can be used with any PETSc object (such as 709 Mat, Vec, KSP, SNES, etc.) or any user-provided object. See 710 PetscContainerCreate() for info on how to create an object from a 711 user-provided pointer that may then be composed with PETSc objects. 712 713 .seealso: PetscObjectQuery(), PetscContainerCreate(), PetscObjectComposeFunction(), PetscObjectQueryFunction() 714 @*/ 715 PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr) 716 { 717 PetscErrorCode ierr; 718 719 PetscFunctionBegin; 720 PetscValidHeader(obj,1); 721 PetscValidCharPointer(name,2); 722 if (ptr) PetscValidHeader(ptr,3); 723 if (obj == ptr) SETERRQ(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot compose object with itself"); 724 ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr); 725 PetscFunctionReturn(0); 726 } 727 728 /*@C 729 PetscObjectQuery - Gets a PETSc object associated with a given object. 730 731 Not Collective 732 733 Input Parameters: 734 + obj - the PETSc object 735 Thus must be cast with a (PetscObject), for example, 736 PetscObjectCompose((PetscObject)mat,...); 737 . name - name associated with child object 738 - ptr - the other PETSc object associated with the PETSc object, this must be 739 cast with (PetscObject*) 740 741 Level: advanced 742 743 The reference count of neither object is increased in this call 744 745 .seealso: PetscObjectCompose(), PetscObjectComposeFunction(), PetscObjectQueryFunction() 746 @*/ 747 PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 748 { 749 PetscErrorCode ierr; 750 751 PetscFunctionBegin; 752 PetscValidHeader(obj,1); 753 PetscValidCharPointer(name,2); 754 PetscValidPointer(ptr,3); 755 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 756 PetscFunctionReturn(0); 757 } 758 759 /*MC 760 PetscObjectComposeFunction - Associates a function with a given PETSc object. 761 762 Synopsis: 763 #include <petscsys.h> 764 PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void)) 765 766 Logically Collective on PetscObject 767 768 Input Parameters: 769 + obj - the PETSc object; this must be cast with a (PetscObject), for example, 770 PetscObjectCompose((PetscObject)mat,...); 771 . name - name associated with the child function 772 . fname - name of the function 773 - fptr - function pointer 774 775 Level: advanced 776 777 Notes: 778 To remove a registered routine, pass in NULL for fptr(). 779 780 PetscObjectComposeFunction() can be used with any PETSc object (such as 781 Mat, Vec, KSP, SNES, etc.) or any user-provided object. 782 783 .seealso: PetscObjectQueryFunction(), PetscContainerCreate() PetscObjectCompose(), PetscObjectQuery() 784 M*/ 785 786 PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void)) 787 { 788 PetscErrorCode ierr; 789 790 PetscFunctionBegin; 791 PetscValidHeader(obj,1); 792 PetscValidCharPointer(name,2); 793 ierr = (*obj->bops->composefunction)(obj,name,fptr);CHKERRQ(ierr); 794 PetscFunctionReturn(0); 795 } 796 797 /*MC 798 PetscObjectQueryFunction - Gets a function associated with a given object. 799 800 Synopsis: 801 #include <petscsys.h> 802 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void)) 803 804 Logically Collective on PetscObject 805 806 Input Parameters: 807 + obj - the PETSc object; this must be cast with (PetscObject), for example, 808 PetscObjectQueryFunction((PetscObject)ksp,...); 809 - name - name associated with the child function 810 811 Output Parameter: 812 . fptr - function pointer 813 814 Level: advanced 815 816 .seealso: PetscObjectComposeFunction(), PetscFunctionListFind(), PetscObjectCompose(), PetscObjectQuery() 817 M*/ 818 PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void)) 819 { 820 PetscErrorCode ierr; 821 822 PetscFunctionBegin; 823 PetscValidHeader(obj,1); 824 PetscValidCharPointer(name,2); 825 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 826 PetscFunctionReturn(0); 827 } 828 829 struct _p_PetscContainer { 830 PETSCHEADER(int); 831 void *ptr; 832 PetscErrorCode (*userdestroy)(void*); 833 }; 834 835 /*@C 836 PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree(). 837 838 Logically Collective on PetscContainer 839 840 Input Parameter: 841 . ctx - pointer to user-provided data 842 843 Level: advanced 844 845 .seealso: PetscContainerDestroy(), PetscContainerSetUserDestroy() 846 @*/ 847 PetscErrorCode PetscContainerUserDestroyDefault(void* ctx) 848 { 849 PetscErrorCode ierr; 850 851 PetscFunctionBegin; 852 ierr = PetscFree(ctx);CHKERRQ(ierr); 853 PetscFunctionReturn(0); 854 } 855 856 /*@C 857 PetscContainerGetPointer - Gets the pointer value contained in the container. 858 859 Not Collective 860 861 Input Parameter: 862 . obj - the object created with PetscContainerCreate() 863 864 Output Parameter: 865 . ptr - the pointer value 866 867 Level: advanced 868 869 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 870 PetscContainerSetPointer() 871 @*/ 872 PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr) 873 { 874 PetscFunctionBegin; 875 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 876 PetscValidPointer(ptr,2); 877 *ptr = obj->ptr; 878 PetscFunctionReturn(0); 879 } 880 881 /*@C 882 PetscContainerSetPointer - Sets the pointer value contained in the container. 883 884 Logically Collective on PetscContainer 885 886 Input Parameters: 887 + obj - the object created with PetscContainerCreate() 888 - ptr - the pointer value 889 890 Level: advanced 891 892 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 893 PetscContainerGetPointer() 894 @*/ 895 PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr) 896 { 897 PetscFunctionBegin; 898 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 899 if (ptr) PetscValidPointer(ptr,2); 900 obj->ptr = ptr; 901 PetscFunctionReturn(0); 902 } 903 904 /*@C 905 PetscContainerDestroy - Destroys a PETSc container object. 906 907 Collective on PetscContainer 908 909 Input Parameter: 910 . obj - an object that was created with PetscContainerCreate() 911 912 Level: advanced 913 914 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy() 915 @*/ 916 PetscErrorCode PetscContainerDestroy(PetscContainer *obj) 917 { 918 PetscErrorCode ierr; 919 920 PetscFunctionBegin; 921 if (!*obj) PetscFunctionReturn(0); 922 PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1); 923 if (--((PetscObject)(*obj))->refct > 0) {*obj = NULL; PetscFunctionReturn(0);} 924 if ((*obj)->userdestroy) { ierr = (*(*obj)->userdestroy)((*obj)->ptr);CHKERRQ(ierr); } 925 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 926 PetscFunctionReturn(0); 927 } 928 929 /*@C 930 PetscContainerSetUserDestroy - Sets name of the user destroy function. 931 932 Logically Collective on PetscContainer 933 934 Input Parameter: 935 + obj - an object that was created with PetscContainerCreate() 936 - des - name of the user destroy function 937 938 Notes: 939 Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation. 940 941 Level: advanced 942 943 .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1() 944 @*/ 945 PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 946 { 947 PetscFunctionBegin; 948 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 949 obj->userdestroy = des; 950 PetscFunctionReturn(0); 951 } 952 953 PetscClassId PETSC_CONTAINER_CLASSID; 954 955 /*@C 956 PetscContainerCreate - Creates a PETSc object that has room to hold 957 a single pointer. This allows one to attach any type of data (accessible 958 through a pointer) with the PetscObjectCompose() function to a PetscObject. 959 The data item itself is attached by a call to PetscContainerSetPointer(). 960 961 Collective 962 963 Input Parameters: 964 . comm - MPI communicator that shares the object 965 966 Output Parameters: 967 . container - the container created 968 969 Level: advanced 970 971 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer(), PetscObjectCompose(), PetscObjectQuery() 972 @*/ 973 PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 974 { 975 PetscErrorCode ierr; 976 PetscContainer contain; 977 978 PetscFunctionBegin; 979 PetscValidPointer(container,2); 980 ierr = PetscSysInitializePackage();CHKERRQ(ierr); 981 ierr = PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);CHKERRQ(ierr); 982 *container = contain; 983 PetscFunctionReturn(0); 984 } 985 986 /*@ 987 PetscObjectSetFromOptions - Sets generic parameters from user options. 988 989 Collective on obj 990 991 Input Parameter: 992 . obj - the PetscObjcet 993 994 Options Database Keys: 995 996 Notes: 997 We have no generic options at present, so this does nothing 998 999 Level: beginner 1000 1001 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 1002 @*/ 1003 PetscErrorCode PetscObjectSetFromOptions(PetscObject obj) 1004 { 1005 PetscFunctionBegin; 1006 PetscValidHeader(obj,1); 1007 PetscFunctionReturn(0); 1008 } 1009 1010 /*@ 1011 PetscObjectSetUp - Sets up the internal data structures for the later use. 1012 1013 Collective on PetscObject 1014 1015 Input Parameters: 1016 . obj - the PetscObject 1017 1018 Notes: 1019 This does nothing at present. 1020 1021 Level: advanced 1022 1023 .seealso: PetscObjectDestroy() 1024 @*/ 1025 PetscErrorCode PetscObjectSetUp(PetscObject obj) 1026 { 1027 PetscFunctionBegin; 1028 PetscValidHeader(obj,1); 1029 PetscFunctionReturn(0); 1030 } 1031