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