Actual source code: inherit.c

      1: #define PETSC_DLL
      2: /*
      3:      Provides utility routines for manipulating any type of PETSc object.
      4: */
     5:  #include petsc.h
     6:  #include petscsys.h

      8: EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm *);
      9: EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
     10: EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject *);
     11: EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],const char[],void (*)(void));
     12: EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
     13: EXTERN PetscErrorCode PetscObjectComposeLanguage_Petsc(PetscObject,PetscLanguage,void *);
     14: EXTERN PetscErrorCode PetscObjectQueryLanguage_Petsc(PetscObject,PetscLanguage,void **);

     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 PETSC_DLLEXPORT PetscHeaderCreate_Private(PetscObject h,PetscCookie cookie,PetscInt type,const char class_name[],MPI_Comm comm,
     23:                                          PetscErrorCode (*des)(PetscObject),PetscErrorCode (*vie)(PetscObject,PetscViewer))
     24: {
     25:   static PetscInt idcnt = 1;
     26:   PetscErrorCode  ierr;

     29:   h->cookie                 = cookie;
     30:   h->type                   = type;
     31:   h->class_name             = (char*)class_name;
     32:   h->prefix                 = 0;
     33:   h->refct                  = 1;
     34:   h->amem                   = -1;
     35:   h->id                     = idcnt++;
     36:   h->parentid               = 0;
     37:   h->qlist                  = 0;
     38:   h->olist                  = 0;
     39:   h->bops->destroy          = des;
     40:   h->bops->view             = vie;
     41:   h->bops->getcomm          = PetscObjectGetComm_Petsc;
     42:   h->bops->compose          = PetscObjectCompose_Petsc;
     43:   h->bops->query            = PetscObjectQuery_Petsc;
     44:   h->bops->composefunction  = PetscObjectComposeFunction_Petsc;
     45:   h->bops->queryfunction    = PetscObjectQueryFunction_Petsc;
     46:   h->bops->querylanguage    = PetscObjectQueryLanguage_Petsc;
     47:   h->bops->composelanguage  = PetscObjectComposeLanguage_Petsc;
     48:   PetscCommDuplicate(comm,&h->comm,&h->tag);
     49:   return(0);
     50: }

     57: /*
     58:     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
     59:     the macro PetscHeaderDestroy().
     60: */
     61: PetscErrorCode PETSC_DLLEXPORT PetscHeaderDestroy_Private(PetscObject h)
     62: {

     66:   if (PetscMemoryCollectMaximumUsage) {
     67:     PetscLogDouble usage;
     68:     PetscMemoryGetCurrentUsage(&usage);
     69:     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
     70:   }
     71:   PetscCommDestroy(&h->comm);
     72:   PetscFree(h->bops);
     73:   PetscFree(h->ops);
     74:   PetscOListDestroy(&h->olist);
     75:   PetscFListDestroy(&h->qlist);
     76:   PetscStrfree(h->type_name);
     77:   PetscStrfree(h->name);
     78:   h->cookie = PETSCFREEDHEADER;
     79:   PetscStrfree(h->prefix);
     80:   if (h->fortran_func_pointers) {
     81:     PetscFree(h->fortran_func_pointers);
     82:   }
     83:   if (h->intcomposeddata) {
     84:     PetscFree(h->intcomposeddata);
     85:   }
     86:   if (h->intcomposedstate) {
     87:     PetscFree(h->intcomposedstate);
     88:   }
     89:   if (h->realcomposeddata) {
     90:     PetscFree(h->realcomposeddata);
     91:   }
     92:   if (h->realcomposedstate) {
     93:     PetscFree(h->realcomposedstate);
     94:   }
     95:   if (h->scalarcomposeddata) {
     96:     PetscFree(h->scalarcomposeddata);
     97:   }
     98:   if (h->scalarcomposedstate) {
     99:     PetscFree(h->scalarcomposedstate);
    100:   }
    101:   return(0);
    102: }

    106: /*@C
    107:    PetscObjectReference - Indicates to any PetscObject that it is being
    108:    referenced by another PetscObject. This increases the reference
    109:    count for that object by one.

    111:    Collective on PetscObject

    113:    Input Parameter:
    114: .  obj - the PETSc object. This must be cast with (PetscObject), for example,
    115:          PetscObjectReference((PetscObject)mat);

    117:    Level: advanced

    119: .seealso: PetscObjectCompose(), PetscObjectDereference()
    120: @*/
    121: PetscErrorCode PETSC_DLLEXPORT PetscObjectReference(PetscObject obj)
    122: {
    125:   obj->refct++;
    126:   return(0);
    127: }

    131: /*@C
    132:    PetscObjectGetReference - Gets the current reference count for
    133:    any PETSc object.

    135:    Not Collective

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

    141:    Output Parameter:
    142: .  cnt - the reference count

    144:    Level: advanced

    146: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
    147: @*/
    148: PetscErrorCode PETSC_DLLEXPORT PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
    149: {
    153:   *cnt = obj->refct;
    154:   return(0);
    155: }

    159: /*@
    160:    PetscObjectDereference - Indicates to any PetscObject that it is being
    161:    referenced by one less PetscObject. This decreases the reference
    162:    count for that object by one.

    164:    Collective on PetscObject

    166:    Input Parameter:
    167: .  obj - the PETSc object; this must be cast with (PetscObject), for example,
    168:          PetscObjectDereference((PetscObject)mat);

    170:    Level: advanced

    172: .seealso: PetscObjectCompose(), PetscObjectReference()
    173: @*/
    174: PetscErrorCode PETSC_DLLEXPORT PetscObjectDereference(PetscObject obj)
    175: {

    180:   if (obj->bops->destroy) {
    181:     (*obj->bops->destroy)(obj);
    182:   } else if (!--obj->refct) {
    183:     SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
    184:   }
    185:   return(0);
    186: }

    188: /* ----------------------------------------------------------------------- */
    189: /*
    190:      The following routines are the versions private to the PETSc object
    191:      data structures.
    192: */
    195: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
    196: {
    198:   *comm = obj->comm;
    199:   return(0);
    200: }

    204: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
    205: {
    207:   char *tname;

    210:   if (ptr) {
    211:     PetscOListReverseFind(ptr->olist,obj,&tname);
    212:     if (tname){
    213:       SETERRQ(PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
    214:     }
    215:   }
    216:   PetscOListAdd(&obj->olist,name,ptr);
    217:   return(0);
    218: }

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

    227:   PetscOListFind(obj->olist,name,ptr);
    228:   return(0);
    229: }

    233: PetscErrorCode PetscObjectComposeLanguage_Petsc(PetscObject obj,PetscLanguage lang,void *vob)
    234: {
    236:   if (lang == PETSC_LANGUAGE_CXX) {
    237:     obj->cpp = vob;
    238:   } else {
    239:     SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
    240:   }
    241:   return(0);
    242: }

    246: PetscErrorCode PetscObjectQueryLanguage_Petsc(PetscObject obj,PetscLanguage lang,void **vob)
    247: {
    249:   if (lang == PETSC_LANGUAGE_C) {
    250:     *vob = (void*)obj;
    251:   } else if (lang == PETSC_LANGUAGE_CXX) {
    252:     if (obj->cpp) {
    253:       *vob = obj->cpp;
    254:     } else {
    255:       SETERRQ(PETSC_ERR_SUP,"No C++ wrapper generated");
    256:     }
    257:   } else {
    258:     SETERRQ(PETSC_ERR_SUP,"No support for this language yet");
    259:   }
    260:   return(0);
    261: }

    265: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
    266: {

    270:   PetscFListAdd(&obj->qlist,name,fname,ptr);
    271:   return(0);
    272: }

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

    281:   PetscFListFind(obj->comm,obj->qlist,name,ptr);
    282:   return(0);
    283: }

    285: /*
    286:         These are the versions that are usable to any CCA compliant objects
    287: */
    290: /*@C
    291:    PetscObjectCompose - Associates another PETSc object with a given PETSc object.
    292:
    293:    Not Collective

    295:    Input Parameters:
    296: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
    297:          PetscObjectCompose((PetscObject)mat,...);
    298: .  name - name associated with the child object
    299: -  ptr - the other PETSc object to associate with the PETSc object; this must also be
    300:          cast with (PetscObject)

    302:    Level: advanced

    304:    Notes:
    305:    The second objects reference count is automatically increased by one when it is
    306:    composed.

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

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

    313:    PetscObjectCompose() can be used with any PETSc object (such as
    314:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
    315:    PetscObjectContainerCreate() for info on how to create an object from a
    316:    user-provided pointer that may then be composed with PETSc objects.
    317:
    318:    Concepts: objects^composing
    319:    Concepts: composing objects

    321: .seealso: PetscObjectQuery(), PetscObjectContainerCreate()
    322: @*/
    323: PetscErrorCode PETSC_DLLEXPORT PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
    324: {

    328:   (*obj->bops->compose)(obj,name,ptr);
    329:   return(0);
    330: }

    334: /*@C
    335:    PetscObjectQuery  - Gets a PETSc object associated with a given object.
    336:
    337:    Not Collective

    339:    Input Parameters:
    340: +  obj - the PETSc object
    341:          Thus must be cast with a (PetscObject), for example,
    342:          PetscObjectCompose((PetscObject)mat,...);
    343: .  name - name associated with child object
    344: -  ptr - the other PETSc object associated with the PETSc object, this must also be
    345:          cast with (PetscObject)

    347:    Level: advanced

    349:    Concepts: objects^composing
    350:    Concepts: composing objects
    351:    Concepts: objects^querying
    352:    Concepts: querying objects

    354: .seealso: PetscObjectQuery()
    355: @*/
    356: PetscErrorCode PETSC_DLLEXPORT PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
    357: {

    361:   (*obj->bops->query)(obj,name,ptr);
    362:   return(0);
    363: }

    367: /*@C
    368:    PetscObjectQueryLanguage - Returns a language specific interface to the given object
    369:
    370:    Not Collective

    372:    Input Parameters:
    373: +  obj - the PETSc object
    374:          Thus must be cast with a (PetscObject), for example,
    375:          PetscObjectCompose((PetscObject)mat,...);
    376: -  lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CXX

    378:    Output Parameter:
    379: .  ptr - the language specific interface

    381:    Level: developer

    383: .seealso: PetscObjectQuery()
    384: @*/
    385: PetscErrorCode PETSC_DLLEXPORT PetscObjectQueryLanguage(PetscObject obj,PetscLanguage lang,void **ptr)
    386: {

    390:   (*obj->bops->querylanguage)(obj,lang,ptr);
    391:   return(0);
    392: }

    396: /*@C
    397:    PetscObjectComposeLanguage - Sets a language specific interface to the given object
    398:
    399:    Not Collective

    401:    Input Parameters:
    402: +  obj - the PETSc object
    403:          Thus must be cast with a (PetscObject), for example,
    404:          PetscObjectCompose((PetscObject)mat,...);
    405: .  lang - one of PETSC_LANGUAGE_C, PETSC_LANGUAGE_F77, PETSC_LANGUAGE_CXX
    406: -  ptr - the language specific interface

    408:    Level: developer

    410: .seealso: PetscObjectQuery()
    411: @*/
    412: PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeLanguage(PetscObject obj,PetscLanguage lang,void *ptr)
    413: {

    417:   (*obj->bops->composelanguage)(obj,lang,ptr);
    418:   return(0);
    419: }

    424: PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
    425: {

    429:   (*obj->bops->composefunction)(obj,name,fname,ptr);
    430:   return(0);
    431: }

    435: /*@C
    436:    PetscObjectQueryFunction - Gets a function associated with a given object.
    437:
    438:    Collective on PetscObject

    440:    Input Parameters:
    441: +  obj - the PETSc object; this must be cast with (PetscObject), for example,
    442:          PetscObjectQueryFunction((PetscObject)ksp,...);
    443: -  name - name associated with the child function

    445:    Output Parameter:
    446: .  ptr - function pointer

    448:    Level: advanced

    450:    Concepts: objects^composing functions
    451:    Concepts: composing functions
    452:    Concepts: functions^querying
    453:    Concepts: objects^querying
    454:    Concepts: querying objects

    456: .seealso: PetscObjectComposeFunctionDynamic()
    457: @*/
    458: PetscErrorCode PETSC_DLLEXPORT PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
    459: {

    463:   (*obj->bops->queryfunction)(obj,name,ptr);
    464:   return(0);
    465: }

    467: struct _p_PetscObjectContainer {
    468:   PETSCHEADER(int);
    469:   void   *ptr;
    470:   PetscErrorCode (*userdestroy)(void*);
    471: };

    475: /*@C
    476:    PetscObjectContainerGetPointer - Gets the pointer value contained in the container.

    478:    Collective on PetscObjectContainer

    480:    Input Parameter:
    481: .  obj - the object created with PetscObjectContainerCreate()

    483:    Output Parameter:
    484: .  ptr - the pointer value

    486:    Level: advanced

    488: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
    489:           PetscObjectContainerSetPointer()
    490: @*/
    491: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerGetPointer(PetscObjectContainer obj,void **ptr)
    492: {
    494:   *ptr = obj->ptr;
    495:   return(0);
    496: }

    501: /*@C
    502:    PetscObjectContainerSetPointer - Sets the pointer value contained in the container.

    504:    Collective on PetscObjectContainer

    506:    Input Parameters:
    507: +  obj - the object created with PetscObjectContainerCreate()
    508: -  ptr - the pointer value

    510:    Level: advanced

    512: .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
    513:           PetscObjectContainerGetPointer()
    514: @*/
    515: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetPointer(PetscObjectContainer obj,void *ptr)
    516: {
    518:   obj->ptr = ptr;
    519:   return(0);
    520: }

    524: /*@C
    525:    PetscObjectContainerDestroy - Destroys a PETSc container object.

    527:    Collective on PetscObjectContainer

    529:    Input Parameter:
    530: .  obj - an object that was created with PetscObjectContainerCreate()

    532:    Level: advanced

    534: .seealso: PetscObjectContainerCreate()
    535: @*/
    536: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerDestroy(PetscObjectContainer obj)
    537: {
    540:   if (--obj->refct > 0) return(0);
    541:   if (obj->userdestroy) (*obj->userdestroy)(obj->ptr);
    542:   PetscHeaderDestroy(obj);
    543:   return(0);
    544: }

    548: /*@C
    549:    PetscObjectContainerSetUserDestroy - Sets name of the user destroy function.

    551:    Collective on PetscObjectContainer

    553:    Input Parameter:
    554: +  obj - an object that was created with PetscObjectContainerCreate()
    555: -  des - name of the user destroy function

    557:    Level: advanced

    559: .seealso: PetscObjectContainerDestroy()
    560: @*/
    561: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetUserDestroy(PetscObjectContainer obj, PetscErrorCode (*des)(void*))
    562: {
    564:   obj->userdestroy = des;
    565:   return(0);
    566: }

    568: PetscCookie PETSC_DLLEXPORT CONTAINER_COOKIE = 0;

    572: /*@C
    573:    PetscObjectContainerCreate - Creates a PETSc object that has room to hold
    574:    a single pointer. This allows one to attach any type of data (accessible
    575:    through a pointer) with the PetscObjectCompose() function to a PetscObject.
    576:    The data item itself is attached by a call to PetscObjectContainerSetPointer.

    578:    Collective on MPI_Comm

    580:    Input Parameters:
    581: .  comm - MPI communicator that shares the object

    583:    Output Parameters:
    584: .  container - the container created

    586:    Level: advanced

    588: .seealso: PetscObjectContainerDestroy(), PetscObjectContainerSetPointer(), PetscObjectContainerSetPointer()
    589: @*/
    590: PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerCreate(MPI_Comm comm,PetscObjectContainer *container)
    591: {
    592:   PetscErrorCode       ierr;
    593:   PetscObjectContainer contain;

    596:   if (!CONTAINER_COOKIE) {
    597:     PetscLogClassRegister(&CONTAINER_COOKIE,          "Container");
    598:   }
    599:   PetscHeaderCreate(contain,_p_PetscObjectContainer,PetscInt,CONTAINER_COOKIE,0,"container",comm,PetscObjectContainerDestroy,0);
    600:   *container = contain;
    601:   return(0);
    602: }

    606: /*@
    607:    PetscObjectSetFromOptions - Sets generic parameters from user options.

    609:    Collective on obj

    611:    Input Parameter:
    612: .  obj - the PetscObjcet

    614:    Options Database Keys:

    616:    Notes:
    617:    We have no generic options at present, so this does nothing

    619:    Level: beginner

    621: .keywords: set, options, database
    622: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
    623: @*/
    624: PetscErrorCode PETSC_DLLEXPORT PetscObjectSetFromOptions(PetscObject obj)
    625: {
    627:   if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
    628:   return(0);
    629: }

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

    636:    Collective on PetscObject

    638:    Input Parameters:
    639: .  obj - the PetscObject

    641:    Notes:
    642:    This does nothing at present.

    644:    Level: advanced

    646: .keywords: setup
    647: .seealso: PetscObjectDestroy()
    648: @*/
    649: PetscErrorCode PETSC_DLLEXPORT PetscObjectSetUp(PetscObject obj)
    650: {
    652:   if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
    653:   return(0);
    654: }