Date: 2016-03-29T14:57:33+00:00

Actual source code: rgbasic.c
slepc-3.6.3 2016-03-29
Report Typos and Errors

      1: /*
      2:    Basic routines

      4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      6:    Copyright (c) 2002-2015, Universitat Politecnica de Valencia, Spain

      8:    This file is part of SLEPc.

     10:    SLEPc is free software: you can redistribute it and/or modify it under  the
     11:    terms of version 3 of the GNU Lesser General Public License as published by
     12:    the Free Software Foundation.

     14:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
     15:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
     16:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
     17:    more details.

     19:    You  should have received a copy of the GNU Lesser General  Public  License
     20:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
     21:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     22: */

     24: #include <slepc/private/rgimpl.h>      /*I "slepcrg.h" I*/

     26: PetscFunctionList RGList = 0;
     27: PetscBool         RGRegisterAllCalled = PETSC_FALSE;
     28: PetscClassId      RG_CLASSID = 0;
     29: static PetscBool  RGPackageInitialized = PETSC_FALSE;

     33: /*@C
     34:    RGFinalizePackage - This function destroys everything in the Slepc interface
     35:    to the RG package. It is called from SlepcFinalize().

     37:    Level: developer

     39: .seealso: SlepcFinalize()
     40: @*/
     41: PetscErrorCode RGFinalizePackage(void)
     42: {

     46:   PetscFunctionListDestroy(&RGList);
     47:   RGPackageInitialized = PETSC_FALSE;
     48:   RGRegisterAllCalled  = PETSC_FALSE;
     49:   return(0);
     50: }

     54: /*@C
     55:   RGInitializePackage - This function initializes everything in the RG package.
     56:   It is called from PetscDLLibraryRegister() when using dynamic libraries, and
     57:   on the first call to RGCreate() when using static libraries.

     59:   Level: developer

     61: .seealso: SlepcInitialize()
     62: @*/
     63: PetscErrorCode RGInitializePackage(void)
     64: {
     65:   char             logList[256];
     66:   char             *className;
     67:   PetscBool        opt;
     68:   PetscErrorCode   ierr;

     71:   if (RGPackageInitialized) return(0);
     72:   RGPackageInitialized = PETSC_TRUE;
     73:   /* Register Classes */
     74:   PetscClassIdRegister("Region",&RG_CLASSID);
     75:   /* Register Constructors */
     76:   RGRegisterAll();
     77:   /* Process info exclusions */
     78:   PetscOptionsGetString(NULL,"-info_exclude",logList,256,&opt);
     79:   if (opt) {
     80:     PetscStrstr(logList,"rg",&className);
     81:     if (className) {
     82:       PetscInfoDeactivateClass(RG_CLASSID);
     83:     }
     84:   }
     85:   /* Process summary exclusions */
     86:   PetscOptionsGetString(NULL,"-log_summary_exclude",logList,256,&opt);
     87:   if (opt) {
     88:     PetscStrstr(logList,"rg",&className);
     89:     if (className) {
     90:       PetscLogEventDeactivateClass(RG_CLASSID);
     91:     }
     92:   }
     93:   PetscRegisterFinalize(RGFinalizePackage);
     94:   return(0);
     95: }

     99: /*@
    100:    RGCreate - Creates an RG context.

    102:    Collective on MPI_Comm

    104:    Input Parameter:
    105: .  comm - MPI communicator

    107:    Output Parameter:
    108: .  newrg - location to put the RG context

    110:    Level: beginner

    112: .seealso: RGDestroy(), RG
    113: @*/
    114: PetscErrorCode RGCreate(MPI_Comm comm,RG *newrg)
    115: {
    116:   RG             rg;

    121:   *newrg = 0;
    122:   RGInitializePackage();
    123:   SlepcHeaderCreate(rg,RG_CLASSID,"RG","Region","RG",comm,RGDestroy,RGView);
    124:   rg->complement = PETSC_FALSE;
    125:   rg->sfactor    = 1.0;
    126:   rg->data       = NULL;

    128:   *newrg = rg;
    129:   return(0);
    130: }

    134: /*@C
    135:    RGSetOptionsPrefix - Sets the prefix used for searching for all
    136:    RG options in the database.

    138:    Logically Collective on RG

    140:    Input Parameters:
    141: +  rg     - the region context
    142: -  prefix - the prefix string to prepend to all RG option requests

    144:    Notes:
    145:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    146:    The first character of all runtime options is AUTOMATICALLY the
    147:    hyphen.

    149:    Level: advanced

    151: .seealso: RGAppendOptionsPrefix()
    152: @*/
    153: PetscErrorCode RGSetOptionsPrefix(RG rg,const char *prefix)
    154: {

    159:   PetscObjectSetOptionsPrefix((PetscObject)rg,prefix);
    160:   return(0);
    161: }

    165: /*@C
    166:    RGAppendOptionsPrefix - Appends to the prefix used for searching for all
    167:    RG options in the database.

    169:    Logically Collective on RG

    171:    Input Parameters:
    172: +  rg     - the region context
    173: -  prefix - the prefix string to prepend to all RG option requests

    175:    Notes:
    176:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    177:    The first character of all runtime options is AUTOMATICALLY the hyphen.

    179:    Level: advanced

    181: .seealso: RGSetOptionsPrefix()
    182: @*/
    183: PetscErrorCode RGAppendOptionsPrefix(RG rg,const char *prefix)
    184: {

    189:   PetscObjectAppendOptionsPrefix((PetscObject)rg,prefix);
    190:   return(0);
    191: }

    195: /*@C
    196:    RGGetOptionsPrefix - Gets the prefix used for searching for all
    197:    RG options in the database.

    199:    Not Collective

    201:    Input Parameters:
    202: .  rg - the region context

    204:    Output Parameters:
    205: .  prefix - pointer to the prefix string used is returned

    207:    Notes: On the fortran side, the user should pass in a string 'prefix' of
    208:    sufficient length to hold the prefix.

    210:    Level: advanced

    212: .seealso: RGSetOptionsPrefix(), RGAppendOptionsPrefix()
    213: @*/
    214: PetscErrorCode RGGetOptionsPrefix(RG rg,const char *prefix[])
    215: {

    221:   PetscObjectGetOptionsPrefix((PetscObject)rg,prefix);
    222:   return(0);
    223: }

    227: /*@C
    228:    RGSetType - Selects the type for the RG object.

    230:    Logically Collective on RG

    232:    Input Parameter:
    233: +  rg   - the region context
    234: -  type - a known type

    236:    Level: intermediate

    238: .seealso: RGGetType()
    239: @*/
    240: PetscErrorCode RGSetType(RG rg,RGType type)
    241: {
    242:   PetscErrorCode ierr,(*r)(RG);
    243:   PetscBool      match;

    249:   PetscObjectTypeCompare((PetscObject)rg,type,&match);
    250:   if (match) return(0);

    252:    PetscFunctionListFind(RGList,type,&r);
    253:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested RG type %s",type);

    255:   if (rg->ops->destroy) { (*rg->ops->destroy)(rg); }
    256:   PetscMemzero(rg->ops,sizeof(struct _RGOps));

    258:   PetscObjectChangeTypeName((PetscObject)rg,type);
    259:   (*r)(rg);
    260:   return(0);
    261: }

    265: /*@C
    266:    RGGetType - Gets the RG type name (as a string) from the RG context.

    268:    Not Collective

    270:    Input Parameter:
    271: .  rg - the region context

    273:    Output Parameter:
    274: .  name - name of the region

    276:    Level: intermediate

    278: .seealso: RGSetType()
    279: @*/
    280: PetscErrorCode RGGetType(RG rg,RGType *type)
    281: {
    285:   *type = ((PetscObject)rg)->type_name;
    286:   return(0);
    287: }

    291: /*@
    292:    RGSetFromOptions - Sets RG options from the options database.

    294:    Collective on RG

    296:    Input Parameters:
    297: .  rg - the region context

    299:    Notes:
    300:    To see all options, run your program with the -help option.

    302:    Level: beginner
    303: @*/
    304: PetscErrorCode RGSetFromOptions(RG rg)
    305: {
    307:   char           type[256];
    308:   PetscBool      flg;

    312:   RGRegisterAll();
    313:   PetscObjectOptionsBegin((PetscObject)rg);
    314:     PetscOptionsFList("-rg_type","Region type","RGSetType",RGList,(char*)(((PetscObject)rg)->type_name?((PetscObject)rg)->type_name:RGINTERVAL),type,256,&flg);
    315:     if (flg) {
    316:       RGSetType(rg,type);
    317:     }
    318:     /*
    319:       Set the type if it was never set.
    320:     */
    321:     if (!((PetscObject)rg)->type_name) {
    322:       RGSetType(rg,RGINTERVAL);
    323:     }

    325:     PetscOptionsBool("-rg_complement","Whether region is complemented or not","RGSetComplement",rg->complement,&rg->complement,&flg);

    327:     if (rg->ops->setfromoptions) {
    328:       (*rg->ops->setfromoptions)(PetscOptionsObject,rg);
    329:     }
    330:     PetscObjectProcessOptionsHandlers((PetscObject)rg);
    331:   PetscOptionsEnd();
    332:   return(0);
    333: }

    337: /*@C
    338:    RGView - Prints the RG data structure.

    340:    Collective on RG

    342:    Input Parameters:
    343: +  rg - the region context
    344: -  viewer - optional visualization context

    346:    Note:
    347:    The available visualization contexts include
    348: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    349: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    350:          output where only the first processor opens
    351:          the file.  All other processors send their
    352:          data to the first processor to print.

    354:    The user can open an alternative visualization context with
    355:    PetscViewerASCIIOpen() - output to a specified file.

    357:    Level: beginner
    358: @*/
    359: PetscErrorCode RGView(RG rg,PetscViewer viewer)
    360: {
    361:   PetscBool      isascii;

    366:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)rg));
    369:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    370:   if (isascii) {
    371:     PetscObjectPrintClassNamePrefixType((PetscObject)rg,viewer);
    372:     if (rg->ops->view) {
    373:       PetscViewerASCIIPushTab(viewer);
    374:       (*rg->ops->view)(rg,viewer);
    375:       PetscViewerASCIIPopTab(viewer);
    376:     }
    377:     if (rg->complement) {
    378:       PetscViewerASCIIPrintf(viewer,"  selected region is the complement of the specified one\n");
    379:     }
    380:     if (rg->sfactor!=1.0) {
    381:       PetscViewerASCIIPrintf(viewer,"  scaling factor = %g\n",(double)rg->sfactor);
    382:     }
    383:   }
    384:   return(0);
    385: }

    389: /*@
    390:    RGIsTrivial - Whether it is the trivial region (whole complex plane).

    392:    Not Collective

    394:    Input Parameter:
    395: .  rg - the region context

    397:    Output Parameter:
    398: .  trivial - true if the region is equal to the whole complex plane, e.g.,
    399:              an interval region with all four endpoints unbounded or an
    400:              ellipse with infinite radius.

    402:    Level: basic
    403: @*/
    404: PetscErrorCode RGIsTrivial(RG rg,PetscBool *trivial)
    405: {

    412:   if (rg->ops->istrivial) {
    413:     (*rg->ops->istrivial)(rg,trivial);
    414:   } else *trivial = PETSC_FALSE;
    415:   return(0);
    416: }

    420: /*@
    421:    RGCheckInside - Determines if a set of given points are inside the region or not.

    423:    Not Collective

    425:    Input Parameters:
    426: +  rg - the region context
    427: .  n  - number of points to check
    428: .  ar - array of real parts
    429: -  ai - array of imaginary parts

    431:    Output Parameter:
    432: .  inside - array of results (1=inside, 0=on the contour, -1=outside)

    434:    Note:
    435:    The point a is expressed as a couple of PetscScalar variables ar,ai.
    436:    If built with complex scalars, the point is supposed to be stored in ar,
    437:    otherwise ar,ai contain the real and imaginary parts, respectively.

    439:    If a scaling factor was set, the points are scaled before checking.

    441:    Level: intermediate

    443: .seealso: RGSetScale(), RGSetComplement()
    444: @*/
    445: PetscErrorCode RGCheckInside(RG rg,PetscInt n,PetscScalar *ar,PetscScalar *ai,PetscInt *inside)
    446: {
    448:   PetscReal      px,py;
    449:   PetscInt       i;

    455: #if defined(PETSC_USE_COMPLEX)
    457: #endif

    460:   for (i=0;i<n;i++) {
    461: #if defined(PETSC_USE_COMPLEX)
    462:     px = PetscRealPart(ar[i]);
    463:     py = PetscImaginaryPart(ar[i]);
    464: #else
    465:     px = ar[i];
    466:     py = ai[i];
    467: #endif
    468:     if (rg->sfactor != 1.0) {
    469:       px *= rg->sfactor;
    470:       py *= rg->sfactor;
    471:     }
    472:     (*rg->ops->checkinside)(rg,px,py,inside+i);
    473:     if (rg->complement) inside[i] = -inside[i];
    474:   }
    475:   return(0);
    476: }

    480: /*@
    481:    RGComputeContour - Computes the coordinates of several points lying in the
    482:    contour of the region.

    484:    Not Collective

    486:    Input Parameters:
    487: +  rg - the region context
    488: -  n  - number of points to compute

    490:    Output Parameter:
    491: +  cr - location to store real parts
    492: -  ci - location to store imaginary parts

    494:    Level: intermediate
    495: @*/
    496: PetscErrorCode RGComputeContour(RG rg,PetscInt n,PetscScalar *cr,PetscScalar *ci)
    497: {

    504: #if !defined(PETSC_USE_COMPLEX)
    506: #endif
    507:   (*rg->ops->computecontour)(rg,n,cr,ci);
    508:   return(0);
    509: }

    513: /*@
    514:    RGSetComplement - Sets a flag to indicate that the region is the complement
    515:    of the specified one.

    517:    Logically Collective on RG

    519:    Input Parameters:
    520: +  rg  - the region context
    521: -  flg - the boolean flag

    523:    Options Database Key:
    524: .  -rg_complement <bool> - Activate/deactivate the complementation of the region.

    526:    Level: intermediate

    528: .seealso: RGGetComplement()
    529: @*/
    530: PetscErrorCode RGSetComplement(RG rg,PetscBool flg)
    531: {
    535:   rg->complement = flg;
    536:   return(0);
    537: }

    541: /*@
    542:    RGGetComplement - Gets a flag that that indicates whether the region
    543:    is complemented or not.

    545:    Not Collective

    547:    Input Parameter:
    548: .  rg - the region context

    550:    Output Parameter:
    551: .  flg - the flag

    553:    Level: intermediate

    555: .seealso: RGSetComplement()
    556: @*/
    557: PetscErrorCode RGGetComplement(RG rg,PetscBool *flg)
    558: {
    562:   *flg = rg->complement;
    563:   return(0);
    564: }

    568: /*@
    569:    RGSetScale - Sets the scaling factor to be used when checking that a
    570:    point is inside the region.

    572:    Logically Collective on RG

    574:    Input Parameters:
    575: +  rg      - the region context
    576: -  sfactor - the scaling factor

    578:    Level: developer

    580: .seealso: RGGetScale(), RGCheckInside()
    581: @*/
    582: PetscErrorCode RGSetScale(RG rg,PetscReal sfactor)
    583: {
    587:   if (sfactor == PETSC_DEFAULT || sfactor == PETSC_DECIDE) rg->sfactor = 1.0;
    588:   else {
    589:     if (sfactor<=0.0) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of scaling factor. Must be > 0");
    590:     rg->sfactor = sfactor;
    591:   }
    592:   return(0);
    593: }

    597: /*@
    598:    RGGetScale - Gets the scaling factor.

    600:    Not Collective

    602:    Input Parameter:
    603: .  rg - the region context

    605:    Output Parameter:
    606: .  flg - the flag

    608:    Level: developer

    610: .seealso: RGSetScale()
    611: @*/
    612: PetscErrorCode RGGetScale(RG rg,PetscReal *sfactor)
    613: {
    617:   *sfactor = rg->sfactor;
    618:   return(0);
    619: }

    623: /*@
    624:    RGDestroy - Destroys RG context that was created with RGCreate().

    626:    Collective on RG

    628:    Input Parameter:
    629: .  rg - the region context

    631:    Level: beginner

    633: .seealso: RGCreate()
    634: @*/
    635: PetscErrorCode RGDestroy(RG *rg)
    636: {

    640:   if (!*rg) return(0);
    642:   if (--((PetscObject)(*rg))->refct > 0) { *rg = 0; return(0); }
    643:   if ((*rg)->ops->destroy) { (*(*rg)->ops->destroy)(*rg); }
    644:   PetscHeaderDestroy(rg);
    645:   return(0);
    646: }

    650: /*@C
    651:    RGRegister - See Adds a mathematical function to the RG package.

    653:    Not collective

    655:    Input Parameters:
    656: +  name - name of a new user-defined RG
    657: -  function - routine to create context

    659:    Notes:
    660:    RGRegister() may be called multiple times to add several user-defined inner products.

    662:    Level: advanced

    664: .seealso: RGRegisterAll()
    665: @*/
    666: PetscErrorCode RGRegister(const char *name,PetscErrorCode (*function)(RG))
    667: {

    671:   PetscFunctionListAdd(&RGList,name,function);
    672:   return(0);
    673: }