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 = PetscMalloc(newPetscObjectsMaxCounts*sizeof(PetscObject),&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 = PetscMalloc(numcb[cbtype]*sizeof(PetscFortranCallback),&dest->fortrancallback[cbtype]);CHKERRQ(ierr); 187 ierr = PetscMemzero(dest->fortrancallback[cbtype],numcb[cbtype]*sizeof(PetscFortranCallback));CHKERRQ(ierr); 188 ierr = PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));CHKERRQ(ierr); 189 } 190 PetscFunctionReturn(0); 191 } 192 193 #undef __FUNCT__ 194 #define __FUNCT__ "PetscObjectSetFortranCallback" 195 /*@C 196 PetscObjectSetFortranCallback - set fortran callback function pointer and context 197 198 Logically Collective 199 200 Input Arguments: 201 + obj - object on which to set callback 202 . cbtype - callback type (class or subtype) 203 . cid - address of callback Id, updated if not yet initialized (zero) 204 . func - Fortran function 205 - ctx - Fortran context 206 207 Level: developer 208 209 .seealso: PetscObjectGetFortranCallback() 210 @*/ 211 PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx) 212 { 213 PetscErrorCode ierr; 214 const char *subtype = NULL; 215 216 PetscFunctionBegin; 217 PetscValidHeader(obj,1); 218 if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name; 219 if (!*cid) {ierr = PetscFortranCallbackRegister(obj->classid,subtype,cid);CHKERRQ(ierr);} 220 if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) { 221 PetscInt oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum); 222 PetscFortranCallback *callback; 223 ierr = PetscMalloc(newnum*sizeof(callback[0]),&callback);CHKERRQ(ierr); 224 ierr = PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));CHKERRQ(ierr); 225 ierr = PetscFree(obj->fortrancallback[cbtype]);CHKERRQ(ierr); 226 227 obj->fortrancallback[cbtype] = callback; 228 obj->num_fortrancallback[cbtype] = newnum; 229 } 230 obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func; 231 obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx; 232 PetscFunctionReturn(0); 233 } 234 235 #undef __FUNCT__ 236 #define __FUNCT__ "PetscObjectGetFortranCallback" 237 /*@C 238 PetscObjectGetFortranCallback - get fortran callback function pointer and context 239 240 Logically Collective 241 242 Input Arguments: 243 + obj - object on which to get callback 244 . cbtype - callback type 245 - cid - address of callback Id 246 247 Output Arguments: 248 + func - Fortran function (or NULL if not needed) 249 - ctx - Fortran context (or NULL if not needed) 250 251 Level: developer 252 253 .seealso: PetscObjectSetFortranCallback() 254 @*/ 255 PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx) 256 { 257 PetscFortranCallback *cb; 258 259 PetscFunctionBegin; 260 PetscValidHeader(obj,1); 261 if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid"); 262 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"); 263 cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK]; 264 if (func) *func = cb->func; 265 if (ctx) *ctx = cb->ctx; 266 PetscFunctionReturn(0); 267 } 268 269 #if defined(PETSC_USE_LOG) 270 #undef __FUNCT__ 271 #define __FUNCT__ "PetscObjectsDump" 272 /*@C 273 PetscObjectsDump - Prints the currently existing objects. 274 275 Logically Collective on PetscViewer 276 277 Input Parameter: 278 + viewer - must be an PETSCVIEWERASCII viewer 279 - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects 280 281 Level: advanced 282 283 Concepts: options database^printing 284 285 @*/ 286 PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all) 287 { 288 PetscErrorCode ierr; 289 PetscInt i; 290 #if defined(PETSC_USE_DEBUG) 291 PetscInt j,k=0; 292 #endif 293 PetscObject h; 294 295 PetscFunctionBegin; 296 if (PetscObjectsCounts) { 297 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");CHKERRQ(ierr); 298 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");CHKERRQ(ierr); 299 for (i=0; i<PetscObjectsMaxCounts; i++) { 300 if ((h = PetscObjects[i])) { 301 ierr = PetscObjectName(h);CHKERRQ(ierr); 302 { 303 #if defined(PETSC_USE_DEBUG) 304 PetscStack *stack = 0; 305 char *create,*rclass; 306 307 /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */ 308 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 309 if (stack) { 310 k = stack->currentsize-2; 311 if (!all) { 312 k = 0; 313 while (!stack->petscroutine[k]) k++; 314 ierr = PetscStrstr(stack->function[k],"Create",&create);CHKERRQ(ierr); 315 if (!create) { 316 ierr = PetscStrstr(stack->function[k],"Get",&create);CHKERRQ(ierr); 317 } 318 ierr = PetscStrstr(stack->function[k],h->class_name,&rclass);CHKERRQ(ierr); 319 if (!create) continue; 320 if (!rclass) continue; 321 } 322 } 323 #endif 324 325 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);CHKERRQ(ierr); 326 327 #if defined(PETSC_USE_DEBUG) 328 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 329 if (stack) { 330 for (j=k; j>=0; j--) { 331 fprintf(fd," [%d] %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]); 332 } 333 } 334 #endif 335 } 336 } 337 } 338 } 339 PetscFunctionReturn(0); 340 } 341 #endif 342 343 #if defined(PETSC_USE_LOG) 344 345 #undef __FUNCT__ 346 #define __FUNCT__ "PetscObjectsView" 347 /*@C 348 PetscObjectsView - Prints the currently existing objects. 349 350 Logically Collective on PetscViewer 351 352 Input Parameter: 353 . viewer - must be an PETSCVIEWERASCII viewer 354 355 Level: advanced 356 357 Concepts: options database^printing 358 359 @*/ 360 PetscErrorCode PetscObjectsView(PetscViewer viewer) 361 { 362 PetscErrorCode ierr; 363 PetscBool isascii; 364 FILE *fd; 365 366 PetscFunctionBegin; 367 if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 368 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 369 if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer"); 370 ierr = PetscViewerASCIIGetPointer(viewer,&fd);CHKERRQ(ierr); 371 ierr = PetscObjectsDump(fd,PETSC_TRUE);CHKERRQ(ierr); 372 PetscFunctionReturn(0); 373 } 374 375 #undef __FUNCT__ 376 #define __FUNCT__ "PetscObjectsGetObject" 377 /*@C 378 PetscObjectsGetObject - Get a pointer to a named object 379 380 Not collective 381 382 Input Parameter: 383 . name - the name of an object 384 385 Output Parameter: 386 . obj - the object or null if there is no object 387 388 Level: advanced 389 390 Concepts: options database^printing 391 392 @*/ 393 PetscErrorCode PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname) 394 { 395 PetscErrorCode ierr; 396 PetscInt i; 397 PetscObject h; 398 PetscBool flg; 399 400 PetscFunctionBegin; 401 *obj = NULL; 402 for (i=0; i<PetscObjectsMaxCounts; i++) { 403 if ((h = PetscObjects[i])) { 404 ierr = PetscObjectName(h);CHKERRQ(ierr); 405 ierr = PetscStrcmp(h->name,name,&flg);CHKERRQ(ierr); 406 if (flg) { 407 *obj = h; 408 if (classname) *classname = h->class_name; 409 PetscFunctionReturn(0); 410 } 411 } 412 } 413 PetscFunctionReturn(0); 414 } 415 416 #undef __FUNCT__ 417 #define __FUNCT__ "PetscObjectsGetObjectMatlab" 418 char *PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj) 419 { 420 PetscErrorCode ierr; 421 PetscInt i; 422 PetscObject h; 423 PetscBool flg; 424 425 PetscFunctionBegin; 426 *obj = NULL; 427 for (i=0; i<PetscObjectsMaxCounts; i++) { 428 if ((h = PetscObjects[i])) { 429 ierr = PetscObjectName(h);if (ierr) PetscFunctionReturn(0); 430 ierr = PetscStrcmp(h->name,name,&flg);if (ierr) PetscFunctionReturn(0); 431 if (flg) { 432 *obj = h; 433 PetscFunctionReturn(h->class_name); 434 } 435 } 436 } 437 PetscFunctionReturn(0); 438 } 439 #endif 440 441 #undef __FUNCT__ 442 #define __FUNCT__ "PetscObjectAddOptionsHandler" 443 /*@C 444 PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called. 445 446 Not Collective 447 448 Input Parameter: 449 + obj - the PETSc object 450 . handle - function that checks for options 451 . destroy - function to destroy context if provided 452 - ctx - optional context for check function 453 454 Level: developer 455 456 457 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers() 458 459 @*/ 460 PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx) 461 { 462 PetscFunctionBegin; 463 PetscValidHeader(obj,1); 464 if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added"); 465 obj->optionhandler[obj->noptionhandler] = handle; 466 obj->optiondestroy[obj->noptionhandler] = destroy; 467 obj->optionctx[obj->noptionhandler++] = ctx; 468 PetscFunctionReturn(0); 469 } 470 471 #undef __FUNCT__ 472 #define __FUNCT__ "PetscObjectProcessOptionsHandlers" 473 /*@C 474 PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object 475 476 Not Collective 477 478 Input Parameter: 479 . obj - the PETSc object 480 481 Level: developer 482 483 484 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers() 485 486 @*/ 487 PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj) 488 { 489 PetscInt i; 490 PetscErrorCode ierr; 491 492 PetscFunctionBegin; 493 PetscValidHeader(obj,1); 494 for (i=0; i<obj->noptionhandler; i++) { 495 ierr = (*obj->optionhandler[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 496 } 497 PetscFunctionReturn(0); 498 } 499 500 #undef __FUNCT__ 501 #define __FUNCT__ "PetscObjectDestroyOptionsHandlers" 502 /*@C 503 PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object 504 505 Not Collective 506 507 Input Parameter: 508 . obj - the PETSc object 509 510 Level: developer 511 512 513 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers() 514 515 @*/ 516 PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj) 517 { 518 PetscInt i; 519 PetscErrorCode ierr; 520 521 PetscFunctionBegin; 522 PetscValidHeader(obj,1); 523 for (i=0; i<obj->noptionhandler; i++) { 524 if (obj->optiondestroy[i]) { 525 ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 526 } 527 } 528 obj->noptionhandler = 0; 529 PetscFunctionReturn(0); 530 } 531 532 533 #undef __FUNCT__ 534 #define __FUNCT__ "PetscObjectReference" 535 /*@ 536 PetscObjectReference - Indicates to any PetscObject that it is being 537 referenced by another PetscObject. This increases the reference 538 count for that object by one. 539 540 Logically Collective on PetscObject 541 542 Input Parameter: 543 . obj - the PETSc object. This must be cast with (PetscObject), for example, 544 PetscObjectReference((PetscObject)mat); 545 546 Level: advanced 547 548 .seealso: PetscObjectCompose(), PetscObjectDereference() 549 @*/ 550 PetscErrorCode PetscObjectReference(PetscObject obj) 551 { 552 PetscFunctionBegin; 553 if (!obj) PetscFunctionReturn(0); 554 PetscValidHeader(obj,1); 555 obj->refct++; 556 PetscFunctionReturn(0); 557 } 558 559 #undef __FUNCT__ 560 #define __FUNCT__ "PetscObjectGetReference" 561 /*@ 562 PetscObjectGetReference - Gets the current reference count for 563 any PETSc object. 564 565 Not Collective 566 567 Input Parameter: 568 . obj - the PETSc object; this must be cast with (PetscObject), for example, 569 PetscObjectGetReference((PetscObject)mat,&cnt); 570 571 Output Parameter: 572 . cnt - the reference count 573 574 Level: advanced 575 576 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference() 577 @*/ 578 PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt) 579 { 580 PetscFunctionBegin; 581 PetscValidHeader(obj,1); 582 PetscValidIntPointer(cnt,2); 583 *cnt = obj->refct; 584 PetscFunctionReturn(0); 585 } 586 587 #undef __FUNCT__ 588 #define __FUNCT__ "PetscObjectDereference" 589 /*@ 590 PetscObjectDereference - Indicates to any PetscObject that it is being 591 referenced by one less PetscObject. This decreases the reference 592 count for that object by one. 593 594 Collective on PetscObject if reference reaches 0 otherwise Logically Collective 595 596 Input Parameter: 597 . obj - the PETSc object; this must be cast with (PetscObject), for example, 598 PetscObjectDereference((PetscObject)mat); 599 600 Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not. 601 602 Level: advanced 603 604 .seealso: PetscObjectCompose(), PetscObjectReference() 605 @*/ 606 PetscErrorCode PetscObjectDereference(PetscObject obj) 607 { 608 PetscErrorCode ierr; 609 610 PetscFunctionBegin; 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