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