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