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