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