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[],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[],const char fname[],void (*ptr)(void)) 658 { 659 PetscErrorCode ierr; 660 661 PetscFunctionBegin; 662 PetscValidHeader(obj,1); 663 ierr = PetscFunctionListAdd(obj->comm,&obj->qlist,name,fname,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->comm,obj->qlist,name,PETSC_FALSE,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[],const char fname[],void *ptr) 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 - ptr - function pointer (or NULL if using dynamic libraries) 803 804 Level: advanced 805 806 Notes: 807 To remove a registered routine, pass in a NULL rname and fnc(). 808 809 PetscObjectComposeFunctionDynamic() 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() 819 M*/ 820 821 #undef __FUNCT__ 822 #define __FUNCT__ "PetscObjectComposeFunction_Private" 823 PetscErrorCode PetscObjectComposeFunction_Private(PetscObject obj,const char name[],const char fname[],void (*ptr)(void)) 824 { 825 PetscErrorCode ierr; 826 827 PetscFunctionBegin; 828 PetscValidHeader(obj,1); 829 PetscValidCharPointer(name,2); 830 ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr); 831 PetscFunctionReturn(0); 832 } 833 834 #undef __FUNCT__ 835 #define __FUNCT__ "PetscObjectQueryFunction" 836 /*@C 837 PetscObjectQueryFunction - Gets a function associated with a given object. 838 839 Logically Collective on PetscObject 840 841 Input Parameters: 842 + obj - the PETSc object; this must be cast with (PetscObject), for example, 843 PetscObjectQueryFunction((PetscObject)ksp,...); 844 - name - name associated with the child function 845 846 Output Parameter: 847 . ptr - function pointer 848 849 Level: advanced 850 851 Concepts: objects^composing functions 852 Concepts: composing functions 853 Concepts: functions^querying 854 Concepts: objects^querying 855 Concepts: querying objects 856 857 .seealso: PetscObjectComposeFunctionDynamic() 858 @*/ 859 PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void)) 860 { 861 PetscErrorCode ierr; 862 863 PetscFunctionBegin; 864 PetscValidHeader(obj,1); 865 PetscValidCharPointer(name,2); 866 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 867 PetscFunctionReturn(0); 868 } 869 870 struct _p_PetscContainer { 871 PETSCHEADER(int); 872 void *ptr; 873 PetscErrorCode (*userdestroy)(void*); 874 }; 875 876 #undef __FUNCT__ 877 #define __FUNCT__ "PetscContainerGetPointer" 878 /*@C 879 PetscContainerGetPointer - Gets the pointer value contained in the container. 880 881 Not Collective 882 883 Input Parameter: 884 . obj - the object created with PetscContainerCreate() 885 886 Output Parameter: 887 . ptr - the pointer value 888 889 Level: advanced 890 891 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 892 PetscContainerSetPointer() 893 @*/ 894 PetscErrorCode PetscContainerGetPointer(PetscContainer obj,void **ptr) 895 { 896 PetscFunctionBegin; 897 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 898 PetscValidPointer(ptr,2); 899 *ptr = obj->ptr; 900 PetscFunctionReturn(0); 901 } 902 903 904 #undef __FUNCT__ 905 #define __FUNCT__ "PetscContainerSetPointer" 906 /*@C 907 PetscContainerSetPointer - Sets the pointer value contained in the container. 908 909 Logically Collective on PetscContainer 910 911 Input Parameters: 912 + obj - the object created with PetscContainerCreate() 913 - ptr - the pointer value 914 915 Level: advanced 916 917 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 918 PetscContainerGetPointer() 919 @*/ 920 PetscErrorCode PetscContainerSetPointer(PetscContainer obj,void *ptr) 921 { 922 PetscFunctionBegin; 923 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 924 if (ptr) PetscValidPointer(ptr,2); 925 obj->ptr = ptr; 926 PetscFunctionReturn(0); 927 } 928 929 #undef __FUNCT__ 930 #define __FUNCT__ "PetscContainerDestroy" 931 /*@C 932 PetscContainerDestroy - Destroys a PETSc container object. 933 934 Collective on PetscContainer 935 936 Input Parameter: 937 . obj - an object that was created with PetscContainerCreate() 938 939 Level: advanced 940 941 .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy() 942 @*/ 943 PetscErrorCode PetscContainerDestroy(PetscContainer *obj) 944 { 945 PetscErrorCode ierr; 946 947 PetscFunctionBegin; 948 if (!*obj) PetscFunctionReturn(0); 949 PetscValidHeaderSpecific(*obj,PETSC_CONTAINER_CLASSID,1); 950 if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; PetscFunctionReturn(0);} 951 if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr); 952 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 953 PetscFunctionReturn(0); 954 } 955 956 #undef __FUNCT__ 957 #define __FUNCT__ "PetscContainerSetUserDestroy" 958 /*@C 959 PetscContainerSetUserDestroy - Sets name of the user destroy function. 960 961 Logically Collective on PetscContainer 962 963 Input Parameter: 964 + obj - an object that was created with PetscContainerCreate() 965 - des - name of the user destroy function 966 967 Level: advanced 968 969 .seealso: PetscContainerDestroy() 970 @*/ 971 PetscErrorCode PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 972 { 973 PetscFunctionBegin; 974 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_CLASSID,1); 975 obj->userdestroy = des; 976 PetscFunctionReturn(0); 977 } 978 979 PetscClassId PETSC_CONTAINER_CLASSID; 980 981 #undef __FUNCT__ 982 #define __FUNCT__ "PetscContainerCreate" 983 /*@C 984 PetscContainerCreate - Creates a PETSc object that has room to hold 985 a single pointer. This allows one to attach any type of data (accessible 986 through a pointer) with the PetscObjectCompose() function to a PetscObject. 987 The data item itself is attached by a call to PetscContainerSetPointer(). 988 989 Collective on MPI_Comm 990 991 Input Parameters: 992 . comm - MPI communicator that shares the object 993 994 Output Parameters: 995 . container - the container created 996 997 Level: advanced 998 999 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer() 1000 @*/ 1001 PetscErrorCode PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 1002 { 1003 PetscErrorCode ierr; 1004 PetscContainer contain; 1005 1006 PetscFunctionBegin; 1007 PetscValidPointer(container,2); 1008 ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);CHKERRQ(ierr); 1009 *container = contain; 1010 PetscFunctionReturn(0); 1011 } 1012 1013 #undef __FUNCT__ 1014 #define __FUNCT__ "PetscObjectSetFromOptions" 1015 /*@ 1016 PetscObjectSetFromOptions - Sets generic parameters from user options. 1017 1018 Collective on obj 1019 1020 Input Parameter: 1021 . obj - the PetscObjcet 1022 1023 Options Database Keys: 1024 1025 Notes: 1026 We have no generic options at present, so this does nothing 1027 1028 Level: beginner 1029 1030 .keywords: set, options, database 1031 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 1032 @*/ 1033 PetscErrorCode PetscObjectSetFromOptions(PetscObject obj) 1034 { 1035 PetscFunctionBegin; 1036 PetscValidHeader(obj,1); 1037 PetscFunctionReturn(0); 1038 } 1039 1040 #undef __FUNCT__ 1041 #define __FUNCT__ "PetscObjectSetUp" 1042 /*@ 1043 PetscObjectSetUp - Sets up the internal data structures for the later use. 1044 1045 Collective on PetscObject 1046 1047 Input Parameters: 1048 . obj - the PetscObject 1049 1050 Notes: 1051 This does nothing at present. 1052 1053 Level: advanced 1054 1055 .keywords: setup 1056 .seealso: PetscObjectDestroy() 1057 @*/ 1058 PetscErrorCode PetscObjectSetUp(PetscObject obj) 1059 { 1060 PetscFunctionBegin; 1061 PetscValidHeader(obj,1); 1062 PetscFunctionReturn(0); 1063 } 1064