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