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