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