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