Date: 2013-07-02T14:38:54+00:00

Actual source code: options.c
petsc-3.4.2 2013-07-02

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

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

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

     13: #include <petsc-private/petscimpl.h>        /*I  "petscsys.h"   I*/
     14: #include <petscviewer.h>
     15: #include <ctype.h>
     16: #if defined(PETSC_HAVE_MALLOC_H)
     17: #include <malloc.h>
     18: #endif
     19: #if defined(PETSC_HAVE_YAML)
     20: #include <yaml.h>
     21: #endif

     23: /*
     24:     This table holds all the options set by the user. For simplicity, we use a static size database
     25: */
     26: #define MAXOPTIONS 512
     27: #define MAXALIASES 25
     28: #define MAXOPTIONSMONITORS 5
     29: #define MAXPREFIXES 25

     31: typedef struct {
     32:   int            N,argc,Naliases;
     33:   char           **args,*names[MAXOPTIONS],*values[MAXOPTIONS];
     34:   char           *aliases1[MAXALIASES],*aliases2[MAXALIASES];
     35:   PetscBool      used[MAXOPTIONS];
     36:   PetscBool      namegiven;
     37:   char           programname[PETSC_MAX_PATH_LEN]; /* HP includes entire path in name */

     39:   /* --------User (or default) routines (most return -1 on error) --------*/
     40:   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], void*); /* returns control to user after */
     41:   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void**);         /* */
     42:   void           *monitorcontext[MAXOPTIONSMONITORS];                  /* to pass arbitrary user data into monitor */
     43:   PetscInt       numbermonitors;                                       /* to, for instance, detect options being set */

     45:   /* Prefixes */
     46:   PetscInt prefixind,prefixstack[MAXPREFIXES];
     47:   char     prefix[2048];
     48: } PetscOptionsTable;

     51: static PetscOptionsTable      *options = 0;
     52: extern PetscOptionsObjectType PetscOptionsObject;

     54: /*
     55:     Options events monitor
     56: */
     57: #define PetscOptionsMonitor(name,value)                              \
     58:   { PetscErrorCode _ierr; PetscInt _i,_im = options->numbermonitors; \
     59:     for (_i=0; _i<_im; _i++) { \
     60:       _(*options->monitor[_i])(name, value, options->monitorcontext[_i]);CHKERRQ(_ierr); \
     61:     } \
     62:   }

     66: /*
     67:    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
     68: */
     69: PetscErrorCode  PetscOptionsStringToInt(const char name[],PetscInt *a)
     70: {
     72:   size_t         i,len;
     73:   PetscBool      decide,tdefault,mouse;

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

     79:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
     80:   if (!tdefault) {
     81:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
     82:   }
     83:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
     84:   if (!decide) {
     85:     PetscStrcasecmp(name,"DECIDE",&decide);
     86:   }
     87:   PetscStrcasecmp(name,"mouse",&mouse);

     89:   if (tdefault)    *a = PETSC_DEFAULT;
     90:   else if (decide) *a = PETSC_DECIDE;
     91:   else if (mouse)  *a = -1;
     92:   else {
     93:     if (name[0] != '+' && name[0] != '-' && name[0] < '0' && name[0] > '9') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);

     95:     for (i=1; i<len; i++) {
     96:       if (name[i] < '0' || name[i] > '9') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);
     97:     }

     99: #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
    100:     *a = atoll(name);
    101: #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
    102:     *a = _atoi64(name);
    103: #else
    104:     *a = (PetscInt)atoi(name);
    105: #endif
    106:   }
    107:   return(0);
    108: }

    112: /*
    113:    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
    114: */
    115: PetscErrorCode  PetscOptionsStringToReal(const char name[],PetscReal *a)
    116: {
    118:   size_t         len;
    119:   PetscBool      decide,tdefault;

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

    125:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
    126:   if (!tdefault) {
    127:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
    128:   }
    129:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
    130:   if (!decide) {
    131:     PetscStrcasecmp(name,"DECIDE",&decide);
    132:   }

    134:   if (tdefault)    *a = PETSC_DEFAULT;
    135:   else if (decide) *a = PETSC_DECIDE;
    136:   else {
    137:     if (name[0] != '+' && name[0] != '-' && name[0] != '.' && name[0] < '0' && name[0] > '9') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
    138:     *a = atof(name);
    139:   }
    140:   return(0);
    141: }

    145: /*
    146:    PetscOptionsStringToBool - Converts string to PetscBool , handles cases like "yes", "no", "true", "false", "0", "1"
    147: */
    148: PetscErrorCode  PetscOptionsStringToBool(const char value[], PetscBool  *a)
    149: {
    150:   PetscBool      istrue, isfalse;
    151:   size_t         len;

    155:   PetscStrlen(value, &len);
    156:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Character string of length zero has no logical value");
    157:   PetscStrcasecmp(value,"TRUE",&istrue);
    158:   if (istrue) {*a = PETSC_TRUE; return(0);}
    159:   PetscStrcasecmp(value,"YES",&istrue);
    160:   if (istrue) {*a = PETSC_TRUE; return(0);}
    161:   PetscStrcasecmp(value,"1",&istrue);
    162:   if (istrue) {*a = PETSC_TRUE; return(0);}
    163:   PetscStrcasecmp(value,"on",&istrue);
    164:   if (istrue) {*a = PETSC_TRUE; return(0);}
    165:   PetscStrcasecmp(value,"FALSE",&isfalse);
    166:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    167:   PetscStrcasecmp(value,"NO",&isfalse);
    168:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    169:   PetscStrcasecmp(value,"0",&isfalse);
    170:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    171:   PetscStrcasecmp(value,"off",&isfalse);
    172:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    173:   SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
    174:   return(0);
    175: }

    179: /*@C
    180:     PetscGetProgramName - Gets the name of the running program.

    182:     Not Collective

    184:     Input Parameter:
    185: .   len - length of the string name

    187:     Output Parameter:
    188: .   name - the name of the running program

    190:    Level: advanced

    192:     Notes:
    193:     The name of the program is copied into the user-provided character
    194:     array of length len.  On some machines the program name includes
    195:     its entire path, so one should generally set len >= PETSC_MAX_PATH_LEN.
    196: @*/
    197: PetscErrorCode  PetscGetProgramName(char name[],size_t len)
    198: {

    202:   if (!options) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call PetscInitialize() first");
    203:   if (!options->namegiven) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to determine program name");
    204:   PetscStrncpy(name,options->programname,len);
    205:   return(0);
    206: }

    210: PetscErrorCode  PetscSetProgramName(const char name[])
    211: {

    215:   options->namegiven = PETSC_TRUE;

    217:   PetscStrncpy(options->programname,name,PETSC_MAX_PATH_LEN);
    218:   return(0);
    219: }

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

    226:    Input Parameter:
    227: .    in_str - string to check if valid

    229:    Output Parameter:
    230: .    key - PETSC_TRUE if a valid key

    232:   Level: intermediate

    234: @*/
    235: PetscErrorCode  PetscOptionsValidKey(const char in_str[],PetscBool  *key)
    236: {
    238:   *key = PETSC_FALSE;
    239:   if (!in_str) return(0);
    240:   if (in_str[0] != '-') return(0);
    241:   if (in_str[1] == '-') in_str++;
    242:   if (!isalpha(in_str[1])) return(0);
    243:   if ((!strncmp(in_str+1,"inf",3) || !strncmp(in_str+1,"INF",3)) && !(in_str[4] == '_' || isalnum(in_str[4]))) return(0);
    244:   *key = PETSC_TRUE;
    245:   return(0);
    246: }

    250: /*@C
    251:      PetscOptionsInsertString - Inserts options into the database from a string

    253:      Not collective: but only processes that call this routine will set the options
    254:                      included in the string

    256:   Input Parameter:
    257: .   in_str - string that contains options separated by blanks

    260:   Level: intermediate

    262:   Contributed by Boyana Norris

    264: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
    265:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    266:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    267:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    268:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    269:           PetscOptionsList(), PetscOptionsEList(), PetscOptionsInsertFile()

    271: @*/
    272: PetscErrorCode  PetscOptionsInsertString(const char in_str[])
    273: {
    274:   char           *first,*second;
    276:   PetscToken     token;
    277:   PetscBool      key,ispush,ispop;

    280:   PetscTokenCreate(in_str,' ',&token);
    281:   PetscTokenFind(token,&first);
    282:   while (first) {
    283:     PetscStrcasecmp(first,"-prefix_push",&ispush);
    284:     PetscStrcasecmp(first,"-prefix_pop",&ispop);
    285:     PetscOptionsValidKey(first,&key);
    286:     if (ispush) {
    287:       PetscTokenFind(token,&second);
    288:       PetscOptionsPrefixPush(second);
    289:       PetscTokenFind(token,&first);
    290:     } else if (ispop) {
    291:       PetscOptionsPrefixPop();
    292:       PetscTokenFind(token,&first);
    293:     } else if (key) {
    294:       PetscTokenFind(token,&second);
    295:       PetscOptionsValidKey(second,&key);
    296:       if (!key) {
    297:         PetscOptionsSetValue(first,second);
    298:         PetscTokenFind(token,&first);
    299:       } else {
    300:         PetscOptionsSetValue(first,NULL);
    301:         first = second;
    302:       }
    303:     } else {
    304:       PetscTokenFind(token,&first);
    305:     }
    306:   }
    307:   PetscTokenDestroy(&token);
    308:   return(0);
    309: }

    311: /*
    312:     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
    313: */
    314: static char *Petscgetline(FILE * f)
    315: {
    316:   size_t size  = 0;
    317:   size_t len   = 0;
    318:   size_t last  = 0;
    319:   char   *buf  = NULL;

    321:   if (feof(f)) return 0;
    322:   do {
    323:     size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
    324:     buf   = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
    325:     /* Actually do the read. Note that fgets puts a terminal '\0' on the
    326:     end of the string, so we make sure we overwrite this */
    327:     if (!fgets(buf+len,size,f)) buf[len]=0;
    328:     PetscStrlen(buf,&len);
    329:     last = len - 1;
    330:   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
    331:   if (len) return buf;
    332:   free(buf);
    333:   return 0;
    334: }

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

    342:      Collective on MPI_Comm

    344:   Input Parameter:
    345: +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
    346: .   file - name of file
    347: -   require - if PETSC_TRUE will generate an error if the file does not exist

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

    352:   Level: developer

    354: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
    355:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    356:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    357:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    358:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    359:           PetscOptionsList(), PetscOptionsEList()

    361: @*/
    362: PetscErrorCode  PetscOptionsInsertFile(MPI_Comm comm,const char file[],PetscBool require)
    363: {
    364:   char           *string,fname[PETSC_MAX_PATH_LEN],*first,*second,*third,*vstring = 0,*astring = 0;
    366:   size_t         i,len,bytes;
    367:   FILE           *fd;
    368:   PetscToken     token;
    369:   int            err;
    370:   char           cmt[1]={'#'},*cmatch;
    371:   PetscMPIInt    rank,cnt=0,acnt=0;
    372:   PetscSegBuffer vseg,aseg;

    375:   MPI_Comm_rank(comm,&rank);
    376:   if (!rank) {
    377:     PetscSegBufferCreate(1,4000,&vseg);
    378:     PetscSegBufferCreate(1,2000,&aseg);
    379:     cnt        = 0;
    380:     acnt       = 0;

    382:     PetscFixFilename(file,fname);
    383:     fd   = fopen(fname,"r");
    384:     if (fd) {
    385:       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
    386:       PetscInfo1(0,"Opened options file %s\n",file);

    388:       while ((string = Petscgetline(fd))) {
    389:         /* eliminate comments from each line */
    390:         for (i=0; i<1; i++) {
    391:           PetscStrchr(string,cmt[i],&cmatch);
    392:           if (cmatch) *cmatch = 0;
    393:         }
    394:         PetscStrlen(string,&len);
    395:         /* replace tabs, ^M, \n with " " */
    396:         for (i=0; i<len; i++) {
    397:           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
    398:             string[i] = ' ';
    399:           }
    400:         }
    401:         PetscTokenCreate(string,' ',&token);
    402:         free(string);
    403:         PetscTokenFind(token,&first);
    404:         if (!first) {
    405:           goto destroy;
    406:         } else if (!first[0]) { /* if first token is empty spaces, redo first token */
    407:           PetscTokenFind(token,&first);
    408:         }
    409:         PetscTokenFind(token,&second);
    410:         if (!first) {
    411:           goto destroy;
    412:         } else if (first[0] == '-') {
    413:           PetscStrlen(first,&len);
    414:           PetscSegBufferGet(vseg,len+1,&vstring);
    415:           PetscMemcpy(vstring,first,len);
    416:           vstring[len] = ' ';
    417:           if (second) {
    418:             PetscStrlen(second,&len);
    419:             PetscSegBufferGet(vseg,len+3,&vstring);
    420:             vstring[0] = '"';
    421:             PetscMemcpy(vstring+1,second,len);
    422:             vstring[len+1] = '"';
    423:             vstring[len+2] = ' ';
    424:           }
    425:         } else {
    426:           PetscBool match;

    428:           PetscStrcasecmp(first,"alias",&match);
    429:           if (match) {
    430:             PetscTokenFind(token,&third);
    431:             if (!third) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file:alias missing (%s)",second);
    432:             PetscStrlen(second,&len);
    433:             PetscSegBufferGet(aseg,len+1,&astring);
    434:             PetscMemcpy(astring,second,len);
    435:             astring[len] = ' ';

    437:             PetscStrlen(third,&len);
    438:             PetscSegBufferGet(aseg,len+1,&astring);
    439:             PetscMemcpy(astring,third,len);
    440:             astring[len] = ' ';
    441:           } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown statement in options file: (%s)",string);
    442:         }
    443: destroy:
    444:         PetscTokenDestroy(&token);
    445:       }
    446:       err = fclose(fd);
    447:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
    448:       PetscSegBufferGetSize(aseg,&bytes); /* size without null termination */
    449:       PetscMPIIntCast(bytes,&acnt);
    450:       PetscSegBufferGet(aseg,1,&astring);
    451:       astring[0] = 0;
    452:       PetscSegBufferExtractInPlace(aseg,&astring);
    453:       PetscSegBufferGetSize(vseg,&bytes); /* size without null termination */
    454:       PetscMPIIntCast(bytes,&cnt);
    455:       PetscSegBufferGet(vseg,1,&vstring);
    456:       vstring[0] = 0;
    457:       PetscSegBufferExtractInPlace(vseg,&vstring);
    458:     } else if (require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open Options File %s",fname);
    459:   }

    461:   MPI_Bcast(&acnt,1,MPI_INT,0,comm);
    462:   if (acnt) {
    463:     PetscToken token;
    464:     char       *first,*second;

    466:     if (rank) {
    467:       PetscMalloc((acnt+1)*sizeof(char),&astring);
    468:     }
    469:     MPI_Bcast(astring,acnt+1,MPI_CHAR,0,comm);
    470:     PetscTokenCreate(astring,' ',&token);
    471:     PetscTokenFind(token,&first);
    472:     while (first) {
    473:       PetscTokenFind(token,&second);
    474:       PetscOptionsSetAlias(first,second);
    475:       PetscTokenFind(token,&first);
    476:     }
    477:     PetscTokenDestroy(&token);
    478:   }

    480:   MPI_Bcast(&cnt,1,MPI_INT,0,comm);
    481:   if (cnt) {
    482:     if (rank) {
    483:       PetscMalloc((cnt+1)*sizeof(char),&vstring);
    484:     }
    485:     MPI_Bcast(vstring,cnt+1,MPI_CHAR,0,comm);
    486:     PetscOptionsInsertString(vstring);
    487:   }
    488:   if (!rank) {
    489:     PetscSegBufferDestroy(&aseg);
    490:     PetscSegBufferDestroy(&vseg);
    491:   } else {
    492:     PetscFree(astring);
    493:     PetscFree(vstring);
    494:   }
    495:   return(0);
    496: }

    500: static PetscErrorCode PetscOptionsInsertArgs_Private(int argc,char *args[])
    501: {
    503:   int            left    = argc - 1;
    504:   char           **eargs = args + 1;

    507:   while (left) {
    508:     PetscBool isoptions_file,isprefixpush,isprefixpop,isp4,tisp4,isp4yourname,isp4rmrank,key;
    509:     PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);
    510:     PetscStrcasecmp(eargs[0],"-prefix_push",&isprefixpush);
    511:     PetscStrcasecmp(eargs[0],"-prefix_pop",&isprefixpop);
    512:     PetscStrcasecmp(eargs[0],"-p4pg",&isp4);
    513:     PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);
    514:     PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);
    515:     PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);
    516:     isp4 = (PetscBool) (isp4 || tisp4);
    517:     PetscStrcasecmp(eargs[0],"-np",&tisp4);
    518:     isp4 = (PetscBool) (isp4 || tisp4);
    519:     PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);
    520:     PetscOptionsValidKey(eargs[0],&key);

    522:     if (!key) {
    523:       eargs++; left--;
    524:     } else if (isoptions_file) {
    525:       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
    526:       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
    527:       PetscOptionsInsertFile(PETSC_COMM_WORLD,eargs[1],PETSC_TRUE);
    528:       eargs += 2; left -= 2;
    529:     } else if (isprefixpush) {
    530:       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
    531:       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
    532:       PetscOptionsPrefixPush(eargs[1]);
    533:       eargs += 2; left -= 2;
    534:     } else if (isprefixpop) {
    535:       PetscOptionsPrefixPop();
    536:       eargs++; left--;

    538:       /*
    539:        These are "bad" options that MPICH, etc put on the command line
    540:        we strip them out here.
    541:        */
    542:     } else if (tisp4 || isp4rmrank) {
    543:       eargs += 1; left -= 1;
    544:     } else if (isp4 || isp4yourname) {
    545:       eargs += 2; left -= 2;
    546:     } else {
    547:       PetscBool nextiskey = PETSC_FALSE;
    548:       if (left >= 2) {PetscOptionsValidKey(eargs[1],&nextiskey);}
    549:       if (left < 2 || nextiskey) {
    550:         PetscOptionsSetValue(eargs[0],NULL);
    551:         eargs++; left--;
    552:       } else {
    553:         PetscOptionsSetValue(eargs[0],eargs[1]);
    554:         eargs += 2; left -= 2;
    555:       }
    556:     }
    557:   }
    558:   return(0);
    559: }

    564: /*@C
    565:    PetscOptionsInsert - Inserts into the options database from the command line,
    566:                    the environmental variable and a file.

    568:    Input Parameters:
    569: +  argc - count of number of command line arguments
    570: .  args - the command line arguments
    571: -  file - optional filename, defaults to ~username/.petscrc

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

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

    582:    Level: advanced

    584:    Concepts: options database^adding

    586: .seealso: PetscOptionsDestroy_Private(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
    587:           PetscInitialize()
    588: @*/
    589: PetscErrorCode  PetscOptionsInsert(int *argc,char ***args,const char file[])
    590: {
    592:   PetscMPIInt    rank;
    593:   char           pfile[PETSC_MAX_PATH_LEN];
    594:   PetscBool      flag = PETSC_FALSE;

    597:   if (!options) {
    598:     fprintf(stderr, "Options have not been enabled.\nYou might have forgotten to call PetscInitialize().\n");
    599:     MPI_Abort(MPI_COMM_WORLD, PETSC_ERR_SUP);
    600:   }
    601:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

    603:   options->argc = (argc) ? *argc : 0;
    604:   options->args = (args) ? *args : NULL;

    606:   if (file && file[0]) {
    607:     char fullpath[PETSC_MAX_PATH_LEN];

    609:     PetscStrreplace(PETSC_COMM_WORLD,file,fullpath,PETSC_MAX_PATH_LEN);
    610:     PetscOptionsInsertFile(PETSC_COMM_WORLD,fullpath,PETSC_TRUE);
    611:   }
    612:   /*
    613:      We want to be able to give -skip_petscrc on the command line, but need to parse it first.  Since the command line
    614:      should take precedence, we insert it twice.  It would be sufficient to just scan for -skip_petscrc.
    615:   */
    616:   if (argc && args && *argc) {PetscOptionsInsertArgs_Private(*argc,*args);}
    617:   PetscOptionsGetBool(NULL,"-skip_petscrc",&flag,NULL);
    618:   if (!flag) {
    619:     PetscGetHomeDirectory(pfile,PETSC_MAX_PATH_LEN-16);
    620:     /* warning: assumes all processes have a home directory or none, but nothing in between */
    621:     if (pfile[0]) {
    622:       PetscStrcat(pfile,"/.petscrc");
    623:       PetscOptionsInsertFile(PETSC_COMM_WORLD,pfile,PETSC_FALSE);
    624:     }
    625:     PetscOptionsInsertFile(PETSC_COMM_WORLD,".petscrc",PETSC_FALSE);
    626:     PetscOptionsInsertFile(PETSC_COMM_WORLD,"petscrc",PETSC_FALSE);
    627:   }

    629:   /* insert environmental options */
    630:   {
    631:     char   *eoptions = 0;
    632:     size_t len       = 0;
    633:     if (!rank) {
    634:       eoptions = (char*)getenv("PETSC_OPTIONS");
    635:       PetscStrlen(eoptions,&len);
    636:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
    637:     } else {
    638:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
    639:       if (len) {
    640:         PetscMalloc((len+1)*sizeof(char*),&eoptions);
    641:       }
    642:     }
    643:     if (len) {
    644:       MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
    645:       if (rank) eoptions[len] = 0;
    646:       PetscOptionsInsertString(eoptions);
    647:       if (rank) {PetscFree(eoptions);}
    648:     }
    649:   }

    651: #if defined(PETSC_HAVE_YAML)
    652:   char      yaml_file[PETSC_MAX_PATH_LEN];
    653:   PetscBool yaml_flg = PETSC_FALSE;
    654:   PetscOptionsGetString(NULL,"-options_file_yaml",yaml_file,PETSC_MAX_PATH_LEN,&yaml_flg);
    655:   if (yaml_flg) PetscOptionsInsertFileYAML(PETSC_COMM_WORLD,yaml_file,PETSC_TRUE);
    656: #endif

    658:   /* insert command line options again because they take precedence over arguments in petscrc/environment */
    659:   if (argc && args && *argc) {PetscOptionsInsertArgs_Private(*argc,*args);}
    660:   return(0);
    661: }

    665: /*@C
    666:    PetscOptionsView - Prints the options that have been loaded. This is
    667:    useful for debugging purposes.

    669:    Logically Collective on PetscViewer

    671:    Input Parameter:
    672: .  viewer - must be an PETSCVIEWERASCII viewer

    674:    Options Database Key:
    675: .  -options_table - Activates PetscOptionsView() within PetscFinalize()

    677:    Level: advanced

    679:    Concepts: options database^printing

    681: .seealso: PetscOptionsAllUsed()
    682: @*/
    683: PetscErrorCode  PetscOptionsView(PetscViewer viewer)
    684: {
    686:   PetscInt       i;
    687:   PetscBool      isascii;

    690:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
    691:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    692:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");

    694:   if (!options) {PetscOptionsInsert(0,0,0);}
    695:   if (options->N) {
    696:     PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");
    697:   } else {
    698:     PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");
    699:   }
    700:   for (i=0; i<options->N; i++) {
    701:     if (options->values[i]) {
    702:       PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);
    703:     } else {
    704:       PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);
    705:     }
    706:   }
    707:   if (options->N) {
    708:     PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");
    709:   }
    710:   return(0);
    711: }

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

    718:    Not Collective

    720:    Output Parameter:
    721: .  copts - pointer where string pointer is stored

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

    725:    Level: advanced

    727:    Concepts: options database^listing

    729: .seealso: PetscOptionsAllUsed(), PetscOptionsView()
    730: @*/
    731: PetscErrorCode  PetscOptionsGetAll(char *copts[])
    732: {
    734:   PetscInt       i;
    735:   size_t         len       = 1,lent = 0;
    736:   char           *coptions = NULL;

    739:   if (!options) {PetscOptionsInsert(0,0,0);}

    741:   /* count the length of the required string */
    742:   for (i=0; i<options->N; i++) {
    743:     PetscStrlen(options->names[i],&lent);
    744:     len += 2 + lent;
    745:     if (options->values[i]) {
    746:       PetscStrlen(options->values[i],&lent);
    747:       len += 1 + lent;
    748:     }
    749:   }
    750:   PetscMalloc(len*sizeof(char),&coptions);
    751:   coptions[0] = 0;
    752:   for (i=0; i<options->N; i++) {
    753:     PetscStrcat(coptions,"-");
    754:     PetscStrcat(coptions,options->names[i]);
    755:     PetscStrcat(coptions," ");
    756:     if (options->values[i]) {
    757:       PetscStrcat(coptions,options->values[i]);
    758:       PetscStrcat(coptions," ");
    759:     }
    760:   }
    761:   *copts = coptions;
    762:   return(0);
    763: }

    767: /*@
    768:    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.

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

    772:    Input Parameter:
    773: .  prefix - The string to append to the existing prefix

    775:    Options Database Keys:
    776:  +   -prefix_push <some_prefix_> - push the given prefix
    777:  -   -prefix_pop - pop the last prefix

    779:    Notes:
    780:    It is common to use this in conjunction with -options_file as in

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

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

    786: Level: advanced

    788: .seealso: PetscOptionsPrefixPop()
    789: @*/
    790: PetscErrorCode  PetscOptionsPrefixPush(const char prefix[])
    791: {
    793:   size_t         n;
    794:   PetscInt       start;
    795:   char           buf[2048];
    796:   PetscBool      key;

    800:   /* Want to check validity of the key using PetscOptionsValidKey(), which requires that the first character is a '-' */
    801:   buf[0] = '-';
    802:   PetscStrncpy(buf+1,prefix,sizeof(buf) - 1);
    803:   buf[sizeof(buf) - 1] = 0;
    804:   PetscOptionsValidKey(buf,&key);
    805:   if (!key) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Given prefix \"%s\" not valid (the first character must be a letter, do not include leading '-')",prefix);

    807:   if (!options) {PetscOptionsInsert(0,0,0);}
    808:   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);
    809:   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
    810:   PetscStrlen(prefix,&n);
    811:   if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
    812:   PetscMemcpy(options->prefix+start,prefix,n+1);
    813:   options->prefixstack[options->prefixind++] = start+n;
    814:   return(0);
    815: }

    819: /*@
    820:    PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details

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

    824:    Level: advanced

    826: .seealso: PetscOptionsPrefixPush()
    827: @*/
    828: PetscErrorCode  PetscOptionsPrefixPop(void)
    829: {
    830:   PetscInt offset;

    833:   if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
    834:   options->prefixind--;
    835:   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
    836:   options->prefix[offset] = 0;
    837:   return(0);
    838: }

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

    845:    Level: developer

    847: .seealso: PetscOptionsInsert()
    848: @*/
    849: PetscErrorCode  PetscOptionsClear(void)
    850: {
    851:   PetscInt i;

    854:   if (!options) return(0);
    855:   for (i=0; i<options->N; i++) {
    856:     if (options->names[i])  free(options->names[i]);
    857:     if (options->values[i]) free(options->values[i]);
    858:   }
    859:   for (i=0; i<options->Naliases; i++) {
    860:     free(options->aliases1[i]);
    861:     free(options->aliases2[i]);
    862:   }
    863:   options->prefix[0] = 0;
    864:   options->prefixind = 0;
    865:   options->N         = 0;
    866:   options->Naliases  = 0;
    867:   return(0);
    868: }

    872: /*@C
    873:     PetscOptionsDestroy - Destroys the option database.

    875:     Note:
    876:     Since PetscOptionsDestroy() is called by PetscFinalize(), the user
    877:     typically does not need to call this routine.

    879:    Level: developer

    881: .seealso: PetscOptionsInsert()
    882: @*/
    883: PetscErrorCode  PetscOptionsDestroy(void)
    884: {

    888:   if (!options) return(0);
    889:   PetscOptionsClear();
    890:   free(options);
    891:   options = 0;
    892:   return(0);
    893: }

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

    901:    Not collective, but setting values on certain processors could cause problems
    902:    for parallel objects looking for options.

    904:    Input Parameters:
    905: +  name - name of option, this SHOULD have the - prepended
    906: -  value - the option value (not used for all options)

    908:    Level: intermediate

    910:    Note:
    911:    Only some options have values associated with them, such as
    912:    -ksp_rtol tol.  Other options stand alone, such as -ksp_monitor.

    914:   Developers Note: Uses malloc() directly because PETSc may not yet have been fully initialized

    916:   Concepts: options database^adding option

    918: .seealso: PetscOptionsInsert()
    919: @*/
    920: PetscErrorCode  PetscOptionsSetValue(const char iname[],const char value[])
    921: {
    922:   size_t         len;
    924:   PetscInt       N,n,i;
    925:   char           **names;
    926:   char           fullname[2048];
    927:   const char     *name = iname;
    928:   PetscBool      gt,match;

    931:   if (!options) {PetscOptionsInsert(0,0,0);}

    933:   /* this is so that -h and -hel\p are equivalent (p4 does not like -help)*/
    934:   PetscStrcasecmp(name,"-h",&match);
    935:   if (match) name = "-help";

    937:   name++; /* skip starting hyphen */
    938:   if (options->prefixind > 0) {
    939:     PetscStrncpy(fullname,options->prefix,sizeof(fullname));
    940:     PetscStrncat(fullname,name,sizeof(fullname));
    941:     name = fullname;
    942:   }

    944:   /* check against aliases */
    945:   N = options->Naliases;
    946:   for (i=0; i<N; i++) {
    947:     PetscStrcasecmp(options->aliases1[i],name,&match);
    948:     if (match) {
    949:       name = options->aliases2[i];
    950:       break;
    951:     }
    952:   }

    954:   N     = options->N;
    955:   n     = N;
    956:   names = options->names;

    958:   for (i=0; i<N; i++) {
    959:     PetscStrcasecmp(names[i],name,&match);
    960:     PetscStrgrt(names[i],name,&gt);
    961:     if (match) {
    962:       if (options->values[i]) free(options->values[i]);
    963:       PetscStrlen(value,&len);
    964:       if (len) {
    965:         options->values[i] = (char*)malloc((len+1)*sizeof(char));
    966:         PetscStrcpy(options->values[i],value);
    967:       } else options->values[i] = 0;
    968:       PetscOptionsMonitor(name,value);
    969:       return(0);
    970:     } else if (gt) {
    971:       n = i;
    972:       break;
    973:     }
    974:   }
    975:   if (N >= MAXOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"No more room in option table, limit %d recompile \n src/sys/objects/options.c with larger value for MAXOPTIONS\n",MAXOPTIONS);

    977:   /* shift remaining values down 1 */
    978:   for (i=N; i>n; i--) {
    979:     options->names[i]  = options->names[i-1];
    980:     options->values[i] = options->values[i-1];
    981:     options->used[i]   = options->used[i-1];
    982:   }
    983:   /* insert new name and value */
    984:   PetscStrlen(name,&len);
    985:   options->names[n] = (char*)malloc((len+1)*sizeof(char));
    986:   PetscStrcpy(options->names[n],name);
    987:   PetscStrlen(value,&len);
    988:   if (len) {
    989:     options->values[n] = (char*)malloc((len+1)*sizeof(char));
    990:     PetscStrcpy(options->values[n],value);
    991:   } else options->values[n] = 0;
    992:   options->used[n] = PETSC_FALSE;
    993:   options->N++;
    994:   PetscOptionsMonitor(name,value);
    995:   return(0);
    996: }

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

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

    1007:    Input Parameter:
    1008: .  name - name of option, this SHOULD have the - prepended

    1010:    Level: intermediate

    1012:    Concepts: options database^removing option
    1013: .seealso: PetscOptionsInsert()
    1014: @*/
    1015: PetscErrorCode  PetscOptionsClearValue(const char iname[])
    1016: {
    1018:   PetscInt       N,n,i;
    1019:   char           **names,*name=(char*)iname;
    1020:   PetscBool      gt,match;

    1023:   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);
    1024:   if (!options) {PetscOptionsInsert(0,0,0);}

    1026:   name++;

    1028:   N     = options->N; n = 0;
    1029:   names = options->names;

    1031:   for (i=0; i<N; i++) {
    1032:     PetscStrcasecmp(names[i],name,&match);
    1033:     PetscStrgrt(names[i],name,&gt);
    1034:     if (match) {
    1035:       if (options->names[i])  free(options->names[i]);
    1036:       if (options->values[i]) free(options->values[i]);
    1037:       PetscOptionsMonitor(name,"");
    1038:       break;
    1039:     } else if (gt) return(0); /* it was not listed */

    1041:     n++;
    1042:   }
    1043:   if (n == N) return(0); /* it was not listed */

    1045:   /* shift remaining values down 1 */
    1046:   for (i=n; i<N-1; i++) {
    1047:     options->names[i]  = options->names[i+1];
    1048:     options->values[i] = options->values[i+1];
    1049:     options->used[i]   = options->used[i+1];
    1050:   }
    1051:   options->N--;
    1052:   return(0);
    1053: }

    1057: /*@C
    1058:    PetscOptionsSetAlias - Makes a key and alias for another key

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

    1063:    Input Parameters:
    1064: +  inewname - the alias
    1065: -  ioldname - the name that alias will refer to

    1067:    Level: advanced

    1069: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
    1070:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
    1071:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1072:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1073:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1074:           PetscOptionsList(), PetscOptionsEList()
    1075: @*/
    1076: PetscErrorCode  PetscOptionsSetAlias(const char inewname[],const char ioldname[])
    1077: {
    1079:   PetscInt       n = options->Naliases;
    1080:   size_t         len;
    1081:   char           *newname = (char*)inewname,*oldname = (char*)ioldname;

    1084:   if (newname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliased must have -: Instead %s",newname);
    1085:   if (oldname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliasee must have -: Instead %s",oldname);
    1086:   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);

    1088:   newname++; oldname++;
    1089:   PetscStrlen(newname,&len);
    1090:   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
    1091:   PetscStrcpy(options->aliases1[n],newname);
    1092:   PetscStrlen(oldname,&len);
    1093:   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
    1094:   PetscStrcpy(options->aliases2[n],oldname);
    1095:   options->Naliases++;
    1096:   return(0);
    1097: }

    1101: PetscErrorCode PetscOptionsFindPair_Private(const char pre[],const char name[],char *value[],PetscBool  *flg)
    1102: {
    1104:   PetscInt       i,N;
    1105:   size_t         len;
    1106:   char           **names,tmp[256];
    1107:   PetscBool      match;

    1110:   if (!options) {PetscOptionsInsert(0,0,0);}
    1111:   N     = options->N;
    1112:   names = options->names;

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

    1116:   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
    1117:   if (pre) {
    1118:     char       *ptr   = tmp;
    1119:     const char *namep = name;
    1120:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
    1121:     if (name[1] == '-') {
    1122:       *ptr++ = '-';
    1123:       namep++;
    1124:     }
    1125:     PetscStrncpy(ptr,pre,tmp+sizeof(tmp)-ptr);
    1126:     tmp[sizeof(tmp)-1] = 0;
    1127:     PetscStrlen(tmp,&len);
    1128:     PetscStrncat(tmp,namep+1,sizeof(tmp)-len-1);
    1129:   } else {
    1130:     PetscStrncpy(tmp,name+1,sizeof(tmp));
    1131:     tmp[sizeof(tmp)-1] = 0;
    1132:   }
    1133: #if defined(PETSC_USE_DEBUG)
    1134:   {
    1135:     PetscBool valid;
    1136:     char      key[sizeof(tmp)+1] = "-";

    1138:     PetscMemcpy(key+1,tmp,sizeof(tmp));
    1139:     PetscOptionsValidKey(key,&valid);
    1140:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
    1141:   }
    1142: #endif

    1144:   /* slow search */
    1145:   *flg = PETSC_FALSE;
    1146:   for (i=0; i<N; i++) {
    1147:     PetscStrcasecmp(names[i],tmp,&match);
    1148:     if (match) {
    1149:       *value           = options->values[i];
    1150:       options->used[i] = PETSC_TRUE;
    1151:       *flg             = PETSC_TRUE;
    1152:       break;
    1153:     }
    1154:   }
    1155:   if (!*flg) {
    1156:     PetscInt j,cnt = 0,locs[16],loce[16];
    1157:     size_t   n;
    1158:     PetscStrlen(tmp,&n);
    1159:     /* determine the location and number of all _%d_ in the key */
    1160:     for (i=0; i< (PetscInt)n; i++) {
    1161:       if (tmp[i] == '_') {
    1162:         for (j=i+1; j< (PetscInt)n; j++) {
    1163:           if (tmp[j] >= '0' && tmp[j] <= '9') continue;
    1164:           if (tmp[j] == '_' && j > i+1) { /* found a number */
    1165:             locs[cnt]   = i+1;
    1166:             loce[cnt++] = j+1;
    1167:           }
    1168:           break;
    1169:         }
    1170:       }
    1171:     }
    1172:     if (cnt) {
    1173:       char tmp2[256];
    1174:       for (i=0; i<cnt; i++) {
    1175:         PetscStrcpy(tmp2,"-");
    1176:         PetscStrncat(tmp2,tmp,locs[i]);
    1177:         PetscStrcat(tmp2,tmp+loce[i]);
    1178:         PetscOptionsFindPair_Private(NULL,tmp2,value,flg);
    1179:         if (*flg) break;
    1180:       }
    1181:     }
    1182:   }
    1183:   return(0);
    1184: }

    1188: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(const char pre[], const char name[], char *value[], PetscBool *flg)
    1189: {
    1191:   PetscInt       i,N;
    1192:   size_t         len;
    1193:   char           **names,tmp[256];
    1194:   PetscBool      match;

    1197:   if (!options) {PetscOptionsInsert(0,0,0);}
    1198:   N     = options->N;
    1199:   names = options->names;

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

    1203:   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
    1204:   if (pre) {
    1205:     char       *ptr   = tmp;
    1206:     const char *namep = name;
    1207:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
    1208:     if (name[1] == '-') {
    1209:       *ptr++ = '-';
    1210:       namep++;
    1211:     }
    1212:     PetscStrncpy(ptr,pre,tmp+sizeof(tmp)-ptr);
    1213:     tmp[sizeof(tmp)-1] = 0;
    1214:     PetscStrlen(tmp,&len);
    1215:     PetscStrncat(tmp,namep+1,sizeof(tmp)-len-1);
    1216:   } else {
    1217:     PetscStrncpy(tmp,name+1,sizeof(tmp));
    1218:     tmp[sizeof(tmp)-1] = 0;
    1219:   }
    1220: #if defined(PETSC_USE_DEBUG)
    1221:   {
    1222:     PetscBool valid;
    1223:     char      key[sizeof(tmp)+1] = "-";

    1225:     PetscMemcpy(key+1,tmp,sizeof(tmp));
    1226:     PetscOptionsValidKey(key,&valid);
    1227:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
    1228:   }
    1229: #endif

    1231:   /* slow search */
    1232:   *flg = PETSC_FALSE;
    1233:   PetscStrlen(tmp,&len);
    1234:   for (i = 0; i < N; ++i) {
    1235:     PetscStrncmp(names[i], tmp, len, &match);
    1236:     if (match) {
    1237:       if (value) *value = options->values[i];
    1238:       options->used[i]  = PETSC_TRUE;
    1239:       if (flg)   *flg   = PETSC_TRUE;
    1240:       break;
    1241:     }
    1242:   }
    1243:   return(0);
    1244: }

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

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

    1254:    Input Parameters:
    1255: +  name - the option one is seeking
    1256: -  mess - error message (may be NULL)

    1258:    Level: advanced

    1260:    Concepts: options database^rejecting option

    1262: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
    1263:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1264:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1265:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1266:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1267:           PetscOptionsList(), PetscOptionsEList()
    1268: @*/
    1269: PetscErrorCode  PetscOptionsReject(const char name[],const char mess[])
    1270: {
    1272:   PetscBool      flag = PETSC_FALSE;

    1275:   PetscOptionsHasName(NULL,name,&flag);
    1276:   if (flag) {
    1277:     if (mess) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s with %s",name,mess);
    1278:     else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s",name);
    1279:   }
    1280:   return(0);
    1281: }

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

    1289:    Not Collective

    1291:    Input Parameters:
    1292: +  name - the option one is seeking
    1293: -  pre - string to prepend to the name or NULL

    1295:    Output Parameters:
    1296: .  set - PETSC_TRUE if found else PETSC_FALSE.

    1298:    Level: beginner

    1300:    Concepts: options database^has option name

    1302:    Notes: Name cannot be simply -h

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

    1306: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    1307:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1308:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1309:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1310:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1311:           PetscOptionsList(), PetscOptionsEList()
    1312: @*/
    1313: PetscErrorCode  PetscOptionsHasName(const char pre[],const char name[],PetscBool  *set)
    1314: {
    1315:   char           *value;
    1317:   PetscBool      flag;

    1320:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    1321:   if (set) *set = flag;
    1322:   return(0);
    1323: }

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

    1330:    Not Collective

    1332:    Input Parameters:
    1333: +  pre - the string to prepend to the name or NULL
    1334: -  name - the option one is seeking

    1336:    Output Parameter:
    1337: +  ivalue - the integer value to return
    1338: -  set - PETSC_TRUE if found, else PETSC_FALSE

    1340:    Level: beginner

    1342:    Concepts: options database^has int

    1344: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    1345:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    1346:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    1347:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1348:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1349:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1350:           PetscOptionsList(), PetscOptionsEList()
    1351: @*/
    1352: PetscErrorCode  PetscOptionsGetInt(const char pre[],const char name[],PetscInt *ivalue,PetscBool  *set)
    1353: {
    1354:   char           *value;
    1356:   PetscBool      flag;

    1361:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    1362:   if (flag) {
    1363:     if (!value) {
    1364:       if (set) *set = PETSC_FALSE;
    1365:     } else {
    1366:       if (set) *set = PETSC_TRUE;
    1367:       PetscOptionsStringToInt(value,ivalue);
    1368:     }
    1369:   } else {
    1370:     if (set) *set = PETSC_FALSE;
    1371:   }
    1372:   return(0);
    1373: }

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

    1380:    Not Collective

    1382:    Input Parameters:
    1383: +  pre - the string to prepend to the name or NULL
    1384: .  opt - option name
    1385: .  list - the possible choices
    1386: .  ntext - number of choices

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

    1392:    Level: intermediate

    1394:    See PetscOptionsList() for when the choices are given in a PetscFunctionList()

    1396:    Concepts: options database^list

    1398: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    1399:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1400:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1401:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1402:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1403:           PetscOptionsList(), PetscOptionsEList()
    1404: @*/
    1405: PetscErrorCode  PetscOptionsGetEList(const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool  *set)
    1406: {
    1408:   size_t         alen,len = 0;
    1409:   char           *svalue;
    1410:   PetscBool      aset,flg = PETSC_FALSE;
    1411:   PetscInt       i;

    1414:   for (i=0; i<ntext; i++) {
    1415:     PetscStrlen(list[i],&alen);
    1416:     if (alen > len) len = alen;
    1417:   }
    1418:   len += 5; /* a little extra space for user mistypes */
    1419:   PetscMalloc(len*sizeof(char),&svalue);
    1420:   PetscOptionsGetString(pre,opt,svalue,len,&aset);
    1421:   if (aset) {
    1422:     PetscEListFind(ntext,list,svalue,value,&flg);
    1423:     if (!flg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre ? pre : "",opt+1);
    1424:     if (set) *set = PETSC_TRUE;
    1425:   } else if (set) *set = PETSC_FALSE;
    1426:   PetscFree(svalue);
    1427:   return(0);
    1428: }

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

    1435:    Not Collective

    1437:    Input Parameters:
    1438: +  pre - option prefix or NULL
    1439: .  opt - option name
    1440: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
    1441: -  defaultv - the default (current) value

    1443:    Output Parameter:
    1444: +  value - the  value to return
    1445: -  set - PETSC_TRUE if found, else PETSC_FALSE

    1447:    Level: beginner

    1449:    Concepts: options database

    1451:    Notes: Must be between a PetscOptionsBegin() and a PetscOptionsEnd()

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

    1455: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
    1456:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    1457:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    1458:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1459:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1460:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1461:           PetscOptionsList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
    1462: @*/
    1463: PetscErrorCode  PetscOptionsGetEnum(const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool  *set)
    1464: {
    1466:   PetscInt       ntext = 0,tval;
    1467:   PetscBool      fset;

    1470:   while (list[ntext++]) {
    1471:     if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
    1472:   }
    1473:   if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
    1474:   ntext -= 3;
    1475:   PetscOptionsGetEList(pre,opt,list,ntext,&tval,&fset);
    1476:   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
    1477:   if (fset) *value = (PetscEnum)tval;
    1478:   if (set) *set = fset;
    1479:   return(0);
    1480: }

    1484: /*@C
    1485:    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
    1486:             option in the database.

    1488:    Not Collective

    1490:    Input Parameters:
    1491: +  pre - the string to prepend to the name or NULL
    1492: -  name - the option one is seeking

    1494:    Output Parameter:
    1495: +  ivalue - the logical value to return
    1496: -  set - PETSC_TRUE  if found, else PETSC_FALSE

    1498:    Level: beginner

    1500:    Notes:
    1501:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
    1502:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

    1504:        If the user does not supply the option (as either true or false) ivalue is NOT changed. Thus
    1505:      you NEED TO ALWAYS initialize the ivalue.

    1507:    Concepts: options database^has logical

    1509: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    1510:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
    1511:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1512:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1513:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1514:           PetscOptionsList(), PetscOptionsEList()
    1515: @*/
    1516: PetscErrorCode  PetscOptionsGetBool(const char pre[],const char name[],PetscBool  *ivalue,PetscBool  *set)
    1517: {
    1518:   char           *value;
    1519:   PetscBool      flag;

    1525:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    1526:   if (flag) {
    1527:     if (set) *set = PETSC_TRUE;
    1528:     if (!value) *ivalue = PETSC_TRUE;
    1529:     else {
    1530:       PetscOptionsStringToBool(value, ivalue);
    1531:     }
    1532:   } else {
    1533:     if (set) *set = PETSC_FALSE;
    1534:   }
    1535:   return(0);
    1536: }

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

    1545:    Not Collective

    1547:    Input Parameters:
    1548: +  pre - string to prepend to each name or NULL
    1549: .  name - the option one is seeking
    1550: -  nmax - maximum number of values to retrieve

    1552:    Output Parameter:
    1553: +  dvalue - the integer values to return
    1554: .  nmax - actual number of values retreived
    1555: -  set - PETSC_TRUE if found, else PETSC_FALSE

    1557:    Level: beginner

    1559:    Concepts: options database^array of ints

    1561:    Notes:
    1562:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
    1563:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

    1565: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    1566:            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1567:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1568:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1569:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1570:           PetscOptionsList(), PetscOptionsEList()
    1571: @*/
    1572: PetscErrorCode  PetscOptionsGetBoolArray(const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool  *set)
    1573: {
    1574:   char           *value;
    1576:   PetscInt       n = 0;
    1577:   PetscBool      flag;
    1578:   PetscToken     token;

    1583:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    1584:   if (!flag)  {if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    1585:   if (!value) {if (set) *set = PETSC_TRUE;  *nmax = 0; return(0);}

    1587:   if (set) *set = PETSC_TRUE;

    1589:   PetscTokenCreate(value,',',&token);
    1590:   PetscTokenFind(token,&value);
    1591:   while (n < *nmax) {
    1592:     if (!value) break;
    1593:     PetscOptionsStringToBool(value,dvalue);
    1594:     PetscTokenFind(token,&value);
    1595:     dvalue++;
    1596:     n++;
    1597:   }
    1598:   PetscTokenDestroy(&token);
    1599:   *nmax = n;
    1600:   return(0);
    1601: }

    1605: /*@C
    1606:    PetscOptionsGetReal - Gets the double precision value for a particular
    1607:    option in the database.

    1609:    Not Collective

    1611:    Input Parameters:
    1612: +  pre - string to prepend to each name or NULL
    1613: -  name - the option one is seeking

    1615:    Output Parameter:
    1616: +  dvalue - the double value to return
    1617: -  set - PETSC_TRUE if found, PETSC_FALSE if not found

    1619:    Note: if the option is given but no value is provided then set is given the value PETSC_FALSE

    1621:    Level: beginner

    1623:    Concepts: options database^has double

    1625: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    1626:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
    1627:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1628:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1629:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1630:           PetscOptionsList(), PetscOptionsEList()
    1631: @*/
    1632: PetscErrorCode  PetscOptionsGetReal(const char pre[],const char name[],PetscReal *dvalue,PetscBool  *set)
    1633: {
    1634:   char           *value;
    1636:   PetscBool      flag;

    1641:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    1642:   if (flag) {
    1643:     if (!value) {
    1644:       if (set) *set = PETSC_FALSE;
    1645:     } else {
    1646:       if (set) *set = PETSC_TRUE;
    1647:       PetscOptionsStringToReal(value,dvalue);
    1648:     }
    1649:   } else {
    1650:     if (set) *set = PETSC_FALSE;
    1651:   }
    1652:   return(0);
    1653: }

    1657: /*@C
    1658:    PetscOptionsGetScalar - Gets the scalar value for a particular
    1659:    option in the database.

    1661:    Not Collective

    1663:    Input Parameters:
    1664: +  pre - string to prepend to each name or NULL
    1665: -  name - the option one is seeking

    1667:    Output Parameter:
    1668: +  dvalue - the double value to return
    1669: -  set - PETSC_TRUE if found, else PETSC_FALSE

    1671:    Level: beginner

    1673:    Usage:
    1674:    A complex number 2+3i can be specified as 2,3 at the command line.
    1675:    or a number 2.0e-10 - 3.3e-20 i  can be specified as 2.0e-10,-3.3e-20

    1677:    Note: if the option is given but no value is provided then set is given the value PETSC_FALSE

    1679:    Concepts: options database^has scalar

    1681: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    1682:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1683:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1684:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1685:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1686:           PetscOptionsList(), PetscOptionsEList()
    1687: @*/
    1688: PetscErrorCode  PetscOptionsGetScalar(const char pre[],const char name[],PetscScalar *dvalue,PetscBool  *set)
    1689: {
    1690:   char           *value;
    1691:   PetscBool      flag;

    1697:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    1698:   if (flag) {
    1699:     if (!value) {
    1700:       if (set) *set = PETSC_FALSE;
    1701:     } else {
    1702: #if !defined(PETSC_USE_COMPLEX)
    1703:       PetscOptionsStringToReal(value,dvalue);
    1704: #else
    1705:       PetscReal  re=0.0,im=0.0;
    1706:       PetscToken token;
    1707:       char       *tvalue = 0;

    1709:       PetscTokenCreate(value,',',&token);
    1710:       PetscTokenFind(token,&tvalue);
    1711:       if (!tvalue) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"unknown string specified\n");
    1712:       PetscOptionsStringToReal(tvalue,&re);
    1713:       PetscTokenFind(token,&tvalue);
    1714:       if (!tvalue) *dvalue = re; /* Unknown separator used. using only real value */
    1715:       else {
    1716:         PetscOptionsStringToReal(tvalue,&im);
    1717:         *dvalue = re + PETSC_i*im;
    1718:       }
    1719:       PetscTokenDestroy(&token);
    1720: #endif
    1721:       if (set) *set = PETSC_TRUE;
    1722:     }
    1723:   } else { /* flag */
    1724:     if (set) *set = PETSC_FALSE;
    1725:   }
    1726:   return(0);
    1727: }

    1731: /*@C
    1732:    PetscOptionsGetRealArray - Gets an array of double precision values for a
    1733:    particular option in the database.  The values must be separated with
    1734:    commas with no intervening spaces.

    1736:    Not Collective

    1738:    Input Parameters:
    1739: +  pre - string to prepend to each name or NULL
    1740: .  name - the option one is seeking
    1741: -  nmax - maximum number of values to retrieve

    1743:    Output Parameters:
    1744: +  dvalue - the double value to return
    1745: .  nmax - actual number of values retreived
    1746: -  set - PETSC_TRUE if found, else PETSC_FALSE

    1748:    Level: beginner

    1750:    Concepts: options database^array of doubles

    1752: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    1753:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    1754:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1755:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1756:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1757:           PetscOptionsList(), PetscOptionsEList()
    1758: @*/
    1759: PetscErrorCode  PetscOptionsGetRealArray(const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool  *set)
    1760: {
    1761:   char           *value;
    1763:   PetscInt       n = 0;
    1764:   PetscBool      flag;
    1765:   PetscToken     token;

    1770:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    1771:   if (!flag) {
    1772:     if (set) *set = PETSC_FALSE;
    1773:     *nmax = 0;
    1774:     return(0);
    1775:   }
    1776:   if (!value) {
    1777:     if (set) *set = PETSC_TRUE;
    1778:     *nmax = 0;
    1779:     return(0);
    1780:   }

    1782:   if (set) *set = PETSC_TRUE;

    1784:   PetscTokenCreate(value,',',&token);
    1785:   PetscTokenFind(token,&value);
    1786:   while (n < *nmax) {
    1787:     if (!value) break;
    1788:     PetscOptionsStringToReal(value,dvalue++);
    1789:     PetscTokenFind(token,&value);
    1790:     n++;
    1791:   }
    1792:   PetscTokenDestroy(&token);
    1793:   *nmax = n;
    1794:   return(0);
    1795: }

    1799: /*@C
    1800:    PetscOptionsGetIntArray - Gets an array of integer values for a particular
    1801:    option in the database.

    1803:    Not Collective

    1805:    Input Parameters:
    1806: +  pre - string to prepend to each name or NULL
    1807: .  name - the option one is seeking
    1808: -  nmax - maximum number of values to retrieve

    1810:    Output Parameter:
    1811: +  dvalue - the integer values to return
    1812: .  nmax - actual number of values retreived
    1813: -  set - PETSC_TRUE if found, else PETSC_FALSE

    1815:    Level: beginner

    1817:    Notes:
    1818:    The array can be passed as
    1819:    a comma seperated list:                                 0,1,2,3,4,5,6,7
    1820:    a range (start-end+1):                                  0-8
    1821:    a range with given increment (start-end+1:inc):         0-7:2
    1822:    a combination of values and ranges seperated by commas: 0,1-8,8-15:2

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

    1826:    Concepts: options database^array of ints

    1828: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    1829:            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1830:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1831:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1832:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1833:           PetscOptionsList(), PetscOptionsEList()
    1834: @*/
    1835: PetscErrorCode  PetscOptionsGetIntArray(const char pre[],const char name[],PetscInt dvalue[],PetscInt *nmax,PetscBool  *set)
    1836: {
    1837:   char           *value;
    1839:   PetscInt       n = 0,i,j,start,end,inc,nvalues;
    1840:   size_t         len;
    1841:   PetscBool      flag,foundrange;
    1842:   PetscToken     token;

    1847:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    1848:   if (!flag) {
    1849:     if (set) *set = PETSC_FALSE;
    1850:     *nmax = 0;
    1851:     return(0);
    1852:   }
    1853:   if (!value) {
    1854:     if (set) *set = PETSC_TRUE;
    1855:     *nmax = 0;
    1856:     return(0);
    1857:   }

    1859:   if (set) *set = PETSC_TRUE;

    1861:   PetscTokenCreate(value,',',&token);
    1862:   PetscTokenFind(token,&value);
    1863:   while (n < *nmax) {
    1864:     if (!value) break;

    1866:     /* look for form  d-D where d and D are integers */
    1867:     foundrange = PETSC_FALSE;
    1868:     PetscStrlen(value,&len);
    1869:     if (value[0] == '-') i=2;
    1870:     else i=1;
    1871:     for (;i<(int)len; i++) {
    1872:       if (value[i] == '-') {
    1873:         if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
    1874:         value[i] = 0;

    1876:         PetscOptionsStringToInt(value,&start);
    1877:         inc  = 1;
    1878:         j    = i+1;
    1879:         for (;j<(int)len; j++) {
    1880:           if (value[j] == ':') {
    1881:             value[j] = 0;

    1883:             PetscOptionsStringToInt(value+j+1,&inc);
    1884:             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);
    1885:             break;
    1886:           }
    1887:         }
    1888:         PetscOptionsStringToInt(value+i+1,&end);
    1889:         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);
    1890:         nvalues = (end-start)/inc + (end-start)%inc;
    1891:         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);
    1892:         for (;start<end; start+=inc) {
    1893:           *dvalue = start; dvalue++;n++;
    1894:         }
    1895:         foundrange = PETSC_TRUE;
    1896:         break;
    1897:       }
    1898:     }
    1899:     if (!foundrange) {
    1900:       PetscOptionsStringToInt(value,dvalue);
    1901:       dvalue++;
    1902:       n++;
    1903:     }
    1904:     PetscTokenFind(token,&value);
    1905:   }
    1906:   PetscTokenDestroy(&token);
    1907:   *nmax = n;
    1908:   return(0);
    1909: }

    1913: /*@C
    1914:    PetscOptionsGetString - Gets the string value for a particular option in
    1915:    the database.

    1917:    Not Collective

    1919:    Input Parameters:
    1920: +  pre - string to prepend to name or NULL
    1921: .  name - the option one is seeking
    1922: -  len - maximum length of the string including null termination

    1924:    Output Parameters:
    1925: +  string - location to copy string
    1926: -  set - PETSC_TRUE if found, else PETSC_FALSE

    1928:    Level: beginner

    1930:    Fortran Note:
    1931:    The Fortran interface is slightly different from the C/C++
    1932:    interface (len is not used).  Sample usage in Fortran follows
    1933: .vb
    1934:       character *20 string
    1935:       integer   flg, ierr
    1936:       call PetscOptionsGetString(NULL_CHARACTER,'-s',string,flg,ierr)
    1937: .ve

    1939:    Notes: 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

    1941:    Concepts: options database^string

    1943:     Note:
    1944:       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).

    1946: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    1947:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1948:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1949:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1950:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1951:           PetscOptionsList(), PetscOptionsEList()
    1952: @*/
    1953: PetscErrorCode  PetscOptionsGetString(const char pre[],const char name[],char string[],size_t len,PetscBool  *set)
    1954: {
    1955:   char           *value;
    1957:   PetscBool      flag;

    1962:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    1963:   if (!flag) {
    1964:     if (set) *set = PETSC_FALSE;
    1965:   } else {
    1966:     if (set) *set = PETSC_TRUE;
    1967:     if (value) {
    1968:       PetscStrncpy(string,value,len);
    1969:       string[len-1] = 0;        /* Ensure that the string is NULL terminated */
    1970:     } else {
    1971:       PetscMemzero(string,len);
    1972:     }
    1973:   }
    1974:   return(0);
    1975: }

    1979: char *PetscOptionsGetStringMatlab(const char pre[],const char name[])
    1980: {
    1981:   char           *value;
    1983:   PetscBool      flag;

    1986:   PetscOptionsFindPair_Private(pre,name,&value,&flag);if (ierr) return(0);
    1987:   if (flag) PetscFunctionReturn(value);
    1988:   else return(0);
    1989: }

    1994: /*@C
    1995:    PetscOptionsGetStringArray - Gets an array of string values for a particular
    1996:    option in the database. The values must be separated with commas with
    1997:    no intervening spaces.

    1999:    Not Collective

    2001:    Input Parameters:
    2002: +  pre - string to prepend to name or NULL
    2003: .  name - the option one is seeking
    2004: -  nmax - maximum number of strings

    2006:    Output Parameter:
    2007: +  strings - location to copy strings
    2008: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2010:    Level: beginner

    2012:    Notes:
    2013:    The user should pass in an array of pointers to char, to hold all the
    2014:    strings returned by this function.

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

    2019:    Contributed by Matthew Knepley.

    2021:    Concepts: options database^array of strings

    2023: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    2024:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2025:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2026:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2027:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2028:           PetscOptionsList(), PetscOptionsEList()
    2029: @*/
    2030: PetscErrorCode  PetscOptionsGetStringArray(const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool  *set)
    2031: {
    2032:   char           *value;
    2034:   PetscInt       n;
    2035:   PetscBool      flag;
    2036:   PetscToken     token;

    2041:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
    2042:   if (!flag) {
    2043:     *nmax = 0;
    2044:     if (set) *set = PETSC_FALSE;
    2045:     return(0);
    2046:   }
    2047:   if (!value) {
    2048:     *nmax = 0;
    2049:     if (set) *set = PETSC_FALSE;
    2050:     return(0);
    2051:   }
    2052:   if (!*nmax) {
    2053:     if (set) *set = PETSC_FALSE;
    2054:     return(0);
    2055:   }
    2056:   if (set) *set = PETSC_TRUE;

    2058:   PetscTokenCreate(value,',',&token);
    2059:   PetscTokenFind(token,&value);
    2060:   n    = 0;
    2061:   while (n < *nmax) {
    2062:     if (!value) break;
    2063:     PetscStrallocpy(value,&strings[n]);
    2064:     PetscTokenFind(token,&value);
    2065:     n++;
    2066:   }
    2067:   PetscTokenDestroy(&token);
    2068:   *nmax = n;
    2069:   return(0);
    2070: }

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

    2077:    Not Collective

    2079:    Input Parameter:
    2080: .    option - string name of option

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

    2085:    Level: advanced

    2087: .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
    2088: @*/
    2089: PetscErrorCode  PetscOptionsUsed(const char *option,PetscBool *used)
    2090: {
    2091:   PetscInt       i;

    2095:   *used = PETSC_FALSE;
    2096:   for (i=0; i<options->N; i++) {
    2097:     PetscStrcmp(options->names[i],option,used);
    2098:     if (*used) {
    2099:       *used = options->used[i];
    2100:       break;
    2101:     }
    2102:   }
    2103:   return(0);
    2104: }

    2108: /*@C
    2109:    PetscOptionsAllUsed - Returns a count of the number of options in the
    2110:    database that have never been selected.

    2112:    Not Collective

    2114:    Output Parameter:
    2115: .   N - count of options not used

    2117:    Level: advanced

    2119: .seealso: PetscOptionsView()
    2120: @*/
    2121: PetscErrorCode  PetscOptionsAllUsed(PetscInt *N)
    2122: {
    2123:   PetscInt i,n = 0;

    2126:   for (i=0; i<options->N; i++) {
    2127:     if (!options->used[i]) n++;
    2128:   }
    2129:   *N = n;
    2130:   return(0);
    2131: }

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

    2138:   Not collective

    2140:    Options Database Key:
    2141: .  -options_left - Activates OptionsAllUsed() within PetscFinalize()

    2143:   Level: advanced

    2145: .seealso: PetscOptionsAllUsed()
    2146: @*/
    2147: PetscErrorCode  PetscOptionsLeft(void)
    2148: {
    2150:   PetscInt       i;

    2153:   for (i=0; i<options->N; i++) {
    2154:     if (!options->used[i]) {
    2155:       if (options->values[i]) {
    2156:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",options->names[i],options->values[i]);
    2157:       } else {
    2158:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",options->names[i]);
    2159:       }
    2160:     }
    2161:   }
    2162:   return(0);
    2163: }

    2168: /*
    2169:     PetscOptionsCreate - Creates the empty options database.

    2171: */
    2172: PetscErrorCode  PetscOptionsCreate(void)
    2173: {

    2177:   options = (PetscOptionsTable*)malloc(sizeof(PetscOptionsTable));
    2178:   PetscMemzero(options,sizeof(PetscOptionsTable));

    2180:   options->namegiven      = PETSC_FALSE;
    2181:   options->N              = 0;
    2182:   options->Naliases       = 0;
    2183:   options->numbermonitors = 0;

    2185:   PetscOptionsObject.prefix = NULL;
    2186:   PetscOptionsObject.title  = NULL;
    2187:   return(0);
    2188: }

    2192: /*@
    2193:    PetscOptionsSetFromOptions - Sets various SNES and KSP parameters from user options.

    2195:    Collective on PETSC_COMM_WORLD

    2197:    Options Database Keys:
    2198: +  -options_monitor <optional filename> - prints the names and values of all runtime options as they are set. The monitor functionality is not
    2199:                 available for options set through a file, environment variable, or on
    2200:                 the command line. Only options set after PetscInitialize completes will
    2201:                 be monitored.
    2202: .  -options_monitor_cancel - cancel all options database monitors

    2204:    Notes:
    2205:    To see all options, run your program with the -help option or consult
    2206:    the <A href="../../docs/manual.pdf">users manual</A>..

    2208:    Level: intermediate

    2210: .keywords: set, options, database
    2211: @*/
    2212: PetscErrorCode  PetscOptionsSetFromOptions(void)
    2213: {
    2214:   PetscBool      flgc,flgm;
    2216:   char           monfilename[PETSC_MAX_PATH_LEN];
    2217:   PetscViewer    monviewer;

    2220:   PetscOptionsBegin(PETSC_COMM_WORLD,"","Options database options","PetscOptions");
    2221:   PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);
    2222:   PetscOptionsBool("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",PETSC_FALSE,&flgc,NULL);
    2223:   PetscOptionsEnd();
    2224:   if (flgm) {
    2225:     PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);
    2226:     PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    2227:   }
    2228:   if (flgc) { PetscOptionsMonitorCancel(); }
    2229:   return(0);
    2230: }

    2235: /*@C
    2236:    PetscOptionsMonitorDefault - Print all options set value events.

    2238:    Logically Collective on PETSC_COMM_WORLD

    2240:    Input Parameters:
    2241: +  name  - option name string
    2242: .  value - option value string
    2243: -  dummy - unused monitor context

    2245:    Level: intermediate

    2247: .keywords: PetscOptions, default, monitor

    2249: .seealso: PetscOptionsMonitorSet()
    2250: @*/
    2251: PetscErrorCode  PetscOptionsMonitorDefault(const char name[], const char value[], void *dummy)
    2252: {
    2254:   PetscViewer    viewer = (PetscViewer) dummy;

    2257:   if (!viewer) {
    2258:     PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);
    2259:   }
    2260:   PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
    2261:   return(0);
    2262: }

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

    2270:    Not collective

    2272:    Input Parameters:
    2273: +  monitor - pointer to function (if this is NULL, it turns off monitoring
    2274: .  mctx    - [optional] context for private data for the
    2275:              monitor routine (use NULL if no context is desired)
    2276: -  monitordestroy - [optional] routine that frees monitor context
    2277:           (may be NULL)

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

    2282: +  name - option name string
    2283: .  value - option value string
    2284: -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()

    2286:    Options Database Keys:
    2287: +    -options_monitor    - sets PetscOptionsMonitorDefault()
    2288: -    -options_monitor_cancel - cancels all monitors that have
    2289:                           been hardwired into a code by
    2290:                           calls to PetscOptionsMonitorSet(), but
    2291:                           does not cancel those set via
    2292:                           the options database.

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

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

    2303:    Level: beginner

    2305: .keywords: PetscOptions, set, monitor

    2307: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
    2308: @*/
    2309: PetscErrorCode  PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
    2310: {
    2312:   if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
    2313:   options->monitor[options->numbermonitors]          = monitor;
    2314:   options->monitordestroy[options->numbermonitors]   = monitordestroy;
    2315:   options->monitorcontext[options->numbermonitors++] = (void*)mctx;
    2316:   return(0);
    2317: }

    2321: /*@
    2322:    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.

    2324:    Not collective

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

    2331:    Level: intermediate

    2333: .keywords: PetscOptions, set, monitor

    2335: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
    2336: @*/
    2337: PetscErrorCode  PetscOptionsMonitorCancel(void)
    2338: {
    2340:   PetscInt       i;

    2343:   for (i=0; i<options->numbermonitors; i++) {
    2344:     if (options->monitordestroy[i]) {
    2345:       (*options->monitordestroy[i])(&options->monitorcontext[i]);
    2346:     }
    2347:   }
    2348:   options->numbermonitors = 0;
    2349:   return(0);
    2350: }