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