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 = PetscObjectListDestroy(&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 = PetscFunctionListDestroy(&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 if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid"); 246 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"); 247 cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK]; 248 if (func) *func = cb->func; 249 if (ctx) *ctx = cb->ctx; 250 PetscFunctionReturn(0); 251 } 252 253 #undef __FUNCT__ 254 #define __FUNCT__ "PetscObjectsDump" 255 /*@C 256 PetscObjectsDump - Prints the currently existing objects. 257 258 Logically Collective on PetscViewer 259 260 Input Parameter: 261 + viewer - must be an PETSCVIEWERASCII viewer 262 - all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects 263 264 Level: advanced 265 266 Concepts: options database^printing 267 268 @*/ 269 PetscErrorCode PetscObjectsDump(FILE *fd,PetscBool all) 270 { 271 PetscErrorCode ierr; 272 PetscInt i; 273 #if defined(PETSC_USE_DEBUG) 274 PetscInt j,k; 275 #endif 276 PetscObject h; 277 278 PetscFunctionBegin; 279 if (PetscObjectsCounts) { 280 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");CHKERRQ(ierr); 281 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");CHKERRQ(ierr); 282 for (i=0; i<PetscObjectsMaxCounts; i++) { 283 if ((h = PetscObjects[i])) { 284 ierr = PetscObjectName(h);CHKERRQ(ierr); 285 { 286 #if defined(PETSC_USE_DEBUG) 287 PetscStack *stack; 288 char *create,*rclass; 289 290 /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */ 291 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 292 k = stack->currentsize-2; 293 if (!all) { 294 k = 0; 295 while (!stack->petscroutine[k]) k++; 296 ierr = PetscStrstr(stack->function[k],"Create",&create);CHKERRQ(ierr); 297 if (!create) { 298 ierr = PetscStrstr(stack->function[k],"Get",&create);CHKERRQ(ierr); 299 } 300 ierr = PetscStrstr(stack->function[k],h->class_name,&rclass);CHKERRQ(ierr); 301 302 if (!create) continue; 303 if (!rclass) continue; 304 } 305 #endif 306 307 ierr = PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);CHKERRQ(ierr); 308 309 #if defined(PETSC_USE_DEBUG) 310 ierr = PetscMallocGetStack(h,&stack);CHKERRQ(ierr); 311 for (j=k; j>=0; j--) { 312 fprintf(fd," [%d] %s() in %s%s\n",PetscGlobalRank,stack->function[j],stack->directory[j],stack->file[j]); 313 } 314 #endif 315 } 316 } 317 } 318 } 319 PetscFunctionReturn(0); 320 } 321 322 323 #undef __FUNCT__ 324 #define __FUNCT__ "PetscObjectsView" 325 /*@C 326 PetscObjectsView - Prints the currently existing objects. 327 328 Logically Collective on PetscViewer 329 330 Input Parameter: 331 . viewer - must be an PETSCVIEWERASCII viewer 332 333 Level: advanced 334 335 Concepts: options database^printing 336 337 @*/ 338 PetscErrorCode PetscObjectsView(PetscViewer viewer) 339 { 340 PetscErrorCode ierr; 341 PetscBool isascii; 342 FILE *fd; 343 344 PetscFunctionBegin; 345 if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 346 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 347 if (!isascii) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Only supports ASCII viewer"); 348 ierr = PetscViewerASCIIGetPointer(viewer,&fd);CHKERRQ(ierr); 349 ierr = PetscObjectsDump(fd,PETSC_TRUE);CHKERRQ(ierr); 350 PetscFunctionReturn(0); 351 } 352 353 #undef __FUNCT__ 354 #define __FUNCT__ "PetscObjectsGetObject" 355 /*@C 356 PetscObjectsGetObject - Get a pointer to a named object 357 358 Not collective 359 360 Input Parameter: 361 . name - the name of an object 362 363 Output Parameter: 364 . obj - the object or null if there is no object 365 366 Level: advanced 367 368 Concepts: options database^printing 369 370 @*/ 371 PetscErrorCode PetscObjectsGetObject(const char* name,PetscObject *obj,char **classname) 372 { 373 PetscErrorCode ierr; 374 PetscInt i; 375 PetscObject h; 376 PetscBool flg; 377 378 PetscFunctionBegin; 379 *obj = PETSC_NULL; 380 for (i=0; i<PetscObjectsMaxCounts; i++) { 381 if ((h = PetscObjects[i])) { 382 ierr = PetscObjectName(h);CHKERRQ(ierr); 383 ierr = PetscStrcmp(h->name,name,&flg);CHKERRQ(ierr); 384 if (flg) { 385 *obj = h; 386 if (classname) *classname = h->class_name; 387 PetscFunctionReturn(0); 388 } 389 } 390 } 391 PetscFunctionReturn(0); 392 } 393 394 #undef __FUNCT__ 395 #define __FUNCT__ "PetscObjectsGetObjectMatlab" 396 char* PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj) 397 { 398 PetscErrorCode ierr; 399 PetscInt i; 400 PetscObject h; 401 PetscBool flg; 402 403 PetscFunctionBegin; 404 *obj = PETSC_NULL; 405 for (i=0; i<PetscObjectsMaxCounts; i++) { 406 if ((h = PetscObjects[i])) { 407 ierr = PetscObjectName(h);if (ierr) PetscFunctionReturn(0); 408 ierr = PetscStrcmp(h->name,name,&flg);if (ierr) PetscFunctionReturn(0); 409 if (flg) { 410 *obj = h; 411 PetscFunctionReturn(h->class_name); 412 } 413 } 414 } 415 PetscFunctionReturn(0); 416 } 417 418 #undef __FUNCT__ 419 #define __FUNCT__ "PetscObjectAddOptionsHandler" 420 /*@C 421 PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called. 422 423 Not Collective 424 425 Input Parameter: 426 + obj - the PETSc object 427 . handle - function that checks for options 428 . destroy - function to destroy context if provided 429 - ctx - optional context for check function 430 431 Level: developer 432 433 434 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers() 435 436 @*/ 437 PetscErrorCode PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx) 438 { 439 PetscFunctionBegin; 440 PetscValidHeader(obj,1); 441 if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added"); 442 obj->optionhandler[obj->noptionhandler] = handle; 443 obj->optiondestroy[obj->noptionhandler] = destroy; 444 obj->optionctx[obj->noptionhandler++] = ctx; 445 PetscFunctionReturn(0); 446 } 447 448 #undef __FUNCT__ 449 #define __FUNCT__ "PetscObjectProcessOptionsHandlers" 450 /*@C 451 PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object 452 453 Not Collective 454 455 Input Parameter: 456 . obj - the PETSc object 457 458 Level: developer 459 460 461 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers() 462 463 @*/ 464 PetscErrorCode PetscObjectProcessOptionsHandlers(PetscObject obj) 465 { 466 PetscInt i; 467 PetscErrorCode ierr; 468 469 PetscFunctionBegin; 470 PetscValidHeader(obj,1); 471 for (i=0; i<obj->noptionhandler; i++) { 472 ierr = (*obj->optionhandler[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 473 } 474 PetscFunctionReturn(0); 475 } 476 477 #undef __FUNCT__ 478 #define __FUNCT__ "PetscObjectDestroyOptionsHandlers" 479 /*@C 480 PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an objeft 481 482 Not Collective 483 484 Input Parameter: 485 . obj - the PETSc object 486 487 Level: developer 488 489 490 .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers() 491 492 @*/ 493 PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject obj) 494 { 495 PetscInt i; 496 PetscErrorCode ierr; 497 498 PetscFunctionBegin; 499 PetscValidHeader(obj,1); 500 for (i=0; i<obj->noptionhandler; i++) { 501 ierr = (*obj->optiondestroy[i])(obj,obj->optionctx[i]);CHKERRQ(ierr); 502 } 503 obj->noptionhandler = 0; 504 PetscFunctionReturn(0); 505 } 506 507 508 #undef __FUNCT__ 509 #define __FUNCT__ "PetscObjectReference" 510 /*@ 511 PetscObjectReference - Indicates to any PetscObject that it is being 512 referenced by another PetscObject. This increases the reference 513 count for that object by one. 514 515 Logically Collective on PetscObject 516 517 Input Parameter: 518 . obj - the PETSc object. This must be cast with (PetscObject), for example, 519 PetscObjectReference((PetscObject)mat); 520 521 Level: advanced 522 523 .seealso: PetscObjectCompose(), PetscObjectDereference() 524 @*/ 525 PetscErrorCode PetscObjectReference(PetscObject obj) 526 { 527 PetscFunctionBegin; 528 if (!obj) PetscFunctionReturn(0); 529 PetscValidHeader(obj,1); 530 obj->refct++; 531 PetscFunctionReturn(0); 532 } 533 534 #undef __FUNCT__ 535 #define __FUNCT__ "PetscObjectGetReference" 536 /*@ 537 PetscObjectGetReference - Gets the current reference count for 538 any PETSc object. 539 540 Not Collective 541 542 Input Parameter: 543 . obj - the PETSc object; this must be cast with (PetscObject), for example, 544 PetscObjectGetReference((PetscObject)mat,&cnt); 545 546 Output Parameter: 547 . cnt - the reference count 548 549 Level: advanced 550 551 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference() 552 @*/ 553 PetscErrorCode PetscObjectGetReference(PetscObject obj,PetscInt *cnt) 554 { 555 PetscFunctionBegin; 556 PetscValidHeader(obj,1); 557 PetscValidIntPointer(cnt,2); 558 *cnt = obj->refct; 559 PetscFunctionReturn(0); 560 } 561 562 #undef __FUNCT__ 563 #define __FUNCT__ "PetscObjectDereference" 564 /*@ 565 PetscObjectDereference - Indicates to any PetscObject that it is being 566 referenced by one less PetscObject. This decreases the reference 567 count for that object by one. 568 569 Collective on PetscObject if reference reaches 0 otherwise Logically Collective 570 571 Input Parameter: 572 . obj - the PETSc object; this must be cast with (PetscObject), for example, 573 PetscObjectDereference((PetscObject)mat); 574 575 Notes: PetscObjectDestroy(PetscObject *obj) sets the obj pointer to null after the call, this routine does not. 576 577 Level: advanced 578 579 .seealso: PetscObjectCompose(), PetscObjectReference() 580 @*/ 581 PetscErrorCode PetscObjectDereference(PetscObject obj) 582 { 583 PetscErrorCode ierr; 584 585 PetscFunctionBegin; 586 PetscValidHeader(obj,1); 587 if (obj->bops->destroy) { 588 ierr = (*obj->bops->destroy)(&obj);CHKERRQ(ierr); 589 } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine"); 590 PetscFunctionReturn(0); 591 } 592 593 /* ----------------------------------------------------------------------- */ 594 /* 595 The following routines are the versions private to the PETSc object 596 data structures. 597 */ 598 #undef __FUNCT__ 599 #define __FUNCT__ "PetscObjectGetComm_Petsc" 600 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm) 601 { 602 PetscFunctionBegin; 603 PetscValidHeader(obj,1); 604 *comm = obj->comm; 605 PetscFunctionReturn(0); 606 } 607 608 #undef __FUNCT__ 609 #define __FUNCT__ "PetscObjectRemoveReference" 610 PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[]) 611 { 612 PetscErrorCode ierr; 613 614 PetscFunctionBegin; 615 PetscValidHeader(obj,1); 616 ierr = PetscObjectListRemoveReference(&obj->olist,name);CHKERRQ(ierr); 617 PetscFunctionReturn(0); 618 } 619 620 #undef __FUNCT__ 621 #define __FUNCT__ "PetscObjectCompose_Petsc" 622 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr) 623 { 624 PetscErrorCode ierr; 625 char *tname; 626 PetscBool skipreference; 627 628 PetscFunctionBegin; 629 if (ptr) { 630 ierr = PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);CHKERRQ(ierr); 631 if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it"); 632 } 633 ierr = PetscObjectListAdd(&obj->olist,name,ptr);CHKERRQ(ierr); 634 PetscFunctionReturn(0); 635 } 636 637 #undef __FUNCT__ 638 #define __FUNCT__ "PetscObjectQuery_Petsc" 639 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr) 640 { 641 PetscErrorCode ierr; 642 643 PetscFunctionBegin; 644 PetscValidHeader(obj,1); 645 ierr = PetscObjectListFind(obj->olist,name,ptr);CHKERRQ(ierr); 646 PetscFunctionReturn(0); 647 } 648 649 #undef __FUNCT__ 650 #define __FUNCT__ "PetscObjectComposeFunction_Petsc" 651 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void)) 652 { 653 PetscErrorCode ierr; 654 655 PetscFunctionBegin; 656 PetscValidHeader(obj,1); 657 ierr = PetscFunctionListAdd(obj->comm,&obj->qlist,name,fname,ptr);CHKERRQ(ierr); 658 PetscFunctionReturn(0); 659 } 660 661 #undef __FUNCT__ 662 #define __FUNCT__ "PetscObjectQueryFunction_Petsc" 663 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void)) 664 { 665 PetscErrorCode ierr; 666 667 PetscFunctionBegin; 668 PetscValidHeader(obj,1); 669 ierr = PetscFunctionListFind(obj->comm,obj->qlist,name,PETSC_FALSE,ptr);CHKERRQ(ierr); 670 PetscFunctionReturn(0); 671 } 672 673 #undef __FUNCT__ 674 #define __FUNCT__ "PetscObjectCompose" 675 /*@C 676 PetscObjectCompose - Associates another PETSc object with a given PETSc object. 677 678 Not Collective 679 680 Input Parameters: 681 + obj - the PETSc object; this must be cast with (PetscObject), for example, 682 PetscObjectCompose((PetscObject)mat,...); 683 . name - name associated with the child object 684 - ptr - the other PETSc object to associate with the PETSc object; this must also be 685 cast with (PetscObject) 686 687 Level: advanced 688 689 Notes: 690 The second objects reference count is automatically increased by one when it is 691 composed. 692 693 Replaces any previous object that had the same name. 694 695 If ptr is null and name has previously been composed using an object, then that 696 entry is removed from the obj. 697 698 PetscObjectCompose() can be used with any PETSc object (such as 699 Mat, Vec, KSP, SNES, etc.) or any user-provided object. See 700 PetscContainerCreate() for info on how to create an object from a 701 user-provided pointer that may then be composed with PETSc objects. 702 703 Concepts: objects^composing 704 Concepts: composing objects 705 706 .seealso: PetscObjectQuery(), PetscContainerCreate() 707 @*/ 708 PetscErrorCode PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr) 709 { 710 PetscErrorCode ierr; 711 712 PetscFunctionBegin; 713 PetscValidHeader(obj,1); 714 PetscValidCharPointer(name,2); 715 if (ptr) PetscValidHeader(ptr,3); 716 ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr); 717 PetscFunctionReturn(0); 718 } 719 720 #undef __FUNCT__ 721 #define __FUNCT__ "PetscObjectSetPrecision" 722 /*@C 723 PetscObjectSetPrecision - sets the precision used within a given object. 724 725 Collective on the PetscObject 726 727 Input Parameters: 728 + obj - the PETSc object; this must be cast with (PetscObject), for example, 729 PetscObjectCompose((PetscObject)mat,...); 730 - precision - the precision 731 732 Level: advanced 733 734 .seealso: PetscObjectQuery(), PetscContainerCreate() 735 @*/ 736 PetscErrorCode PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision) 737 { 738 PetscFunctionBegin; 739 PetscValidHeader(obj,1); 740 obj->precision = precision; 741 PetscFunctionReturn(0); 742 } 743 744 #undef __FUNCT__ 745 #define __FUNCT__ "PetscObjectQuery" 746 /*@C 747 PetscObjectQuery - Gets a PETSc object associated with a given object. 748 749 Not Collective 750 751 Input Parameters: 752 + obj - the PETSc object 753 Thus must be cast with a (PetscObject), for example, 754 PetscObjectCompose((PetscObject)mat,...); 755 . name - name associated with child object 756 - ptr - the other PETSc object associated with the PETSc object, this must be 757 cast with (PetscObject *) 758 759 Level: advanced 760 761 The reference count of neither object is increased in this call 762 763 Concepts: objects^composing 764 Concepts: composing objects 765 Concepts: objects^querying 766 Concepts: querying objects 767 768 .seealso: PetscObjectCompose() 769 @*/ 770 PetscErrorCode PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 771 { 772 PetscErrorCode ierr; 773 774 PetscFunctionBegin; 775 PetscValidHeader(obj,1); 776 PetscValidCharPointer(name,2); 777 PetscValidPointer(ptr,3); 778 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 779 PetscFunctionReturn(0); 780 } 781 782 #undef __FUNCT__ 783 #define __FUNCT__ "PetscObjectComposeFunction" 784 PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void)) 785 { 786 PetscErrorCode ierr; 787 788 PetscFunctionBegin; 789 PetscValidHeader(obj,1); 790 PetscValidCharPointer(name,2); 791 ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr); 792 PetscFunctionReturn(0); 793 } 794 795 #undef __FUNCT__ 796 #define __FUNCT__ "PetscObjectQueryFunction" 797 /*@C 798 PetscObjectQueryFunction - Gets a function associated with a given object. 799 800 Logically Collective on PetscObject 801 802 Input Parameters: 803 + obj - the PETSc object; this must be cast with (PetscObject), for example, 804 PetscObjectQueryFunction((PetscObject)ksp,...); 805 - name - name associated with the child function 806 807 Output Parameter: 808 . ptr - function pointer 809 810 Level: advanced 811 812 Concepts: objects^composing functions 813 Concepts: composing functions 814 Concepts: functions^querying 815 Concepts: objects^querying 816 Concepts: querying objects 817 818 .seealso: PetscObjectComposeFunctionDynamic() 819 @*/ 820 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void)) 821 { 822 PetscErrorCode ierr; 823 824 PetscFunctionBegin; 825 PetscValidHeader(obj,1); 826 PetscValidCharPointer(name,2); 827 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 828 PetscFunctionReturn(0); 829 } 830 831 struct _p_PetscContainer { 832 PETSCHEADER(int); 833 void *ptr; 834 PetscErrorCode (*userdestroy)(void*); 835 }; 836 837 #undef __FUNCT__ 838 #define __FUNCT__ "PetscContainerGetPointer" 839 /*@C 840 PetscContainerGetPointer - Gets the pointer value contained in the container. 841 842 Not Collective 843 844 Input Parameter: 845 . obj - the object created with PetscContainerCreate() 846 847 Output Parameter: 848 . ptr - the pointer value 849 850 Level: advanced 851 852 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 853 PetscContainerSetPointer() 854 @*/ 855 PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr) 856 { 857 PetscFunctionBegin; 858 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 859 PetscValidPointer(ptr,2); 860 *ptr = obj->ptr; 861 PetscFunctionReturn(0); 862 } 863 864 865 #undef __FUNCT__ 866 #define __FUNCT__ "PetscContainerSetPointer" 867 /*@C 868 PetscContainerSetPointer - Sets the pointer value contained in the container. 869 870 Logically Collective on PetscContainer 871 872 Input Parameters: 873 + obj - the object created with PetscContainerCreate() 874 - ptr - the pointer value 875 876 Level: advanced 877 878 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 879 PetscContainerGetPointer() 880 @*/ 881 PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr) 882 { 883 PetscFunctionBegin; 884 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 885 if (ptr) PetscValidPointer(ptr,2); 886 obj->ptr = ptr; 887 PetscFunctionReturn(0); 888 } 889 890 #undef __FUNCT__ 891 #define __FUNCT__ "PetscContainerDestroy" 892 /*@C 893 PetscContainerDestroy - Destroys a PETSc container object. 894 895 Collective on PetscContainer 896 897 Input Parameter: 898 . obj - an object that was created with PetscContainerCreate() 899 900 Level: advanced 901 902 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy() 903 @*/ 904 PetscErrorCode PetscContainerDestroy(PetscContainer *obj) 905 { 906 PetscErrorCode ierr; 907 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