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