Actual source code: pf.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      1: /*
      2:     The PF mathematical functions interface routines, callable by users.
      3: */
      4: #include <../src/vec/pf/pfimpl.h>            /*I "petscpf.h" I*/

      6: PetscClassId      PF_CLASSID          = 0;
      7: PetscFunctionList PFList              = NULL;   /* list of all registered PD functions */
      8: PetscBool         PFRegisterAllCalled = PETSC_FALSE;

     12: /*@C
     13:    PFSet - Sets the C/C++/Fortran functions to be used by the PF function

     15:    Collective on PF

     17:    Input Parameter:
     18: +  pf - the function context
     19: .  apply - function to apply to an array
     20: .  applyvec - function to apply to a Vec
     21: .  view - function that prints information about the PF
     22: .  destroy - function to free the private function context
     23: -  ctx - private function context

     25:    Level: beginner

     27: .keywords: PF, setting

     29: .seealso: PFCreate(), PFDestroy(), PFSetType(), PFApply(), PFApplyVec()
     30: @*/
     31: PetscErrorCode  PFSet(PF pf,PetscErrorCode (*apply)(void*,PetscInt,const PetscScalar*,PetscScalar*),PetscErrorCode (*applyvec)(void*,Vec,Vec),PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*destroy)(void*),void*ctx)
     32: {
     35:   pf->data          = ctx;
     36:   pf->ops->destroy  = destroy;
     37:   pf->ops->apply    = apply;
     38:   pf->ops->applyvec = applyvec;
     39:   pf->ops->view     = view;
     40:   return(0);
     41: }

     45: /*@C
     46:    PFDestroy - Destroys PF context that was created with PFCreate().

     48:    Collective on PF

     50:    Input Parameter:
     51: .  pf - the function context

     53:    Level: beginner

     55: .keywords: PF, destroy

     57: .seealso: PFCreate(), PFSet(), PFSetType()
     58: @*/
     59: PetscErrorCode  PFDestroy(PF *pf)
     60: {

     64:   if (!*pf) return(0);
     66:   if (--((PetscObject)(*pf))->refct > 0) return(0);

     68:   PFViewFromOptions(*pf,NULL,"-pf_view");
     69:   /* if memory was published with SAWs then destroy it */
     70:   PetscObjectSAWsViewOff((PetscObject)*pf);

     72:   if ((*pf)->ops->destroy) { (*(*pf)->ops->destroy)((*pf)->data);}
     73:   PetscHeaderDestroy(pf);
     74:   return(0);
     75: }

     79: /*@C
     80:    PFCreate - Creates a mathematical function context.

     82:    Collective on MPI_Comm

     84:    Input Parameter:
     85: +  comm - MPI communicator
     86: .  dimin - dimension of the space you are mapping from
     87: -  dimout - dimension of the space you are mapping to

     89:    Output Parameter:
     90: .  pf - the function context

     92:    Level: developer

     94: .keywords: PF, create, context

     96: .seealso: PFSet(), PFApply(), PFDestroy(), PFApplyVec()
     97: @*/
     98: PetscErrorCode  PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf)
     99: {
    100:   PF             newpf;

    105:   *pf = NULL;
    106:   PFInitializePackage();

    108:   PetscHeaderCreate(newpf,PF_CLASSID,"PF","Mathematical functions","Vec",comm,PFDestroy,PFView);
    109:   newpf->data          = 0;
    110:   newpf->ops->destroy  = 0;
    111:   newpf->ops->apply    = 0;
    112:   newpf->ops->applyvec = 0;
    113:   newpf->ops->view     = 0;
    114:   newpf->dimin         = dimin;
    115:   newpf->dimout        = dimout;

    117:   *pf                  = newpf;
    118:   return(0);

    120: }

    122: /* -------------------------------------------------------------------------------*/

    126: /*@
    127:    PFApplyVec - Applies the mathematical function to a vector

    129:    Collective on PF

    131:    Input Parameters:
    132: +  pf - the function context
    133: -  x - input vector (or NULL for the vector (0,1, .... N-1)

    135:    Output Parameter:
    136: .  y - output vector

    138:    Level: beginner

    140: .keywords: PF, apply

    142: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
    143: @*/
    144: PetscErrorCode  PFApplyVec(PF pf,Vec x,Vec y)
    145: {
    147:   PetscInt       i,rstart,rend,n,p;
    148:   PetscBool      nox = PETSC_FALSE;

    153:   if (x) {
    155:     if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
    156:   } else {
    157:     PetscScalar *xx;
    158:     PetscInt    lsize;

    160:     VecGetLocalSize(y,&lsize);
    161:     lsize = pf->dimin*lsize/pf->dimout;
    162:     VecCreateMPI(PetscObjectComm((PetscObject)y),lsize,PETSC_DETERMINE,&x);
    163:     nox   = PETSC_TRUE;
    164:     VecGetOwnershipRange(x,&rstart,&rend);
    165:     VecGetArray(x,&xx);
    166:     for (i=rstart; i<rend; i++) xx[i-rstart] = (PetscScalar)i;
    167:     VecRestoreArray(x,&xx);
    168:   }

    170:   VecGetLocalSize(x,&n);
    171:   VecGetLocalSize(y,&p);
    172:   if ((pf->dimin*(n/pf->dimin)) != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local input vector length %D not divisible by dimin %D of function",n,pf->dimin);
    173:   if ((pf->dimout*(p/pf->dimout)) != p) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local output vector length %D not divisible by dimout %D of function",p,pf->dimout);
    174:   if ((n/pf->dimin) != (p/pf->dimout)) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local vector lengths %D %D are wrong for dimin and dimout %D %D of function",n,p,pf->dimin,pf->dimout);

    176:   if (pf->ops->applyvec) {
    177:     (*pf->ops->applyvec)(pf->data,x,y);
    178:   } else {
    179:     PetscScalar *xx,*yy;

    181:     VecGetLocalSize(x,&n);
    182:     n    = n/pf->dimin;
    183:     VecGetArray(x,&xx);
    184:     VecGetArray(y,&yy);
    185:     if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
    186:     (*pf->ops->apply)(pf->data,n,xx,yy);
    187:     VecRestoreArray(x,&xx);
    188:     VecRestoreArray(y,&yy);
    189:   }
    190:   if (nox) {
    191:     VecDestroy(&x);
    192:   }
    193:   return(0);
    194: }

    198: /*@
    199:    PFApply - Applies the mathematical function to an array of values.

    201:    Collective on PF

    203:    Input Parameters:
    204: +  pf - the function context
    205: .  n - number of pointwise function evaluations to perform, each pointwise function evaluation
    206:        is a function of dimin variables and computes dimout variables where dimin and dimout are defined
    207:        in the call to PFCreate()
    208: -  x - input array

    210:    Output Parameter:
    211: .  y - output array

    213:    Level: beginner

    215:    Notes:

    217: .keywords: PF, apply

    219: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
    220: @*/
    221: PetscErrorCode  PFApply(PF pf,PetscInt n,const PetscScalar *x,PetscScalar *y)
    222: {

    229:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different arrays");
    230:   if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");

    232:   (*pf->ops->apply)(pf->data,n,x,y);
    233:   return(0);
    234: }

    238: /*@
    239:    PFView - Prints information about a mathematical function

    241:    Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF

    243:    Input Parameters:
    244: +  PF - the PF context
    245: -  viewer - optional visualization context

    247:    Note:
    248:    The available visualization contexts include
    249: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    250: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    251:          output where only the first processor opens
    252:          the file.  All other processors send their
    253:          data to the first processor to print.

    255:    The user can open an alternative visualization contexts with
    256:    PetscViewerASCIIOpen() (output to a specified file).

    258:    Level: developer

    260: .keywords: PF, view

    262: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
    263: @*/
    264: PetscErrorCode  PFView(PF pf,PetscViewer viewer)
    265: {
    266:   PetscErrorCode    ierr;
    267:   PetscBool         iascii;
    268:   PetscViewerFormat format;

    272:   if (!viewer) {
    273:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);
    274:   }

    278:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    279:   if (iascii) {
    280:     PetscViewerGetFormat(viewer,&format);
    281:     PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer);
    282:     if (pf->ops->view) {
    283:       PetscViewerASCIIPushTab(viewer);
    284:       (*pf->ops->view)(pf->data,viewer);
    285:       PetscViewerASCIIPopTab(viewer);
    286:     }
    287:   }
    288:   return(0);
    289: }

    294: /*@C
    295:    PFRegister - Adds a method to the mathematical function package.

    297:    Not collective

    299:    Input Parameters:
    300: +  name_solver - name of a new user-defined solver
    301: -  routine_create - routine to create method context

    303:    Notes:
    304:    PFRegister() may be called multiple times to add several user-defined functions

    306:    Sample usage:
    307: .vb
    308:    PFRegister("my_function",MyFunctionSetCreate);
    309: .ve

    311:    Then, your solver can be chosen with the procedural interface via
    312: $     PFSetType(pf,"my_function")
    313:    or at runtime via the option
    314: $     -pf_type my_function

    316:    Level: advanced

    318: .keywords: PF, register

    320: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
    321: @*/
    322: PetscErrorCode  PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*))
    323: {

    327:   PetscFunctionListAdd(&PFList,sname,function);
    328:   return(0);
    329: }

    333: /*@C
    334:    PFGetType - Gets the PF method type and name (as a string) from the PF
    335:    context.

    337:    Not Collective

    339:    Input Parameter:
    340: .  pf - the function context

    342:    Output Parameter:
    343: .  type - name of function

    345:    Level: intermediate

    347: .keywords: PF, get, method, name, type

    349: .seealso: PFSetType()

    351: @*/
    352: PetscErrorCode  PFGetType(PF pf,PFType *type)
    353: {
    357:   *type = ((PetscObject)pf)->type_name;
    358:   return(0);
    359: }

    364: /*@C
    365:    PFSetType - Builds PF for a particular function

    367:    Collective on PF

    369:    Input Parameter:
    370: +  pf - the function context.
    371: .  type - a known method
    372: -  ctx - optional type dependent context

    374:    Options Database Key:
    375: .  -pf_type <type> - Sets PF type

    378:   Notes:
    379:   See "petsc/include/petscpf.h" for available methods (for instance,
    380:   PFCONSTANT)

    382:   Level: intermediate

    384: .keywords: PF, set, method, type

    386: .seealso: PFSet(), PFRegister(), PFCreate(), DMDACreatePF()

    388: @*/
    389: PetscErrorCode  PFSetType(PF pf,PFType type,void *ctx)
    390: {
    391:   PetscErrorCode ierr,(*r)(PF,void*);
    392:   PetscBool      match;

    398:   PetscObjectTypeCompare((PetscObject)pf,type,&match);
    399:   if (match) return(0);

    401:   if (pf->ops->destroy) { (*pf->ops->destroy)(pf);}
    402:   pf->data = 0;

    404:   /* Determine the PFCreateXXX routine for a particular function */
    405:   PetscFunctionListFind(PFList,type,&r);
    406:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type);
    407:   pf->ops->destroy  = 0;
    408:   pf->ops->view     = 0;
    409:   pf->ops->apply    = 0;
    410:   pf->ops->applyvec = 0;

    412:   /* Call the PFCreateXXX routine for this particular function */
    413:   (*r)(pf,ctx);

    415:   PetscObjectChangeTypeName((PetscObject)pf,type);
    416:   return(0);
    417: }

    421: /*@
    422:    PFSetFromOptions - Sets PF options from the options database.

    424:    Collective on PF

    426:    Input Parameters:
    427: .  pf - the mathematical function context

    429:    Options Database Keys:

    431:    Notes:
    432:    To see all options, run your program with the -help option
    433:    or consult the users manual.

    435:    Level: intermediate

    437: .keywords: PF, set, from, options, database

    439: .seealso:
    440: @*/
    441: PetscErrorCode  PFSetFromOptions(PF pf)
    442: {
    444:   char           type[256];
    445:   PetscBool      flg;

    450:   PetscObjectOptionsBegin((PetscObject)pf);
    451:   PetscOptionsFList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);
    452:   if (flg) {
    453:     PFSetType(pf,type,NULL);
    454:   }
    455:   if (pf->ops->setfromoptions) {
    456:     (*pf->ops->setfromoptions)(PetscOptionsObject,pf);
    457:   }

    459:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
    460:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pf);
    461:   PetscOptionsEnd();
    462:   return(0);
    463: }

    465: static PetscBool PFPackageInitialized = PETSC_FALSE;
    468: /*@C
    469:   PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
    470:   called from PetscFinalize().

    472:   Level: developer

    474: .keywords: Petsc, destroy, package, mathematica
    475: .seealso: PetscFinalize()
    476: @*/
    477: PetscErrorCode  PFFinalizePackage(void)
    478: {

    482:   PetscFunctionListDestroy(&PFList);
    483:   PFPackageInitialized = PETSC_FALSE;
    484:   PFRegisterAllCalled  = PETSC_FALSE;
    485:   return(0);
    486: }

    490: /*@C
    491:   PFInitializePackage - This function initializes everything in the PF package. It is called
    492:   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate()
    493:   when using static libraries.

    495:   Level: developer

    497: .keywords: Vec, initialize, package
    498: .seealso: PetscInitialize()
    499: @*/
    500: PetscErrorCode  PFInitializePackage(void)
    501: {
    502:   char           logList[256];
    503:   char           *className;
    504:   PetscBool      opt;

    508:   if (PFPackageInitialized) return(0);
    509:   PFPackageInitialized = PETSC_TRUE;
    510:   /* Register Classes */
    511:   PetscClassIdRegister("PointFunction",&PF_CLASSID);
    512:   /* Register Constructors */
    513:   PFRegisterAll();
    514:   /* Process info exclusions */
    515:   PetscOptionsGetString(NULL,NULL, "-info_exclude", logList, 256, &opt);
    516:   if (opt) {
    517:     PetscStrstr(logList, "pf", &className);
    518:     if (className) {
    519:       PetscInfoDeactivateClass(PF_CLASSID);
    520:     }
    521:   }
    522:   /* Process summary exclusions */
    523:   PetscOptionsGetString(NULL,NULL, "-log_exclude", logList, 256, &opt);
    524:   if (opt) {
    525:     PetscStrstr(logList, "pf", &className);
    526:     if (className) {
    527:       PetscLogEventDeactivateClass(PF_CLASSID);
    528:     }
    529:   }
    530:   PetscRegisterFinalize(PFFinalizePackage);
    531:   return(0);
    532: }