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