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