Date: 2024-12-02T08:58:26+00:00

Actual source code: rgbasic.c
slepc-3.22.2 2024-12-02
Report Typos and Errors

      1: /*
      2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      4:    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain

      6:    This file is part of SLEPc.
      7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
      8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      9: */
     10: /*
     11:    Basic RG routines
     12: */

     14: #include <slepc/private/rgimpl.h>

     16: PetscFunctionList RGList = NULL;
     17: PetscBool         RGRegisterAllCalled = PETSC_FALSE;
     18: PetscClassId      RG_CLASSID = 0;
     19: static PetscBool  RGPackageInitialized = PETSC_FALSE;

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

     25:    Level: developer

     27: .seealso: SlepcFinalize()
     28: @*/
     29: PetscErrorCode RGFinalizePackage(void)
     30: {
     31:   PetscFunctionBegin;
     32:   PetscCall(PetscFunctionListDestroy(&RGList));
     33:   RGPackageInitialized = PETSC_FALSE;
     34:   RGRegisterAllCalled  = PETSC_FALSE;
     35:   PetscFunctionReturn(PETSC_SUCCESS);
     36: }

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

     43:   Level: developer

     45: .seealso: SlepcInitialize()
     46: @*/
     47: PetscErrorCode RGInitializePackage(void)
     48: {
     49:   char           logList[256];
     50:   PetscBool      opt,pkg;
     51:   PetscClassId   classids[1];

     53:   PetscFunctionBegin;
     54:   if (RGPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
     55:   RGPackageInitialized = PETSC_TRUE;
     56:   /* Register Classes */
     57:   PetscCall(PetscClassIdRegister("Region",&RG_CLASSID));
     58:   /* Register Constructors */
     59:   PetscCall(RGRegisterAll());
     60:   /* Process Info */
     61:   classids[0] = RG_CLASSID;
     62:   PetscCall(PetscInfoProcessClass("rg",1,&classids[0]));
     63:   /* Process summary exclusions */
     64:   PetscCall(PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt));
     65:   if (opt) {
     66:     PetscCall(PetscStrInList("rg",logList,',',&pkg));
     67:     if (pkg) PetscCall(PetscLogEventDeactivateClass(RG_CLASSID));
     68:   }
     69:   /* Register package finalizer */
     70:   PetscCall(PetscRegisterFinalize(RGFinalizePackage));
     71:   PetscFunctionReturn(PETSC_SUCCESS);
     72: }

     74: /*@
     75:    RGCreate - Creates an RG context.

     77:    Collective

     79:    Input Parameter:
     80: .  comm - MPI communicator

     82:    Output Parameter:
     83: .  newrg - location to put the RG context

     85:    Level: beginner

     87: .seealso: RGDestroy(), RG
     88: @*/
     89: PetscErrorCode RGCreate(MPI_Comm comm,RG *newrg)
     90: {
     91:   RG             rg;

     93:   PetscFunctionBegin;
     94:   PetscAssertPointer(newrg,2);
     95:   PetscCall(RGInitializePackage());
     96:   PetscCall(SlepcHeaderCreate(rg,RG_CLASSID,"RG","Region","RG",comm,RGDestroy,RGView));
     97:   rg->complement = PETSC_FALSE;
     98:   rg->sfactor    = 1.0;
     99:   rg->osfactor   = 0.0;
    100:   rg->data       = NULL;

    102:   *newrg = rg;
    103:   PetscFunctionReturn(PETSC_SUCCESS);
    104: }

    106: /*@
    107:    RGSetOptionsPrefix - Sets the prefix used for searching for all
    108:    RG options in the database.

    110:    Logically Collective

    112:    Input Parameters:
    113: +  rg     - the region context
    114: -  prefix - the prefix string to prepend to all RG option requests

    116:    Notes:
    117:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    118:    The first character of all runtime options is AUTOMATICALLY the
    119:    hyphen.

    121:    Level: advanced

    123: .seealso: RGAppendOptionsPrefix()
    124: @*/
    125: PetscErrorCode RGSetOptionsPrefix(RG rg,const char *prefix)
    126: {
    127:   PetscFunctionBegin;
    129:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)rg,prefix));
    130:   PetscFunctionReturn(PETSC_SUCCESS);
    131: }

    133: /*@
    134:    RGAppendOptionsPrefix - Appends to the prefix used for searching for all
    135:    RG options in the database.

    137:    Logically Collective

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

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

    147:    Level: advanced

    149: .seealso: RGSetOptionsPrefix()
    150: @*/
    151: PetscErrorCode RGAppendOptionsPrefix(RG rg,const char *prefix)
    152: {
    153:   PetscFunctionBegin;
    155:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)rg,prefix));
    156:   PetscFunctionReturn(PETSC_SUCCESS);
    157: }

    159: /*@
    160:    RGGetOptionsPrefix - Gets the prefix used for searching for all
    161:    RG options in the database.

    163:    Not Collective

    165:    Input Parameters:
    166: .  rg - the region context

    168:    Output Parameters:
    169: .  prefix - pointer to the prefix string used is returned

    171:    Note:
    172:    On the Fortran side, the user should pass in a string 'prefix' of
    173:    sufficient length to hold the prefix.

    175:    Level: advanced

    177: .seealso: RGSetOptionsPrefix(), RGAppendOptionsPrefix()
    178: @*/
    179: PetscErrorCode RGGetOptionsPrefix(RG rg,const char *prefix[])
    180: {
    181:   PetscFunctionBegin;
    183:   PetscAssertPointer(prefix,2);
    184:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)rg,prefix));
    185:   PetscFunctionReturn(PETSC_SUCCESS);
    186: }

    188: /*@
    189:    RGSetType - Selects the type for the RG object.

    191:    Logically Collective

    193:    Input Parameters:
    194: +  rg   - the region context
    195: -  type - a known type

    197:    Level: intermediate

    199: .seealso: RGGetType()
    200: @*/
    201: PetscErrorCode RGSetType(RG rg,RGType type)
    202: {
    203:   PetscErrorCode (*r)(RG);
    204:   PetscBool      match;

    206:   PetscFunctionBegin;
    208:   PetscAssertPointer(type,2);

    210:   PetscCall(PetscObjectTypeCompare((PetscObject)rg,type,&match));
    211:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

    213:   PetscCall(PetscFunctionListFind(RGList,type,&r));
    214:   PetscCheck(r,PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested RG type %s",type);

    216:   PetscTryTypeMethod(rg,destroy);
    217:   PetscCall(PetscMemzero(rg->ops,sizeof(struct _RGOps)));

    219:   PetscCall(PetscObjectChangeTypeName((PetscObject)rg,type));
    220:   PetscCall((*r)(rg));
    221:   PetscFunctionReturn(PETSC_SUCCESS);
    222: }

    224: /*@
    225:    RGGetType - Gets the RG type name (as a string) from the RG context.

    227:    Not Collective

    229:    Input Parameter:
    230: .  rg - the region context

    232:    Output Parameter:
    233: .  type - name of the region

    235:    Level: intermediate

    237: .seealso: RGSetType()
    238: @*/
    239: PetscErrorCode RGGetType(RG rg,RGType *type)
    240: {
    241:   PetscFunctionBegin;
    243:   PetscAssertPointer(type,2);
    244:   *type = ((PetscObject)rg)->type_name;
    245:   PetscFunctionReturn(PETSC_SUCCESS);
    246: }

    248: /*@
    249:    RGSetFromOptions - Sets RG options from the options database.

    251:    Collective

    253:    Input Parameters:
    254: .  rg - the region context

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

    259:    Level: beginner

    261: .seealso: RGSetOptionsPrefix()
    262: @*/
    263: PetscErrorCode RGSetFromOptions(RG rg)
    264: {
    265:   char           type[256];
    266:   PetscBool      flg;
    267:   PetscReal      sfactor;

    269:   PetscFunctionBegin;
    271:   PetscCall(RGRegisterAll());
    272:   PetscObjectOptionsBegin((PetscObject)rg);
    273:     PetscCall(PetscOptionsFList("-rg_type","Region type","RGSetType",RGList,(char*)(((PetscObject)rg)->type_name?((PetscObject)rg)->type_name:RGINTERVAL),type,sizeof(type),&flg));
    274:     if (flg) PetscCall(RGSetType(rg,type));
    275:     else if (!((PetscObject)rg)->type_name) PetscCall(RGSetType(rg,RGINTERVAL));

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

    279:     PetscCall(PetscOptionsReal("-rg_scale","Scaling factor","RGSetScale",1.0,&sfactor,&flg));
    280:     if (flg) PetscCall(RGSetScale(rg,sfactor));

    282:     PetscTryTypeMethod(rg,setfromoptions,PetscOptionsObject);
    283:     PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)rg,PetscOptionsObject));
    284:   PetscOptionsEnd();
    285:   PetscFunctionReturn(PETSC_SUCCESS);
    286: }

    288: /*@
    289:    RGView - Prints the RG data structure.

    291:    Collective

    293:    Input Parameters:
    294: +  rg - the region context
    295: -  viewer - optional visualization context

    297:    Note:
    298:    The available visualization contexts include
    299: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    300: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    301:          output where only the first processor opens
    302:          the file.  All other processors send their
    303:          data to the first processor to print.

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

    308:    Level: beginner

    310: .seealso: RGCreate()
    311: @*/
    312: PetscErrorCode RGView(RG rg,PetscViewer viewer)
    313: {
    314:   PetscBool      isdraw,isascii;

    316:   PetscFunctionBegin;
    318:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)rg),&viewer));
    320:   PetscCheckSameComm(rg,1,viewer,2);
    321:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
    322:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
    323:   if (isascii) {
    324:     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)rg,viewer));
    325:     PetscCall(PetscViewerASCIIPushTab(viewer));
    326:     PetscTryTypeMethod(rg,view,viewer);
    327:     PetscCall(PetscViewerASCIIPopTab(viewer));
    328:     if (rg->complement) PetscCall(PetscViewerASCIIPrintf(viewer,"  selected region is the complement of the specified one\n"));
    329:     if (rg->sfactor!=1.0) PetscCall(PetscViewerASCIIPrintf(viewer,"  scaling factor = %g\n",(double)rg->sfactor));
    330:   } else if (isdraw) PetscTryTypeMethod(rg,view,viewer);
    331:   PetscFunctionReturn(PETSC_SUCCESS);
    332: }

    334: /*@
    335:    RGViewFromOptions - View from options

    337:    Collective

    339:    Input Parameters:
    340: +  rg   - the region context
    341: .  obj  - optional object
    342: -  name - command line option

    344:    Level: intermediate

    346: .seealso: RGView(), RGCreate()
    347: @*/
    348: PetscErrorCode RGViewFromOptions(RG rg,PetscObject obj,const char name[])
    349: {
    350:   PetscFunctionBegin;
    352:   PetscCall(PetscObjectViewFromOptions((PetscObject)rg,obj,name));
    353:   PetscFunctionReturn(PETSC_SUCCESS);
    354: }

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

    359:    Not Collective

    361:    Input Parameter:
    362: .  rg - the region context

    364:    Output Parameter:
    365: .  trivial - true if the region is equal to the whole complex plane, e.g.,
    366:              an interval region with all four endpoints unbounded or an
    367:              ellipse with infinite radius.

    369:    Level: beginner

    371: .seealso: RGCheckInside()
    372: @*/
    373: PetscErrorCode RGIsTrivial(RG rg,PetscBool *trivial)
    374: {
    375:   PetscFunctionBegin;
    378:   PetscAssertPointer(trivial,2);
    379:   *trivial = PETSC_FALSE;
    380:   PetscTryTypeMethod(rg,istrivial,trivial);
    381:   PetscFunctionReturn(PETSC_SUCCESS);
    382: }

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

    387:    Not Collective

    389:    Input Parameters:
    390: +  rg - the region context
    391: .  n  - number of points to check
    392: .  ar - array of real parts
    393: -  ai - array of imaginary parts

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

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

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

    405:    Level: intermediate

    407: .seealso: RGSetScale(), RGSetComplement()
    408: @*/
    409: PetscErrorCode RGCheckInside(RG rg,PetscInt n,PetscScalar *ar,PetscScalar *ai,PetscInt *inside)
    410: {
    411:   PetscReal      px,py;
    412:   PetscInt       i;

    414:   PetscFunctionBegin;
    417:   PetscAssertPointer(ar,3);
    418: #if !defined(PETSC_USE_COMPLEX)
    419:   PetscAssertPointer(ai,4);
    420: #endif
    421:   PetscAssertPointer(inside,5);

    423:   for (i=0;i<n;i++) {
    424: #if defined(PETSC_USE_COMPLEX)
    425:     px = PetscRealPart(ar[i]);
    426:     py = PetscImaginaryPart(ar[i]);
    427: #else
    428:     px = ar[i];
    429:     py = ai[i];
    430: #endif
    431:     if (PetscUnlikely(rg->sfactor != 1.0)) {
    432:       px /= rg->sfactor;
    433:       py /= rg->sfactor;
    434:     }
    435:     PetscUseTypeMethod(rg,checkinside,px,py,inside+i);
    436:     if (PetscUnlikely(rg->complement)) inside[i] = -inside[i];
    437:   }
    438:   PetscFunctionReturn(PETSC_SUCCESS);
    439: }

    441: /*@
    442:    RGIsAxisymmetric - Determines if the region is symmetric with respect
    443:    to the real or imaginary axis.

    445:    Not Collective

    447:    Input Parameters:
    448: +  rg       - the region context
    449: -  vertical - true if symmetry must be checked against the vertical axis

    451:    Output Parameter:
    452: .  symm - true if the region is axisymmetric

    454:    Note:
    455:    If the vertical argument is true, symmetry is checked with respect to
    456:    the vertical axis, otherwise with respect to the horizontal axis.

    458:    Level: intermediate

    460: .seealso: RGCanUseConjugates()
    461: @*/
    462: PetscErrorCode RGIsAxisymmetric(RG rg,PetscBool vertical,PetscBool *symm)
    463: {
    464:   PetscFunctionBegin;
    467:   PetscAssertPointer(symm,3);
    468:   *symm = PETSC_FALSE;
    469:   PetscTryTypeMethod(rg,isaxisymmetric,vertical,symm);
    470:   PetscFunctionReturn(PETSC_SUCCESS);
    471: }

    473: /*@
    474:    RGCanUseConjugates - Used in contour integral methods to determine whether
    475:    half of integration points can be avoided (use their conjugates).

    477:    Not Collective

    479:    Input Parameters:
    480: +  rg       - the region context
    481: -  realmats - true if the problem matrices are real

    483:    Output Parameter:
    484: .  useconj  - whether it is possible to use conjugates

    486:    Notes:
    487:    If some integration points are the conjugates of other points, then the
    488:    associated computational cost can be saved. This depends on the problem
    489:    matrices being real and also the region being symmetric with respect to
    490:    the horizontal axis. The result is false if using real arithmetic or
    491:    in the case of a flat region (height equal to zero).

    493:    Level: developer

    495: .seealso: RGIsAxisymmetric()
    496: @*/
    497: PetscErrorCode RGCanUseConjugates(RG rg,PetscBool realmats,PetscBool *useconj)
    498: {
    499: #if defined(PETSC_USE_COMPLEX)
    500:   PetscReal      c,d;
    501:   PetscBool      isaxisymm;
    502: #endif

    504:   PetscFunctionBegin;
    507:   PetscAssertPointer(useconj,3);
    508:   *useconj = PETSC_FALSE;
    509: #if defined(PETSC_USE_COMPLEX)
    510:   if (realmats) {
    511:     PetscCall(RGIsAxisymmetric(rg,PETSC_FALSE,&isaxisymm));
    512:     if (isaxisymm) {
    513:       PetscCall(RGComputeBoundingBox(rg,NULL,NULL,&c,&d));
    514:       if (c!=d) *useconj = PETSC_TRUE;
    515:     }
    516:   }
    517: #endif
    518:   PetscFunctionReturn(PETSC_SUCCESS);
    519: }

    521: /*@
    522:    RGComputeContour - Computes the coordinates of several points lying on the
    523:    contour of the region.

    525:    Not Collective

    527:    Input Parameters:
    528: +  rg - the region context
    529: -  n  - number of points to compute

    531:    Output Parameters:
    532: +  cr - location to store real parts
    533: -  ci - location to store imaginary parts

    535:    Notes:
    536:    In real scalars, either cr or ci can be NULL (but not both). In complex
    537:    scalars, the coordinates are stored in cr, which cannot be NULL (ci is
    538:    not referenced).

    540:    Level: intermediate

    542: .seealso: RGComputeBoundingBox()
    543: @*/
    544: PetscErrorCode RGComputeContour(RG rg,PetscInt n,PetscScalar cr[],PetscScalar ci[])
    545: {
    546:   PetscInt       i;

    548:   PetscFunctionBegin;
    551: #if defined(PETSC_USE_COMPLEX)
    552:   PetscAssertPointer(cr,3);
    553: #else
    554:   PetscCheck(cr || ci,PetscObjectComm((PetscObject)rg),PETSC_ERR_SUP,"cr and ci cannot be NULL simultaneously");
    555: #endif
    556:   PetscCheck(!rg->complement,PetscObjectComm((PetscObject)rg),PETSC_ERR_SUP,"Cannot compute contour of region with complement flag set");
    557:   PetscUseTypeMethod(rg,computecontour,n,cr,ci);
    558:   for (i=0;i<n;i++) {
    559:     if (cr) cr[i] *= rg->sfactor;
    560:     if (ci) ci[i] *= rg->sfactor;
    561:   }
    562:   PetscFunctionReturn(PETSC_SUCCESS);
    563: }

    565: /*@
    566:    RGComputeBoundingBox - Determines the endpoints of a rectangle in the complex plane that
    567:    contains the region.

    569:    Not Collective

    571:    Input Parameter:
    572: .  rg - the region context

    574:    Output Parameters:
    575: +  a - left endpoint of the bounding box in the real axis
    576: .  b - right endpoint of the bounding box in the real axis
    577: .  c - bottom endpoint of the bounding box in the imaginary axis
    578: -  d - top endpoint of the bounding box in the imaginary axis

    580:    Notes:
    581:    The bounding box is defined as [a,b]x[c,d]. In regions that are not bounded (e.g. an
    582:    open interval) or with the complement flag set, it makes no sense to compute a bounding
    583:    box, so the return values are infinite.

    585:    Level: intermediate

    587: .seealso: RGComputeContour()
    588: @*/
    589: PetscErrorCode RGComputeBoundingBox(RG rg,PetscReal *a,PetscReal *b,PetscReal *c,PetscReal *d)
    590: {
    591:   PetscFunctionBegin;

    595:   if (rg->complement) {  /* cannot compute bounding box */
    596:     if (a) *a = -PETSC_MAX_REAL;
    597:     if (b) *b =  PETSC_MAX_REAL;
    598:     if (c) *c = -PETSC_MAX_REAL;
    599:     if (d) *d =  PETSC_MAX_REAL;
    600:   } else {
    601:     PetscUseTypeMethod(rg,computebbox,a,b,c,d);
    602:     if (a && *a!=-PETSC_MAX_REAL) *a *= rg->sfactor;
    603:     if (b && *b!= PETSC_MAX_REAL) *b *= rg->sfactor;
    604:     if (c && *c!=-PETSC_MAX_REAL) *c *= rg->sfactor;
    605:     if (d && *d!= PETSC_MAX_REAL) *d *= rg->sfactor;
    606:   }
    607:   PetscFunctionReturn(PETSC_SUCCESS);
    608: }

    610: /*@
    611:    RGComputeQuadrature - Computes the values of the parameters used in a
    612:    quadrature rule for a contour integral around the boundary of the region.

    614:    Not Collective

    616:    Input Parameters:
    617: +  rg   - the region context
    618: .  quad - the type of quadrature
    619: -  n    - number of quadrature points to compute

    621:    Output Parameters:
    622: +  z  - quadrature points
    623: .  zn - normalized quadrature points
    624: -  w  - quadrature weights

    626:    Notes:
    627:    In complex scalars, the values returned in z are often the same as those
    628:    computed by RGComputeContour(), but this is not the case in real scalars
    629:    where all output arguments are real.

    631:    The computed values change for different quadrature rules (trapezoidal
    632:    or Chebyshev).

    634:    Level: intermediate

    636: .seealso: RGComputeContour()
    637: @*/
    638: PetscErrorCode RGComputeQuadrature(RG rg,RGQuadRule quad,PetscInt n,PetscScalar z[],PetscScalar zn[],PetscScalar w[])
    639: {
    640:   PetscFunctionBegin;
    643:   PetscAssertPointer(z,4);
    644:   PetscAssertPointer(zn,5);
    645:   PetscAssertPointer(w,6);

    647:   PetscCall(RGComputeContour(rg,n,z,NULL));
    648:   PetscUseTypeMethod(rg,computequadrature,quad,n,z,zn,w);
    649:   PetscFunctionReturn(PETSC_SUCCESS);
    650: }

    652: /*@
    653:    RGSetComplement - Sets a flag to indicate that the region is the complement
    654:    of the specified one.

    656:    Logically Collective

    658:    Input Parameters:
    659: +  rg  - the region context
    660: -  flg - the boolean flag

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

    665:    Level: intermediate

    667: .seealso: RGGetComplement()
    668: @*/
    669: PetscErrorCode RGSetComplement(RG rg,PetscBool flg)
    670: {
    671:   PetscFunctionBegin;
    674:   rg->complement = flg;
    675:   PetscFunctionReturn(PETSC_SUCCESS);
    676: }

    678: /*@
    679:    RGGetComplement - Gets a flag that indicates whether the region
    680:    is complemented or not.

    682:    Not Collective

    684:    Input Parameter:
    685: .  rg - the region context

    687:    Output Parameter:
    688: .  flg - the flag

    690:    Level: intermediate

    692: .seealso: RGSetComplement()
    693: @*/
    694: PetscErrorCode RGGetComplement(RG rg,PetscBool *flg)
    695: {
    696:   PetscFunctionBegin;
    698:   PetscAssertPointer(flg,2);
    699:   *flg = rg->complement;
    700:   PetscFunctionReturn(PETSC_SUCCESS);
    701: }

    703: /*@
    704:    RGSetScale - Sets the scaling factor to be used when checking that a
    705:    point is inside the region and when computing the contour.

    707:    Logically Collective

    709:    Input Parameters:
    710: +  rg      - the region context
    711: -  sfactor - the scaling factor

    713:    Options Database Key:
    714: .  -rg_scale <real> - Sets the scaling factor

    716:    Level: advanced

    718: .seealso: RGGetScale(), RGCheckInside()
    719: @*/
    720: PetscErrorCode RGSetScale(RG rg,PetscReal sfactor)
    721: {
    722:   PetscFunctionBegin;
    725:   if (sfactor == (PetscReal)PETSC_DEFAULT || sfactor == (PetscReal)PETSC_DECIDE) sfactor = 1.0;
    726:   PetscCheck(sfactor>0.0,PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of scaling factor. Must be > 0");
    727:   rg->sfactor = sfactor;
    728:   PetscFunctionReturn(PETSC_SUCCESS);
    729: }

    731: /*@
    732:    RGGetScale - Gets the scaling factor.

    734:    Not Collective

    736:    Input Parameter:
    737: .  rg - the region context

    739:    Output Parameter:
    740: .  sfactor - the scaling factor

    742:    Level: advanced

    744: .seealso: RGSetScale()
    745: @*/
    746: PetscErrorCode RGGetScale(RG rg,PetscReal *sfactor)
    747: {
    748:   PetscFunctionBegin;
    750:   PetscAssertPointer(sfactor,2);
    751:   *sfactor = rg->sfactor;
    752:   PetscFunctionReturn(PETSC_SUCCESS);
    753: }

    755: /*@
    756:    RGPushScale - Sets an additional scaling factor, that will multiply the
    757:    user-defined scaling factor.

    759:    Logically Collective

    761:    Input Parameters:
    762: +  rg      - the region context
    763: -  sfactor - the scaling factor

    765:    Notes:
    766:    The current implementation does not allow pushing several scaling factors.

    768:    This is intended for internal use, for instance in polynomial eigensolvers
    769:    that use parameter scaling.

    771:    Level: developer

    773: .seealso: RGPopScale(), RGSetScale()
    774: @*/
    775: PetscErrorCode RGPushScale(RG rg,PetscReal sfactor)
    776: {
    777:   PetscFunctionBegin;
    780:   PetscCheck(sfactor>0.0,PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of scaling factor. Must be > 0");
    781:   PetscCheck(!rg->osfactor,PetscObjectComm((PetscObject)rg),PETSC_ERR_SUP,"Current implementation does not allow pushing several scaling factors");
    782:   rg->osfactor = rg->sfactor;
    783:   rg->sfactor *= sfactor;
    784:   PetscFunctionReturn(PETSC_SUCCESS);
    785: }

    787: /*@
    788:    RGPopScale - Pops the scaling factor set with RGPushScale().

    790:    Logically Collective

    792:    Input Parameter:
    793: .  rg - the region context

    795:    Level: developer

    797: .seealso: RGPushScale()
    798: @*/
    799: PetscErrorCode RGPopScale(RG rg)
    800: {
    801:   PetscFunctionBegin;
    803:   PetscCheck(rg->osfactor,PetscObjectComm((PetscObject)rg),PETSC_ERR_ORDER,"Must call RGPushScale first");
    804:   rg->sfactor  = rg->osfactor;
    805:   rg->osfactor = 0.0;
    806:   PetscFunctionReturn(PETSC_SUCCESS);
    807: }

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

    812:    Collective

    814:    Input Parameter:
    815: .  rg - the region context

    817:    Level: beginner

    819: .seealso: RGCreate()
    820: @*/
    821: PetscErrorCode RGDestroy(RG *rg)
    822: {
    823:   PetscFunctionBegin;
    824:   if (!*rg) PetscFunctionReturn(PETSC_SUCCESS);
    826:   if (--((PetscObject)*rg)->refct > 0) { *rg = NULL; PetscFunctionReturn(PETSC_SUCCESS); }
    827:   PetscTryTypeMethod(*rg,destroy);
    828:   PetscCall(PetscHeaderDestroy(rg));
    829:   PetscFunctionReturn(PETSC_SUCCESS);
    830: }

    832: /*@C
    833:    RGRegister - Adds a region to the RG package.

    835:    Not Collective

    837:    Input Parameters:
    838: +  name - name of a new user-defined RG
    839: -  function - routine to create context

    841:    Notes:
    842:    RGRegister() may be called multiple times to add several user-defined regions.

    844:    Level: advanced

    846: .seealso: RGRegisterAll()
    847: @*/
    848: PetscErrorCode RGRegister(const char *name,PetscErrorCode (*function)(RG))
    849: {
    850:   PetscFunctionBegin;
    851:   PetscCall(RGInitializePackage());
    852:   PetscCall(PetscFunctionListAdd(&RGList,name,function));
    853:   PetscFunctionReturn(PETSC_SUCCESS);
    854: }