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 418 #undef __FUNCT__ 419 #define __FUNCT__ "PetscObjectsGetObjectMatlab" 420 char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj) 421 { 422 PetscErrorCode ierr; 423 PetscInt i; 424 PetscObject h; 425 PetscBool flg; 426 427 PetscFunctionBegin; 428 *obj = NULL; 429 for (i=0; i<PetscObjectsMaxCounts; i++) { 430 if ((h = PetscObjects[i])) { 431 ierr = PetscObjectName(h);if (ierr) PetscFunctionReturn(0); 432 ierr = PetscStrcmp(h->name,name,&flg);if (ierr) PetscFunctionReturn(0); 433 if (flg) { 434 *obj = h; 435 PetscFunctionReturn(h->class_name); 436 } 437 } 438 } 439 PetscFunctionReturn(0); 440 } 441 #endif 442 443 #undef __FUNCT__ 444 #define __FUNCT__ "PetscObjectAddOptionsHandler" 445 /*@C 446 PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called. 447 448 Not Collective 449 450 Input Parameter: 451 + obj - the PETSc object 452 . handle - function that checks for options 453 . destroy - function to destroy context if provided 454 - ctx - optional context for check function 455 456 Level: developer 457 458 459 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers() 460 461 @*/ 462 PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx) 463 { 464 PetscFunctionBegin; 465 PetscValidHeader(obj,1); 466 if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added"); 467 obj->optionhandler[obj->noptionhandler] = handle; 468 obj->optiondestroy[obj->noptionhandler] = destroy; 469 obj->optionctx[obj->noptionhandler++] = ctx; 470 PetscFunctionReturn(0); 471 } 472 473 #undef __FUNCT__ 474 #define __FUNCT__ "PetscObjectProcessOptionsHandlers" 475 /*@C 476 PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object 477 478 Not Collective 479 480 Input Parameter: 481 . obj - the PETSc object 482 483 Level: developer 484 485 486 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers() 487 488 @*/ 489 PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj) 490 { 491 PetscInt i; 492 PetscErrorCode ierr; 493 494 PetscFunctionBegin; 495 PetscValidHeader(obj,1); 496 for (i=0; i<obj->noptionhandler; i++) { 497 ierr = (*obj->optionhandler[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 498 } 499 PetscFunctionReturn(0); 500 } 501 502 #undef __FUNCT__ 503 #define __FUNCT__ "PetscObjectDestroyOptionsHandlers" 504 /*@C 505 PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object 506 507 Not Collective 508 509 Input Parameter: 510 . obj - the PETSc object 511 512 Level: developer 513 514 515 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers() 516 517 @*/ 518 PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj) 519 { 520 PetscInt i; 521 PetscErrorCode ierr; 522 523 PetscFunctionBegin; 524 PetscValidHeader(obj,1); 525 for (i=0; i<obj->noptionhandler; i++) { 526 if (obj->optiondestroy[i]) { 527 ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 528 } 529 } 530 obj->noptionhandler = 0; 531 PetscFunctionReturn(0); 532 } 533 534 535 #undef __FUNCT__ 536 #define __FUNCT__ "PetscObjectReference" 537 /*@ 538 PetscObjectReference - Indicates to any PetscObject that it is being 539 referenced by another PetscObject. This increases the reference 540 count for that object by one. 541 542 Logically Collective on PetscObject 543 544 Input Parameter: 545 . obj - the PETSc object. This must be cast with (PetscObject), for example, 546 PetscObjectReference((PetscObject)mat); 547 548 Level: advanced 549 550 .seealso: PetscObjectCompose(), PetscObjectDereference() 551 @*/ 552 PetscErrorCode PetscObjectReference(PetscObject obj) 553 { 554 PetscFunctionBegin; 555 if (!obj) PetscFunctionReturn(0); 556 PetscValidHeader(obj,1); 557 obj->refct++; 558 PetscFunctionReturn(0); 559 } 560 561 #undef __FUNCT__ 562 #define __FUNCT__ "PetscObjectGetReference" 563 /*@ 564 PetscObjectGetReference - Gets the current reference count for 565 any PETSc object. 566 567 Not Collective 568 569 Input Parameter: 570 . obj - the PETSc object; this must be cast with (PetscObject), for example, 571 PetscObjectGetReference((PetscObject)mat,&cnt); 572 573 Output Parameter: 574 . cnt - the reference count 575 576 Level: advanced 577 578 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference() 579 @*/ 580 PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt) 581 { 582 PetscFunctionBegin; 583 PetscValidHeader(obj,1); 584 PetscValidIntPointer(cnt,2); 585 *cnt = obj->refct; 586 PetscFunctionReturn(0); 587 } 588 589 #undef __FUNCT__ 590 #define __FUNCT__ "PetscObjectDereference" 591 /*@ 592 PetscObjectDereference - Indicates to any PetscObject that it is being 593 referenced by one less PetscObject. This decreases the reference 594 count for that object by one. 595 596 Collective on PetscObject if reference reaches 0 otherwise Logically Collective 597 598 Input Parameter: 599 . obj - the PETSc object; this must be cast with (PetscObject), for example, 600 PetscObjectDereference((PetscObject)mat); 601 602 Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not. 603 604 Level: advanced 605 606 .seealso: PetscObjectCompose(), PetscObjectReference() 607 @*/ 608 PetscErrorCode PetscObjectDereference(PetscObject obj) 609 { 610 PetscErrorCode ierr; 611 612 PetscFunctionBegin; 613 if (!obj) PetscFunctionReturn(0); 614 PetscValidHeader(obj,1); 615 if (obj->bops->destroy) { 616 ierr = (*obj->bops->destroy)(&obj);CHKERRQ(ierr); 617 } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine"); 618 PetscFunctionReturn(0); 619 } 620 621 /* ----------------------------------------------------------------------- */ 622 /* 623 The following routines are the versions private to the PETSc object 624 data structures. 625 */ 626 #undef __FUNCT__ 627 #define __FUNCT__ "PetscObjectGetComm_Petsc" 628 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm) 629 { 630 PetscFunctionBegin; 631 PetscValidHeader(obj,1); 632 *comm = obj->comm; 633 PetscFunctionReturn(0); 634 } 635 636 #undef __FUNCT__ 637 #define __FUNCT__ "PetscObjectRemoveReference" 638 PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[]) 639 { 640 PetscErrorCode ierr; 641 642 PetscFunctionBegin; 643 PetscValidHeader(obj,1); 644 ierr = PetscObjectListRemoveReference(&obj->olist,name);CHKERRQ(ierr); 645 PetscFunctionReturn(0); 646 } 647 648 #undef __FUNCT__ 649 #define __FUNCT__ "PetscObjectCompose_Petsc" 650 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr) 651 { 652 PetscErrorCode ierr; 653 char *tname; 654 PetscBool skipreference; 655 656 PetscFunctionBegin; 657 if (ptr) { 658 ierr = PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);CHKERRQ(ierr); 659 if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it"); 660 } 661 ierr = PetscObjectListAdd(&obj->olist,name,ptr);CHKERRQ(ierr); 662 PetscFunctionReturn(0); 663 } 664 665 #undef __FUNCT__ 666 #define __FUNCT__ "PetscObjectQuery_Petsc" 667 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr) 668 { 669 PetscErrorCode ierr; 670 671 PetscFunctionBegin; 672 PetscValidHeader(obj,1); 673 ierr = PetscObjectListFind(obj->olist,name,ptr);CHKERRQ(ierr); 674 PetscFunctionReturn(0); 675 } 676 677 #undef __FUNCT__ 678 #define __FUNCT__ "PetscObjectComposeFunction_Petsc" 679 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void)) 680 { 681 PetscErrorCode ierr; 682 683 PetscFunctionBegin; 684 PetscValidHeader(obj,1); 685 ierr = PetscFunctionListAdd(&obj->qlist,name,ptr);CHKERRQ(ierr); 686 PetscFunctionReturn(0); 687 } 688 689 #undef __FUNCT__ 690 #define __FUNCT__ "PetscObjectQueryFunction_Petsc" 691 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void)) 692 { 693 PetscErrorCode ierr; 694 695 PetscFunctionBegin; 696 PetscValidHeader(obj,1); 697 ierr = PetscFunctionListFind(obj->qlist,name,ptr);CHKERRQ(ierr); 698 PetscFunctionReturn(0); 699 } 700 701 #undef __FUNCT__ 702 #define __FUNCT__ "PetscObjectCompose" 703 /*@C 704 PetscObjectCompose - Associates another PETSc object with a given PETSc object. 705 706 Not Collective 707 708 Input Parameters: 709 + obj - the PETSc object; this must be cast with (PetscObject), for example, 710 PetscObjectCompose((PetscObject)mat,...); 711 . name - name associated with the child object 712 - ptr - the other PETSc object to associate with the PETSc object; this must also be 713 cast with (PetscObject) 714 715 Level: advanced 716 717 Notes: 718 The second objects reference count is automatically increased by one when it is 719 composed. 720 721 Replaces any previous object that had the same name. 722 723 If ptr is null and name has previously been composed using an object, then that 724 entry is removed from the obj. 725 726 PetscObjectCompose() can be used with any PETSc object (such as 727 Mat, Vec, KSP, SNES, etc.) or any user-provided object. See 728 PetscContainerCreate() for info on how to create an object from a 729 user-provided pointer that may then be composed with PETSc objects. 730 731 Concepts: objects^composing 732 Concepts: composing objects 733 734 .seealso: PetscObjectQuery(), PetscContainerCreate() 735 @*/ 736 PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr) 737 { 738 PetscErrorCode ierr; 739 740 PetscFunctionBegin; 741 PetscValidHeader(obj,1); 742 PetscValidCharPointer(name,2); 743 if (ptr) PetscValidHeader(ptr,3); 744 ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr); 745 PetscFunctionReturn(0); 746 } 747 748 #undef __FUNCT__ 749 #define __FUNCT__ "PetscObjectSetPrecision" 750 /*@C 751 PetscObjectSetPrecision - sets the precision used within a given object. 752 753 Collective on the PetscObject 754 755 Input Parameters: 756 + obj - the PETSc object; this must be cast with (PetscObject), for example, 757 PetscObjectCompose((PetscObject)mat,...); 758 - precision - the precision 759 760 Level: advanced 761 762 .seealso: PetscObjectQuery(), PetscContainerCreate() 763 @*/ 764 PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision) 765 { 766 PetscFunctionBegin; 767 PetscValidHeader(obj,1); 768 obj->precision = precision; 769 PetscFunctionReturn(0); 770 } 771 772 #undef __FUNCT__ 773 #define __FUNCT__ "PetscObjectQuery" 774 /*@C 775 PetscObjectQuery - Gets a PETSc object associated with a given object. 776 777 Not Collective 778 779 Input Parameters: 780 + obj - the PETSc object 781 Thus must be cast with a (PetscObject), for example, 782 PetscObjectCompose((PetscObject)mat,...); 783 . name - name associated with child object 784 - ptr - the other PETSc object associated with the PETSc object, this must be 785 cast with (PetscObject*) 786 787 Level: advanced 788 789 The reference count of neither object is increased in this call 790 791 Concepts: objects^composing 792 Concepts: composing objects 793 Concepts: objects^querying 794 Concepts: querying objects 795 796 .seealso: PetscObjectCompose() 797 @*/ 798 PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 799 { 800 PetscErrorCode ierr; 801 802 PetscFunctionBegin; 803 PetscValidHeader(obj,1); 804 PetscValidCharPointer(name,2); 805 PetscValidPointer(ptr,3); 806 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 807 PetscFunctionReturn(0); 808 } 809 810 /*MC 811 PetscObjectComposeFunction - Associates a function with a given PETSc object. 812 813 Synopsis: 814 #include <petscsys.h> 815 PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void)) 816 817 Logically Collective on PetscObject 818 819 Input Parameters: 820 + obj - the PETSc object; this must be cast with a (PetscObject), for example, 821 PetscObjectCompose((PetscObject)mat,...); 822 . name - name associated with the child function 823 . fname - name of the function 824 - fptr - function pointer 825 826 Level: advanced 827 828 Notes: 829 To remove a registered routine, pass in NULL for fptr(). 830 831 PetscObjectComposeFunction() can be used with any PETSc object (such as 832 Mat, Vec, KSP, SNES, etc.) or any user-provided object. 833 834 Concepts: objects^composing functions 835 Concepts: composing functions 836 Concepts: functions^querying 837 Concepts: objects^querying 838 Concepts: querying objects 839 840 .seealso: PetscObjectQueryFunction(), PetscContainerCreate() 841 M*/ 842 843 #undef __FUNCT__ 844 #define __FUNCT__ "PetscObjectComposeFunction_Private" 845 PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void)) 846 { 847 PetscErrorCode ierr; 848 849 PetscFunctionBegin; 850 PetscValidHeader(obj,1); 851 PetscValidCharPointer(name,2); 852 ierr = (*obj->bops->composefunction)(obj,name,fptr);CHKERRQ(ierr); 853 PetscFunctionReturn(0); 854 } 855 856 /*MC 857 PetscObjectQueryFunction - Gets a function associated with a given object. 858 859 Synopsis: 860 #include <petscsys.h> 861 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void)) 862 863 Logically Collective on PetscObject 864 865 Input Parameters: 866 + obj - the PETSc object; this must be cast with (PetscObject), for example, 867 PetscObjectQueryFunction((PetscObject)ksp,...); 868 - name - name associated with the child function 869 870 Output Parameter: 871 . fptr - function pointer 872 873 Level: advanced 874 875 Concepts: objects^composing functions 876 Concepts: composing functions 877 Concepts: functions^querying 878 Concepts: objects^querying 879 Concepts: querying objects 880 881 .seealso: PetscObjectComposeFunction(), PetscFunctionListFind() 882 M*/ 883 #undef __FUNCT__ 884 #define __FUNCT__ "PetscObjectQueryFunction_Private" 885 PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void)) 886 { 887 PetscErrorCode ierr; 888 889 PetscFunctionBegin; 890 PetscValidHeader(obj,1); 891 PetscValidCharPointer(name,2); 892 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 893 PetscFunctionReturn(0); 894 } 895 896 struct _p_PetscContainer { 897 PETSCHEADER(int); 898 void *ptr; 899 PetscErrorCode (*userdestroy)(void*); 900 }; 901 902 #undef __FUNCT__ 903 #define __FUNCT__ "PetscContainerGetPointer" 904 /*@C 905 PetscContainerGetPointer - Gets the pointer value contained in the container. 906 907 Not Collective 908 909 Input Parameter: 910 . obj - the object created with PetscContainerCreate() 911 912 Output Parameter: 913 . ptr - the pointer value 914 915 Level: advanced 916 917 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 918 PetscContainerSetPointer() 919 @*/ 920 PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr) 921 { 922 PetscFunctionBegin; 923 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 924 PetscValidPointer(ptr,2); 925 *ptr = obj->ptr; 926 PetscFunctionReturn(0); 927 } 928 929 930 #undef __FUNCT__ 931 #define __FUNCT__ "PetscContainerSetPointer" 932 /*@C 933 PetscContainerSetPointer - Sets the pointer value contained in the container. 934 935 Logically Collective on PetscContainer 936 937 Input Parameters: 938 + obj - the object created with PetscContainerCreate() 939 - ptr - the pointer value 940 941 Level: advanced 942 943 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 944 PetscContainerGetPointer() 945 @*/ 946 PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr) 947 { 948 PetscFunctionBegin; 949 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 950 if (ptr) PetscValidPointer(ptr,2); 951 obj->ptr = ptr; 952 PetscFunctionReturn(0); 953 } 954 955 #undef __FUNCT__ 956 #define __FUNCT__ "PetscContainerDestroy" 957 /*@C 958 PetscContainerDestroy - Destroys a PETSc container object. 959 960 Collective on PetscContainer 961 962 Input Parameter: 963 . obj - an object that was created with PetscContainerCreate() 964 965 Level: advanced 966 967 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy() 968 @*/ 969 PetscErrorCode PetscContainerDestroy(PetscContainer *obj) 970 { 971 PetscErrorCode ierr; 972 973 PetscFunctionBegin; 974 if (!*obj) PetscFunctionReturn(0); 975 PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1); 976 if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);} 977 if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr); 978 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 979 PetscFunctionReturn(0); 980 } 981 982 #undef __FUNCT__ 983 #define __FUNCT__ "PetscContainerSetUserDestroy" 984 /*@C 985 PetscContainerSetUserDestroy - Sets name of the user destroy function. 986 987 Logically Collective on PetscContainer 988 989 Input Parameter: 990 + obj - an object that was created with PetscContainerCreate() 991 - des - name of the user destroy function 992 993 Level: advanced 994 995 .seealso: PetscContainerDestroy() 996 @*/ 997 PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 998 { 999 PetscFunctionBegin; 1000 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 1001 obj->userdestroy = des; 1002 PetscFunctionReturn(0); 1003 } 1004 1005 PetscClassId PETSC_CONTAINER_CLASSID; 1006 1007 #undef __FUNCT__ 1008 #define __FUNCT__ "PetscContainerCreate" 1009 /*@C 1010 PetscContainerCreate - Creates a PETSc object that has room to hold 1011 a single pointer. This allows one to attach any type of data (accessible 1012 through a pointer) with the PetscObjectCompose() function to a PetscObject. 1013 The data item itself is attached by a call to PetscContainerSetPointer(). 1014 1015 Collective on MPI_Comm 1016 1017 Input Parameters: 1018 . comm - MPI communicator that shares the object 1019 1020 Output Parameters: 1021 . container - the container created 1022 1023 Level: advanced 1024 1025 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer() 1026 @*/ 1027 PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 1028 { 1029 PetscErrorCode ierr; 1030 PetscContainer contain; 1031 1032 PetscFunctionBegin; 1033 PetscValidPointer(container,2); 1034 ierr = PetscSysInitializePackage();CHKERRQ(ierr); 1035 ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);CHKERRQ(ierr); 1036 *container = contain; 1037 PetscFunctionReturn(0); 1038 } 1039 1040 #undef __FUNCT__ 1041 #define __FUNCT__ "PetscObjectSetFromOptions" 1042 /*@ 1043 PetscObjectSetFromOptions - Sets generic parameters from user options. 1044 1045 Collective on obj 1046 1047 Input Parameter: 1048 . obj - the PetscObjcet 1049 1050 Options Database Keys: 1051 1052 Notes: 1053 We have no generic options at present, so this does nothing 1054 1055 Level: beginner 1056 1057 .keywords: set, options, database 1058 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 1059 @*/ 1060 PetscErrorCode PetscObjectSetFromOptions(PetscObject obj) 1061 { 1062 PetscFunctionBegin; 1063 PetscValidHeader(obj,1); 1064 PetscFunctionReturn(0); 1065 } 1066 1067 #undef __FUNCT__ 1068 #define __FUNCT__ "PetscObjectSetUp" 1069 /*@ 1070 PetscObjectSetUp - Sets up the internal data structures for the later use. 1071 1072 Collective on PetscObject 1073 1074 Input Parameters: 1075 . obj - the PetscObject 1076 1077 Notes: 1078 This does nothing at present. 1079 1080 Level: advanced 1081 1082 .keywords: setup 1083 .seealso: PetscObjectDestroy() 1084 @*/ 1085 PetscErrorCode PetscObjectSetUp(PetscObject obj) 1086 { 1087 PetscFunctionBegin; 1088 PetscValidHeader(obj,1); 1089 PetscFunctionReturn(0); 1090 } 1091