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->precision = (PetscPrecision) sizeof(PetscReal); 50 h->bops->destroy = destroy; 51 h->bops->view = view; 52 h->bops->getcomm = PetscObjectGetComm_Petsc; 53 h->bops->compose = PetscObjectCompose_Petsc; 54 h->bops->query = PetscObjectQuery_Petsc; 55 h->bops->composefunction = PetscObjectComposeFunction_Petsc; 56 h->bops->queryfunction = PetscObjectQueryFunction_Petsc; 57 58 ierr = PetscCommDuplicate(comm,&h->comm,&h->tag);CHKERRQ(ierr); 59 60 #if defined(PETSC_USE_LOG) 61 /* Keep a record of object created */ 62 if (PetscObjectsLog) { 63 PetscObjectsCounts++; 64 for (i=0; i<PetscObjectsMaxCounts; i++) { 65 if (!PetscObjects[i]) { 66 PetscObjects[i] = h; 67 PetscFunctionReturn(0); 68 } 69 } 70 /* Need to increase the space for storing PETSc objects */ 71 if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100; 72 else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts; 73 ierr = PetscMalloc1(newPetscObjectsMaxCounts,&newPetscObjects);CHKERRQ(ierr); 74 ierr = PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));CHKERRQ(ierr); 75 ierr = PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));CHKERRQ(ierr); 76 ierr = PetscFree(PetscObjects);CHKERRQ(ierr); 77 78 PetscObjects = newPetscObjects; 79 PetscObjects[PetscObjectsMaxCounts] = h; 80 PetscObjectsMaxCounts = newPetscObjectsMaxCounts; 81 } 82 #endif 83 PetscFunctionReturn(0); 84 } 85 86 extern PetscBool PetscMemoryCollectMaximumUsage; 87 extern PetscLogDouble PetscMemoryMaximumUsage; 88 89 /* 90 PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by 91 the macro PetscHeaderDestroy(). 92 */ 93 PetscErrorCode PetscHeaderDestroy_Private(PetscObject h) 94 { 95 PetscErrorCode ierr; 96 97 PetscFunctionBegin; 98 PetscValidHeader(h,1); 99 ierr = PetscLogObjectDestroy(h);CHKERRQ(ierr); 100 ierr = PetscComposedQuantitiesDestroy(h);CHKERRQ(ierr); 101 if (PetscMemoryCollectMaximumUsage) { 102 PetscLogDouble usage; 103 ierr = PetscMemoryGetCurrentUsage(&usage);CHKERRQ(ierr); 104 if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage; 105 } 106 /* first destroy things that could execute arbitrary code */ 107 if (h->python_destroy) { 108 void *python_context = h->python_context; 109 PetscErrorCode (*python_destroy)(void*) = h->python_destroy; 110 h->python_context = 0; 111 h->python_destroy = 0; 112 113 ierr = (*python_destroy)(python_context);CHKERRQ(ierr); 114 } 115 ierr = PetscObjectDestroyOptionsHandlers(h);CHKERRQ(ierr); 116 ierr = PetscObjectListDestroy(&h->olist);CHKERRQ(ierr); 117 ierr = PetscCommDestroy(&h->comm);CHKERRQ(ierr); 118 /* next destroy other things */ 119 h->classid = PETSCFREEDHEADER; 120 121 ierr = PetscFunctionListDestroy(&h->qlist);CHKERRQ(ierr); 122 ierr = PetscFree(h->type_name);CHKERRQ(ierr); 123 ierr = PetscFree(h->name);CHKERRQ(ierr); 124 ierr = PetscFree(h->prefix);CHKERRQ(ierr); 125 ierr = PetscFree(h->fortran_func_pointers);CHKERRQ(ierr); 126 ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);CHKERRQ(ierr); 127 ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);CHKERRQ(ierr); 128 129 #if defined(PETSC_USE_LOG) 130 if (PetscObjectsLog) { 131 PetscInt i; 132 /* Record object removal from list of all objects */ 133 for (i=0; i<PetscObjectsMaxCounts; i++) { 134 if (PetscObjects[i] == h) { 135 PetscObjects[i] = 0; 136 PetscObjectsCounts--; 137 break; 138 } 139 } 140 if (!PetscObjectsCounts) { 141 ierr = PetscFree(PetscObjects);CHKERRQ(ierr); 142 PetscObjectsMaxCounts = 0; 143 } 144 } 145 #endif 146 PetscFunctionReturn(0); 147 } 148 149 /*@C 150 PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object 151 152 Logically Collective on PetscObject 153 154 Input Parameter: 155 + src - source object 156 - dest - destination object 157 158 Level: developer 159 160 Note: 161 Both objects must have the same class. 162 @*/ 163 PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest) 164 { 165 PetscErrorCode ierr; 166 PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE]; 167 168 PetscFunctionBegin; 169 PetscValidHeader(src,1); 170 PetscValidHeader(dest,2); 171 if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class"); 172 173 ierr = PetscFree(dest->fortran_func_pointers);CHKERRQ(ierr); 174 ierr = PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);CHKERRQ(ierr); 175 ierr = PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));CHKERRQ(ierr); 176 177 dest->num_fortran_func_pointers = src->num_fortran_func_pointers; 178 179 ierr = PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);CHKERRQ(ierr); 180 for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) { 181 ierr = PetscFree(dest->fortrancallback[cbtype]);CHKERRQ(ierr); 182 ierr = PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);CHKERRQ(ierr); 183 ierr = PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));CHKERRQ(ierr); 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 PetscObjectSetPrecision - sets the precision used within a given object. 686 687 Collective on the PetscObject 688 689 Input Parameters: 690 + obj - the PETSc object; this must be cast with (PetscObject), for example, 691 PetscObjectCompose((PetscObject)mat,...); 692 - precision - the precision 693 694 Level: advanced 695 696 .seealso: PetscObjectQuery(), PetscContainerCreate() 697 @*/ 698 PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision) 699 { 700 PetscFunctionBegin; 701 PetscValidHeader(obj,1); 702 obj->precision = precision; 703 PetscFunctionReturn(0); 704 } 705 706 /*@C 707 PetscObjectQuery - Gets a PETSc object associated with a given object. 708 709 Not Collective 710 711 Input Parameters: 712 + obj - the PETSc object 713 Thus must be cast with a (PetscObject), for example, 714 PetscObjectCompose((PetscObject)mat,...); 715 . name - name associated with child object 716 - ptr - the other PETSc object associated with the PETSc object, this must be 717 cast with (PetscObject*) 718 719 Level: advanced 720 721 The reference count of neither object is increased in this call 722 723 Concepts: objects^composing 724 Concepts: composing objects 725 Concepts: objects^querying 726 Concepts: querying objects 727 728 .seealso: PetscObjectCompose() 729 @*/ 730 PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 731 { 732 PetscErrorCode ierr; 733 734 PetscFunctionBegin; 735 PetscValidHeader(obj,1); 736 PetscValidCharPointer(name,2); 737 PetscValidPointer(ptr,3); 738 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 739 PetscFunctionReturn(0); 740 } 741 742 /*MC 743 PetscObjectComposeFunction - Associates a function with a given PETSc object. 744 745 Synopsis: 746 #include <petscsys.h> 747 PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void)) 748 749 Logically Collective on PetscObject 750 751 Input Parameters: 752 + obj - the PETSc object; this must be cast with a (PetscObject), for example, 753 PetscObjectCompose((PetscObject)mat,...); 754 . name - name associated with the child function 755 . fname - name of the function 756 - fptr - function pointer 757 758 Level: advanced 759 760 Notes: 761 To remove a registered routine, pass in NULL for fptr(). 762 763 PetscObjectComposeFunction() can be used with any PETSc object (such as 764 Mat, Vec, KSP, SNES, etc.) or any user-provided object. 765 766 Concepts: objects^composing functions 767 Concepts: composing functions 768 Concepts: functions^querying 769 Concepts: objects^querying 770 Concepts: querying objects 771 772 .seealso: PetscObjectQueryFunction(), PetscContainerCreate() 773 M*/ 774 775 PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void)) 776 { 777 PetscErrorCode ierr; 778 779 PetscFunctionBegin; 780 PetscValidHeader(obj,1); 781 PetscValidCharPointer(name,2); 782 ierr = (*obj->bops->composefunction)(obj,name,fptr);CHKERRQ(ierr); 783 PetscFunctionReturn(0); 784 } 785 786 /*MC 787 PetscObjectQueryFunction - Gets a function associated with a given object. 788 789 Synopsis: 790 #include <petscsys.h> 791 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void)) 792 793 Logically Collective on PetscObject 794 795 Input Parameters: 796 + obj - the PETSc object; this must be cast with (PetscObject), for example, 797 PetscObjectQueryFunction((PetscObject)ksp,...); 798 - name - name associated with the child function 799 800 Output Parameter: 801 . fptr - function pointer 802 803 Level: advanced 804 805 Concepts: objects^composing functions 806 Concepts: composing functions 807 Concepts: functions^querying 808 Concepts: objects^querying 809 Concepts: querying objects 810 811 .seealso: PetscObjectComposeFunction(), PetscFunctionListFind() 812 M*/ 813 PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void)) 814 { 815 PetscErrorCode ierr; 816 817 PetscFunctionBegin; 818 PetscValidHeader(obj,1); 819 PetscValidCharPointer(name,2); 820 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 821 PetscFunctionReturn(0); 822 } 823 824 struct _p_PetscContainer { 825 PETSCHEADER(int); 826 void *ptr; 827 PetscErrorCode (*userdestroy)(void*); 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 Level: advanced 914 915 .seealso: PetscContainerDestroy() 916 @*/ 917 PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 918 { 919 PetscFunctionBegin; 920 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 921 obj->userdestroy = des; 922 PetscFunctionReturn(0); 923 } 924 925 PetscClassId PETSC_CONTAINER_CLASSID; 926 927 /*@C 928 PetscContainerCreate - Creates a PETSc object that has room to hold 929 a single pointer. This allows one to attach any type of data (accessible 930 through a pointer) with the PetscObjectCompose() function to a PetscObject. 931 The data item itself is attached by a call to PetscContainerSetPointer(). 932 933 Collective on MPI_Comm 934 935 Input Parameters: 936 . comm - MPI communicator that shares the object 937 938 Output Parameters: 939 . container - the container created 940 941 Level: advanced 942 943 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer() 944 @*/ 945 PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 946 { 947 PetscErrorCode ierr; 948 PetscContainer contain; 949 950 PetscFunctionBegin; 951 PetscValidPointer(container,2); 952 ierr = PetscSysInitializePackage();CHKERRQ(ierr); 953 ierr = PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);CHKERRQ(ierr); 954 *container = contain; 955 PetscFunctionReturn(0); 956 } 957 958 /*@ 959 PetscObjectSetFromOptions - Sets generic parameters from user options. 960 961 Collective on obj 962 963 Input Parameter: 964 . obj - the PetscObjcet 965 966 Options Database Keys: 967 968 Notes: 969 We have no generic options at present, so this does nothing 970 971 Level: beginner 972 973 .keywords: set, options, database 974 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 975 @*/ 976 PetscErrorCode PetscObjectSetFromOptions(PetscObject obj) 977 { 978 PetscFunctionBegin; 979 PetscValidHeader(obj,1); 980 PetscFunctionReturn(0); 981 } 982 983 /*@ 984 PetscObjectSetUp - Sets up the internal data structures for the later use. 985 986 Collective on PetscObject 987 988 Input Parameters: 989 . obj - the PetscObject 990 991 Notes: 992 This does nothing at present. 993 994 Level: advanced 995 996 .keywords: setup 997 .seealso: PetscObjectDestroy() 998 @*/ 999 PetscErrorCode PetscObjectSetUp(PetscObject obj) 1000 { 1001 PetscFunctionBegin; 1002 PetscValidHeader(obj,1); 1003 PetscFunctionReturn(0); 1004 } 1005