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