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 PetscValidHeader(obj,1); 611 if (obj->bops->destroy) { 612 ierr = (*obj->bops->destroy)(&obj);CHKERRQ(ierr); 613 } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine"); 614 PetscFunctionReturn(0); 615 } 616 617 /* ----------------------------------------------------------------------- */ 618 /* 619 The following routines are the versions private to the PETSc object 620 data structures. 621 */ 622 #undef __FUNCT__ 623 #define __FUNCT__ "PetscObjectGetComm_Petsc" 624 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm) 625 { 626 PetscFunctionBegin; 627 PetscValidHeader(obj,1); 628 *comm = obj->comm; 629 PetscFunctionReturn(0); 630 } 631 632 #undef __FUNCT__ 633 #define __FUNCT__ "PetscObjectRemoveReference" 634 PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[]) 635 { 636 PetscErrorCode ierr; 637 638 PetscFunctionBegin; 639 PetscValidHeader(obj,1); 640 ierr = PetscObjectListRemoveReference(&obj->olist,name);CHKERRQ(ierr); 641 PetscFunctionReturn(0); 642 } 643 644 #undef __FUNCT__ 645 #define __FUNCT__ "PetscObjectCompose_Petsc" 646 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr) 647 { 648 PetscErrorCode ierr; 649 char *tname; 650 PetscBool skipreference; 651 652 PetscFunctionBegin; 653 if (ptr) { 654 ierr = PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);CHKERRQ(ierr); 655 if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it"); 656 } 657 ierr = PetscObjectListAdd(&obj->olist,name,ptr);CHKERRQ(ierr); 658 PetscFunctionReturn(0); 659 } 660 661 #undef __FUNCT__ 662 #define __FUNCT__ "PetscObjectQuery_Petsc" 663 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr) 664 { 665 PetscErrorCode ierr; 666 667 PetscFunctionBegin; 668 PetscValidHeader(obj,1); 669 ierr = PetscObjectListFind(obj->olist,name,ptr);CHKERRQ(ierr); 670 PetscFunctionReturn(0); 671 } 672 673 #undef __FUNCT__ 674 #define __FUNCT__ "PetscObjectComposeFunction_Petsc" 675 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void)) 676 { 677 PetscErrorCode ierr; 678 679 PetscFunctionBegin; 680 PetscValidHeader(obj,1); 681 ierr = PetscFunctionListAdd(&obj->qlist,name,ptr);CHKERRQ(ierr); 682 PetscFunctionReturn(0); 683 } 684 685 #undef __FUNCT__ 686 #define __FUNCT__ "PetscObjectQueryFunction_Petsc" 687 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void)) 688 { 689 PetscErrorCode ierr; 690 691 PetscFunctionBegin; 692 PetscValidHeader(obj,1); 693 ierr = PetscFunctionListFind(obj->qlist,name,ptr);CHKERRQ(ierr); 694 PetscFunctionReturn(0); 695 } 696 697 #undef __FUNCT__ 698 #define __FUNCT__ "PetscObjectCompose" 699 /*@C 700 PetscObjectCompose - Associates another PETSc object with a given PETSc object. 701 702 Not Collective 703 704 Input Parameters: 705 + obj - the PETSc object; this must be cast with (PetscObject), for example, 706 PetscObjectCompose((PetscObject)mat,...); 707 . name - name associated with the child object 708 - ptr - the other PETSc object to associate with the PETSc object; this must also be 709 cast with (PetscObject) 710 711 Level: advanced 712 713 Notes: 714 The second objects reference count is automatically increased by one when it is 715 composed. 716 717 Replaces any previous object that had the same name. 718 719 If ptr is null and name has previously been composed using an object, then that 720 entry is removed from the obj. 721 722 PetscObjectCompose() can be used with any PETSc object (such as 723 Mat, Vec, KSP, SNES, etc.) or any user-provided object. See 724 PetscContainerCreate() for info on how to create an object from a 725 user-provided pointer that may then be composed with PETSc objects. 726 727 Concepts: objects^composing 728 Concepts: composing objects 729 730 .seealso: PetscObjectQuery(), PetscContainerCreate() 731 @*/ 732 PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr) 733 { 734 PetscErrorCode ierr; 735 736 PetscFunctionBegin; 737 PetscValidHeader(obj,1); 738 PetscValidCharPointer(name,2); 739 if (ptr) PetscValidHeader(ptr,3); 740 ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr); 741 PetscFunctionReturn(0); 742 } 743 744 #undef __FUNCT__ 745 #define __FUNCT__ "PetscObjectSetPrecision" 746 /*@C 747 PetscObjectSetPrecision - sets the precision used within a given object. 748 749 Collective on the PetscObject 750 751 Input Parameters: 752 + obj - the PETSc object; this must be cast with (PetscObject), for example, 753 PetscObjectCompose((PetscObject)mat,...); 754 - precision - the precision 755 756 Level: advanced 757 758 .seealso: PetscObjectQuery(), PetscContainerCreate() 759 @*/ 760 PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision) 761 { 762 PetscFunctionBegin; 763 PetscValidHeader(obj,1); 764 obj->precision = precision; 765 PetscFunctionReturn(0); 766 } 767 768 #undef __FUNCT__ 769 #define __FUNCT__ "PetscObjectQuery" 770 /*@C 771 PetscObjectQuery - Gets a PETSc object associated with a given object. 772 773 Not Collective 774 775 Input Parameters: 776 + obj - the PETSc object 777 Thus must be cast with a (PetscObject), for example, 778 PetscObjectCompose((PetscObject)mat,...); 779 . name - name associated with child object 780 - ptr - the other PETSc object associated with the PETSc object, this must be 781 cast with (PetscObject*) 782 783 Level: advanced 784 785 The reference count of neither object is increased in this call 786 787 Concepts: objects^composing 788 Concepts: composing objects 789 Concepts: objects^querying 790 Concepts: querying objects 791 792 .seealso: PetscObjectCompose() 793 @*/ 794 PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 795 { 796 PetscErrorCode ierr; 797 798 PetscFunctionBegin; 799 PetscValidHeader(obj,1); 800 PetscValidCharPointer(name,2); 801 PetscValidPointer(ptr,3); 802 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 803 PetscFunctionReturn(0); 804 } 805 806 /*MC 807 PetscObjectComposeFunction - Associates a function with a given PETSc object. 808 809 Synopsis: 810 #include <petscsys.h> 811 PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void)) 812 813 Logically Collective on PetscObject 814 815 Input Parameters: 816 + obj - the PETSc object; this must be cast with a (PetscObject), for example, 817 PetscObjectCompose((PetscObject)mat,...); 818 . name - name associated with the child function 819 . fname - name of the function 820 - fptr - function pointer 821 822 Level: advanced 823 824 Notes: 825 To remove a registered routine, pass in NULL for fptr(). 826 827 PetscObjectComposeFunction() can be used with any PETSc object (such as 828 Mat, Vec, KSP, SNES, etc.) or any user-provided object. 829 830 Concepts: objects^composing functions 831 Concepts: composing functions 832 Concepts: functions^querying 833 Concepts: objects^querying 834 Concepts: querying objects 835 836 .seealso: PetscObjectQueryFunction(), PetscContainerCreate() 837 M*/ 838 839 #undef __FUNCT__ 840 #define __FUNCT__ "PetscObjectComposeFunction_Private" 841 PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void)) 842 { 843 PetscErrorCode ierr; 844 845 PetscFunctionBegin; 846 PetscValidHeader(obj,1); 847 PetscValidCharPointer(name,2); 848 ierr = (*obj->bops->composefunction)(obj,name,fptr);CHKERRQ(ierr); 849 PetscFunctionReturn(0); 850 } 851 852 /*MC 853 PetscObjectQueryFunction - Gets a function associated with a given object. 854 855 Synopsis: 856 #include <petscsys.h> 857 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void)) 858 859 Logically Collective on PetscObject 860 861 Input Parameters: 862 + obj - the PETSc object; this must be cast with (PetscObject), for example, 863 PetscObjectQueryFunction((PetscObject)ksp,...); 864 - name - name associated with the child function 865 866 Output Parameter: 867 . fptr - function pointer 868 869 Level: advanced 870 871 Concepts: objects^composing functions 872 Concepts: composing functions 873 Concepts: functions^querying 874 Concepts: objects^querying 875 Concepts: querying objects 876 877 .seealso: PetscObjectComposeFunction(), PetscFunctionListFind() 878 M*/ 879 #undef __FUNCT__ 880 #define __FUNCT__ "PetscObjectQueryFunction_Private" 881 PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void)) 882 { 883 PetscErrorCode ierr; 884 885 PetscFunctionBegin; 886 PetscValidHeader(obj,1); 887 PetscValidCharPointer(name,2); 888 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 889 PetscFunctionReturn(0); 890 } 891 892 struct _p_PetscContainer { 893 PETSCHEADER(int); 894 void *ptr; 895 PetscErrorCode (*userdestroy)(void*); 896 }; 897 898 #undef __FUNCT__ 899 #define __FUNCT__ "PetscContainerGetPointer" 900 /*@C 901 PetscContainerGetPointer - Gets the pointer value contained in the container. 902 903 Not Collective 904 905 Input Parameter: 906 . obj - the object created with PetscContainerCreate() 907 908 Output Parameter: 909 . ptr - the pointer value 910 911 Level: advanced 912 913 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 914 PetscContainerSetPointer() 915 @*/ 916 PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr) 917 { 918 PetscFunctionBegin; 919 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 920 PetscValidPointer(ptr,2); 921 *ptr = obj->ptr; 922 PetscFunctionReturn(0); 923 } 924 925 926 #undef __FUNCT__ 927 #define __FUNCT__ "PetscContainerSetPointer" 928 /*@C 929 PetscContainerSetPointer - Sets the pointer value contained in the container. 930 931 Logically Collective on PetscContainer 932 933 Input Parameters: 934 + obj - the object created with PetscContainerCreate() 935 - ptr - the pointer value 936 937 Level: advanced 938 939 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 940 PetscContainerGetPointer() 941 @*/ 942 PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr) 943 { 944 PetscFunctionBegin; 945 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 946 if (ptr) PetscValidPointer(ptr,2); 947 obj->ptr = ptr; 948 PetscFunctionReturn(0); 949 } 950 951 #undef __FUNCT__ 952 #define __FUNCT__ "PetscContainerDestroy" 953 /*@C 954 PetscContainerDestroy - Destroys a PETSc container object. 955 956 Collective on PetscContainer 957 958 Input Parameter: 959 . obj - an object that was created with PetscContainerCreate() 960 961 Level: advanced 962 963 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy() 964 @*/ 965 PetscErrorCode PetscContainerDestroy(PetscContainer *obj) 966 { 967 PetscErrorCode ierr; 968 969 PetscFunctionBegin; 970 if (!*obj) PetscFunctionReturn(0); 971 PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1); 972 if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);} 973 if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr); 974 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 975 PetscFunctionReturn(0); 976 } 977 978 #undef __FUNCT__ 979 #define __FUNCT__ "PetscContainerSetUserDestroy" 980 /*@C 981 PetscContainerSetUserDestroy - Sets name of the user destroy function. 982 983 Logically Collective on PetscContainer 984 985 Input Parameter: 986 + obj - an object that was created with PetscContainerCreate() 987 - des - name of the user destroy function 988 989 Level: advanced 990 991 .seealso: PetscContainerDestroy() 992 @*/ 993 PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 994 { 995 PetscFunctionBegin; 996 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 997 obj->userdestroy = des; 998 PetscFunctionReturn(0); 999 } 1000 1001 PetscClassId PETSC_CONTAINER_CLASSID; 1002 1003 #undef __FUNCT__ 1004 #define __FUNCT__ "PetscContainerCreate" 1005 /*@C 1006 PetscContainerCreate - Creates a PETSc object that has room to hold 1007 a single pointer. This allows one to attach any type of data (accessible 1008 through a pointer) with the PetscObjectCompose() function to a PetscObject. 1009 The data item itself is attached by a call to PetscContainerSetPointer(). 1010 1011 Collective on MPI_Comm 1012 1013 Input Parameters: 1014 . comm - MPI communicator that shares the object 1015 1016 Output Parameters: 1017 . container - the container created 1018 1019 Level: advanced 1020 1021 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer() 1022 @*/ 1023 PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 1024 { 1025 PetscErrorCode ierr; 1026 PetscContainer contain; 1027 1028 PetscFunctionBegin; 1029 PetscValidPointer(container,2); 1030 ierr = PetscSysInitializePackage();CHKERRQ(ierr); 1031 ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);CHKERRQ(ierr); 1032 *container = contain; 1033 PetscFunctionReturn(0); 1034 } 1035 1036 #undef __FUNCT__ 1037 #define __FUNCT__ "PetscObjectSetFromOptions" 1038 /*@ 1039 PetscObjectSetFromOptions - Sets generic parameters from user options. 1040 1041 Collective on obj 1042 1043 Input Parameter: 1044 . obj - the PetscObjcet 1045 1046 Options Database Keys: 1047 1048 Notes: 1049 We have no generic options at present, so this does nothing 1050 1051 Level: beginner 1052 1053 .keywords: set, options, database 1054 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 1055 @*/ 1056 PetscErrorCode PetscObjectSetFromOptions(PetscObject obj) 1057 { 1058 PetscFunctionBegin; 1059 PetscValidHeader(obj,1); 1060 PetscFunctionReturn(0); 1061 } 1062 1063 #undef __FUNCT__ 1064 #define __FUNCT__ "PetscObjectSetUp" 1065 /*@ 1066 PetscObjectSetUp - Sets up the internal data structures for the later use. 1067 1068 Collective on PetscObject 1069 1070 Input Parameters: 1071 . obj - the PetscObject 1072 1073 Notes: 1074 This does nothing at present. 1075 1076 Level: advanced 1077 1078 .keywords: setup 1079 .seealso: PetscObjectDestroy() 1080 @*/ 1081 PetscErrorCode PetscObjectSetUp(PetscObject obj) 1082 { 1083 PetscFunctionBegin; 1084 PetscValidHeader(obj,1); 1085 PetscFunctionReturn(0); 1086 } 1087