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