Actual source code: options.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      1: /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
      2: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for atoll() */

      4: /*
      5:    These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
      6:    This provides the low-level interface, the high level interface is in aoptions.c

      8:    Some routines use regular malloc and free because it cannot know  what malloc is requested with the
      9:    options database until it has already processed the input.
     10: */

     12:  #include <petsc/private/petscimpl.h>
     13:  #include <petscviewer.h>
     14: #include <ctype.h>
     15: #if defined(PETSC_HAVE_MALLOC_H)
     16: #include <malloc.h>
     17: #endif
     18: #if defined(PETSC_HAVE_STRING_H)
     19: #include <string.h>             /* strcasecmp */
     20: #endif
     21: #if defined(PETSC_HAVE_STRINGS_H)
     22: #  include <strings.h>          /* strcasecmp */
     23: #endif
     24: #if defined(PETSC_HAVE_YAML)
     25: #include <yaml.h>
     26: #endif

     28: #if defined(PETSC_HAVE_STRCASECMP)
     29: #define PetscOptNameCmp(a,b) strcasecmp(a,b)
     30: #elif defined(PETSC_HAVE_STRICMP)
     31: #define PetscOptNameCmp(a,b) stricmp(a,b)
     32: #else
     33: #define PetscOptNameCmp(a,b) Error_strcasecmp_not_found
     34: #endif

     36:  #include <petsc/private/hashtable.h>

     38: /* This assumes ASCII encoding and ignores locale settings */
     39: /* Using tolower() is about 2X slower in microbenchmarks   */
     40: PETSC_STATIC_INLINE int PetscToLower(int c)
     41: {
     42:   return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
     43: }

     45: /* Bob Jenkins's one at a time hash function (case-insensitive) */
     46: PETSC_STATIC_INLINE unsigned int PetscOptHash(const char key[])
     47: {
     48:   unsigned int hash = 0;
     49:   while (*key) {
     50:     hash += PetscToLower(*key++);
     51:     hash += hash << 10;
     52:     hash ^= hash >>  6;
     53:   }
     54:   hash += hash <<  3;
     55:   hash ^= hash >> 11;
     56:   hash += hash << 15;
     57:   return hash;
     58: }

     60: PETSC_STATIC_INLINE int PetscOptEqual(const char a[],const char b[])
     61: {
     62:   return !PetscOptNameCmp(a,b);
     63: }

     65: KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)

     67: /*
     68:     This table holds all the options set by the user. For simplicity, we use a static size database
     69: */
     70: #define MAXOPTNAME 512
     71: #define MAXOPTIONS 512
     72: #define MAXALIASES  25
     73: #define MAXPREFIXES 25
     74: #define MAXOPTIONSMONITORS 5

     76: struct  _n_PetscOptions {
     77:   int        N;                    /* number of options */
     78:   char       *names[MAXOPTIONS];   /* option names */
     79:   char       *values[MAXOPTIONS];  /* option values */
     80:   PetscBool  used[MAXOPTIONS];     /* flag option use */

     82:   /* Hash table */
     83:   khash_t(HO) *ht;

     85:   /* Prefixes */
     86:   int   prefixind;
     87:   int   prefixstack[MAXPREFIXES];
     88:   char  prefix[MAXOPTNAME];

     90:   /* Aliases */
     91:   int  Naliases;                   /* number or aliases */
     92:   char *aliases1[MAXALIASES];      /* aliased */
     93:   char *aliases2[MAXALIASES];      /* aliasee */

     95:   /* Help */
     96:   PetscBool help; /* flag whether "-help" is in the database */

     98:   /* Monitors */
     99:   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[],const char[],void*); /* returns control to user after */
    100:   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void**);         /* */
    101:   void           *monitorcontext[MAXOPTIONSMONITORS];                  /* to pass arbitrary user data into monitor */
    102:   PetscInt       numbermonitors;                                       /* to, for instance, detect options being set */
    103: };

    105: static PetscOptions defaultoptions = NULL;

    108: /*
    109:     Options events monitor
    110: */
    111: static PetscErrorCode PetscOptionsMonitor(PetscOptions options,const char name[],const char value[])
    112: {
    113:   PetscInt       i;

    116:   if (!PetscInitializeCalled) return 0;
    118:   for (i=0; i<options->numbermonitors; i++) {
    119:     (*options->monitor[i])(name,value,options->monitorcontext[i]);
    120:   }
    121:   return(0);
    122: }

    124: /*@
    125:    PetscOptionsCreate - Creates an empty options database.

    127:    Output Parameter:
    128: .  options - Options database object

    130:    Level: advanced

    132: .seealso: PetscOptionsDestroy()
    133: @*/
    134: PetscErrorCode PetscOptionsCreate(PetscOptions *options)
    135: {
    136:   if (!options) return PETSC_ERR_ARG_NULL;
    137:   *options = (PetscOptions)calloc(1,sizeof(**options));
    138:   if (!*options) return PETSC_ERR_MEM;
    139:   return 0;
    140: }

    142: /*@
    143:     PetscOptionsDestroy - Destroys an option database.

    145:   Input Parameter:
    146: .  options - the PetscOptions object

    148:    Level: developer

    150: .seealso: PetscOptionsInsert()
    151: @*/
    152: PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
    153: {

    156:   if (!*options) return 0;
    157:   PetscOptionsClear(*options);if (ierr) return ierr;
    158:   /* XXX what about monitors ? */
    159:   free(*options);
    160:   *options = NULL;
    161:   return(0);
    162: }

    164: /*
    165:     PetscOptionsCreateDefault - Creates the default global options database
    166: */
    167: PetscErrorCode PetscOptionsCreateDefault(void)
    168: {

    171:   if (!defaultoptions) {
    172:     PetscOptionsCreate(&defaultoptions);if (ierr) return ierr;
    173:   }
    174:   return 0;
    175: }

    177: /*
    178:     PetscOptionsDestroyDefault - Destroys the default global options database
    179: */
    180: PetscErrorCode PetscOptionsDestroyDefault(void)
    181: {

    184:   PetscOptionsDestroy(&defaultoptions);if (ierr) return ierr;
    185:   return 0;
    186: }

    188: /*@C
    189:    PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.

    191:    Input Parameter:
    192: .  key - string to check if valid

    194:    Output Parameter:
    195: .  valid - PETSC_TRUE if a valid key

    197:    Level: intermediate
    198: @*/
    199: PetscErrorCode PetscOptionsValidKey(const char key[],PetscBool *valid)
    200: {
    201:   char           *ptr;

    206:   *valid = PETSC_FALSE;
    207:   if (!key) return(0);
    208:   if (key[0] != '-') return(0);
    209:   if (key[1] == '-') key++;
    210:   if (!isalpha((int)(key[1]))) return(0);
    211:   (void) strtod(key,&ptr);
    212:   if (ptr != key && !(*ptr == '_' || isalnum(*ptr))) return(0);
    213:   *valid = PETSC_TRUE;
    214:   return(0);
    215: }

    217: /*@C
    218:    PetscOptionsInsertString - Inserts options into the database from a string

    220:    Not Collective, but only processes that call this routine will set the options
    221:    included in the string

    223:    Input Parameter:
    224: .  in_str - string that contains options separated by blanks

    227:    Level: intermediate

    229:    Contributed by Boyana Norris

    231: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
    232:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    233:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    234:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    235:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    236:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile()
    237: @*/
    238: PetscErrorCode PetscOptionsInsertString(PetscOptions options,const char in_str[])
    239: {
    240:   char           *first,*second;
    242:   PetscToken     token;
    243:   PetscBool      key,ispush,ispop;

    246:   PetscTokenCreate(in_str,' ',&token);
    247:   PetscTokenFind(token,&first);
    248:   while (first) {
    249:     PetscStrcasecmp(first,"-prefix_push",&ispush);
    250:     PetscStrcasecmp(first,"-prefix_pop",&ispop);
    251:     PetscOptionsValidKey(first,&key);
    252:     if (ispush) {
    253:       PetscTokenFind(token,&second);
    254:       PetscOptionsPrefixPush(options,second);
    255:       PetscTokenFind(token,&first);
    256:     } else if (ispop) {
    257:       PetscOptionsPrefixPop(options);
    258:       PetscTokenFind(token,&first);
    259:     } else if (key) {
    260:       PetscTokenFind(token,&second);
    261:       PetscOptionsValidKey(second,&key);
    262:       if (!key) {
    263:         PetscOptionsSetValue(options,first,second);
    264:         PetscTokenFind(token,&first);
    265:       } else {
    266:         PetscOptionsSetValue(options,first,NULL);
    267:         first = second;
    268:       }
    269:     } else {
    270:       PetscTokenFind(token,&first);
    271:     }
    272:   }
    273:   PetscTokenDestroy(&token);
    274:   return(0);
    275: }

    277: /*
    278:     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
    279: */
    280: static char *Petscgetline(FILE * f)
    281: {
    282:   size_t size  = 0;
    283:   size_t len   = 0;
    284:   size_t last  = 0;
    285:   char   *buf  = NULL;

    287:   if (feof(f)) return 0;
    288:   do {
    289:     size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
    290:     buf   = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
    291:     /* Actually do the read. Note that fgets puts a terminal '\0' on the
    292:     end of the string, so we make sure we overwrite this */
    293:     if (!fgets(buf+len,1024,f)) buf[len]=0;
    294:     PetscStrlen(buf,&len);
    295:     last = len - 1;
    296:   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
    297:   if (len) return buf;
    298:   free(buf);
    299:   return 0;
    300: }

    302: /*@C
    303:      PetscOptionsInsertFile - Inserts options into the database from a file.

    305:      Collective on MPI_Comm

    307:   Input Parameter:
    308: +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
    309: .   options - options database, use NULL for default global database
    310: .   file - name of file
    311: -   require - if PETSC_TRUE will generate an error if the file does not exist

    314:   Notes:
    315:     Use  # for lines that are comments and which should be ignored.

    317:    Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
    318:    such as -log_view or -malloc_debug are processed properly. This routine only sets options into the options database that will be processed by later
    319:    calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().

    321:   Level: developer

    323: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
    324:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    325:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    326:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    327:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    328:           PetscOptionsFList(), PetscOptionsEList()

    330: @*/
    331: PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
    332: {
    333:   char           *string,fname[PETSC_MAX_PATH_LEN],*first,*second,*third,*vstring = 0,*astring = 0,*packed = 0;
    335:   size_t         i,len,bytes;
    336:   FILE           *fd;
    337:   PetscToken     token;
    338:   int            err;
    339:   char           cmt[1]={'#'},*cmatch;
    340:   PetscMPIInt    rank,cnt=0,acnt=0,counts[2];
    341:   PetscBool      isdir;

    344:   MPI_Comm_rank(comm,&rank);
    345:   if (!rank) {
    346:     cnt        = 0;
    347:     acnt       = 0;

    349:     PetscFixFilename(file,fname);
    350:     fd   = fopen(fname,"r");
    351:     PetscTestDirectory(fname,'r',&isdir);
    352:     if (isdir && require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Specified options file %s is a directory",fname);
    353:     if (fd && !isdir) {
    354:       PetscSegBuffer vseg,aseg;
    355:       PetscSegBufferCreate(1,4000,&vseg);
    356:       PetscSegBufferCreate(1,2000,&aseg);

    358:       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
    359:       PetscInfo1(0,"Opened options file %s\n",file);

    361:       while ((string = Petscgetline(fd))) {
    362:         /* eliminate comments from each line */
    363:         for (i=0; i<1; i++) {
    364:           PetscStrchr(string,cmt[i],&cmatch);
    365:           if (cmatch) *cmatch = 0;
    366:         }
    367:         PetscStrlen(string,&len);
    368:         /* replace tabs, ^M, \n with " " */
    369:         for (i=0; i<len; i++) {
    370:           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
    371:             string[i] = ' ';
    372:           }
    373:         }
    374:         PetscTokenCreate(string,' ',&token);
    375:         PetscTokenFind(token,&first);
    376:         if (!first) {
    377:           goto destroy;
    378:         } else if (!first[0]) { /* if first token is empty spaces, redo first token */
    379:           PetscTokenFind(token,&first);
    380:         }
    381:         PetscTokenFind(token,&second);
    382:         if (!first) {
    383:           goto destroy;
    384:         } else if (first[0] == '-') {
    385:           PetscStrlen(first,&len);
    386:           PetscSegBufferGet(vseg,len+1,&vstring);
    387:           PetscMemcpy(vstring,first,len);
    388:           vstring[len] = ' ';
    389:           if (second) {
    390:             PetscStrlen(second,&len);
    391:             PetscSegBufferGet(vseg,len+3,&vstring);
    392:             vstring[0] = '"';
    393:             PetscMemcpy(vstring+1,second,len);
    394:             vstring[len+1] = '"';
    395:             vstring[len+2] = ' ';
    396:           }
    397:         } else {
    398:           PetscBool match;

    400:           PetscStrcasecmp(first,"alias",&match);
    401:           if (match) {
    402:             PetscTokenFind(token,&third);
    403:             if (!third) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file:alias missing (%s)",second);
    404:             PetscStrlen(second,&len);
    405:             PetscSegBufferGet(aseg,len+1,&astring);
    406:             PetscMemcpy(astring,second,len);
    407:             astring[len] = ' ';

    409:             PetscStrlen(third,&len);
    410:             PetscSegBufferGet(aseg,len+1,&astring);
    411:             PetscMemcpy(astring,third,len);
    412:             astring[len] = ' ';
    413:           } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown statement in options file: (%s)",string);
    414:         }
    415: destroy:
    416:         free(string);
    417:         PetscTokenDestroy(&token);
    418:       }
    419:       err = fclose(fd);
    420:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
    421:       PetscSegBufferGetSize(aseg,&bytes); /* size without null termination */
    422:       PetscMPIIntCast(bytes,&acnt);
    423:       PetscSegBufferGet(aseg,1,&astring);
    424:       astring[0] = 0;
    425:       PetscSegBufferGetSize(vseg,&bytes); /* size without null termination */
    426:       PetscMPIIntCast(bytes,&cnt);
    427:       PetscSegBufferGet(vseg,1,&vstring);
    428:       vstring[0] = 0;
    429:       PetscMalloc1(2+acnt+cnt,&packed);
    430:       PetscSegBufferExtractTo(aseg,packed);
    431:       PetscSegBufferExtractTo(vseg,packed+acnt+1);
    432:       PetscSegBufferDestroy(&aseg);
    433:       PetscSegBufferDestroy(&vseg);
    434:     } else if (require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open Options File %s",fname);
    435:   }

    437:   counts[0] = acnt;
    438:   counts[1] = cnt;
    439:   MPI_Bcast(counts,2,MPI_INT,0,comm);
    440:   acnt = counts[0];
    441:   cnt = counts[1];
    442:   if (rank) {
    443:     PetscMalloc1(2+acnt+cnt,&packed);
    444:   }
    445:   if (acnt || cnt) {
    446:     MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm);
    447:     astring = packed;
    448:     vstring = packed + acnt + 1;
    449:   }

    451:   if (acnt) {
    452:     PetscToken token;
    453:     char       *first,*second;

    455:     PetscTokenCreate(astring,' ',&token);
    456:     PetscTokenFind(token,&first);
    457:     while (first) {
    458:       PetscTokenFind(token,&second);
    459:       PetscOptionsSetAlias(options,first,second);
    460:       PetscTokenFind(token,&first);
    461:     }
    462:     PetscTokenDestroy(&token);
    463:   }

    465:   if (cnt) {
    466:     PetscOptionsInsertString(options,vstring);
    467:   }
    468:   PetscFree(packed);
    469:   return(0);
    470: }

    472: static PetscErrorCode PetscOptionsInsertArgs(PetscOptions options,int argc,char *args[])
    473: {
    475:   int            left    = argc - 1;
    476:   char           **eargs = args + 1;

    479:   while (left) {
    480:     PetscBool isoptions_file,isprefixpush,isprefixpop,isp4,tisp4,isp4yourname,isp4rmrank,key;
    481:     PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);
    482:     PetscStrcasecmp(eargs[0],"-prefix_push",&isprefixpush);
    483:     PetscStrcasecmp(eargs[0],"-prefix_pop",&isprefixpop);
    484:     PetscStrcasecmp(eargs[0],"-p4pg",&isp4);
    485:     PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);
    486:     PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);
    487:     PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);
    488:     isp4 = (PetscBool) (isp4 || tisp4);
    489:     PetscStrcasecmp(eargs[0],"-np",&tisp4);
    490:     isp4 = (PetscBool) (isp4 || tisp4);
    491:     PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);
    492:     PetscOptionsValidKey(eargs[0],&key);

    494:     if (!key) {
    495:       eargs++; left--;
    496:     } else if (isoptions_file) {
    497:       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
    498:       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
    499:       PetscOptionsInsertFile(PETSC_COMM_WORLD,options,eargs[1],PETSC_TRUE);
    500:       eargs += 2; left -= 2;
    501:     } else if (isprefixpush) {
    502:       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
    503:       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
    504:       PetscOptionsPrefixPush(options,eargs[1]);
    505:       eargs += 2; left -= 2;
    506:     } else if (isprefixpop) {
    507:       PetscOptionsPrefixPop(options);
    508:       eargs++; left--;

    510:       /*
    511:        These are "bad" options that MPICH, etc put on the command line
    512:        we strip them out here.
    513:        */
    514:     } else if (tisp4 || isp4rmrank) {
    515:       eargs += 1; left -= 1;
    516:     } else if (isp4 || isp4yourname) {
    517:       eargs += 2; left -= 2;
    518:     } else {
    519:       PetscBool nextiskey = PETSC_FALSE;
    520:       if (left >= 2) {PetscOptionsValidKey(eargs[1],&nextiskey);}
    521:       if (left < 2 || nextiskey) {
    522:         PetscOptionsSetValue(options,eargs[0],NULL);
    523:         eargs++; left--;
    524:       } else {
    525:         PetscOptionsSetValue(options,eargs[0],eargs[1]);
    526:         eargs += 2; left -= 2;
    527:       }
    528:     }
    529:   }
    530:   return(0);
    531: }

    534: /*@C
    535:    PetscOptionsInsert - Inserts into the options database from the command line,
    536:                    the environmental variable and a file.

    538:    Input Parameters:
    539: +  options - options database or NULL for the default global database
    540: .  argc - count of number of command line arguments
    541: .  args - the command line arguments
    542: -  file - optional filename, defaults to ~username/.petscrc

    544:    Note:
    545:    Since PetscOptionsInsert() is automatically called by PetscInitialize(),
    546:    the user does not typically need to call this routine. PetscOptionsInsert()
    547:    can be called several times, adding additional entries into the database.

    549:    Options Database Keys:
    550: +   -options_monitor <optional filename> - print options names and values as they are set
    551: .   -options_file <filename> - read options from a file

    553:    Level: advanced

    555:    Concepts: options database^adding

    557: .seealso: PetscOptionsDestroy(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
    558:           PetscInitialize()
    559: @*/
    560: PetscErrorCode PetscOptionsInsert(PetscOptions options,int *argc,char ***args,const char file[])
    561: {
    563:   PetscMPIInt    rank;
    564:   char           filename[PETSC_MAX_PATH_LEN];
    565:   PetscBool      flag = PETSC_FALSE;

    569:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

    571:   if (file && file[0]) {
    572:     PetscStrreplace(PETSC_COMM_WORLD,file,filename,PETSC_MAX_PATH_LEN);
    573:     PetscOptionsInsertFile(PETSC_COMM_WORLD,options,filename,PETSC_TRUE);
    574:   }
    575:   /*
    576:      We want to be able to give -skip_petscrc on the command line, but need to parse it first.  Since the command line
    577:      should take precedence, we insert it twice.  It would be sufficient to just scan for -skip_petscrc.
    578:   */
    579:   if (argc && args && *argc) {PetscOptionsInsertArgs(options,*argc,*args);}
    580:   PetscOptionsGetBool(NULL,NULL,"-skip_petscrc",&flag,NULL);
    581:   if (!flag) {
    582:     PetscGetHomeDirectory(filename,PETSC_MAX_PATH_LEN-16);
    583:     /* PetscOptionsInsertFile() does a fopen() on rank0 only - so only rank0 HomeDir value is relavent */
    584:     if (filename[0]) { PetscStrcat(filename,"/.petscrc"); }
    585:     PetscOptionsInsertFile(PETSC_COMM_WORLD,options,filename,PETSC_FALSE);
    586:     PetscOptionsInsertFile(PETSC_COMM_WORLD,options,".petscrc",PETSC_FALSE);
    587:     PetscOptionsInsertFile(PETSC_COMM_WORLD,options,"petscrc",PETSC_FALSE);
    588:   }

    590:   /* insert environment options */
    591:   {
    592:     char   *eoptions = NULL;
    593:     size_t len       = 0;
    594:     if (!rank) {
    595:       eoptions = (char*)getenv("PETSC_OPTIONS");
    596:       PetscStrlen(eoptions,&len);
    597:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
    598:     } else {
    599:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
    600:       if (len) {
    601:         PetscMalloc1(len+1,&eoptions);
    602:       }
    603:     }
    604:     if (len) {
    605:       MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
    606:       if (rank) eoptions[len] = 0;
    607:       PetscOptionsInsertString(options,eoptions);
    608:       if (rank) {PetscFree(eoptions);}
    609:     }
    610:   }

    612: #if defined(PETSC_HAVE_YAML)
    613:   {
    614:     char      yaml_file[PETSC_MAX_PATH_LEN];
    615:     PetscBool yaml_flg;
    616:     PetscOptionsGetString(NULL,NULL,"-options_file_yaml",yaml_file,PETSC_MAX_PATH_LEN,&yaml_flg);
    617:     if (yaml_flg) {
    618:       PetscOptionsInsertFileYAML(PETSC_COMM_WORLD,yaml_file,PETSC_TRUE);
    619:     }
    620:   }
    621: #endif

    623:   /* insert command line options again because they take precedence over arguments in petscrc/environment */
    624:   if (argc && args && *argc) {PetscOptionsInsertArgs(options,*argc,*args);}
    625:   return(0);
    626: }

    628: /*@C
    629:    PetscOptionsView - Prints the options that have been loaded. This is
    630:    useful for debugging purposes.

    632:    Logically Collective on PetscViewer

    634:    Input Parameter:
    635: -  options - options database, use NULL for default global database
    636: +  viewer - must be an PETSCVIEWERASCII viewer

    638:    Options Database Key:
    639: .  -options_view - Activates PetscOptionsView() within PetscFinalize()

    641:    Level: advanced

    643:    Concepts: options database^printing

    645: .seealso: PetscOptionsAllUsed()
    646: @*/
    647: PetscErrorCode PetscOptionsView(PetscOptions options,PetscViewer viewer)
    648: {
    650:   PetscInt       i;
    651:   PetscBool      isascii;

    655:   options = options ? options : defaultoptions;
    656:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
    657:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    658:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");

    660:   if (!options->N) {
    661:     PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");
    662:     return(0);
    663:   }

    665:   PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");
    666:   for (i=0; i<options->N; i++) {
    667:     if (options->values[i]) {
    668:       PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);
    669:     } else {
    670:       PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);
    671:     }
    672:   }
    673:   PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");
    674:   return(0);
    675: }

    677: /*
    678:    Called by error handlers to print options used in run
    679: */
    680: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
    681: {
    682:   PetscInt     i;
    683:   PetscOptions options = defaultoptions;

    686:   if (options->N) {
    687:     (*PetscErrorPrintf)("PETSc Option Table entries:\n");
    688:   } else {
    689:     (*PetscErrorPrintf)("No PETSc Option Table entries\n");
    690:   }
    691:   for (i=0; i<options->N; i++) {
    692:     if (options->values[i]) {
    693:       (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]);
    694:     } else {
    695:       (*PetscErrorPrintf)("-%s\n",options->names[i]);
    696:     }
    697:   }
    698:   return(0);
    699: }

    701: /*@C
    702:    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.

    704:    Not Collective, but prefix will only be applied on calling ranks

    706:    Input Parameter:
    707: +  options - options database, or NULL for the default global database
    708: -  prefix - The string to append to the existing prefix

    710:    Options Database Keys:
    711:  +   -prefix_push <some_prefix_> - push the given prefix
    712:  -   -prefix_pop - pop the last prefix

    714:    Notes:
    715:    It is common to use this in conjunction with -options_file as in

    717:  $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop

    719:    where the files no longer require all options to be prefixed with -system2_.

    721: Level: advanced

    723: .seealso: PetscOptionsPrefixPop()
    724: @*/
    725: PetscErrorCode PetscOptionsPrefixPush(PetscOptions options,const char prefix[])
    726: {
    728:   size_t         n;
    729:   PetscInt       start;
    730:   char           key[MAXOPTNAME+1];
    731:   PetscBool      valid;

    735:   options = options ? options : defaultoptions;
    736:   if (options->prefixind >= MAXPREFIXES) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum depth of prefix stack %d exceeded, recompile \n src/sys/objects/options.c with larger value for MAXPREFIXES",MAXPREFIXES);
    737:   key[0] = '-'; /* keys must start with '-' */
    738:   PetscStrncpy(key+1,prefix,sizeof(key)-1);
    739:   PetscOptionsValidKey(key,&valid);
    740:   if (!valid) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Given prefix \"%s\" not valid (the first character must be a letter, do not include leading '-')",prefix);
    741:   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
    742:   PetscStrlen(prefix,&n);
    743:   if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
    744:   PetscMemcpy(options->prefix+start,prefix,n+1);
    745:   options->prefixstack[options->prefixind++] = start+n;
    746:   return(0);
    747: }

    749: /*@C
    750:    PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details

    752:    Not  Collective, but prefix will only be popped on calling ranks

    754:   Input Parameters:
    755: .  options - options database, or NULL for the default global database

    757:    Level: advanced

    759: .seealso: PetscOptionsPrefixPush()
    760: @*/
    761: PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
    762: {
    763:   PetscInt offset;

    766:   options = options ? options : defaultoptions;
    767:   if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
    768:   options->prefixind--;
    769:   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
    770:   options->prefix[offset] = 0;
    771:   return(0);
    772: }

    774: /*@C
    775:     PetscOptionsClear - Removes all options form the database leaving it empty.

    777:   Input Parameters:
    778: .  options - options database, use NULL for the default global database

    780:    Level: developer

    782: .seealso: PetscOptionsInsert()
    783: @*/
    784: PetscErrorCode PetscOptionsClear(PetscOptions options)
    785: {
    786:   PetscInt i;

    788:   options = options ? options : defaultoptions;
    789:   if (!options) return 0;

    791:   for (i=0; i<options->N; i++) {
    792:     if (options->names[i])  free(options->names[i]);
    793:     if (options->values[i]) free(options->values[i]);
    794:   }
    795:   options->N = 0;

    797:   for (i=0; i<options->Naliases; i++) {
    798:     free(options->aliases1[i]);
    799:     free(options->aliases2[i]);
    800:   }
    801:   options->Naliases = 0;

    803:   /* destroy hash table */
    804:   kh_destroy(HO,options->ht);
    805:   options->ht = NULL;

    807:   options->prefixind = 0;
    808:   options->prefix[0] = 0;
    809:   options->help      = PETSC_FALSE;
    810:   return 0;
    811: }

    813: /*@C
    814:    PetscOptionsSetAlias - Makes a key and alias for another key

    816:    Not Collective, but setting values on certain processors could cause problems
    817:    for parallel objects looking for options.

    819:    Input Parameters:
    820: +  options - options database, or NULL for default global database
    821: .  newname - the alias
    822: -  oldname - the name that alias will refer to

    824:    Level: advanced

    826: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
    827:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
    828:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    829:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    830:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    831:           PetscOptionsFList(), PetscOptionsEList()
    832: @*/
    833: PetscErrorCode PetscOptionsSetAlias(PetscOptions options,const char newname[],const char oldname[])
    834: {
    835:   PetscInt       n;
    836:   size_t         len;

    842:   options = options ? options : defaultoptions;
    843:   if (newname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliased must start with '-': Instead %s",newname);
    844:   if (oldname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliasee must start with '-': Instead %s",oldname);

    846:   n = options->Naliases;
    847:   if (n >= MAXALIASES) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MEM,"You have defined to many PETSc options aliases, limit %d recompile \n  src/sys/objects/options.c with larger value for MAXALIASES",MAXALIASES);

    849:   newname++; oldname++;
    850:   PetscStrlen(newname,&len);
    851:   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
    852:   PetscStrcpy(options->aliases1[n],newname);
    853:   PetscStrlen(oldname,&len);
    854:   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
    855:   PetscStrcpy(options->aliases2[n],oldname);
    856:   options->Naliases++;
    857:   return(0);
    858: }

    860: /*@C
    861:    PetscOptionsSetValue - Sets an option name-value pair in the options
    862:    database, overriding whatever is already present.

    864:    Not Collective, but setting values on certain processors could cause problems
    865:    for parallel objects looking for options.

    867:    Input Parameters:
    868: +  options - options database, use NULL for the default global database
    869: .  name - name of option, this SHOULD have the - prepended
    870: -  value - the option value (not used for all options, so can be NULL)

    872:    Level: intermediate

    874:    Note:
    875:    This function can be called BEFORE PetscInitialize()

    877:    Developers Note: Uses malloc() directly because PETSc may not be initialized yet.

    879:    Concepts: options database^adding option

    881: .seealso: PetscOptionsInsert(), PetscOptionsClearValue()
    882: @*/
    883: PetscErrorCode PetscOptionsSetValue(PetscOptions options,const char name[],const char value[])
    884: {
    885:   size_t         len;
    886:   int            N,n,i;
    887:   char           **names;
    888:   char           fullname[MAXOPTNAME] = "";

    891:   if (!options && !defaultoptions) {
    892:     PetscOptionsCreateDefault();if (ierr) return ierr;
    893:   }
    894:   options = options ? options : defaultoptions;

    896:   if (name[0] != '-') return PETSC_ERR_ARG_OUTOFRANGE;

    898:   /* this is so that -h and -help are equivalent (p4 does not like -help)*/
    899:   if (!strcmp(name,"-h")) name = "-help";
    900:   if (!PetscOptNameCmp(name,"-help")) options->help = PETSC_TRUE;

    902:   name++; /* skip starting dash */

    904:   if (options->prefixind > 0) {
    905:     strncpy(fullname,options->prefix,sizeof(fullname));
    906:     fullname[sizeof(fullname)-1] = 0;
    907:     strncat(fullname,name,sizeof(fullname)-strlen(fullname)-1);
    908:     fullname[sizeof(fullname)-1] = 0;
    909:     name = fullname;
    910:   }

    912:   /* check against aliases */
    913:   N = options->Naliases;
    914:   for (i=0; i<N; i++) {
    915:     int result = PetscOptNameCmp(options->aliases1[i],name);
    916:     if (!result) { name = options->aliases2[i]; break; }
    917:   }

    919:   /* slow search */
    920:   N = n = options->N;
    921:   names = options->names;
    922:   for (i=0; i<N; i++) {
    923:     int result = PetscOptNameCmp(names[i],name);
    924:     if (!result) {
    925:       n = i; goto setvalue;
    926:     } else if (result > 0) {
    927:       n = i; break;
    928:     }
    929:   }
    930:   if (N >= MAXOPTIONS) return PETSC_ERR_MEM;
    931:   /* shift remaining values up 1 */
    932:   for (i=N; i>n; i--) {
    933:     options->names[i]  = options->names[i-1];
    934:     options->values[i] = options->values[i-1];
    935:     options->used[i]   = options->used[i-1];
    936:   }
    937:   options->names[n]  = NULL;
    938:   options->values[n] = NULL;
    939:   options->used[n]   = PETSC_FALSE;
    940:   options->N++;

    942:   /* destroy hash table */
    943:   kh_destroy(HO,options->ht);
    944:   options->ht = NULL;

    946:   /* set new name */
    947:   len = strlen(name);
    948:   options->names[n] = (char*)malloc((len+1)*sizeof(char));
    949:   if (!options->names[n]) return PETSC_ERR_MEM;
    950:   strcpy(options->names[n],name);

    952: setvalue:
    953:   /* set new value */
    954:   if (options->values[n]) free(options->values[n]);
    955:   len = value ? strlen(value) : 0;
    956:   if (len) {
    957:     options->values[n] = (char*)malloc((len+1)*sizeof(char));
    958:     if (!options->values[n]) return PETSC_ERR_MEM;
    959:     strcpy(options->values[n],value);
    960:   } else {
    961:     options->values[n] = NULL;
    962:   }

    964:   PetscOptionsMonitor(options,name,value?value:"");if (ierr) return ierr;
    965:   return 0;
    966: }

    968: /*@C
    969:    PetscOptionsClearValue - Clears an option name-value pair in the options
    970:    database, overriding whatever is already present.

    972:    Not Collective, but setting values on certain processors could cause problems
    973:    for parallel objects looking for options.

    975:    Input Parameter:
    976: +  options - options database, use NULL for the default global database
    977: .  name - name of option, this SHOULD have the - prepended

    979:    Level: intermediate

    981:    Concepts: options database^removing option
    982: .seealso: PetscOptionsInsert()
    983: @*/
    984: PetscErrorCode PetscOptionsClearValue(PetscOptions options,const char name[])
    985: {
    986:   int            N,n,i;
    987:   char           **names;

    991:   options = options ? options : defaultoptions;
    992:   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);

    994:   /* this is so that -h and -help are equivalent (p4 does not like -help)*/
    995:   if (!strcmp(name,"-h")) name = "-help";
    996:   if (!PetscOptNameCmp(name,"-help")) options->help = PETSC_FALSE;

    998:   name++; /* skip starting dash */

    1000:   /* slow search */
    1001:   N = n = options->N;
    1002:   names = options->names;
    1003:   for (i=0; i<N; i++) {
    1004:     int result = PetscOptNameCmp(names[i],name);
    1005:     if (!result) {
    1006:       n = i; break;
    1007:     } else if (result > 0) {
    1008:       n = N; break;
    1009:     }
    1010:   }
    1011:   if (n == N) return(0); /* it was not present */

    1013:   /* remove name and value */
    1014:   if (options->names[n])  free(options->names[n]);
    1015:   if (options->values[n]) free(options->values[n]);
    1016:   /* shift remaining values down 1 */
    1017:   for (i=n; i<N-1; i++) {
    1018:     options->names[i]  = options->names[i+1];
    1019:     options->values[i] = options->values[i+1];
    1020:     options->used[i]   = options->used[i+1];
    1021:   }
    1022:   options->N--;

    1024:   /* destroy hash table */
    1025:   kh_destroy(HO,options->ht);
    1026:   options->ht = NULL;

    1028:   PetscOptionsMonitor(options,name,NULL);
    1029:   return(0);
    1030: }

    1032: /*@C
    1033:    PetscOptionsFindPair - Gets an option name-value pair from the options database.

    1035:    Not Collective

    1037:    Input Parameters:
    1038: +  options - options database, use NULL for the default global database
    1039: .  pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
    1040: -  name - name of option, this SHOULD have the "-" prepended

    1042:    Output Parameters:
    1043: +  value - the option value (optional, not used for all options)
    1044: -  set - whether the option is set (optional)

    1046:    Level: developer

    1048:   Concepts: options database^getting option

    1050: .seealso: PetscOptionsSetValue(), PetscOptionsClearValue()
    1051: @*/
    1052: PetscErrorCode PetscOptionsFindPair(PetscOptions options,const char pre[],const char name[],const char *value[],PetscBool *set)
    1053: {
    1054:   char           buf[MAXOPTNAME];
    1055:   PetscBool      usehashtable = PETSC_TRUE;
    1056:   PetscBool      matchnumbers = PETSC_TRUE;

    1060:   options = options ? options : defaultoptions;
    1061:   if (pre && PetscUnlikely(pre[0] == '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
    1062:   if (PetscUnlikely(name[0] != '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);

    1064:   name++; /* skip starting dash */

    1066:   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
    1067:   if (pre && pre[0]) {
    1068:     char *ptr = buf;
    1069:     if (name[0] == '-') { *ptr++ = '-';  name++; }
    1070:     PetscStrncpy(ptr,pre,buf+sizeof(buf)-ptr);
    1071:     PetscStrlcat(buf,name,sizeof(buf));
    1072:     name = buf;
    1073:   }

    1075: #if defined(PETSC_USE_DEBUG)
    1076:   {
    1077:     PetscBool valid;
    1078:     char      key[MAXOPTNAME+1] = "-";
    1079:     PetscStrncpy(key+1,name,sizeof(key)-1);
    1080:     PetscOptionsValidKey(key,&valid);
    1081:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
    1082:   }
    1083: #endif

    1085:   if (!options->ht && usehashtable) {
    1086:     int i,ret;
    1087:     khiter_t it;
    1088:     khash_t(HO) *ht;
    1089:     ht = kh_init(HO);
    1090:     if (PetscUnlikely(!ht)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
    1091:     ret = kh_resize(HO,ht,options->N*2); /* twice the required size to reduce risk of collisions */
    1092:     if (PetscUnlikely(ret)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
    1093:     for (i=0; i<options->N; i++) {
    1094:       it = kh_put(HO,ht,options->names[i],&ret);
    1095:       if (PetscUnlikely(ret != 1)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
    1096:       kh_val(ht,it) = i;
    1097:     }
    1098:     options->ht = ht;
    1099:   }

    1101:   if (usehashtable)
    1102:   { /* fast search */
    1103:     khash_t(HO) *ht = options->ht;
    1104:     khiter_t it = kh_get(HO,ht,name);
    1105:     if (it != kh_end(ht)) {
    1106:       int i = kh_val(ht,it);
    1107:       options->used[i]  = PETSC_TRUE;
    1108:       if (value) *value = options->values[i];
    1109:       if (set)   *set   = PETSC_TRUE;
    1110:       return(0);
    1111:     }
    1112:   } else
    1113:   { /* slow search */
    1114:     int i, N = options->N;
    1115:     for (i=0; i<N; i++) {
    1116:       int result = PetscOptNameCmp(options->names[i],name);
    1117:       if (!result) {
    1118:         options->used[i]  = PETSC_TRUE;
    1119:         if (value) *value = options->values[i];
    1120:         if (set)   *set   = PETSC_TRUE;
    1121:         return(0);
    1122:       } else if (result > 0) {
    1123:         break;
    1124:       }
    1125:     }
    1126:   }

    1128:   /*
    1129:    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
    1130:    Maybe this special lookup mode should be enabled on request with a push/pop API.
    1131:    The feature of matching _%d_ used sparingly in the codebase.
    1132:    */
    1133:   if (matchnumbers) {
    1134:     int i,j,cnt = 0,locs[16],loce[16];
    1135:     /* determine the location and number of all _%d_ in the key */
    1136:     for (i=0; name[i]; i++) {
    1137:       if (name[i] == '_') {
    1138:         for (j=i+1; name[j]; j++) {
    1139:           if (name[j] >= '0' && name[j] <= '9') continue;
    1140:           if (name[j] == '_' && j > i+1) { /* found a number */
    1141:             locs[cnt]   = i+1;
    1142:             loce[cnt++] = j+1;
    1143:           }
    1144:           i = j-1;
    1145:           break;
    1146:         }
    1147:       }
    1148:     }
    1149:     for (i=0; i<cnt; i++) {
    1150:       PetscBool found;
    1151:       char      opt[MAXOPTNAME+1] = "-", tmp[MAXOPTNAME];
    1152:       PetscStrncpy(tmp,name,PetscMin((size_t)(locs[i]+1),sizeof(tmp)));
    1153:       PetscStrlcat(opt,tmp,sizeof(opt));
    1154:       PetscStrlcat(opt,name+loce[i],sizeof(opt));
    1155:       PetscOptionsFindPair(options,NULL,opt,value,&found);
    1156:       if (found) {if (set) *set = PETSC_TRUE; return(0);}
    1157:     }
    1158:   }

    1160:   if (set) *set = PETSC_FALSE;
    1161:   return(0);
    1162: }

    1164: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options,const char pre[], const char name[],const char *value[],PetscBool *set)
    1165: {
    1166:   char           buf[MAXOPTNAME];

    1170:   options = options ? options : defaultoptions;
    1171:   if (pre && pre[0] == '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
    1172:   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);

    1174:   name++; /* skip starting dash */

    1176:   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
    1177:   if (pre && pre[0]) {
    1178:     char *ptr = buf;
    1179:     if (name[0] == '-') { *ptr++ = '-';  name++; }
    1180:     PetscStrncpy(ptr,pre,sizeof(buf)+(size_t)(ptr-buf));
    1181:     PetscStrlcat(buf,name,sizeof(buf));
    1182:     name = buf;
    1183:   }

    1185: #if defined(PETSC_USE_DEBUG)
    1186:   {
    1187:     PetscBool valid;
    1188:     char      key[MAXOPTNAME+1] = "-";
    1189:     PetscStrncpy(key+1,name,sizeof(key)-1);
    1190:     PetscOptionsValidKey(key,&valid);
    1191:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
    1192:   }
    1193: #endif

    1195:   { /* slow search */
    1196:     int       i;
    1197:     size_t    len;
    1198:     PetscBool match;
    1199:     PetscStrlen(name,&len);
    1200:     for (i=0; i<options->N; i++) {
    1201:       PetscStrncmp(options->names[i],name,len,&match);
    1202:       if (match) {
    1203:         options->used[i]  = PETSC_TRUE;
    1204:         if (value) *value = options->values[i];
    1205:         if (set)   *set   = PETSC_TRUE;
    1206:         return(0);
    1207:       }
    1208:     }
    1209:   }

    1211:   if (set) *set = PETSC_FALSE;
    1212:   return(0);
    1213: }

    1215: /*@C
    1216:    PetscOptionsReject - Generates an error if a certain option is given.

    1218:    Not Collective, but setting values on certain processors could cause problems
    1219:    for parallel objects looking for options.

    1221:    Input Parameters:
    1222: +  options - options database, use NULL for default global database
    1223: .  pre - the option prefix (may be NULL)
    1224: .  name - the option name one is seeking
    1225: -  mess - error message (may be NULL)

    1227:    Level: advanced

    1229:    Concepts: options database^rejecting option

    1231: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
    1232:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1233:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1234:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1235:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1236:           PetscOptionsFList(), PetscOptionsEList()
    1237: @*/
    1238: PetscErrorCode PetscOptionsReject(PetscOptions options,const char pre[],const char name[],const char mess[])
    1239: {
    1241:   PetscBool      flag = PETSC_FALSE;

    1244:   PetscOptionsHasName(options,pre,name,&flag);
    1245:   if (flag) {
    1246:     if (mess && mess[0]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s with %s",pre?pre:"",name+1,mess);
    1247:     else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s",pre?pre:"",name+1);
    1248:   }
    1249:   return(0);
    1250: }

    1252: /*@C
    1253:    PetscOptionsHasHelp - Determines whether the "-help" option is in the database.

    1255:    Not Collective

    1257:    Input Parameters:
    1258: .  options - options database, use NULL for default global database

    1260:    Output Parameters:
    1261: .  set - PETSC_TRUE if found else PETSC_FALSE.

    1263:    Level: advanced

    1265:    Concepts: options database^help

    1267: .seealso: PetscOptionsHasName()
    1268: @*/
    1269: PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set)
    1270: {
    1273:   options = options ? options : defaultoptions;
    1274:   *set = options->help;
    1275:   return(0);
    1276: }

    1278: /*@C
    1279:    PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or boolean, even
    1280:                       its value is set to false.

    1282:    Not Collective

    1284:    Input Parameters:
    1285: +  options - options database, use NULL for default global database
    1286: .  pre - string to prepend to the name or NULL
    1287: -  name - the option one is seeking

    1289:    Output Parameters:
    1290: .  set - PETSC_TRUE if found else PETSC_FALSE.

    1292:    Level: beginner

    1294:    Concepts: options database^has option name

    1296:    Notes:
    1297:    Name cannot be simply "-h".

    1299:    In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.

    1301: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    1302:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1303:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1304:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1305:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1306:           PetscOptionsFList(), PetscOptionsEList()
    1307: @*/
    1308: PetscErrorCode PetscOptionsHasName(PetscOptions options,const char pre[],const char name[],PetscBool *set)
    1309: {
    1310:   const char     *value;
    1312:   PetscBool      flag;

    1315:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    1316:   if (set) *set = flag;
    1317:   return(0);
    1318: }

    1320: /*@C
    1321:    PetscOptionsGetAll - Lists all the options the program was run with in a single string.

    1323:    Not Collective

    1325:    Input Paramter:
    1326: .  options - the options database, use NULL for the default global database

    1328:    Output Parameter:
    1329: .  copts - pointer where string pointer is stored

    1331:    Notes:
    1332:     the array and each entry in the array should be freed with PetscFree()

    1334:    Level: advanced

    1336:    Concepts: options database^listing

    1338: .seealso: PetscOptionsAllUsed(), PetscOptionsView()
    1339: @*/
    1340: PetscErrorCode PetscOptionsGetAll(PetscOptions options,char *copts[])
    1341: {
    1343:   PetscInt       i;
    1344:   size_t         len = 1,lent = 0;
    1345:   char           *coptions = NULL;

    1349:   options = options ? options : defaultoptions;
    1350:   /* count the length of the required string */
    1351:   for (i=0; i<options->N; i++) {
    1352:     PetscStrlen(options->names[i],&lent);
    1353:     len += 2 + lent;
    1354:     if (options->values[i]) {
    1355:       PetscStrlen(options->values[i],&lent);
    1356:       len += 1 + lent;
    1357:     }
    1358:   }
    1359:   PetscMalloc1(len,&coptions);
    1360:   coptions[0] = 0;
    1361:   for (i=0; i<options->N; i++) {
    1362:     PetscStrcat(coptions,"-");
    1363:     PetscStrcat(coptions,options->names[i]);
    1364:     PetscStrcat(coptions," ");
    1365:     if (options->values[i]) {
    1366:       PetscStrcat(coptions,options->values[i]);
    1367:       PetscStrcat(coptions," ");
    1368:     }
    1369:   }
    1370:   *copts = coptions;
    1371:   return(0);
    1372: }

    1374: /*@C
    1375:    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database

    1377:    Not Collective

    1379:    Input Parameter:
    1380: +  options - options database, use NULL for default global database
    1381: -  name - string name of option

    1383:    Output Parameter:
    1384: .  used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database

    1386:    Level: advanced

    1388: .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
    1389: @*/
    1390: PetscErrorCode PetscOptionsUsed(PetscOptions options,const char *name,PetscBool *used)
    1391: {
    1392:   PetscInt       i;

    1398:   options = options ? options : defaultoptions;
    1399:   *used = PETSC_FALSE;
    1400:   for (i=0; i<options->N; i++) {
    1401:     PetscStrcmp(options->names[i],name,used);
    1402:     if (*used) {
    1403:       *used = options->used[i];
    1404:       break;
    1405:     }
    1406:   }
    1407:   return(0);
    1408: }

    1410: /*@
    1411:    PetscOptionsAllUsed - Returns a count of the number of options in the
    1412:    database that have never been selected.

    1414:    Not Collective

    1416:    Input Parameter:
    1417: .  options - options database, use NULL for default global database

    1419:    Output Parameter:
    1420: .  N - count of options not used

    1422:    Level: advanced

    1424: .seealso: PetscOptionsView()
    1425: @*/
    1426: PetscErrorCode PetscOptionsAllUsed(PetscOptions options,PetscInt *N)
    1427: {
    1428:   PetscInt     i,n = 0;

    1432:   options = options ? options : defaultoptions;
    1433:   for (i=0; i<options->N; i++) {
    1434:     if (!options->used[i]) n++;
    1435:   }
    1436:   *N = n;
    1437:   return(0);
    1438: }

    1440: /*@
    1441:    PetscOptionsLeft - Prints to screen any options that were set and never used.

    1443:    Not Collective

    1445:    Input Parameter:
    1446: .  options - options database; use NULL for default global database

    1448:    Options Database Key:
    1449: .  -options_left - Activates OptionsAllUsed() within PetscFinalize()

    1451:    Level: advanced

    1453: .seealso: PetscOptionsAllUsed()
    1454: @*/
    1455: PetscErrorCode PetscOptionsLeft(PetscOptions options)
    1456: {
    1458:   PetscInt       i;

    1461:   options = options ? options : defaultoptions;
    1462:   for (i=0; i<options->N; i++) {
    1463:     if (!options->used[i]) {
    1464:       if (options->values[i]) {
    1465:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",options->names[i],options->values[i]);
    1466:       } else {
    1467:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",options->names[i]);
    1468:       }
    1469:     }
    1470:   }
    1471:   return(0);
    1472: }

    1474: /*@C
    1475:    PetscOptionsLeftGet - Returns all options that were set and never used.

    1477:    Not Collective

    1479:    Input Parameter:
    1480: .  options - options database, use NULL for default global database

    1482:    Output Parameter:
    1483: .  N - count of options not used
    1484: .  names - names of options not used
    1485: .  values - values of options not used

    1487:    Level: advanced

    1489:    Notes:
    1490:    Users should call PetscOptionsLeftRestore() to free the memory allocated in this routine

    1492: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft()
    1493: @*/
    1494: PetscErrorCode PetscOptionsLeftGet(PetscOptions options,PetscInt *N,char **names[],char **values[])
    1495: {
    1497:   PetscInt       i,n;

    1503:   options = options ? options : defaultoptions;

    1505:   /* The number of unused PETSc options */
    1506:   n = 0;
    1507:   for (i=0; i<options->N; i++) {
    1508:     if (!options->used[i]) n++;
    1509:   }
    1510:   if (N) { *N = n; }
    1511:   if (names)  { PetscMalloc1(n,names); }
    1512:   if (values) { PetscMalloc1(n,values); }

    1514:   n = 0;
    1515:   if (names || values) {
    1516:     for (i=0; i<options->N; i++) {
    1517:       if (!options->used[i]) {
    1518:         if (names)  (*names)[n]  = options->names[i];
    1519:         if (values) (*values)[n] = options->values[i];
    1520:         n++;
    1521:       }
    1522:     }
    1523:   }
    1524:   return(0);
    1525: }

    1527: /*@C
    1528:    PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using PetscOptionsLeftGet.

    1530:    Not Collective

    1532:    Input Parameter:
    1533: .  options - options database, use NULL for default global database
    1534: .  names - names of options not used
    1535: .  values - values of options not used

    1537:    Level: advanced

    1539: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft(), PetscOptionsLeftGet()
    1540: @*/
    1541: PetscErrorCode PetscOptionsLeftRestore(PetscOptions options,PetscInt *N,char **names[],char **values[])
    1542: {

    1549:   if (N) { *N = 0; }
    1550:   if (names)  { PetscFree(*names); }
    1551:   if (values) { PetscFree(*values); }
    1552:   return(0);
    1553: }

    1555: /*@C
    1556:    PetscOptionsSetFromOptions - Sets options related to the handling of options in PETSc

    1558:    Collective on PETSC_COMM_WORLD

    1560:    Input Parameter:
    1561: .  options - options database, use NULL for default global database

    1563:    Options Database Keys:
    1564: +  -options_monitor <optional filename> - prints the names and values of all runtime options as they are set. The monitor functionality is not
    1565:                 available for options set through a file, environment variable, or on
    1566:                 the command line. Only options set after PetscInitialize() completes will
    1567:                 be monitored.
    1568: .  -options_monitor_cancel - cancel all options database monitors

    1570:    Notes:
    1571:    To see all options, run your program with the -help option or consult Users-Manual: Introduction

    1573:    Level: intermediate

    1575: .keywords: set, options, database
    1576: @*/
    1577: PetscErrorCode PetscOptionsSetFromOptions(PetscOptions options)
    1578: {
    1579:   PetscBool      flgc = PETSC_FALSE,flgm;
    1581:   char           monfilename[PETSC_MAX_PATH_LEN];
    1582:   PetscViewer    monviewer;

    1585:   /*
    1586:      The options argument is currently ignored since we currently maintain only a single options database

    1588:      options = options ? options : defaultoptions;
    1589:   */
    1590:   PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for handling options","PetscOptions");
    1591:   PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);
    1592:   PetscOptionsBool("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",flgc,&flgc,NULL);
    1593:   PetscOptionsEnd();
    1594:   if (flgm) {
    1595:     PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);
    1596:     PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    1597:   }
    1598:   if (flgc) { PetscOptionsMonitorCancel(); }
    1599:   return(0);
    1600: }

    1602: /*@C
    1603:    PetscOptionsMonitorDefault - Print all options set value events.

    1605:    Logically Collective on PETSC_COMM_WORLD

    1607:    Input Parameters:
    1608: +  name  - option name string
    1609: .  value - option value string
    1610: -  ctx - an ASCII viewer

    1612:    Level: intermediate

    1614: .keywords: PetscOptions, default, monitor

    1616: .seealso: PetscOptionsMonitorSet()
    1617: @*/
    1618: PetscErrorCode PetscOptionsMonitorDefault(const char name[],const char value[],void *ctx)
    1619: {
    1621:   PetscViewer    viewer = (PetscViewer)ctx;

    1624:   if (!value) {
    1625:     PetscViewerASCIIPrintf(viewer,"Removing option: %s\n",name,value);
    1626:   } else if (!value[0]) {
    1627:     PetscViewerASCIIPrintf(viewer,"Setting option: %s (no value)\n",name);
    1628:   } else {
    1629:     PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
    1630:   }
    1631:   return(0);
    1632: }

    1634: /*@C
    1635:    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
    1636:    modified the PETSc options database.

    1638:    Not Collective

    1640:    Input Parameters:
    1641: +  monitor - pointer to function (if this is NULL, it turns off monitoring
    1642: .  mctx    - [optional] context for private data for the
    1643:              monitor routine (use NULL if no context is desired)
    1644: -  monitordestroy - [optional] routine that frees monitor context
    1645:           (may be NULL)

    1647:    Calling Sequence of monitor:
    1648: $     monitor (const char name[], const char value[], void *mctx)

    1650: +  name - option name string
    1651: .  value - option value string
    1652: -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()

    1654:    Options Database Keys:
    1655: +    -options_monitor    - sets PetscOptionsMonitorDefault()
    1656: -    -options_monitor_cancel - cancels all monitors that have
    1657:                           been hardwired into a code by
    1658:                           calls to PetscOptionsMonitorSet(), but
    1659:                           does not cancel those set via
    1660:                           the options database.

    1662:    Notes:
    1663:    The default is to do nothing.  To print the name and value of options
    1664:    being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
    1665:    with a null monitoring context.

    1667:    Several different monitoring routines may be set by calling
    1668:    PetscOptionsMonitorSet() multiple times; all will be called in the
    1669:    order in which they were set.

    1671:    Level: beginner

    1673: .keywords: PetscOptions, set, monitor

    1675: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
    1676: @*/
    1677: PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
    1678: {
    1679:   PetscOptions options = defaultoptions;

    1682:   if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
    1683:   options->monitor[options->numbermonitors]          = monitor;
    1684:   options->monitordestroy[options->numbermonitors]   = monitordestroy;
    1685:   options->monitorcontext[options->numbermonitors++] = (void*)mctx;
    1686:   return(0);
    1687: }

    1689: /*@
    1690:    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.

    1692:    Not Collective

    1694:    Options Database Key:
    1695: .  -options_monitor_cancel - Cancels all monitors that have
    1696:     been hardwired into a code by calls to PetscOptionsMonitorSet(),
    1697:     but does not cancel those set via the options database.

    1699:    Level: intermediate

    1701: .keywords: PetscOptions, set, monitor

    1703: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
    1704: @*/
    1705: PetscErrorCode PetscOptionsMonitorCancel(void)
    1706: {
    1708:   PetscInt       i;
    1709:   PetscOptions   options = defaultoptions;

    1712:   for (i=0; i<options->numbermonitors; i++) {
    1713:     if (options->monitordestroy[i]) {
    1714:       (*options->monitordestroy[i])(&options->monitorcontext[i]);
    1715:     }
    1716:   }
    1717:   options->numbermonitors = 0;
    1718:   return(0);
    1719: }

    1721: /*
    1722:    PetscOptionsStringToBool - Converts string to PetscBool , handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
    1723: */
    1724: PetscErrorCode PetscOptionsStringToBool(const char value[],PetscBool *a)
    1725: {
    1726:   PetscBool      istrue,isfalse;
    1727:   size_t         len;

    1731:   PetscStrlen(value,&len);
    1732:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Character string of length zero has no logical value");
    1733:   PetscStrcasecmp(value,"TRUE",&istrue);
    1734:   if (istrue) {*a = PETSC_TRUE; return(0);}
    1735:   PetscStrcasecmp(value,"YES",&istrue);
    1736:   if (istrue) {*a = PETSC_TRUE; return(0);}
    1737:   PetscStrcasecmp(value,"1",&istrue);
    1738:   if (istrue) {*a = PETSC_TRUE; return(0);}
    1739:   PetscStrcasecmp(value,"on",&istrue);
    1740:   if (istrue) {*a = PETSC_TRUE; return(0);}
    1741:   PetscStrcasecmp(value,"FALSE",&isfalse);
    1742:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    1743:   PetscStrcasecmp(value,"NO",&isfalse);
    1744:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    1745:   PetscStrcasecmp(value,"0",&isfalse);
    1746:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    1747:   PetscStrcasecmp(value,"off",&isfalse);
    1748:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    1749:   SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value);
    1750: }

    1752: /*
    1753:    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
    1754: */
    1755: PetscErrorCode PetscOptionsStringToInt(const char name[],PetscInt *a)
    1756: {
    1758:   size_t         len;
    1759:   PetscBool      decide,tdefault,mouse;

    1762:   PetscStrlen(name,&len);
    1763:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");

    1765:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
    1766:   if (!tdefault) {
    1767:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
    1768:   }
    1769:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
    1770:   if (!decide) {
    1771:     PetscStrcasecmp(name,"DECIDE",&decide);
    1772:   }
    1773:   PetscStrcasecmp(name,"mouse",&mouse);

    1775:   if (tdefault)    *a = PETSC_DEFAULT;
    1776:   else if (decide) *a = PETSC_DECIDE;
    1777:   else if (mouse)  *a = -1;
    1778:   else {
    1779:     char *endptr;
    1780:     long strtolval;

    1782:     strtolval = strtol(name,&endptr,10);
    1783:     if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);

    1785: #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
    1786:     (void) strtolval;
    1787:     *a = atoll(name);
    1788: #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
    1789:     (void) strtolval;
    1790:     *a = _atoi64(name);
    1791: #else
    1792:     *a = (PetscInt)strtolval;
    1793: #endif
    1794:   }
    1795:   return(0);
    1796: }

    1798: #if defined(PETSC_USE_REAL___FLOAT128)
    1799: #include <quadmath.h>
    1800: #endif

    1802: static PetscErrorCode PetscStrtod(const char name[],PetscReal *a,char **endptr)
    1803: {
    1805: #if defined(PETSC_USE_REAL___FLOAT128)
    1806:   *a = strtoflt128(name,endptr);
    1807: #else
    1808:   *a = (PetscReal)strtod(name,endptr);
    1809: #endif
    1810:   return(0);
    1811: }

    1813: static PetscErrorCode PetscStrtoz(const char name[],PetscScalar *a,char **endptr,PetscBool *isImaginary)
    1814: {
    1815:   PetscBool      hasi = PETSC_FALSE;
    1816:   char           *ptr;
    1817:   PetscReal      strtoval;

    1821:   PetscStrtod(name,&strtoval,&ptr);
    1822:   if (ptr == name) {
    1823:     strtoval = 1.;
    1824:     hasi = PETSC_TRUE;
    1825:     if (name[0] == 'i') {
    1826:       ptr++;
    1827:     } else if (name[0] == '+' && name[1] == 'i') {
    1828:       ptr += 2;
    1829:     } else if (name[0] == '-' && name[1] == 'i') {
    1830:       strtoval = -1.;
    1831:       ptr += 2;
    1832:     }
    1833:   } else if (*ptr == 'i') {
    1834:     hasi = PETSC_TRUE;
    1835:     ptr++;
    1836:   }
    1837:   *endptr = ptr;
    1838:   *isImaginary = hasi;
    1839:   if (hasi) {
    1840: #if !defined(PETSC_USE_COMPLEX)
    1841:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s contains imaginary but complex not supported ",name);
    1842: #else
    1843:     *a = PetscCMPLX(0.,strtoval);
    1844: #endif
    1845:   } else {
    1846:     *a = strtoval;
    1847:   }
    1848:   return(0);
    1849: }

    1851: /*
    1852:    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
    1853: */
    1854: PetscErrorCode PetscOptionsStringToReal(const char name[],PetscReal *a)
    1855: {
    1856:   size_t         len;
    1857:   PetscBool      match;
    1858:   char           *endptr;

    1862:   PetscStrlen(name,&len);
    1863:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"String of length zero has no numerical value");

    1865:   PetscStrcasecmp(name,"PETSC_DEFAULT",&match);
    1866:   if (!match) {
    1867:     PetscStrcasecmp(name,"DEFAULT",&match);
    1868:   }
    1869:   if (match) {*a = PETSC_DEFAULT; return(0);}

    1871:   PetscStrcasecmp(name,"PETSC_DECIDE",&match);
    1872:   if (!match) {
    1873:     PetscStrcasecmp(name,"DECIDE",&match);
    1874:   }
    1875:   if (match) {*a = PETSC_DECIDE; return(0);}

    1877:   PetscStrtod(name,a,&endptr);
    1878:   if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value",name);
    1879:   return(0);
    1880: }

    1882: PetscErrorCode PetscOptionsStringToScalar(const char name[],PetscScalar *a)
    1883: {
    1884:   PetscBool      imag1;
    1885:   size_t         len;
    1886:   PetscScalar    val = 0.;
    1887:   char           *ptr = NULL;

    1891:   PetscStrlen(name,&len);
    1892:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
    1893:   PetscStrtoz(name,&val,&ptr,&imag1);
    1894: #if defined(PETSC_USE_COMPLEX)
    1895:   if ((size_t) (ptr - name) < len) {
    1896:     PetscBool   imag2;
    1897:     PetscScalar val2;

    1899:     PetscStrtoz(ptr,&val2,&ptr,&imag2);
    1900:     if (imag1 || !imag2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s: must specify imaginary component second",name);
    1901:     val = PetscCMPLX(PetscRealPart(val),PetscImaginaryPart(val2));
    1902:   }
    1903: #endif
    1904:   if ((size_t) (ptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
    1905:   *a = val;
    1906:   return(0);
    1907: }

    1909: /*@C
    1910:    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
    1911:             option in the database.

    1913:    Not Collective

    1915:    Input Parameters:
    1916: +  options - options database, use NULL for default global database
    1917: .  pre - the string to prepend to the name or NULL
    1918: -  name - the option one is seeking

    1920:    Output Parameter:
    1921: +  ivalue - the logical value to return
    1922: -  set - PETSC_TRUE  if found, else PETSC_FALSE

    1924:    Level: beginner

    1926:    Notes:
    1927:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
    1928:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

    1930:       If the option is given, but no value is provided, then ivalue and set are both given the value PETSC_TRUE. That is -requested_bool
    1931:      is equivalent to -requested_bool true

    1933:        If the user does not supply the option at all ivalue is NOT changed. Thus
    1934:      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.

    1936:    Concepts: options database^has logical

    1938: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    1939:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
    1940:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1941:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1942:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1943:           PetscOptionsFList(), PetscOptionsEList()
    1944: @*/
    1945: PetscErrorCode PetscOptionsGetBool(PetscOptions options,const char pre[],const char name[],PetscBool *ivalue,PetscBool *set)
    1946: {
    1947:   const char     *value;
    1948:   PetscBool      flag;

    1954:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    1955:   if (flag) {
    1956:     if (set) *set = PETSC_TRUE;
    1957:     if (!value) {
    1958:       if (ivalue) *ivalue = PETSC_TRUE;
    1959:     } else {
    1960:       PetscOptionsStringToBool(value, &flag);
    1961:       if (ivalue) *ivalue = flag;
    1962:     }
    1963:   } else {
    1964:     if (set) *set = PETSC_FALSE;
    1965:   }
    1966:   return(0);
    1967: }

    1969: /*@C
    1970:    PetscOptionsGetEList - Puts a list of option values that a single one may be selected from

    1972:    Not Collective

    1974:    Input Parameters:
    1975: +  options - options database, use NULL for default global database
    1976: .  pre - the string to prepend to the name or NULL
    1977: .  opt - option name
    1978: .  list - the possible choices (one of these must be selected, anything else is invalid)
    1979: .  ntext - number of choices

    1981:    Output Parameter:
    1982: +  value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
    1983: -  set - PETSC_TRUE if found, else PETSC_FALSE

    1985:    Level: intermediate

    1987:    Notes:
    1988:     If the user does not supply the option value is NOT changed. Thus
    1989:      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.

    1991:    See PetscOptionsFList() for when the choices are given in a PetscFunctionList()

    1993:    Concepts: options database^list

    1995: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    1996:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1997:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1998:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1999:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2000:           PetscOptionsFList(), PetscOptionsEList()
    2001: @*/
    2002: PetscErrorCode PetscOptionsGetEList(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool *set)
    2003: {
    2005:   size_t         alen,len = 0;
    2006:   char           *svalue;
    2007:   PetscBool      aset,flg = PETSC_FALSE;
    2008:   PetscInt       i;

    2012:   for (i=0; i<ntext; i++) {
    2013:     PetscStrlen(list[i],&alen);
    2014:     if (alen > len) len = alen;
    2015:   }
    2016:   len += 5; /* a little extra space for user mistypes */
    2017:   PetscMalloc1(len,&svalue);
    2018:   PetscOptionsGetString(options,pre,opt,svalue,len,&aset);
    2019:   if (aset) {
    2020:     PetscEListFind(ntext,list,svalue,value,&flg);
    2021:     if (!flg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre ? pre : "",opt+1);
    2022:     if (set) *set = PETSC_TRUE;
    2023:   } else if (set) *set = PETSC_FALSE;
    2024:   PetscFree(svalue);
    2025:   return(0);
    2026: }

    2028: /*@C
    2029:    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.

    2031:    Not Collective

    2033:    Input Parameters:
    2034: +  options - options database, use NULL for default global database
    2035: .  pre - option prefix or NULL
    2036: .  opt - option name
    2037: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
    2038: -  defaultv - the default (current) value

    2040:    Output Parameter:
    2041: +  value - the  value to return
    2042: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2044:    Level: beginner

    2046:    Concepts: options database

    2048:    Notes:
    2049:     If the user does not supply the option value is NOT changed. Thus
    2050:      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.

    2052:           List is usually something like PCASMTypes or some other predefined list of enum names

    2054: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
    2055:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    2056:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    2057:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2058:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2059:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2060:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
    2061: @*/
    2062: PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set)
    2063: {
    2065:   PetscInt       ntext = 0,tval;
    2066:   PetscBool      fset;

    2070:   while (list[ntext++]) {
    2071:     if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
    2072:   }
    2073:   if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
    2074:   ntext -= 3;
    2075:   PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset);
    2076:   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
    2077:   if (fset) *value = (PetscEnum)tval;
    2078:   if (set) *set = fset;
    2079:   return(0);
    2080: }

    2082: /*@C
    2083:    PetscOptionsGetInt - Gets the integer value for a particular option in the database.

    2085:    Not Collective

    2087:    Input Parameters:
    2088: +  options - options database, use NULL for default global database
    2089: .  pre - the string to prepend to the name or NULL
    2090: -  name - the option one is seeking

    2092:    Output Parameter:
    2093: +  ivalue - the integer value to return
    2094: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2096:    Level: beginner

    2098:    Notes:
    2099:    If the user does not supply the option ivalue is NOT changed. Thus
    2100:    you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.

    2102:    Concepts: options database^has int

    2104: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    2105:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    2106:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    2107:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2108:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2109:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2110:           PetscOptionsFList(), PetscOptionsEList()
    2111: @*/
    2112: PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set)
    2113: {
    2114:   const char     *value;
    2116:   PetscBool      flag;

    2121:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    2122:   if (flag) {
    2123:     if (!value) {
    2124:       if (set) *set = PETSC_FALSE;
    2125:     } else {
    2126:       if (set) *set = PETSC_TRUE;
    2127:       PetscOptionsStringToInt(value,ivalue);
    2128:     }
    2129:   } else {
    2130:     if (set) *set = PETSC_FALSE;
    2131:   }
    2132:   return(0);
    2133: }

    2135: /*@C
    2136:    PetscOptionsGetReal - Gets the double precision value for a particular
    2137:    option in the database.

    2139:    Not Collective

    2141:    Input Parameters:
    2142: +  options - options database, use NULL for default global database
    2143: .  pre - string to prepend to each name or NULL
    2144: -  name - the option one is seeking

    2146:    Output Parameter:
    2147: +  dvalue - the double value to return
    2148: -  set - PETSC_TRUE if found, PETSC_FALSE if not found

    2150:    Notes:
    2151:     If the user does not supply the option dvalue is NOT changed. Thus
    2152:      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.

    2154:    Level: beginner

    2156:    Concepts: options database^has double

    2158: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2159:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
    2160:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2161:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2162:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2163:           PetscOptionsFList(), PetscOptionsEList()
    2164: @*/
    2165: PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set)
    2166: {
    2167:   const char     *value;
    2168:   PetscBool      flag;

    2174:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    2175:   if (flag) {
    2176:     if (!value) {
    2177:       if (set) *set = PETSC_FALSE;
    2178:     } else {
    2179:       if (set) *set = PETSC_TRUE;
    2180:       PetscOptionsStringToReal(value,dvalue);
    2181:     }
    2182:   } else {
    2183:     if (set) *set = PETSC_FALSE;
    2184:   }
    2185:   return(0);
    2186: }

    2188: /*@C
    2189:    PetscOptionsGetScalar - Gets the scalar value for a particular
    2190:    option in the database.

    2192:    Not Collective

    2194:    Input Parameters:
    2195: +  options - options database, use NULL for default global database
    2196: .  pre - string to prepend to each name or NULL
    2197: -  name - the option one is seeking

    2199:    Output Parameter:
    2200: +  dvalue - the double value to return
    2201: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2203:    Level: beginner

    2205:    Usage:
    2206:    A complex number 2+3i must be specified with NO spaces

    2208:    Notes:
    2209:     If the user does not supply the option dvalue is NOT changed. Thus
    2210:      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.

    2212:    Concepts: options database^has scalar

    2214: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2215:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2216:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2217:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2218:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2219:           PetscOptionsFList(), PetscOptionsEList()
    2220: @*/
    2221: PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set)
    2222: {
    2223:   const char     *value;
    2224:   PetscBool      flag;

    2230:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    2231:   if (flag) {
    2232:     if (!value) {
    2233:       if (set) *set = PETSC_FALSE;
    2234:     } else {
    2235: #if !defined(PETSC_USE_COMPLEX)
    2236:       PetscOptionsStringToReal(value,dvalue);
    2237: #else
    2238:       PetscOptionsStringToScalar(value,dvalue);
    2239: #endif
    2240:       if (set) *set = PETSC_TRUE;
    2241:     }
    2242:   } else { /* flag */
    2243:     if (set) *set = PETSC_FALSE;
    2244:   }
    2245:   return(0);
    2246: }

    2248: /*@C
    2249:    PetscOptionsGetString - Gets the string value for a particular option in
    2250:    the database.

    2252:    Not Collective

    2254:    Input Parameters:
    2255: +  options - options database, use NULL for default global database
    2256: .  pre - string to prepend to name or NULL
    2257: .  name - the option one is seeking
    2258: -  len - maximum length of the string including null termination

    2260:    Output Parameters:
    2261: +  string - location to copy string
    2262: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2264:    Level: beginner

    2266:    Fortran Note:
    2267:    The Fortran interface is slightly different from the C/C++
    2268:    interface (len is not used).  Sample usage in Fortran follows
    2269: .vb
    2270:       character *20    string
    2271:       PetscErrorCode   ierr
    2272:       PetscBool        set
    2273:       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
    2274: .ve

    2276:    Notes:
    2277:     if the option is given but no string is provided then an empty string is returned and set is given the value of PETSC_TRUE

    2279:            If the user does not use the option then the string is not changed. Thus
    2280:            you should ALWAYS initialize the string if you access it without first checking if the set flag is true.

    2282:    Concepts: options database^string

    2284:     Note:
    2285:       Even if the user provided no string (for example -optionname -someotheroption) the flag is set to PETSC_TRUE (and the string is fulled with nulls).

    2287: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    2288:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2289:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2290:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2291:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2292:           PetscOptionsFList(), PetscOptionsEList()
    2293: @*/
    2294: PetscErrorCode PetscOptionsGetString(PetscOptions options,const char pre[],const char name[],char string[],size_t len,PetscBool *set)
    2295: {
    2296:   const char     *value;
    2297:   PetscBool      flag;

    2303:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    2304:   if (!flag) {
    2305:     if (set) *set = PETSC_FALSE;
    2306:   } else {
    2307:     if (set) *set = PETSC_TRUE;
    2308:     if (value) {
    2309:       PetscStrncpy(string,value,len);
    2310:     } else {
    2311:       PetscMemzero(string,len);
    2312:     }
    2313:   }
    2314:   return(0);
    2315: }

    2317: char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[])
    2318: {
    2319:   const char     *value;
    2320:   PetscBool      flag;

    2324:   PetscOptionsFindPair(options,pre,name,&value,&flag);if (ierr) return(0);
    2325:   if (flag) PetscFunctionReturn((char*)value);
    2326:   else return(0);
    2327: }

    2329: /*@C
    2330:    PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
    2331:    option in the database.  The values must be separated with commas with
    2332:    no intervening spaces.

    2334:    Not Collective

    2336:    Input Parameters:
    2337: +  options - options database, use NULL for default global database
    2338: .  pre - string to prepend to each name or NULL
    2339: .  name - the option one is seeking
    2340: -  nmax - maximum number of values to retrieve

    2342:    Output Parameter:
    2343: +  dvalue - the integer values to return
    2344: .  nmax - actual number of values retreived
    2345: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2347:    Level: beginner

    2349:    Concepts: options database^array of ints

    2351:    Notes:
    2352:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
    2353:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

    2355: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2356:           PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2357:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2358:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2359:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2360:           PetscOptionsFList(), PetscOptionsEList()
    2361: @*/
    2362: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set)
    2363: {
    2364:   const char     *svalue;
    2365:   char           *value;
    2367:   PetscInt       n = 0;
    2368:   PetscBool      flag;
    2369:   PetscToken     token;

    2376:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2377:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2378:   if (set) *set = PETSC_TRUE;
    2379:   PetscTokenCreate(svalue,',',&token);
    2380:   PetscTokenFind(token,&value);
    2381:   while (value && n < *nmax) {
    2382:     PetscOptionsStringToBool(value,dvalue);
    2383:     PetscTokenFind(token,&value);
    2384:     dvalue++;
    2385:     n++;
    2386:   }
    2387:   PetscTokenDestroy(&token);
    2388:   *nmax = n;
    2389:   return(0);
    2390: }

    2392: /*@C
    2393:    PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.

    2395:    Not Collective

    2397:    Input Parameters:
    2398: +  options - options database, use NULL for default global database
    2399: .  pre - option prefix or NULL
    2400: .  name - option name
    2401: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
    2402: -  nmax - maximum number of values to retrieve

    2404:    Output Parameters:
    2405: +  ivalue - the  enum values to return
    2406: .  nmax - actual number of values retreived
    2407: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2409:    Level: beginner

    2411:    Concepts: options database

    2413:    Notes:
    2414:    The array must be passed as a comma separated list.

    2416:    There must be no intervening spaces between the values.

    2418:    list is usually something like PCASMTypes or some other predefined list of enum names.

    2420: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
    2421:           PetscOptionsGetEnum(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    2422:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(),
    2423:           PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(),
    2424:           PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2425:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
    2426: @*/
    2427: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set)
    2428: {
    2429:   const char     *svalue;
    2430:   char           *value;
    2431:   PetscInt       n = 0;
    2432:   PetscEnum      evalue;
    2433:   PetscBool      flag;
    2434:   PetscToken     token;

    2443:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2444:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2445:   if (set) *set = PETSC_TRUE;
    2446:   PetscTokenCreate(svalue,',',&token);
    2447:   PetscTokenFind(token,&value);
    2448:   while (value && n < *nmax) {
    2449:     PetscEnumFind(list,value,&evalue,&flag);
    2450:     if (!flag) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
    2451:     ivalue[n++] = evalue;
    2452:     PetscTokenFind(token,&value);
    2453:   }
    2454:   PetscTokenDestroy(&token);
    2455:   *nmax = n;
    2456:   return(0);
    2457: }

    2459: /*@C
    2460:    PetscOptionsGetIntArray - Gets an array of integer values for a particular
    2461:    option in the database.

    2463:    Not Collective

    2465:    Input Parameters:
    2466: +  options - options database, use NULL for default global database
    2467: .  pre - string to prepend to each name or NULL
    2468: .  name - the option one is seeking
    2469: -  nmax - maximum number of values to retrieve

    2471:    Output Parameter:
    2472: +  ivalue - the integer values to return
    2473: .  nmax - actual number of values retreived
    2474: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2476:    Level: beginner

    2478:    Notes:
    2479:    The array can be passed as
    2480:    a comma separated list:                                 0,1,2,3,4,5,6,7
    2481:    a range (start-end+1):                                  0-8
    2482:    a range with given increment (start-end+1:inc):         0-7:2
    2483:    a combination of values and ranges separated by commas: 0,1-8,8-15:2

    2485:    There must be no intervening spaces between the values.

    2487:    Concepts: options database^array of ints

    2489: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2490:           PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2491:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2492:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2493:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2494:           PetscOptionsFList(), PetscOptionsEList()
    2495: @*/
    2496: PetscErrorCode PetscOptionsGetIntArray(PetscOptions options,const char pre[],const char name[],PetscInt ivalue[],PetscInt *nmax,PetscBool *set)
    2497: {
    2498:   const char     *svalue;
    2499:   char           *value;
    2501:   PetscInt       n = 0,i,j,start,end,inc,nvalues;
    2502:   size_t         len;
    2503:   PetscBool      flag,foundrange;
    2504:   PetscToken     token;

    2511:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2512:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2513:   if (set) *set = PETSC_TRUE;
    2514:   PetscTokenCreate(svalue,',',&token);
    2515:   PetscTokenFind(token,&value);
    2516:   while (value && n < *nmax) {
    2517:     /* look for form  d-D where d and D are integers */
    2518:     foundrange = PETSC_FALSE;
    2519:     PetscStrlen(value,&len);
    2520:     if (value[0] == '-') i=2;
    2521:     else i=1;
    2522:     for (;i<(int)len; i++) {
    2523:       if (value[i] == '-') {
    2524:         if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
    2525:         value[i] = 0;

    2527:         PetscOptionsStringToInt(value,&start);
    2528:         inc  = 1;
    2529:         j    = i+1;
    2530:         for (;j<(int)len; j++) {
    2531:           if (value[j] == ':') {
    2532:             value[j] = 0;

    2534:             PetscOptionsStringToInt(value+j+1,&inc);
    2535:             if (inc <= 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry,%s cannot have negative increment",n,value+j+1);
    2536:             break;
    2537:           }
    2538:         }
    2539:         PetscOptionsStringToInt(value+i+1,&end);
    2540:         if (end <= start) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry, %s-%s cannot have decreasing list",n,value,value+i+1);
    2541:         nvalues = (end-start)/inc + (end-start)%inc;
    2542:         if (n + nvalues  > *nmax) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry, not enough space left in array (%D) to contain entire range from %D to %D",n,*nmax-n,start,end);
    2543:         for (;start<end; start+=inc) {
    2544:           *ivalue = start; ivalue++;n++;
    2545:         }
    2546:         foundrange = PETSC_TRUE;
    2547:         break;
    2548:       }
    2549:     }
    2550:     if (!foundrange) {
    2551:       PetscOptionsStringToInt(value,ivalue);
    2552:       ivalue++;
    2553:       n++;
    2554:     }
    2555:     PetscTokenFind(token,&value);
    2556:   }
    2557:   PetscTokenDestroy(&token);
    2558:   *nmax = n;
    2559:   return(0);
    2560: }

    2562: /*@C
    2563:    PetscOptionsGetRealArray - Gets an array of double precision values for a
    2564:    particular option in the database.  The values must be separated with
    2565:    commas with no intervening spaces.

    2567:    Not Collective

    2569:    Input Parameters:
    2570: +  options - options database, use NULL for default global database
    2571: .  pre - string to prepend to each name or NULL
    2572: .  name - the option one is seeking
    2573: -  nmax - maximum number of values to retrieve

    2575:    Output Parameters:
    2576: +  dvalue - the double values to return
    2577: .  nmax - actual number of values retreived
    2578: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2580:    Level: beginner

    2582:    Concepts: options database^array of doubles

    2584: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2585:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    2586:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2587:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2588:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2589:           PetscOptionsFList(), PetscOptionsEList()
    2590: @*/
    2591: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set)
    2592: {
    2593:   const char     *svalue;
    2594:   char           *value;
    2596:   PetscInt       n = 0;
    2597:   PetscBool      flag;
    2598:   PetscToken     token;

    2605:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2606:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2607:   if (set) *set = PETSC_TRUE;
    2608:   PetscTokenCreate(svalue,',',&token);
    2609:   PetscTokenFind(token,&value);
    2610:   while (value && n < *nmax) {
    2611:     PetscOptionsStringToReal(value,dvalue++);
    2612:     PetscTokenFind(token,&value);
    2613:     n++;
    2614:   }
    2615:   PetscTokenDestroy(&token);
    2616:   *nmax = n;
    2617:   return(0);
    2618: }

    2620: /*@C
    2621:    PetscOptionsGetScalarArray - Gets an array of scalars for a
    2622:    particular option in the database.  The values must be separated with
    2623:    commas with no intervening spaces.

    2625:    Not Collective

    2627:    Input Parameters:
    2628: +  options - options database, use NULL for default global database
    2629: .  pre - string to prepend to each name or NULL
    2630: .  name - the option one is seeking
    2631: -  nmax - maximum number of values to retrieve

    2633:    Output Parameters:
    2634: +  dvalue - the scalar values to return
    2635: .  nmax - actual number of values retreived
    2636: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2638:    Level: beginner

    2640:    Concepts: options database^array of doubles

    2642: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2643:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    2644:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2645:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2646:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2647:           PetscOptionsFList(), PetscOptionsEList()
    2648: @*/
    2649: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set)
    2650: {
    2651:   const char     *svalue;
    2652:   char           *value;
    2654:   PetscInt       n = 0;
    2655:   PetscBool      flag;
    2656:   PetscToken     token;

    2663:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2664:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2665:   if (set) *set = PETSC_TRUE;
    2666:   PetscTokenCreate(svalue,',',&token);
    2667:   PetscTokenFind(token,&value);
    2668:   while (value && n < *nmax) {
    2669:     PetscOptionsStringToScalar(value,dvalue++);
    2670:     PetscTokenFind(token,&value);
    2671:     n++;
    2672:   }
    2673:   PetscTokenDestroy(&token);
    2674:   *nmax = n;
    2675:   return(0);
    2676: }

    2678: /*@C
    2679:    PetscOptionsGetStringArray - Gets an array of string values for a particular
    2680:    option in the database. The values must be separated with commas with
    2681:    no intervening spaces.

    2683:    Not Collective

    2685:    Input Parameters:
    2686: +  options - options database, use NULL for default global database
    2687: .  pre - string to prepend to name or NULL
    2688: .  name - the option one is seeking
    2689: -  nmax - maximum number of strings

    2691:    Output Parameter:
    2692: +  strings - location to copy strings
    2693: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2695:    Level: beginner

    2697:    Notes:
    2698:    The user should pass in an array of pointers to char, to hold all the
    2699:    strings returned by this function.

    2701:    The user is responsible for deallocating the strings that are
    2702:    returned. The Fortran interface for this routine is not supported.

    2704:    Contributed by Matthew Knepley.

    2706:    Concepts: options database^array of strings

    2708: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    2709:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2710:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2711:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2712:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2713:           PetscOptionsFList(), PetscOptionsEList()
    2714: @*/
    2715: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set)
    2716: {
    2717:   const char     *svalue;
    2718:   char           *value;
    2720:   PetscInt       n = 0;
    2721:   PetscBool      flag;
    2722:   PetscToken     token;

    2729:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2730:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2731:   if (set) *set = PETSC_TRUE;
    2732:   PetscTokenCreate(svalue,',',&token);
    2733:   PetscTokenFind(token,&value);
    2734:   while (value && n < *nmax) {
    2735:     PetscStrallocpy(value,&strings[n]);
    2736:     PetscTokenFind(token,&value);
    2737:     n++;
    2738:   }
    2739:   PetscTokenDestroy(&token);
    2740:   *nmax = n;
    2741:   return(0);
    2742: }

    2744: /*@C
    2745:    PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one

    2747:    Prints a deprecation warning, unless an option is supplied to suppress.

    2749:    Not Collective

    2751:    Input Parameters:
    2752: +  pre - string to prepend to name or NULL
    2753: .  oldname - the old, deprecated option
    2754: .  newname - the new option, or NULL if option is purely removed
    2755: .  version - a string describing the version of first deprecation, e.g. "3.9"
    2756: -  info - additional information string, or NULL.

    2758:    Options Database Keys:
    2759: . -options_suppress_deprecated_warnings - do not print deprecation warnings

    2761:    Notes:
    2762:    Must be called between PetscOptionsBegin() and PetscOptionsEnd().
    2763:    If newname is provided, the old option is replaced. Otherwise, it remains
    2764:    in the options database.
    2765:    If an option is not replaced, the info argument should be used to advise the user
    2766:    on how to proceed.
    2767:    There is a limit on the length of the warning printed, so very long strings
    2768:    provided as info may be truncated.

    2770:    Level: developer

    2772: .seealso: PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsScalar(), PetscOptionsBool(), PetscOptionsString(), PetscOptionsSetValue()

    2774: @*/
    2775: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[])
    2776: {
    2777:   PetscErrorCode     ierr;
    2778:   PetscBool          found,quiet;
    2779:   const char         *value;
    2780:   const char * const quietopt="-options_suppress_deprecated_warnings";
    2781:   char               msg[4096];

    2787:   PetscOptionsFindPair(PetscOptionsObject->options,PetscOptionsObject->prefix,oldname,&value,&found);
    2788:   if (found) {
    2789:     if (newname) {
    2790:       if (PetscOptionsObject->prefix) {
    2791:         PetscOptionsPrefixPush(PetscOptionsObject->options,PetscOptionsObject->prefix);
    2792:       }
    2793:       PetscOptionsSetValue(PetscOptionsObject->options,newname,value);
    2794:       if (PetscOptionsObject->prefix) {
    2795:         PetscOptionsPrefixPop(PetscOptionsObject->options);
    2796:       }
    2797:       PetscOptionsClearValue(PetscOptionsObject->options,oldname);
    2798:     }
    2799:     quiet = PETSC_FALSE;
    2800:     PetscOptionsGetBool(PetscOptionsObject->options,NULL,quietopt,&quiet,NULL);
    2801:     if (!quiet) {
    2802:       PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option ");
    2803:       PetscStrcat(msg,oldname);
    2804:       PetscStrcat(msg," is deprecated as of version ");
    2805:       PetscStrcat(msg,version);
    2806:       PetscStrcat(msg," and will be removed in a future release.");
    2807:       if (newname) {
    2808:         PetscStrcat(msg," Please use the option ");
    2809:         PetscStrcat(msg,newname);
    2810:         PetscStrcat(msg," instead.");
    2811:       }
    2812:       if (info) {
    2813:         PetscStrcat(msg," ");
    2814:         PetscStrcat(msg,info);
    2815:       }
    2816:       PetscStrcat(msg," (Silence this warning with ");
    2817:       PetscStrcat(msg,quietopt);
    2818:       PetscStrcat(msg,")\n");
    2819:       PetscPrintf(PetscOptionsObject->comm,msg);
    2820:     }
    2821:   }
    2822:   return(0);
    2823: }