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