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 7 PetscObject *PetscObjects = 0; 8 PetscInt PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0; 9 10 extern PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm*); 11 extern PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject); 12 extern PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject*); 13 extern PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],const char[],void (*)(void)); 14 extern PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void)); 15 16 #undef __FUNCT__ 17 #define __FUNCT__ "PetscHeaderCreate_Private" 18 /* 19 PetscHeaderCreate_Private - Creates a base PETSc object header and fills 20 in the default values. Called by the macro PetscHeaderCreate(). 21 */ 22 PetscErrorCode PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[], 23 MPI_Comm comm,PetscErrorCode (*des)(PetscObject*),PetscErrorCode (*vie)(PetscObject,PetscViewer)) 24 { 25 static PetscInt idcnt = 1; 26 PetscErrorCode ierr; 27 PetscObject *newPetscObjects; 28 PetscInt newPetscObjectsMaxCounts,i; 29 30 PetscFunctionBegin; 31 h->classid = classid; 32 h->type = 0; 33 h->class_name = (char*)class_name; 34 h->description = (char*)descr; 35 h->mansec = (char*)mansec; 36 h->prefix = 0; 37 h->refct = 1; 38 h->amem = -1; 39 h->id = idcnt++; 40 h->parentid = 0; 41 h->qlist = 0; 42 h->olist = 0; 43 h->precision = (PetscPrecision) sizeof(PetscReal); 44 h->bops->destroy = des; 45 h->bops->view = vie; 46 h->bops->getcomm = PetscObjectGetComm_Petsc; 47 h->bops->compose = PetscObjectCompose_Petsc; 48 h->bops->query = PetscObjectQuery_Petsc; 49 h->bops->composefunction = PetscObjectComposeFunction_Petsc; 50 h->bops->queryfunction = PetscObjectQueryFunction_Petsc; 51 52 ierr = PetscCommDuplicate(comm,&h->comm,&h->tag);CHKERRQ(ierr); 53 54 /* Keep a record of object created */ 55 PetscObjectsCounts++; 56 for (i=0; i<PetscObjectsMaxCounts; i++) { 57 if (!PetscObjects[i]) { 58 PetscObjects[i] = h; 59 PetscFunctionReturn(0); 60 } 61 } 62 /* Need to increase the space for storing PETSc objects */ 63 if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100; 64 else newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts; 65 ierr = PetscMalloc(newPetscObjectsMaxCounts*sizeof(PetscObject),&newPetscObjects);CHKERRQ(ierr); 66 ierr = PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));CHKERRQ(ierr); 67 ierr = PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));CHKERRQ(ierr); 68 ierr = PetscFree(PetscObjects);CHKERRQ(ierr); 69 70 PetscObjects = newPetscObjects; 71 PetscObjects[PetscObjectsMaxCounts] = h; 72 PetscObjectsMaxCounts = newPetscObjectsMaxCounts; 73 PetscFunctionReturn(0); 74 } 75 76 extern PetscBool PetscMemoryCollectMaximumUsage; 77 extern PetscLogDouble PetscMemoryMaximumUsage; 78 79 #undef __FUNCT__ 80 #define __FUNCT__ "PetscHeaderDestroy_Private" 81 /* 82 PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by 83 the macro PetscHeaderDestroy(). 84 */ 85 PetscErrorCode PetscHeaderDestroy_Private(PetscObject h) 86 { 87 PetscErrorCode ierr; 88 PetscInt i; 89 90 PetscFunctionBegin; 91 PetscValidHeader(h,1); 92 ierr = PetscLogObjectDestroy(h);CHKERRQ(ierr); 93 ierr = PetscComposedQuantitiesDestroy(h); 94 #if defined(PETSC_HAVE_AMS) 95 if (PetscAMSPublishAll) { 96 ierr = PetscObjectUnPublish((PetscObject)h);CHKERRQ(ierr); 97 } 98 #endif 99 if (PetscMemoryCollectMaximumUsage) { 100 PetscLogDouble usage; 101 ierr = PetscMemoryGetCurrentUsage(&usage);CHKERRQ(ierr); 102 if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage; 103 } 104 /* first destroy things that could execute arbitrary code */ 105 if (h->python_destroy) { 106 void *python_context = h->python_context; 107 PetscErrorCode (*python_destroy)(void*) = h->python_destroy; 108 h->python_context = 0; 109 h->python_destroy = 0; 110 111 ierr = (*python_destroy)(python_context);CHKERRQ(ierr); 112 } 113 ierr = PetscObjectListDestroy(&h->olist);CHKERRQ(ierr); 114 ierr = PetscCommDestroy(&h->comm);CHKERRQ(ierr); 115 /* next destroy other things */ 116 h->classid = PETSCFREEDHEADER; 117 118 ierr = PetscFree(h->bops);CHKERRQ(ierr); 119 ierr = PetscFunctionListDestroy(&h->qlist);CHKERRQ(ierr); 120 ierr = PetscFree(h->type_name);CHKERRQ(ierr); 121 ierr = PetscFree(h->name);CHKERRQ(ierr); 122 ierr = PetscFree(h->prefix);CHKERRQ(ierr); 123 ierr = PetscFree(h->fortran_func_pointers);CHKERRQ(ierr); 124 ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);CHKERRQ(ierr); 125 ierr = PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);CHKERRQ(ierr); 126 127 /* Record object removal from list of all objects */ 128 for (i=0; i<PetscObjectsMaxCounts; i++) { 129 if (PetscObjects[i] == h) { 130 PetscObjects[i] = 0; 131 PetscObjectsCounts--; 132 break; 133 } 134 } 135 if (!PetscObjectsCounts) { 136 ierr = PetscFree(PetscObjects);CHKERRQ(ierr); 137 PetscObjectsMaxCounts = 0; 138 } 139 PetscFunctionReturn(0); 140 } 141 142 #undef __FUNCT__ 143 #define __FUNCT__ "PetscObjectCopyFortranFunctionPointers" 144 /*@C 145 PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object 146 147 Logically Collective on PetscObject 148 149 Input Parameter: 150 + src - source object 151 - dest - destination object 152 153 Level: developer 154 155 Note: 156 Both objects must have the same class. 157 @*/ 158 PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest) 159 { 160 PetscErrorCode ierr; 161 PetscInt cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE]; 162 163 PetscFunctionBegin; 164 PetscValidHeader(src,1); 165 PetscValidHeader(dest,2); 166 if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class"); 167 168 ierr = PetscFree(dest->fortran_func_pointers);CHKERRQ(ierr); 169 ierr = PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);CHKERRQ(ierr); 170 ierr = PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));CHKERRQ(ierr); 171 172 dest->num_fortran_func_pointers = src->num_fortran_func_pointers; 173 174 ierr = PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);CHKERRQ(ierr); 175 for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) { 176 ierr = PetscFree(dest->fortrancallback[cbtype]);CHKERRQ(ierr); 177 ierr = PetscMalloc(numcb[cbtype]*sizeof(PetscFortranCallback),&dest->fortrancallback[cbtype]);CHKERRQ(ierr); 178 ierr = PetscMemzero(dest->fortrancallback[cbtype],numcb[cbtype]*sizeof(PetscFortranCallback));CHKERRQ(ierr); 179 ierr = PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));CHKERRQ(ierr); 180 } 181 PetscFunctionReturn(0); 182 } 183 184 #undef __FUNCT__ 185 #define __FUNCT__ "PetscObjectSetFortranCallback" 186 /*@C 187 PetscObjectSetFortranCallback - set fortran callback function pointer and context 188 189 Logically Collective 190 191 Input Arguments: 192 + obj - object on which to set callback 193 . cbtype - callback type (class or subtype) 194 . cid - address of callback Id, updated if not yet initialized (zero) 195 . func - Fortran function 196 - ctx - Fortran context 197 198 Level: developer 199 200 .seealso: PetscObjectGetFortranCallback() 201 @*/ 202 PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx) 203 { 204 PetscErrorCode ierr; 205 const char *subtype = NULL; 206 207 PetscFunctionBegin; 208 PetscValidHeader(obj,1); 209 if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name; 210 if (!*cid) {ierr = PetscFortranCallbackRegister(obj->classid,subtype,cid);CHKERRQ(ierr);} 211 if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) { 212 PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum); 213 PetscFortranCallback *callback; 214 ierr = PetscMalloc(newnum*sizeof(callback[0]),&callback);CHKERRQ(ierr); 215 ierr = PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));CHKERRQ(ierr); 216 ierr = PetscFree(obj->fortrancallback[cbtype]);CHKERRQ(ierr); 217 218 obj->fortrancallback[cbtype] = callback; 219 obj->num_fortrancallback[cbtype] = newnum; 220 } 221 obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func; 222 obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx; 223 PetscFunctionReturn(0); 224 } 225 226 #undef __FUNCT__ 227 #define __FUNCT__ "PetscObjectGetFortranCallback" 228 /*@C 229 PetscObjectGetFortranCallback - get fortran callback function pointer and context 230 231 Logically Collective 232 233 Input Arguments: 234 + obj - object on which to get callback 235 . cbtype - callback type 236 - cid - address of callback Id 237 238 Output Arguments: 239 + func - Fortran function (or NULL if not needed) 240 - ctx - Fortran context (or NULL if not needed) 241 242 Level: developer 243 244 .seealso: PetscObjectSetFortranCallback() 245 @*/ 246 PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx) 247 { 248 PetscFortranCallback *cb; 249 250 PetscFunctionBegin; 251 PetscValidHeader(obj,1); 252 if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid"); 253 if (PetscUnlikely(cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype])) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback not set on this object"); 254 cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK]; 255 if (func) *func = cb->func; 256 if (ctx) *ctx = cb->ctx; 257 PetscFunctionReturn(0); 258 } 259 260 #undef __FUNCT__ 261 #define __FUNCT__ "PetscObjectsDump" 262 /*@C 263 PetscObjectsDump - Prints the currently existing objects. 264 265 Logically Collective on PetscViewer 266 267 Input Parameter: 268 + viewer - must be an PETSCVIEWERASCII viewer 269 - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects 270 271 Level: advanced 272 273 Concepts: options database^printing 274 275 @*/ 276 PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all) 277 { 278 PetscErrorCode ierr; 279 PetscInt i; 280 #if defined(PETSC_USE_DEBUG) 281 PetscInt j,k; 282 #endif 283 PetscObject h; 284 285 PetscFunctionBegin; 286 if (PetscObjectsCounts) { 287 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");CHKERRQ(ierr); 288 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");CHKERRQ(ierr); 289 for (i=0; i<PetscObjectsMaxCounts; i++) { 290 if ((h = PetscObjects[i])) { 291 ierr = PetscObjectName(h);CHKERRQ(ierr); 292 { 293 #if defined(PETSC_USE_DEBUG) 294 PetscStack *stack; 295 char *create,*rclass; 296 297 /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */ 298 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 299 k = stack->currentsize-2; 300 if (!all) { 301 k = 0; 302 while (!stack->petscroutine[k]) k++; 303 ierr = PetscStrstr(stack->function[k],"Create",&create);CHKERRQ(ierr); 304 if (!create) { 305 ierr = PetscStrstr(stack->function[k],"Get",&create);CHKERRQ(ierr); 306 } 307 ierr = PetscStrstr(stack->function[k],h->class_name,&rclass);CHKERRQ(ierr); 308 309 if (!create) continue; 310 if (!rclass) continue; 311 } 312 #endif 313 314 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);CHKERRQ(ierr); 315 316 #if defined(PETSC_USE_DEBUG) 317 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 318 for (j=k; j>=0; j--) { 319 fprintf(fd," [%d] %s() in %s%s\n",PetscGlobalRank,stack->function[j],stack->directory[j],stack->file[j]); 320 } 321 #endif 322 } 323 } 324 } 325 } 326 PetscFunctionReturn(0); 327 } 328 329 330 #undef __FUNCT__ 331 #define __FUNCT__ "PetscObjectsView" 332 /*@C 333 PetscObjectsView - Prints the currently existing objects. 334 335 Logically Collective on PetscViewer 336 337 Input Parameter: 338 . viewer - must be an PETSCVIEWERASCII viewer 339 340 Level: advanced 341 342 Concepts: options database^printing 343 344 @*/ 345 PetscErrorCode PetscObjectsView(PetscViewer viewer) 346 { 347 PetscErrorCode ierr; 348 PetscBool isascii; 349 FILE *fd; 350 351 PetscFunctionBegin; 352 if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 353 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 354 if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer"); 355 ierr = PetscViewerASCIIGetPointer(viewer,&fd);CHKERRQ(ierr); 356 ierr = PetscObjectsDump(fd,PETSC_TRUE);CHKERRQ(ierr); 357 PetscFunctionReturn(0); 358 } 359 360 #undef __FUNCT__ 361 #define __FUNCT__ "PetscObjectsGetObject" 362 /*@C 363 PetscObjectsGetObject - Get a pointer to a named object 364 365 Not collective 366 367 Input Parameter: 368 . name - the name of an object 369 370 Output Parameter: 371 . obj - the object or null if there is no object 372 373 Level: advanced 374 375 Concepts: options database^printing 376 377 @*/ 378 PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname) 379 { 380 PetscErrorCode ierr; 381 PetscInt i; 382 PetscObject h; 383 PetscBool flg; 384 385 PetscFunctionBegin; 386 *obj = NULL; 387 for (i=0; i<PetscObjectsMaxCounts; i++) { 388 if ((h = PetscObjects[i])) { 389 ierr = PetscObjectName(h);CHKERRQ(ierr); 390 ierr = PetscStrcmp(h->name,name,&flg);CHKERRQ(ierr); 391 if (flg) { 392 *obj = h; 393 if (classname) *classname = h->class_name; 394 PetscFunctionReturn(0); 395 } 396 } 397 } 398 PetscFunctionReturn(0); 399 } 400 401 #undef __FUNCT__ 402 #define __FUNCT__ "PetscObjectsGetObjectMatlab" 403 char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj) 404 { 405 PetscErrorCode ierr; 406 PetscInt i; 407 PetscObject h; 408 PetscBool flg; 409 410 PetscFunctionBegin; 411 *obj = NULL; 412 for (i=0; i<PetscObjectsMaxCounts; i++) { 413 if ((h = PetscObjects[i])) { 414 ierr = PetscObjectName(h);if (ierr) PetscFunctionReturn(0); 415 ierr = PetscStrcmp(h->name,name,&flg);if (ierr) PetscFunctionReturn(0); 416 if (flg) { 417 *obj = h; 418 PetscFunctionReturn(h->class_name); 419 } 420 } 421 } 422 PetscFunctionReturn(0); 423 } 424 425 #undef __FUNCT__ 426 #define __FUNCT__ "PetscObjectAddOptionsHandler" 427 /*@C 428 PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called. 429 430 Not Collective 431 432 Input Parameter: 433 + obj - the PETSc object 434 . handle - function that checks for options 435 . destroy - function to destroy context if provided 436 - ctx - optional context for check function 437 438 Level: developer 439 440 441 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers() 442 443 @*/ 444 PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx) 445 { 446 PetscFunctionBegin; 447 PetscValidHeader(obj,1); 448 if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added"); 449 obj->optionhandler[obj->noptionhandler] = handle; 450 obj->optiondestroy[obj->noptionhandler] = destroy; 451 obj->optionctx[obj->noptionhandler++] = ctx; 452 PetscFunctionReturn(0); 453 } 454 455 #undef __FUNCT__ 456 #define __FUNCT__ "PetscObjectProcessOptionsHandlers" 457 /*@C 458 PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object 459 460 Not Collective 461 462 Input Parameter: 463 . obj - the PETSc object 464 465 Level: developer 466 467 468 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers() 469 470 @*/ 471 PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj) 472 { 473 PetscInt i; 474 PetscErrorCode ierr; 475 476 PetscFunctionBegin; 477 PetscValidHeader(obj,1); 478 for (i=0; i<obj->noptionhandler; i++) { 479 ierr = (*obj->optionhandler[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 480 } 481 PetscFunctionReturn(0); 482 } 483 484 #undef __FUNCT__ 485 #define __FUNCT__ "PetscObjectDestroyOptionsHandlers" 486 /*@C 487 PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an objeft 488 489 Not Collective 490 491 Input Parameter: 492 . obj - the PETSc object 493 494 Level: developer 495 496 497 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers() 498 499 @*/ 500 PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj) 501 { 502 PetscInt i; 503 PetscErrorCode ierr; 504 505 PetscFunctionBegin; 506 PetscValidHeader(obj,1); 507 for (i=0; i<obj->noptionhandler; i++) { 508 ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 509 } 510 obj->noptionhandler = 0; 511 PetscFunctionReturn(0); 512 } 513 514 515 #undef __FUNCT__ 516 #define __FUNCT__ "PetscObjectReference" 517 /*@ 518 PetscObjectReference - Indicates to any PetscObject that it is being 519 referenced by another PetscObject. This increases the reference 520 count for that object by one. 521 522 Logically Collective on PetscObject 523 524 Input Parameter: 525 . obj - the PETSc object. This must be cast with (PetscObject), for example, 526 PetscObjectReference((PetscObject)mat); 527 528 Level: advanced 529 530 .seealso: PetscObjectCompose(), PetscObjectDereference() 531 @*/ 532 PetscErrorCode PetscObjectReference(PetscObject obj) 533 { 534 PetscFunctionBegin; 535 if (!obj) PetscFunctionReturn(0); 536 PetscValidHeader(obj,1); 537 obj->refct++; 538 PetscFunctionReturn(0); 539 } 540 541 #undef __FUNCT__ 542 #define __FUNCT__ "PetscObjectGetReference" 543 /*@ 544 PetscObjectGetReference - Gets the current reference count for 545 any PETSc object. 546 547 Not Collective 548 549 Input Parameter: 550 . obj - the PETSc object; this must be cast with (PetscObject), for example, 551 PetscObjectGetReference((PetscObject)mat,&cnt); 552 553 Output Parameter: 554 . cnt - the reference count 555 556 Level: advanced 557 558 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference() 559 @*/ 560 PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt) 561 { 562 PetscFunctionBegin; 563 PetscValidHeader(obj,1); 564 PetscValidIntPointer(cnt,2); 565 *cnt = obj->refct; 566 PetscFunctionReturn(0); 567 } 568 569 #undef __FUNCT__ 570 #define __FUNCT__ "PetscObjectDereference" 571 /*@ 572 PetscObjectDereference - Indicates to any PetscObject that it is being 573 referenced by one less PetscObject. This decreases the reference 574 count for that object by one. 575 576 Collective on PetscObject if reference reaches 0 otherwise Logically Collective 577 578 Input Parameter: 579 . obj - the PETSc object; this must be cast with (PetscObject), for example, 580 PetscObjectDereference((PetscObject)mat); 581 582 Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not. 583 584 Level: advanced 585 586 .seealso: PetscObjectCompose(), PetscObjectReference() 587 @*/ 588 PetscErrorCode PetscObjectDereference(PetscObject obj) 589 { 590 PetscErrorCode ierr; 591 592 PetscFunctionBegin; 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[],const char fname[],void (*ptr)(void)) 659 { 660 PetscErrorCode ierr; 661 662 PetscFunctionBegin; 663 PetscValidHeader(obj,1); 664 ierr = PetscFunctionListAdd(obj->comm,&obj->qlist,name,fname,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->comm,obj->qlist,name,PETSC_FALSE,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 #undef __FUNCT__ 790 #define __FUNCT__ "PetscObjectComposeFunction" 791 PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void)) 792 { 793 PetscErrorCode ierr; 794 795 PetscFunctionBegin; 796 PetscValidHeader(obj,1); 797 PetscValidCharPointer(name,2); 798 ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr); 799 PetscFunctionReturn(0); 800 } 801 802 #undef __FUNCT__ 803 #define __FUNCT__ "PetscObjectQueryFunction" 804 /*@C 805 PetscObjectQueryFunction - Gets a function associated with a given object. 806 807 Logically Collective on PetscObject 808 809 Input Parameters: 810 + obj - the PETSc object; this must be cast with (PetscObject), for example, 811 PetscObjectQueryFunction((PetscObject)ksp,...); 812 - name - name associated with the child function 813 814 Output Parameter: 815 . ptr - function pointer 816 817 Level: advanced 818 819 Concepts: objects^composing functions 820 Concepts: composing functions 821 Concepts: functions^querying 822 Concepts: objects^querying 823 Concepts: querying objects 824 825 .seealso: PetscObjectComposeFunctionDynamic() 826 @*/ 827 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void)) 828 { 829 PetscErrorCode ierr; 830 831 PetscFunctionBegin; 832 PetscValidHeader(obj,1); 833 PetscValidCharPointer(name,2); 834 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 835 PetscFunctionReturn(0); 836 } 837 838 struct _p_PetscContainer { 839 PETSCHEADER(int); 840 void *ptr; 841 PetscErrorCode (*userdestroy)(void*); 842 }; 843 844 #undef __FUNCT__ 845 #define __FUNCT__ "PetscContainerGetPointer" 846 /*@C 847 PetscContainerGetPointer - Gets the pointer value contained in the container. 848 849 Not Collective 850 851 Input Parameter: 852 . obj - the object created with PetscContainerCreate() 853 854 Output Parameter: 855 . ptr - the pointer value 856 857 Level: advanced 858 859 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 860 PetscContainerSetPointer() 861 @*/ 862 PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr) 863 { 864 PetscFunctionBegin; 865 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 866 PetscValidPointer(ptr,2); 867 *ptr = obj->ptr; 868 PetscFunctionReturn(0); 869 } 870 871 872 #undef __FUNCT__ 873 #define __FUNCT__ "PetscContainerSetPointer" 874 /*@C 875 PetscContainerSetPointer - Sets the pointer value contained in the container. 876 877 Logically Collective on PetscContainer 878 879 Input Parameters: 880 + obj - the object created with PetscContainerCreate() 881 - ptr - the pointer value 882 883 Level: advanced 884 885 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 886 PetscContainerGetPointer() 887 @*/ 888 PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr) 889 { 890 PetscFunctionBegin; 891 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 892 if (ptr) PetscValidPointer(ptr,2); 893 obj->ptr = ptr; 894 PetscFunctionReturn(0); 895 } 896 897 #undef __FUNCT__ 898 #define __FUNCT__ "PetscContainerDestroy" 899 /*@C 900 PetscContainerDestroy - Destroys a PETSc container object. 901 902 Collective on PetscContainer 903 904 Input Parameter: 905 . obj - an object that was created with PetscContainerCreate() 906 907 Level: advanced 908 909 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy() 910 @*/ 911 PetscErrorCode PetscContainerDestroy(PetscContainer *obj) 912 { 913 PetscErrorCode ierr; 914 915 PetscFunctionBegin; 916 if (!*obj) PetscFunctionReturn(0); 917 PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1); 918 if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);} 919 if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr); 920 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 921 PetscFunctionReturn(0); 922 } 923 924 #undef __FUNCT__ 925 #define __FUNCT__ "PetscContainerSetUserDestroy" 926 /*@C 927 PetscContainerSetUserDestroy - Sets name of the user destroy function. 928 929 Logically Collective on PetscContainer 930 931 Input Parameter: 932 + obj - an object that was created with PetscContainerCreate() 933 - des - name of the user destroy function 934 935 Level: advanced 936 937 .seealso: PetscContainerDestroy() 938 @*/ 939 PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 940 { 941 PetscFunctionBegin; 942 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 943 obj->userdestroy = des; 944 PetscFunctionReturn(0); 945 } 946 947 PetscClassId PETSC_CONTAINER_CLASSID; 948 949 #undef __FUNCT__ 950 #define __FUNCT__ "PetscContainerCreate" 951 /*@C 952 PetscContainerCreate - Creates a PETSc object that has room to hold 953 a single pointer. This allows one to attach any type of data (accessible 954 through a pointer) with the PetscObjectCompose() function to a PetscObject. 955 The data item itself is attached by a call to PetscContainerSetPointer(). 956 957 Collective on MPI_Comm 958 959 Input Parameters: 960 . comm - MPI communicator that shares the object 961 962 Output Parameters: 963 . container - the container created 964 965 Level: advanced 966 967 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer() 968 @*/ 969 PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 970 { 971 PetscErrorCode ierr; 972 PetscContainer contain; 973 974 PetscFunctionBegin; 975 PetscValidPointer(container,2); 976 ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);CHKERRQ(ierr); 977 *container = contain; 978 PetscFunctionReturn(0); 979 } 980 981 #undef __FUNCT__ 982 #define __FUNCT__ "PetscObjectSetFromOptions" 983 /*@ 984 PetscObjectSetFromOptions - Sets generic parameters from user options. 985 986 Collective on obj 987 988 Input Parameter: 989 . obj - the PetscObjcet 990 991 Options Database Keys: 992 993 Notes: 994 We have no generic options at present, so this does nothing 995 996 Level: beginner 997 998 .keywords: set, options, database 999 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 1000 @*/ 1001 PetscErrorCode PetscObjectSetFromOptions(PetscObject obj) 1002 { 1003 PetscFunctionBegin; 1004 PetscValidHeader(obj,1); 1005 PetscFunctionReturn(0); 1006 } 1007 1008 #undef __FUNCT__ 1009 #define __FUNCT__ "PetscObjectSetUp" 1010 /*@ 1011 PetscObjectSetUp - Sets up the internal data structures for the later use. 1012 1013 Collective on PetscObject 1014 1015 Input Parameters: 1016 . obj - the PetscObject 1017 1018 Notes: 1019 This does nothing at present. 1020 1021 Level: advanced 1022 1023 .keywords: setup 1024 .seealso: PetscObjectDestroy() 1025 @*/ 1026 PetscErrorCode PetscObjectSetUp(PetscObject obj) 1027 { 1028 PetscFunctionBegin; 1029 PetscValidHeader(obj,1); 1030 PetscFunctionReturn(0); 1031 } 1032