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