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