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