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