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 /*@ 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 /*@ 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 /*@ 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 ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr); 681 PetscFunctionReturn(0); 682 } 683 684 /*@C 685 PetscObjectQuery - Gets a PETSc object associated with a given object. 686 687 Not Collective 688 689 Input Parameters: 690 + obj - the PETSc object 691 Thus must be cast with a (PetscObject), for example, 692 PetscObjectCompose((PetscObject)mat,...); 693 . name - name associated with child object 694 - ptr - the other PETSc object associated with the PETSc object, this must be 695 cast with (PetscObject*) 696 697 Level: advanced 698 699 The reference count of neither object is increased in this call 700 701 Concepts: objects^composing 702 Concepts: composing objects 703 Concepts: objects^querying 704 Concepts: querying objects 705 706 .seealso: PetscObjectCompose() 707 @*/ 708 PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 709 { 710 PetscErrorCode ierr; 711 712 PetscFunctionBegin; 713 PetscValidHeader(obj,1); 714 PetscValidCharPointer(name,2); 715 PetscValidPointer(ptr,3); 716 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 717 PetscFunctionReturn(0); 718 } 719 720 /*MC 721 PetscObjectComposeFunction - Associates a function with a given PETSc object. 722 723 Synopsis: 724 #include <petscsys.h> 725 PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void)) 726 727 Logically Collective on PetscObject 728 729 Input Parameters: 730 + obj - the PETSc object; this must be cast with a (PetscObject), for example, 731 PetscObjectCompose((PetscObject)mat,...); 732 . name - name associated with the child function 733 . fname - name of the function 734 - fptr - function pointer 735 736 Level: advanced 737 738 Notes: 739 To remove a registered routine, pass in NULL for fptr(). 740 741 PetscObjectComposeFunction() can be used with any PETSc object (such as 742 Mat, Vec, KSP, SNES, etc.) or any user-provided object. 743 744 Concepts: objects^composing functions 745 Concepts: composing functions 746 Concepts: functions^querying 747 Concepts: objects^querying 748 Concepts: querying objects 749 750 .seealso: PetscObjectQueryFunction(), PetscContainerCreate() 751 M*/ 752 753 PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void)) 754 { 755 PetscErrorCode ierr; 756 757 PetscFunctionBegin; 758 PetscValidHeader(obj,1); 759 PetscValidCharPointer(name,2); 760 ierr = (*obj->bops->composefunction)(obj,name,fptr);CHKERRQ(ierr); 761 PetscFunctionReturn(0); 762 } 763 764 /*MC 765 PetscObjectQueryFunction - Gets a function associated with a given object. 766 767 Synopsis: 768 #include <petscsys.h> 769 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void)) 770 771 Logically Collective on PetscObject 772 773 Input Parameters: 774 + obj - the PETSc object; this must be cast with (PetscObject), for example, 775 PetscObjectQueryFunction((PetscObject)ksp,...); 776 - name - name associated with the child function 777 778 Output Parameter: 779 . fptr - function pointer 780 781 Level: advanced 782 783 Concepts: objects^composing functions 784 Concepts: composing functions 785 Concepts: functions^querying 786 Concepts: objects^querying 787 Concepts: querying objects 788 789 .seealso: PetscObjectComposeFunction(), PetscFunctionListFind() 790 M*/ 791 PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void)) 792 { 793 PetscErrorCode ierr; 794 795 PetscFunctionBegin; 796 PetscValidHeader(obj,1); 797 PetscValidCharPointer(name,2); 798 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 799 PetscFunctionReturn(0); 800 } 801 802 struct _p_PetscContainer { 803 PETSCHEADER(int); 804 void *ptr; 805 PetscErrorCode (*userdestroy)(void*); 806 }; 807 808 /*@C 809 PetscContainerUserDestroyDefault - Default destroy routine for user-provided data that simply calls PetscFree(). 810 811 Logically Collective on PetscContainer 812 813 Input Parameter: 814 . ctx - pointer to user-provided data 815 816 Level: advanced 817 818 .seealso: PetscContainerDestroy(), PetscContainterSetUserDestroy() 819 @*/ 820 PetscErrorCode PetscContainerUserDestroyDefault(void* ctx) 821 { 822 PetscErrorCode ierr; 823 824 PetscFunctionBegin; 825 PetscValidPointer(ctx,1); 826 ierr = PetscFree(ctx);CHKERRQ(ierr); 827 PetscFunctionReturn(0); 828 } 829 830 /*@C 831 PetscContainerGetPointer - Gets the pointer value contained in the container. 832 833 Not Collective 834 835 Input Parameter: 836 . obj - the object created with PetscContainerCreate() 837 838 Output Parameter: 839 . ptr - the pointer value 840 841 Level: advanced 842 843 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 844 PetscContainerSetPointer() 845 @*/ 846 PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr) 847 { 848 PetscFunctionBegin; 849 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 850 PetscValidPointer(ptr,2); 851 *ptr = obj->ptr; 852 PetscFunctionReturn(0); 853 } 854 855 856 /*@C 857 PetscContainerSetPointer - Sets the pointer value contained in the container. 858 859 Logically Collective on PetscContainer 860 861 Input Parameters: 862 + obj - the object created with PetscContainerCreate() 863 - ptr - the pointer value 864 865 Level: advanced 866 867 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 868 PetscContainerGetPointer() 869 @*/ 870 PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr) 871 { 872 PetscFunctionBegin; 873 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 874 if (ptr) PetscValidPointer(ptr,2); 875 obj->ptr = ptr; 876 PetscFunctionReturn(0); 877 } 878 879 /*@C 880 PetscContainerDestroy - Destroys a PETSc container object. 881 882 Collective on PetscContainer 883 884 Input Parameter: 885 . obj - an object that was created with PetscContainerCreate() 886 887 Level: advanced 888 889 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy() 890 @*/ 891 PetscErrorCode PetscContainerDestroy(PetscContainer *obj) 892 { 893 PetscErrorCode ierr; 894 895 PetscFunctionBegin; 896 if (!*obj) PetscFunctionReturn(0); 897 PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1); 898 if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);} 899 if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr); 900 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 901 PetscFunctionReturn(0); 902 } 903 904 /*@C 905 PetscContainerSetUserDestroy - Sets name of the user destroy function. 906 907 Logically Collective on PetscContainer 908 909 Input Parameter: 910 + obj - an object that was created with PetscContainerCreate() 911 - des - name of the user destroy function 912 913 Notes: 914 Use PetscContainerUserDestroyDefault() if the memory was obtained by calling PetscMalloc or one of its variants for single memory allocation. 915 916 Level: advanced 917 918 .seealso: PetscContainerDestroy(), PetscContainerUserDestroyDefault(), PetscMalloc(), PetscMalloc1(), PetscCalloc(), PetscCalloc1() 919 @*/ 920 PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 921 { 922 PetscFunctionBegin; 923 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 924 obj->userdestroy = des; 925 PetscFunctionReturn(0); 926 } 927 928 PetscClassId PETSC_CONTAINER_CLASSID; 929 930 /*@C 931 PetscContainerCreate - Creates a PETSc object that has room to hold 932 a single pointer. This allows one to attach any type of data (accessible 933 through a pointer) with the PetscObjectCompose() function to a PetscObject. 934 The data item itself is attached by a call to PetscContainerSetPointer(). 935 936 Collective on MPI_Comm 937 938 Input Parameters: 939 . comm - MPI communicator that shares the object 940 941 Output Parameters: 942 . container - the container created 943 944 Level: advanced 945 946 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer() 947 @*/ 948 PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 949 { 950 PetscErrorCode ierr; 951 PetscContainer contain; 952 953 PetscFunctionBegin; 954 PetscValidPointer(container,2); 955 ierr = PetscSysInitializePackage();CHKERRQ(ierr); 956 ierr = PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);CHKERRQ(ierr); 957 *container = contain; 958 PetscFunctionReturn(0); 959 } 960 961 /*@ 962 PetscObjectSetFromOptions - Sets generic parameters from user options. 963 964 Collective on obj 965 966 Input Parameter: 967 . obj - the PetscObjcet 968 969 Options Database Keys: 970 971 Notes: 972 We have no generic options at present, so this does nothing 973 974 Level: beginner 975 976 .keywords: set, options, database 977 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 978 @*/ 979 PetscErrorCode PetscObjectSetFromOptions(PetscObject obj) 980 { 981 PetscFunctionBegin; 982 PetscValidHeader(obj,1); 983 PetscFunctionReturn(0); 984 } 985 986 /*@ 987 PetscObjectSetUp - Sets up the internal data structures for the later use. 988 989 Collective on PetscObject 990 991 Input Parameters: 992 . obj - the PetscObject 993 994 Notes: 995 This does nothing at present. 996 997 Level: advanced 998 999 .keywords: setup 1000 .seealso: PetscObjectDestroy() 1001 @*/ 1002 PetscErrorCode PetscObjectSetUp(PetscObject obj) 1003 { 1004 PetscFunctionBegin; 1005 PetscValidHeader(obj,1); 1006 PetscFunctionReturn(0); 1007 } 1008