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