Date: 2015-10-02T22:00:07+00:00

Actual source code: inherit.c
petsc-3.6.2 2015-10-02
Report Typos and Errors

      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>

      8: #if defined(PETSC_USE_LOG)
      9: PetscObject *PetscObjects      = 0;
     10: PetscInt    PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;
     11: PetscBool   PetscObjectsLog    = PETSC_FALSE;
     12: #endif

     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));

     22: /*
     23:    PetscHeaderCreate_Private - Creates a base PETSc object header and fills
     24:    in the default values.  Called by the macro PetscHeaderCreate().
     25: */
     26: PetscErrorCode  PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
     27:                                           MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
     28: {
     29:   static PetscInt idcnt = 1;
     30:   PetscErrorCode  ierr;
     31: #if defined(PETSC_USE_LOG)
     32:   PetscObject     *newPetscObjects;
     33:   PetscInt         newPetscObjectsMaxCounts,i;
     34: #endif

     37:   h->classid               = classid;
     38:   h->type                  = 0;
     39:   h->class_name            = (char*)class_name;
     40:   h->description           = (char*)descr;
     41:   h->mansec                = (char*)mansec;
     42:   h->prefix                = 0;
     43:   h->refct                 = 1;
     44: #if defined(PETSC_HAVE_SAWS)
     45:   h->amsmem                = PETSC_FALSE;
     46: #endif
     47:   h->id                    = idcnt++;
     48:   h->parentid              = 0;
     49:   h->qlist                 = 0;
     50:   h->olist                 = 0;
     51:   h->precision             = (PetscPrecision) sizeof(PetscReal);
     52:   h->bops->destroy         = destroy;
     53:   h->bops->view            = view;
     54:   h->bops->getcomm         = PetscObjectGetComm_Petsc;
     55:   h->bops->compose         = PetscObjectCompose_Petsc;
     56:   h->bops->query           = PetscObjectQuery_Petsc;
     57:   h->bops->composefunction = PetscObjectComposeFunction_Petsc;
     58:   h->bops->queryfunction   = PetscObjectQueryFunction_Petsc;

     60:   PetscCommDuplicate(comm,&h->comm,&h->tag);

     62: #if defined(PETSC_USE_LOG)
     63:   /* Keep a record of object created */
     64:   if (PetscObjectsLog) {
     65:     PetscObjectsCounts++;
     66:     for (i=0; i<PetscObjectsMaxCounts; i++) {
     67:       if (!PetscObjects[i]) {
     68:         PetscObjects[i] = h;
     69:         return(0);
     70:       }
     71:     }
     72:     /* Need to increase the space for storing PETSc objects */
     73:     if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
     74:     else                        newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
     75:     PetscMalloc1(newPetscObjectsMaxCounts,&newPetscObjects);
     76:     PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
     77:     PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
     78:     PetscFree(PetscObjects);

     80:     PetscObjects                        = newPetscObjects;
     81:     PetscObjects[PetscObjectsMaxCounts] = h;
     82:     PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;
     83:   }
     84: #endif
     85:   return(0);
     86: }

     88: extern PetscBool      PetscMemoryCollectMaximumUsage;
     89: extern PetscLogDouble PetscMemoryMaximumUsage;

     93: /*
     94:     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
     95:     the macro PetscHeaderDestroy().
     96: */
     97: PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
     98: {

    103:   PetscLogObjectDestroy(h);
    104:   PetscComposedQuantitiesDestroy(h);
    105:   if (PetscMemoryCollectMaximumUsage) {
    106:     PetscLogDouble usage;
    107:     PetscMemoryGetCurrentUsage(&usage);
    108:     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
    109:   }
    110:   /* first destroy things that could execute arbitrary code */
    111:   if (h->python_destroy) {
    112:     void           *python_context = h->python_context;
    113:     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
    114:     h->python_context = 0;
    115:     h->python_destroy = 0;

    117:     (*python_destroy)(python_context);
    118:   }
    119:   PetscObjectDestroyOptionsHandlers(h);
    120:   PetscObjectListDestroy(&h->olist);
    121:   PetscCommDestroy(&h->comm);
    122:   /* next destroy other things */
    123:   h->classid = PETSCFREEDHEADER;

    125:   PetscFunctionListDestroy(&h->qlist);
    126:   PetscFree(h->type_name);
    127:   PetscFree(h->name);
    128:   PetscFree(h->prefix);
    129:   PetscFree(h->fortran_func_pointers);
    130:   PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_CLASS]);
    131:   PetscFree(h->fortrancallback[PETSC_FORTRAN_CALLBACK_SUBTYPE]);

    133: #if defined(PETSC_USE_LOG)
    134:   if (PetscObjectsLog) {
    135:     PetscInt i;
    136:     /* Record object removal from list of all objects */
    137:     for (i=0; i<PetscObjectsMaxCounts; i++) {
    138:       if (PetscObjects[i] == h) {
    139:         PetscObjects[i] = 0;
    140:         PetscObjectsCounts--;
    141:         break;
    142:       }
    143:     }
    144:     if (!PetscObjectsCounts) {
    145:       PetscFree(PetscObjects);
    146:       PetscObjectsMaxCounts = 0;
    147:     }
    148:   }
    149: #endif
    150:   return(0);
    151: }

    155: /*@C
    156:    PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object

    158:    Logically Collective on PetscObject

    160:    Input Parameter:
    161: +  src - source object
    162: -  dest - destination object

    164:    Level: developer

    166:    Note:
    167:    Both objects must have the same class.
    168: @*/
    169: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
    170: {
    172:   PetscInt       cbtype,numcb[PETSC_FORTRAN_CALLBACK_MAXTYPE];

    177:   if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");

    179:   PetscFree(dest->fortran_func_pointers);
    180:   PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
    181:   PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));

    183:   dest->num_fortran_func_pointers = src->num_fortran_func_pointers;

    185:   PetscFortranCallbackGetSizes(src->classid,&numcb[PETSC_FORTRAN_CALLBACK_CLASS],&numcb[PETSC_FORTRAN_CALLBACK_SUBTYPE]);
    186:   for (cbtype=PETSC_FORTRAN_CALLBACK_CLASS; cbtype<PETSC_FORTRAN_CALLBACK_MAXTYPE; cbtype++) {
    187:     PetscFree(dest->fortrancallback[cbtype]);
    188:     PetscCalloc1(numcb[cbtype],&dest->fortrancallback[cbtype]);
    189:     PetscMemcpy(dest->fortrancallback[cbtype],src->fortrancallback[cbtype],src->num_fortrancallback[cbtype]*sizeof(PetscFortranCallback));
    190:   }
    191:   return(0);
    192: }

    196: /*@C
    197:    PetscObjectSetFortranCallback - set fortran callback function pointer and context

    199:    Logically Collective

    201:    Input Arguments:
    202: +  obj - object on which to set callback
    203: .  cbtype - callback type (class or subtype)
    204: .  cid - address of callback Id, updated if not yet initialized (zero)
    205: .  func - Fortran function
    206: -  ctx - Fortran context

    208:    Level: developer

    210: .seealso: PetscObjectGetFortranCallback()
    211: @*/
    212: PetscErrorCode PetscObjectSetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId *cid,void (*func)(void),void *ctx)
    213: {
    215:   const char     *subtype = NULL;

    219:   if (cbtype == PETSC_FORTRAN_CALLBACK_SUBTYPE) subtype = obj->type_name;
    220:   if (!*cid) {PetscFortranCallbackRegister(obj->classid,subtype,cid);}
    221:   if (*cid >= PETSC_SMALLEST_FORTRAN_CALLBACK+obj->num_fortrancallback[cbtype]) {
    222:     PetscInt             oldnum = obj->num_fortrancallback[cbtype],newnum = PetscMax(1,2*oldnum);
    223:     PetscFortranCallback *callback;
    224:     PetscMalloc1(newnum,&callback);
    225:     PetscMemcpy(callback,obj->fortrancallback[cbtype],oldnum*sizeof(*obj->fortrancallback[cbtype]));
    226:     PetscFree(obj->fortrancallback[cbtype]);

    228:     obj->fortrancallback[cbtype] = callback;
    229:     obj->num_fortrancallback[cbtype] = newnum;
    230:   }
    231:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].func = func;
    232:   obj->fortrancallback[cbtype][*cid-PETSC_SMALLEST_FORTRAN_CALLBACK].ctx = ctx;
    233:   return(0);
    234: }

    238: /*@C
    239:    PetscObjectGetFortranCallback - get fortran callback function pointer and context

    241:    Logically Collective

    243:    Input Arguments:
    244: +  obj - object on which to get callback
    245: .  cbtype - callback type
    246: -  cid - address of callback Id

    248:    Output Arguments:
    249: +  func - Fortran function (or NULL if not needed)
    250: -  ctx - Fortran context (or NULL if not needed)

    252:    Level: developer

    254: .seealso: PetscObjectSetFortranCallback()
    255: @*/
    256: PetscErrorCode PetscObjectGetFortranCallback(PetscObject obj,PetscFortranCallbackType cbtype,PetscFortranCallbackId cid,void (**func)(void),void **ctx)
    257: {
    258:   PetscFortranCallback *cb;

    262:   if (PetscUnlikely(cid < PETSC_SMALLEST_FORTRAN_CALLBACK)) SETERRQ(obj->comm,PETSC_ERR_ARG_CORRUPT,"Fortran callback Id invalid");
    263:   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");
    264:   cb = &obj->fortrancallback[cbtype][cid-PETSC_SMALLEST_FORTRAN_CALLBACK];
    265:   if (func) *func = cb->func;
    266:   if (ctx) *ctx = cb->ctx;
    267:   return(0);
    268: }

    270: #if defined(PETSC_USE_LOG)
    273: /*@C
    274:    PetscObjectsDump - Prints the currently existing objects.

    276:    Logically Collective on PetscViewer

    278:    Input Parameter:
    279: +  fd - file pointer
    280: -  all - by default only tries to display objects created explicitly by the user, if all is PETSC_TRUE then lists all outstanding objects

    282:    Options Database:
    283: .  -objects_dump <all>

    285:    Level: advanced

    287:    Concepts: options database^printing

    289: @*/
    290: PetscErrorCode  PetscObjectsDump(FILE *fd,PetscBool all)
    291: {
    293:   PetscInt       i;
    294: #if defined(PETSC_USE_DEBUG)
    295:   PetscInt       j,k=0;
    296: #endif
    297:   PetscObject    h;

    300:   if (PetscObjectsCounts) {
    301:     PetscFPrintf(PETSC_COMM_WORLD,fd,"The following objects were never freed\n");
    302:     PetscFPrintf(PETSC_COMM_WORLD,fd,"-----------------------------------------\n");
    303:     for (i=0; i<PetscObjectsMaxCounts; i++) {
    304:       if ((h = PetscObjects[i])) {
    305:         PetscObjectName(h);
    306:         {
    307: #if defined(PETSC_USE_DEBUG)
    308:         PetscStack *stack = 0;
    309:         char       *create,*rclass;

    311:         /* if the PETSc function the user calls is not a create then this object was NOT directly created by them */
    312:         PetscMallocGetStack(h,&stack);
    313:         if (stack) {
    314:           k = stack->currentsize-2;
    315:           if (!all) {
    316:             k = 0;
    317:             while (!stack->petscroutine[k]) k++;
    318:             PetscStrstr(stack->function[k],"Create",&create);
    319:             if (!create) {
    320:               PetscStrstr(stack->function[k],"Get",&create);
    321:             }
    322:             PetscStrstr(stack->function[k],h->class_name,&rclass);
    323:             if (!create) continue;
    324:             if (!rclass) continue;
    325:           }
    326:         }
    327: #endif

    329:         PetscFPrintf(PETSC_COMM_WORLD,fd,"[%d] %s %s %s\n",PetscGlobalRank,h->class_name,h->type_name,h->name);

    331: #if defined(PETSC_USE_DEBUG)
    332:         PetscMallocGetStack(h,&stack);
    333:         if (stack) {
    334:           for (j=k; j>=0; j--) {
    335:             fprintf(fd,"      [%d]  %s() in %s\n",PetscGlobalRank,stack->function[j],stack->file[j]);
    336:           }
    337:         }
    338: #endif
    339:         }
    340:       }
    341:     }
    342:   }
    343:   return(0);
    344: }
    345: #endif

    347: #if defined(PETSC_USE_LOG)

    351: /*@C
    352:    PetscObjectsView - Prints the currently existing objects.

    354:    Logically Collective on PetscViewer

    356:    Input Parameter:
    357: .  viewer - must be an PETSCVIEWERASCII viewer

    359:    Level: advanced

    361:    Concepts: options database^printing

    363: @*/
    364: PetscErrorCode  PetscObjectsView(PetscViewer viewer)
    365: {
    367:   PetscBool      isascii;
    368:   FILE           *fd;

    371:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
    372:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    373:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
    374:   PetscViewerASCIIGetPointer(viewer,&fd);
    375:   PetscObjectsDump(fd,PETSC_TRUE);
    376:   return(0);
    377: }

    381: /*@C
    382:    PetscObjectsGetObject - Get a pointer to a named object

    384:    Not collective

    386:    Input Parameter:
    387: .  name - the name of an object

    389:    Output Parameter:
    390: .   obj - the object or null if there is no object

    392:    Level: advanced

    394:    Concepts: options database^printing

    396: @*/
    397: PetscErrorCode  PetscObjectsGetObject(const char *name,PetscObject *obj,char **classname)
    398: {
    400:   PetscInt       i;
    401:   PetscObject    h;
    402:   PetscBool      flg;

    405:   *obj = NULL;
    406:   for (i=0; i<PetscObjectsMaxCounts; i++) {
    407:     if ((h = PetscObjects[i])) {
    408:       PetscObjectName(h);
    409:       PetscStrcmp(h->name,name,&flg);
    410:       if (flg) {
    411:         *obj = h;
    412:         if (classname) *classname = h->class_name;
    413:         return(0);
    414:       }
    415:     }
    416:   }
    417:   return(0);
    418: }
    419: #endif

    423: /*@C
    424:     PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.

    426:     Not Collective

    428:     Input Parameter:
    429: +   obj - the PETSc object
    430: .   handle - function that checks for options
    431: .   destroy - function to destroy context if provided
    432: -   ctx - optional context for check function

    434:     Level: developer

    437: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()

    439: @*/
    440: PetscErrorCode  PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
    441: {
    444:   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
    445:   obj->optionhandler[obj->noptionhandler] = handle;
    446:   obj->optiondestroy[obj->noptionhandler] = destroy;
    447:   obj->optionctx[obj->noptionhandler++]   = ctx;
    448:   return(0);
    449: }

    453: /*@C
    454:     PetscObjectProcessOptionsHandlers - Calls all the options handlers attached to an object

    456:     Not Collective

    458:     Input Parameter:
    459: .   obj - the PETSc object

    461:     Level: developer

    464: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()

    466: @*/
    467: PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscObject obj)
    468: {
    469:   PetscInt       i;

    474:   for (i=0; i<obj->noptionhandler; i++) {
    475:     (*obj->optionhandler[i])(obj,obj->optionctx[i]);
    476:   }
    477:   return(0);
    478: }

    482: /*@C
    483:     PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an object

    485:     Not Collective

    487:     Input Parameter:
    488: .   obj - the PETSc object

    490:     Level: developer

    493: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()

    495: @*/
    496: PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
    497: {
    498:   PetscInt       i;

    503:   for (i=0; i<obj->noptionhandler; i++) {
    504:     if (obj->optiondestroy[i]) {
    505:       (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
    506:     }
    507:   }
    508:   obj->noptionhandler = 0;
    509:   return(0);
    510: }

    515: /*@
    516:    PetscObjectReference - Indicates to any PetscObject that it is being
    517:    referenced by another PetscObject. This increases the reference
    518:    count for that object by one.

    520:    Logically Collective on PetscObject

    522:    Input Parameter:
    523: .  obj - the PETSc object. This must be cast with (PetscObject), for example,
    524:          PetscObjectReference((PetscObject)mat);

    526:    Level: advanced

    528: .seealso: PetscObjectCompose(), PetscObjectDereference()
    529: @*/
    530: PetscErrorCode  PetscObjectReference(PetscObject obj)
    531: {
    533:   if (!obj) return(0);
    535:   obj->refct++;
    536:   return(0);
    537: }

    541: /*@
    542:    PetscObjectGetReference - Gets the current reference count for
    543:    any PETSc object.

    545:    Not Collective

    547:    Input Parameter:
    548: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
    549:          PetscObjectGetReference((PetscObject)mat,&cnt);

    551:    Output Parameter:
    552: .  cnt - the reference count

    554:    Level: advanced

    556: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
    557: @*/
    558: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
    559: {
    563:   *cnt = obj->refct;
    564:   return(0);
    565: }

    569: /*@
    570:    PetscObjectDereference - Indicates to any PetscObject that it is being
    571:    referenced by one less PetscObject. This decreases the reference
    572:    count for that object by one.

    574:    Collective on PetscObject if reference reaches 0 otherwise Logically Collective

    576:    Input Parameter:
    577: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
    578:          PetscObjectDereference((PetscObject)mat);

    580:    Notes: PetscObjectDestroy(PetscObject *obj)  sets the obj pointer to null after the call, this routine does not.

    582:    Level: advanced

    584: .seealso: PetscObjectCompose(), PetscObjectReference()
    585: @*/
    586: PetscErrorCode  PetscObjectDereference(PetscObject obj)
    587: {

    591:   if (!obj) return(0);
    593:   if (obj->bops->destroy) {
    594:     (*obj->bops->destroy)(&obj);
    595:   } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
    596:   return(0);
    597: }

    599: /* ----------------------------------------------------------------------- */
    600: /*
    601:      The following routines are the versions private to the PETSc object
    602:      data structures.
    603: */
    606: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
    607: {
    610:   *comm = obj->comm;
    611:   return(0);
    612: }

    616: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
    617: {

    622:   PetscObjectListRemoveReference(&obj->olist,name);
    623:   return(0);
    624: }

    628: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
    629: {
    631:   char           *tname;
    632:   PetscBool      skipreference;

    635:   if (ptr) {
    636:     PetscObjectListReverseFind(ptr->olist,obj,&tname,&skipreference);
    637:     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was composed with it");
    638:   }
    639:   PetscObjectListAdd(&obj->olist,name,ptr);
    640:   return(0);
    641: }

    645: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
    646: {

    651:   PetscObjectListFind(obj->olist,name,ptr);
    652:   return(0);
    653: }

    657: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],void (*ptr)(void))
    658: {

    663:   PetscFunctionListAdd(&obj->qlist,name,ptr);
    664:   return(0);
    665: }

    669: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
    670: {

    675:   PetscFunctionListFind(obj->qlist,name,ptr);
    676:   return(0);
    677: }

    681: /*@C
    682:    PetscObjectCompose - Associates another PETSc object with a given PETSc object.

    684:    Not Collective

    686:    Input Parameters:
    687: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
    688:          PetscObjectCompose((PetscObject)mat,...);
    689: .  name - name associated with the child object
    690: -  ptr - the other PETSc object to associate with the PETSc object; this must also be
    691:          cast with (PetscObject)

    693:    Level: advanced

    695:    Notes:
    696:    The second objects reference count is automatically increased by one when it is
    697:    composed.

    699:    Replaces any previous object that had the same name.

    701:    If ptr is null and name has previously been composed using an object, then that
    702:    entry is removed from the obj.

    704:    PetscObjectCompose() can be used with any PETSc object (such as
    705:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
    706:    PetscContainerCreate() for info on how to create an object from a
    707:    user-provided pointer that may then be composed with PETSc objects.

    709:    Concepts: objects^composing
    710:    Concepts: composing objects

    712: .seealso: PetscObjectQuery(), PetscContainerCreate()
    713: @*/
    714: PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
    715: {

    722:   (*obj->bops->compose)(obj,name,ptr);
    723:   return(0);
    724: }

    728: /*@C
    729:    PetscObjectSetPrecision - sets the precision used within a given object.

    731:    Collective on the PetscObject

    733:    Input Parameters:
    734: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
    735:          PetscObjectCompose((PetscObject)mat,...);
    736: -  precision - the precision

    738:    Level: advanced

    740: .seealso: PetscObjectQuery(), PetscContainerCreate()
    741: @*/
    742: PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
    743: {
    746:   obj->precision = precision;
    747:   return(0);
    748: }

    752: /*@C
    753:    PetscObjectQuery  - Gets a PETSc object associated with a given object.

    755:    Not Collective

    757:    Input Parameters:
    758: +  obj - the PETSc object
    759:          Thus must be cast with a (PetscObject), for example,
    760:          PetscObjectCompose((PetscObject)mat,...);
    761: .  name - name associated with child object
    762: -  ptr - the other PETSc object associated with the PETSc object, this must be
    763:          cast with (PetscObject*)

    765:    Level: advanced

    767:    The reference count of neither object is increased in this call

    769:    Concepts: objects^composing
    770:    Concepts: composing objects
    771:    Concepts: objects^querying
    772:    Concepts: querying objects

    774: .seealso: PetscObjectCompose()
    775: @*/
    776: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
    777: {

    784:   (*obj->bops->query)(obj,name,ptr);
    785:   return(0);
    786: }

    788: /*MC
    789:    PetscObjectComposeFunction - Associates a function with a given PETSc object.

    791:     Synopsis:
    792:     #include <petscsys.h>
    793:     PetscErrorCode PetscObjectComposeFunction(PetscObject obj,const char name[],void (*fptr)(void))

    795:    Logically Collective on PetscObject

    797:    Input Parameters:
    798: +  obj - the PETSc object; this must be cast with a (PetscObject), for example,
    799:          PetscObjectCompose((PetscObject)mat,...);
    800: .  name - name associated with the child function
    801: .  fname - name of the function
    802: -  fptr - function pointer

    804:    Level: advanced

    806:    Notes:
    807:    To remove a registered routine, pass in NULL for fptr().

    809:    PetscObjectComposeFunction() can be used with any PETSc object (such as
    810:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.

    812:    Concepts: objects^composing functions
    813:    Concepts: composing functions
    814:    Concepts: functions^querying
    815:    Concepts: objects^querying
    816:    Concepts: querying objects

    818: .seealso: PetscObjectQueryFunction(), PetscContainerCreate()
    819: M*/

    823: PetscErrorCode  PetscObjectComposeFunction_Private(PetscObject obj,const char name[],void (*fptr)(void))
    824: {

    830:   (*obj->bops->composefunction)(obj,name,fptr);
    831:   return(0);
    832: }

    834: /*MC
    835:    PetscObjectQueryFunction - Gets a function associated with a given object.

    837:     Synopsis:
    838:     #include <petscsys.h>
    839:     PetscErrorCode PetscObjectQueryFunction(PetscObject obj,const char name[],void (**fptr)(void))

    841:    Logically Collective on PetscObject

    843:    Input Parameters:
    844: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
    845:          PetscObjectQueryFunction((PetscObject)ksp,...);
    846: -  name - name associated with the child function

    848:    Output Parameter:
    849: .  fptr - function pointer

    851:    Level: advanced

    853:    Concepts: objects^composing functions
    854:    Concepts: composing functions
    855:    Concepts: functions^querying
    856:    Concepts: objects^querying
    857:    Concepts: querying objects

    859: .seealso: PetscObjectComposeFunction(), PetscFunctionListFind()
    860: M*/
    863: PETSC_EXTERN PetscErrorCode PetscObjectQueryFunction_Private(PetscObject obj,const char name[],void (**ptr)(void))
    864: {

    870:   (*obj->bops->queryfunction)(obj,name,ptr);
    871:   return(0);
    872: }

    874: struct _p_PetscContainer {
    875:   PETSCHEADER(int);
    876:   void           *ptr;
    877:   PetscErrorCode (*userdestroy)(void*);
    878: };

    882: /*@C
    883:    PetscContainerGetPointer - Gets the pointer value contained in the container.

    885:    Not Collective

    887:    Input Parameter:
    888: .  obj - the object created with PetscContainerCreate()

    890:    Output Parameter:
    891: .  ptr - the pointer value

    893:    Level: advanced

    895: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
    896:           PetscContainerSetPointer()
    897: @*/
    898: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
    899: {
    903:   *ptr = obj->ptr;
    904:   return(0);
    905: }

    910: /*@C
    911:    PetscContainerSetPointer - Sets the pointer value contained in the container.

    913:    Logically Collective on PetscContainer

    915:    Input Parameters:
    916: +  obj - the object created with PetscContainerCreate()
    917: -  ptr - the pointer value

    919:    Level: advanced

    921: .seealso: PetscContainerCreate(), PetscContainerDestroy(),
    922:           PetscContainerGetPointer()
    923: @*/
    924: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
    925: {
    929:   obj->ptr = ptr;
    930:   return(0);
    931: }

    935: /*@C
    936:    PetscContainerDestroy - Destroys a PETSc container object.

    938:    Collective on PetscContainer

    940:    Input Parameter:
    941: .  obj - an object that was created with PetscContainerCreate()

    943:    Level: advanced

    945: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
    946: @*/
    947: PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
    948: {

    952:   if (!*obj) return(0);
    954:   if (--((PetscObject)(*obj))->refct > 0) {*obj = 0; return(0);}
    955:   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
    956:   PetscHeaderDestroy(obj);
    957:   return(0);
    958: }

    962: /*@C
    963:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

    965:    Logically Collective on PetscContainer

    967:    Input Parameter:
    968: +  obj - an object that was created with PetscContainerCreate()
    969: -  des - name of the user destroy function

    971:    Level: advanced

    973: .seealso: PetscContainerDestroy()
    974: @*/
    975: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
    976: {
    979:   obj->userdestroy = des;
    980:   return(0);
    981: }

    983: PetscClassId PETSC_CONTAINER_CLASSID;

    987: /*@C
    988:    PetscContainerCreate - Creates a PETSc object that has room to hold
    989:    a single pointer. This allows one to attach any type of data (accessible
    990:    through a pointer) with the PetscObjectCompose() function to a PetscObject.
    991:    The data item itself is attached by a call to PetscContainerSetPointer().

    993:    Collective on MPI_Comm

    995:    Input Parameters:
    996: .  comm - MPI communicator that shares the object

    998:    Output Parameters:
    999: .  container - the container created

    1001:    Level: advanced

    1003: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
    1004: @*/
    1005: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
    1006: {
    1008:   PetscContainer contain;

    1012:   PetscSysInitializePackage();
    1013:   PetscHeaderCreate(contain,PETSC_CONTAINER_CLASSID,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,NULL);
    1014:   *container = contain;
    1015:   return(0);
    1016: }

    1020: /*@
    1021:    PetscObjectSetFromOptions - Sets generic parameters from user options.

    1023:    Collective on obj

    1025:    Input Parameter:
    1026: .  obj - the PetscObjcet

    1028:    Options Database Keys:

    1030:    Notes:
    1031:    We have no generic options at present, so this does nothing

    1033:    Level: beginner

    1035: .keywords: set, options, database
    1036: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
    1037: @*/
    1038: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
    1039: {
    1042:   return(0);
    1043: }

    1047: /*@
    1048:    PetscObjectSetUp - Sets up the internal data structures for the later use.

    1050:    Collective on PetscObject

    1052:    Input Parameters:
    1053: .  obj - the PetscObject

    1055:    Notes:
    1056:    This does nothing at present.

    1058:    Level: advanced

    1060: .keywords: setup
    1061: .seealso: PetscObjectDestroy()
    1062: @*/
    1063: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
    1064: {
    1067:   return(0);
    1068: }