Actual source code: options.c
petsc-3.13.6 2020-09-29
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_STRINGS_H)
     19: #  include <strings.h>          /* strcasecmp */
     20: #endif
     21: #if defined(PETSC_HAVE_YAML)
     22: #include <yaml.h>
     23: #endif

     25: #if defined(PETSC_HAVE_STRCASECMP)
     26: #define PetscOptNameCmp(a,b) strcasecmp(a,b)
     27: #elif defined(PETSC_HAVE_STRICMP)
     28: #define PetscOptNameCmp(a,b) stricmp(a,b)
     29: #else
     30: #define PetscOptNameCmp(a,b) Error_strcasecmp_not_found
     31: #endif

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

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

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

     57: PETSC_STATIC_INLINE int PetscOptEqual(const char a[],const char b[])
     58: {
     59:   return !PetscOptNameCmp(a,b);
     60: }

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

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

     73: struct  _n_PetscOptions {
     74:   PetscOptions   previous;
     75:   int            N;                    /* number of options */
     76:   char           *names[MAXOPTIONS];   /* option names */
     77:   char           *values[MAXOPTIONS];  /* option values */
     78:   PetscBool      used[MAXOPTIONS];     /* flag option use */

     80:   /* Hash table */
     81:   khash_t(HO)    *ht;

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

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

     93:   /* Help */
     94:   PetscBool      help; /* flag whether "-help" is in the database */

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

    103: static PetscOptions defaultoptions = NULL;  /* the options database routines query this object for options */

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

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

    121: /*@
    122:    PetscOptionsCreate - Creates an empty options database.

    124:    Logically collective

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

    129:    Level: advanced

    131:    Developer Note: We may want eventually to pass a MPI_Comm to determine the ownership of the object

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

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

    146:     Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()

    148:   Input Parameter:
    149: .  options - the PetscOptions object

    151:    Level: advanced

    153: .seealso: PetscOptionsInsert(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsInsert(), PetscOptionsSetValue()
    154: @*/
    155: PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
    156: {

    159:   if (!*options) return 0;
    160:   if ((*options)->previous) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"You are destroying an option that has been used with PetscOptionsPush() but does not have a corresponding PetscOptionsPop()");
    161:   PetscOptionsClear(*options);if (ierr) return ierr;
    162:   /* XXX what about monitors ? */
    163:   free(*options);
    164:   *options = NULL;
    165:   return(0);
    166: }

    168: /*
    169:     PetscOptionsCreateDefault - Creates the default global options database
    170: */
    171: PetscErrorCode PetscOptionsCreateDefault(void)
    172: {

    175:   if (!defaultoptions) {
    176:     PetscOptionsCreate(&defaultoptions);if (ierr) return ierr;
    177:   }
    178:   return 0;
    179: }

    181: /*@
    182:       PetscOptionsPush - Push a new PetscOptions object as the default provider of options
    183:                          Allows using different parts of a code to use different options databases

    185:   Logically Collective

    187:   Input Parameter:
    188: .   opt - the options obtained with PetscOptionsCreate()

    190:   Notes:
    191:   Use PetscOptionsPop() to return to the previous default options database

    193:   The collectivity of this routine is complex; only the MPI processes that call this routine will
    194:   have the affect of these options. If some processes that create objects call this routine and others do
    195:   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
    196:   on different ranks.

    198:    Level: advanced

    200: .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsInsert(), PetscOptionsSetValue(), PetscOptionsLeft()

    202: @*/
    203: PetscErrorCode PetscOptionsPush(PetscOptions opt)
    204: {

    208:   if (!defaultoptions) {
    209:     PetscOptionsCreateDefault();
    210:   }
    211:   opt->previous        = defaultoptions;
    212:   defaultoptions       = opt;
    213:   return(0);
    214: }

    216: /*@
    217:       PetscOptionsPop - Pop the most recent PetscOptionsPush() to return to the previous default options

    219:       Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()

    221:   Notes:
    222:   Use PetscOptionsPop() to return to the previous default options database
    223:   Allows using different parts of a code to use different options databases

    225:    Level: advanced

    227: .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsInsert(), PetscOptionsSetValue(), PetscOptionsLeft()

    229: @*/
    230: PetscErrorCode PetscOptionsPop(void)
    231: {
    232:   PetscOptions current = defaultoptions;

    235:   if (!defaultoptions) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing default options");
    236:   if (!defaultoptions->previous) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PetscOptionsPop() called too many times");
    237:   defaultoptions = defaultoptions->previous;
    238:   current->previous    = NULL;
    239:   return(0);
    240: }

    242: /*
    243:     PetscOptionsDestroyDefault - Destroys the default global options database
    244: */
    245: PetscErrorCode PetscOptionsDestroyDefault(void)
    246: {
    248:   PetscOptions   tmp;

    250:   /* Destroy any options that the user forgot to pop */
    251:   while (defaultoptions->previous) {
    252:     tmp = defaultoptions;
    253:     PetscOptionsPop();
    254:     PetscOptionsDestroy(&tmp);
    255:   }
    256:   PetscOptionsDestroy(&defaultoptions);if (ierr) return ierr;
    257:   return 0;
    258: }

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

    263:    Not collective

    265:    Input Parameter:
    266: .  key - string to check if valid

    268:    Output Parameter:
    269: .  valid - PETSC_TRUE if a valid key

    271:    Level: intermediate
    272: @*/
    273: PetscErrorCode PetscOptionsValidKey(const char key[],PetscBool *valid)
    274: {
    275:   char           *ptr;

    280:   *valid = PETSC_FALSE;
    281:   if (!key) return(0);
    282:   if (key[0] != '-') return(0);
    283:   if (key[1] == '-') key++;
    284:   if (!isalpha((int)key[1])) return(0);
    285:   (void) strtod(key,&ptr);
    286:   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) return(0);
    287:   *valid = PETSC_TRUE;
    288:   return(0);
    289: }

    291: /*@C
    292:    PetscOptionsInsertString - Inserts options into the database from a string

    294:    Logically Collective

    296:    Input Parameter:
    297: .  in_str - string that contains options separated by blanks

    299:    Level: intermediate

    301:   The collectivity of this routine is complex; only the MPI processes that call this routine will
    302:   have the affect of these options. If some processes that create objects call this routine and others do
    303:   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
    304:   on different ranks.

    306:    Contributed by Boyana Norris

    308: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
    309:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    310:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    311:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    312:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    313:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile()
    314: @*/
    315: PetscErrorCode PetscOptionsInsertString(PetscOptions options,const char in_str[])
    316: {
    317:   char           *first,*second;
    319:   PetscToken     token;
    320:   PetscBool      key,ispush,ispop,isopts;

    323:   PetscTokenCreate(in_str,' ',&token);
    324:   PetscTokenFind(token,&first);
    325:   while (first) {
    326:     PetscStrcasecmp(first,"-prefix_push",&ispush);
    327:     PetscStrcasecmp(first,"-prefix_pop",&ispop);
    328:     PetscStrcasecmp(first,"-options_file",&isopts);
    329:     PetscOptionsValidKey(first,&key);
    330:     if (ispush) {
    331:       PetscTokenFind(token,&second);
    332:       PetscOptionsPrefixPush(options,second);
    333:       PetscTokenFind(token,&first);
    334:     } else if (ispop) {
    335:       PetscOptionsPrefixPop(options);
    336:       PetscTokenFind(token,&first);
    337:     } else if (isopts) {
    338:       PetscTokenFind(token,&second);
    339:       PetscOptionsInsertFile(PETSC_COMM_SELF,options,second,PETSC_TRUE);
    340:       PetscTokenFind(token,&first);
    341:     } else if (key) {
    342:       PetscTokenFind(token,&second);
    343:       PetscOptionsValidKey(second,&key);
    344:       if (!key) {
    345:         PetscOptionsSetValue(options,first,second);
    346:         PetscTokenFind(token,&first);
    347:       } else {
    348:         PetscOptionsSetValue(options,first,NULL);
    349:         first = second;
    350:       }
    351:     } else {
    352:       PetscTokenFind(token,&first);
    353:     }
    354:   }
    355:   PetscTokenDestroy(&token);
    356:   return(0);
    357: }

    359: /*
    360:     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
    361: */
    362: static char *Petscgetline(FILE * f)
    363: {
    364:   size_t size  = 0;
    365:   size_t len   = 0;
    366:   size_t last  = 0;
    367:   char   *buf  = NULL;

    369:   if (feof(f)) return NULL;
    370:   do {
    371:     size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
    372:     buf   = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
    373:     /* Actually do the read. Note that fgets puts a terminal '\0' on the
    374:     end of the string, so we make sure we overwrite this */
    375:     if (!fgets(buf+len,1024,f)) buf[len]=0;
    376:     PetscStrlen(buf,&len);
    377:     last = len - 1;
    378:   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
    379:   if (len) return buf;
    380:   free(buf);
    381:   return NULL;
    382: }

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

    387:      Collective

    389:   Input Parameter:
    390: +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
    391: .   options - options database, use NULL for default global database
    392: .   file - name of file
    393: -   require - if PETSC_TRUE will generate an error if the file does not exist

    396:   Notes:
    397:     Use  # for lines that are comments and which should be ignored.
    398:     Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
    399:    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
    400:    calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().
    401:    The collectivity of this routine is complex; only the MPI processes in comm will
    402:    have the affect of these options. If some processes that create objects call this routine and others do
    403:    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
    404:    on different ranks.

    406:   Level: developer

    408: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
    409:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    410:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    411:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    412:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    413:           PetscOptionsFList(), PetscOptionsEList()

    415: @*/
    416: PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
    417: {
    418:   char           *string,fname[PETSC_MAX_PATH_LEN],*first,*second,*third,*vstring = NULL,*astring = NULL,*packed = NULL;
    420:   size_t         i,len,bytes;
    421:   FILE           *fd;
    422:   PetscToken     token;
    423:   int            err;
    424:   char           cmt[1]={'#'},*cmatch;
    425:   PetscMPIInt    rank,cnt=0,acnt=0,counts[2];
    426:   PetscBool      isdir;

    429:   MPI_Comm_rank(comm,&rank);
    430:   if (!rank) {
    431:     cnt        = 0;
    432:     acnt       = 0;

    434:     PetscFixFilename(file,fname);
    435:     fd   = fopen(fname,"r");
    436:     PetscTestDirectory(fname,'r',&isdir);
    437:     if (isdir && require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Specified options file %s is a directory",fname);
    438:     if (fd && !isdir) {
    439:       PetscSegBuffer vseg,aseg;
    440:       PetscSegBufferCreate(1,4000,&vseg);
    441:       PetscSegBufferCreate(1,2000,&aseg);

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

    446:       while ((string = Petscgetline(fd))) {
    447:         /* eliminate comments from each line */
    448:         for (i=0; i<1; i++) {
    449:           PetscStrchr(string,cmt[i],&cmatch);
    450:           if (cmatch) *cmatch = 0;
    451:         }
    452:         PetscStrlen(string,&len);
    453:         /* replace tabs, ^M, \n with " " */
    454:         for (i=0; i<len; i++) {
    455:           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
    456:             string[i] = ' ';
    457:           }
    458:         }
    459:         PetscTokenCreate(string,' ',&token);
    460:         PetscTokenFind(token,&first);
    461:         if (!first) {
    462:           goto destroy;
    463:         } else if (!first[0]) { /* if first token is empty spaces, redo first token */
    464:           PetscTokenFind(token,&first);
    465:         }
    466:         PetscTokenFind(token,&second);
    467:         if (!first) {
    468:           goto destroy;
    469:         } else if (first[0] == '-') {
    470:           PetscStrlen(first,&len);
    471:           PetscSegBufferGet(vseg,len+1,&vstring);
    472:           PetscArraycpy(vstring,first,len);
    473:           vstring[len] = ' ';
    474:           if (second) {
    475:             PetscStrlen(second,&len);
    476:             PetscSegBufferGet(vseg,len+3,&vstring);
    477:             vstring[0] = '"';
    478:             PetscArraycpy(vstring+1,second,len);
    479:             vstring[len+1] = '"';
    480:             vstring[len+2] = ' ';
    481:           }
    482:         } else {
    483:           PetscBool match;

    485:           PetscStrcasecmp(first,"alias",&match);
    486:           if (match) {
    487:             PetscTokenFind(token,&third);
    488:             if (!third) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file:alias missing (%s)",second);
    489:             PetscStrlen(second,&len);
    490:             PetscSegBufferGet(aseg,len+1,&astring);
    491:             PetscArraycpy(astring,second,len);
    492:             astring[len] = ' ';

    494:             PetscStrlen(third,&len);
    495:             PetscSegBufferGet(aseg,len+1,&astring);
    496:             PetscArraycpy(astring,third,len);
    497:             astring[len] = ' ';
    498:           } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown statement in options file: (%s)",string);
    499:         }
    500: destroy:
    501:         free(string);
    502:         PetscTokenDestroy(&token);
    503:       }
    504:       err = fclose(fd);
    505:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
    506:       PetscSegBufferGetSize(aseg,&bytes); /* size without null termination */
    507:       PetscMPIIntCast(bytes,&acnt);
    508:       PetscSegBufferGet(aseg,1,&astring);
    509:       astring[0] = 0;
    510:       PetscSegBufferGetSize(vseg,&bytes); /* size without null termination */
    511:       PetscMPIIntCast(bytes,&cnt);
    512:       PetscSegBufferGet(vseg,1,&vstring);
    513:       vstring[0] = 0;
    514:       PetscMalloc1(2+acnt+cnt,&packed);
    515:       PetscSegBufferExtractTo(aseg,packed);
    516:       PetscSegBufferExtractTo(vseg,packed+acnt+1);
    517:       PetscSegBufferDestroy(&aseg);
    518:       PetscSegBufferDestroy(&vseg);
    519:     } else if (require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open Options File %s",fname);
    520:   }

    522:   counts[0] = acnt;
    523:   counts[1] = cnt;
    524:   MPI_Bcast(counts,2,MPI_INT,0,comm);
    525:   acnt = counts[0];
    526:   cnt = counts[1];
    527:   if (rank) {
    528:     PetscMalloc1(2+acnt+cnt,&packed);
    529:   }
    530:   if (acnt || cnt) {
    531:     MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm);
    532:     astring = packed;
    533:     vstring = packed + acnt + 1;
    534:   }

    536:   if (acnt) {
    537:     PetscToken token;
    538:     char       *first,*second;

    540:     PetscTokenCreate(astring,' ',&token);
    541:     PetscTokenFind(token,&first);
    542:     while (first) {
    543:       PetscTokenFind(token,&second);
    544:       PetscOptionsSetAlias(options,first,second);
    545:       PetscTokenFind(token,&first);
    546:     }
    547:     PetscTokenDestroy(&token);
    548:   }

    550:   if (cnt) {
    551:     PetscOptionsInsertString(options,vstring);
    552:   }
    553:   PetscFree(packed);
    554:   return(0);
    555: }

    557: static PetscErrorCode PetscOptionsInsertArgs(PetscOptions options,int argc,char *args[])
    558: {
    560:   int            left    = argc - 1;
    561:   char           **eargs = args + 1;

    564:   while (left) {
    565:     PetscBool isoptions_file,isprefixpush,isprefixpop,isp4,tisp4,isp4yourname,isp4rmrank,key;
    566:     PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);
    567:     PetscStrcasecmp(eargs[0],"-prefix_push",&isprefixpush);
    568:     PetscStrcasecmp(eargs[0],"-prefix_pop",&isprefixpop);
    569:     PetscStrcasecmp(eargs[0],"-p4pg",&isp4);
    570:     PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);
    571:     PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);
    572:     PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);
    573:     isp4 = (PetscBool) (isp4 || tisp4);
    574:     PetscStrcasecmp(eargs[0],"-np",&tisp4);
    575:     isp4 = (PetscBool) (isp4 || tisp4);
    576:     PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);
    577:     PetscOptionsValidKey(eargs[0],&key);

    579:     if (!key) {
    580:       eargs++; left--;
    581:     } else if (isoptions_file) {
    582:       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
    583:       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
    584:       PetscOptionsInsertFile(PETSC_COMM_WORLD,options,eargs[1],PETSC_TRUE);
    585:       eargs += 2; left -= 2;
    586:     } else if (isprefixpush) {
    587:       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
    588:       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
    589:       PetscOptionsPrefixPush(options,eargs[1]);
    590:       eargs += 2; left -= 2;
    591:     } else if (isprefixpop) {
    592:       PetscOptionsPrefixPop(options);
    593:       eargs++; left--;

    595:       /*
    596:        These are "bad" options that MPICH, etc put on the command line
    597:        we strip them out here.
    598:        */
    599:     } else if (tisp4 || isp4rmrank) {
    600:       eargs += 1; left -= 1;
    601:     } else if (isp4 || isp4yourname) {
    602:       eargs += 2; left -= 2;
    603:     } else {
    604:       PetscBool nextiskey = PETSC_FALSE;
    605:       if (left >= 2) {PetscOptionsValidKey(eargs[1],&nextiskey);}
    606:       if (left < 2 || nextiskey) {
    607:         PetscOptionsSetValue(options,eargs[0],NULL);
    608:         eargs++; left--;
    609:       } else {
    610:         PetscOptionsSetValue(options,eargs[0],eargs[1]);
    611:         eargs += 2; left -= 2;
    612:       }
    613:     }
    614:   }
    615:   return(0);
    616: }

    619: /*@C
    620:    PetscOptionsInsert - Inserts into the options database from the command line,
    621:                         the environmental variable and a file.

    623:    Collective on PETSC_COMM_WORLD

    625:    Input Parameters:
    626: +  options - options database or NULL for the default global database
    627: .  argc - count of number of command line arguments
    628: .  args - the command line arguments
    629: -  file - optional filename, defaults to ~username/.petscrc

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

    636:    Options Database Keys:
    637: +   -options_monitor <optional filename> - print options names and values as they are set
    638: -   -options_file <filename> - read options from a file

    640:    Level: advanced

    642: .seealso: PetscOptionsDestroy(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
    643:           PetscInitialize()
    644: @*/
    645: PetscErrorCode PetscOptionsInsert(PetscOptions options,int *argc,char ***args,const char file[])
    646: {
    648:   PetscMPIInt    rank;
    649:   char           filename[PETSC_MAX_PATH_LEN];
    650:   PetscBool      flag = PETSC_FALSE;

    654:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

    656:   if (file && file[0]) {
    657:     PetscStrreplace(PETSC_COMM_WORLD,file,filename,PETSC_MAX_PATH_LEN);
    658:     PetscOptionsInsertFile(PETSC_COMM_WORLD,options,filename,PETSC_TRUE);
    659:   }
    660:   /*
    661:      We want to be able to give -skip_petscrc on the command line, but need to parse it first.  Since the command line
    662:      should take precedence, we insert it twice.  It would be sufficient to just scan for -skip_petscrc.
    663:   */
    664:   if (argc && args && *argc) {PetscOptionsInsertArgs(options,*argc,*args);}
    665:   PetscOptionsGetBool(NULL,NULL,"-skip_petscrc",&flag,NULL);
    666:   if (!flag) {
    667:     PetscGetHomeDirectory(filename,PETSC_MAX_PATH_LEN-16);
    668:     /* PetscOptionsInsertFile() does a fopen() on rank0 only - so only rank0 HomeDir value is relavent */
    669:     if (filename[0]) { PetscStrcat(filename,"/.petscrc"); }
    670:     PetscOptionsInsertFile(PETSC_COMM_WORLD,options,filename,PETSC_FALSE);
    671:     PetscOptionsInsertFile(PETSC_COMM_WORLD,options,".petscrc",PETSC_FALSE);
    672:     PetscOptionsInsertFile(PETSC_COMM_WORLD,options,"petscrc",PETSC_FALSE);
    673:   }

    675:   /* insert environment options */
    676:   {
    677:     char   *eoptions = NULL;
    678:     size_t len       = 0;
    679:     if (!rank) {
    680:       eoptions = (char*)getenv("PETSC_OPTIONS");
    681:       PetscStrlen(eoptions,&len);
    682:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
    683:     } else {
    684:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
    685:       if (len) {
    686:         PetscMalloc1(len+1,&eoptions);
    687:       }
    688:     }
    689:     if (len) {
    690:       MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
    691:       if (rank) eoptions[len] = 0;
    692:       PetscOptionsInsertString(options,eoptions);
    693:       if (rank) {PetscFree(eoptions);}
    694:     }
    695:   }

    697: #if defined(PETSC_HAVE_YAML)
    698:   {
    699:     char      yaml_file[PETSC_MAX_PATH_LEN];
    700:     PetscBool yaml_flg;
    701:     PetscOptionsGetString(NULL,NULL,"-options_file_yaml",yaml_file,PETSC_MAX_PATH_LEN,&yaml_flg);
    702:     if (yaml_flg) {
    703:       PetscOptionsInsertFileYAML(PETSC_COMM_WORLD,yaml_file,PETSC_TRUE);
    704:     }
    705:   }
    706: #endif

    708:   /* insert command line options again because they take precedence over arguments in petscrc/environment */
    709:   if (argc && args && *argc) {PetscOptionsInsertArgs(options,*argc,*args);}
    710:   return(0);
    711: }

    713: /*@C
    714:    PetscOptionsView - Prints the options that have been loaded. This is
    715:    useful for debugging purposes.

    717:    Logically Collective on PetscViewer

    719:    Input Parameter:
    720: +  options - options database, use NULL for default global database
    721: -  viewer - must be an PETSCVIEWERASCII viewer

    723:    Options Database Key:
    724: .  -options_view - Activates PetscOptionsView() within PetscFinalize()

    726:    Notes:
    727:    Only the rank zero process of MPI_Comm used to create view prints the option values. Other processes
    728:    may have different values but they are not printed.

    730:    Level: advanced

    732: .seealso: PetscOptionsAllUsed()
    733: @*/
    734: PetscErrorCode PetscOptionsView(PetscOptions options,PetscViewer viewer)
    735: {
    737:   PetscInt       i;
    738:   PetscBool      isascii;

    742:   options = options ? options : defaultoptions;
    743:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
    744:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    745:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");

    747:   if (!options->N) {
    748:     PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");
    749:     return(0);
    750:   }

    752:   PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");
    753:   for (i=0; i<options->N; i++) {
    754:     if (options->values[i]) {
    755:       PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);
    756:     } else {
    757:       PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);
    758:     }
    759:   }
    760:   PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");
    761:   return(0);
    762: }

    764: /*
    765:    Called by error handlers to print options used in run
    766: */
    767: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
    768: {
    769:   PetscInt     i;
    770:   PetscOptions options = defaultoptions;

    773:   if (options->N) {
    774:     (*PetscErrorPrintf)("PETSc Option Table entries:\n");
    775:   } else {
    776:     (*PetscErrorPrintf)("No PETSc Option Table entries\n");
    777:   }
    778:   for (i=0; i<options->N; i++) {
    779:     if (options->values[i]) {
    780:       (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]);
    781:     } else {
    782:       (*PetscErrorPrintf)("-%s\n",options->names[i]);
    783:     }
    784:   }
    785:   return(0);
    786: }

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

    791:    Logically Collective

    793:    Input Parameter:
    794: +  options - options database, or NULL for the default global database
    795: -  prefix - The string to append to the existing prefix

    797:    Options Database Keys:
    798: +   -prefix_push <some_prefix_> - push the given prefix
    799: -   -prefix_pop - pop the last prefix

    801:    Notes:
    802:    It is common to use this in conjunction with -options_file as in

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

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

    808:    The collectivity of this routine is complex; only the MPI processes that call this routine will
    809:    have the affect of these options. If some processes that create objects call this routine and others do
    810:    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
    811:    on different ranks.

    813: Level: advanced

    815: .seealso: PetscOptionsPrefixPop(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue()
    816: @*/
    817: PetscErrorCode PetscOptionsPrefixPush(PetscOptions options,const char prefix[])
    818: {
    820:   size_t         n;
    821:   PetscInt       start;
    822:   char           key[MAXOPTNAME+1];
    823:   PetscBool      valid;

    827:   options = options ? options : defaultoptions;
    828:   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);
    829:   key[0] = '-'; /* keys must start with '-' */
    830:   PetscStrncpy(key+1,prefix,sizeof(key)-1);
    831:   PetscOptionsValidKey(key,&valid);
    832:   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);
    833:   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
    834:   PetscStrlen(prefix,&n);
    835:   if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
    836:   PetscArraycpy(options->prefix+start,prefix,n+1);
    837:   options->prefixstack[options->prefixind++] = start+n;
    838:   return(0);
    839: }

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

    844:    Logically Collective on the MPI_Comm that called PetscOptionsPrefixPush()

    846:   Input Parameters:
    847: .  options - options database, or NULL for the default global database

    849:    Level: advanced

    851: .seealso: PetscOptionsPrefixPush(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue()
    852: @*/
    853: PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
    854: {
    855:   PetscInt offset;

    858:   options = options ? options : defaultoptions;
    859:   if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
    860:   options->prefixind--;
    861:   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
    862:   options->prefix[offset] = 0;
    863:   return(0);
    864: }

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

    869:     Logically Collective

    871:   Input Parameters:
    872: .  options - options database, use NULL for the default global database

    874:    The collectivity of this routine is complex; only the MPI processes that call this routine will
    875:    have the affect of these options. If some processes that create objects call this routine and others do
    876:    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
    877:    on different ranks.

    879:    Level: developer

    881: .seealso: PetscOptionsInsert()
    882: @*/
    883: PetscErrorCode PetscOptionsClear(PetscOptions options)
    884: {
    885:   PetscInt i;

    887:   options = options ? options : defaultoptions;
    888:   if (!options) return 0;

    890:   for (i=0; i<options->N; i++) {
    891:     if (options->names[i])  free(options->names[i]);
    892:     if (options->values[i]) free(options->values[i]);
    893:   }
    894:   options->N = 0;

    896:   for (i=0; i<options->Naliases; i++) {
    897:     free(options->aliases1[i]);
    898:     free(options->aliases2[i]);
    899:   }
    900:   options->Naliases = 0;

    902:   /* destroy hash table */
    903:   kh_destroy(HO,options->ht);
    904:   options->ht = NULL;

    906:   options->prefixind = 0;
    907:   options->prefix[0] = 0;
    908:   options->help      = PETSC_FALSE;
    909:   return 0;
    910: }

    912: /*@C
    913:    PetscOptionsSetAlias - Makes a key and alias for another key

    915:    Logically Collective

    917:    Input Parameters:
    918: +  options - options database, or NULL for default global database
    919: .  newname - the alias
    920: -  oldname - the name that alias will refer to

    922:    Level: advanced

    924:    The collectivity of this routine is complex; only the MPI processes that call this routine will
    925:    have the affect of these options. If some processes that create objects call this routine and others do
    926:    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
    927:    on different ranks.

    929: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
    930:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
    931:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    932:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    933:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    934:           PetscOptionsFList(), PetscOptionsEList()
    935: @*/
    936: PetscErrorCode PetscOptionsSetAlias(PetscOptions options,const char newname[],const char oldname[])
    937: {
    938:   PetscInt       n;
    939:   size_t         len;

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

    949:   n = options->Naliases;
    950:   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);

    952:   newname++; oldname++;
    953:   PetscStrlen(newname,&len);
    954:   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
    955:   PetscStrcpy(options->aliases1[n],newname);
    956:   PetscStrlen(oldname,&len);
    957:   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
    958:   PetscStrcpy(options->aliases2[n],oldname);
    959:   options->Naliases++;
    960:   return(0);
    961: }

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

    967:    Logically Collective

    969:    Input Parameters:
    970: +  options - options database, use NULL for the default global database
    971: .  name - name of option, this SHOULD have the - prepended
    972: -  value - the option value (not used for all options, so can be NULL)

    974:    Level: intermediate

    976:    Note:
    977:    This function can be called BEFORE PetscInitialize()

    979:    The collectivity of this routine is complex; only the MPI processes that call this routine will
    980:    have the affect of these options. If some processes that create objects call this routine and others do
    981:    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
    982:    on different ranks.

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

    986: .seealso: PetscOptionsInsert(), PetscOptionsClearValue()
    987: @*/
    988: PetscErrorCode PetscOptionsSetValue(PetscOptions options,const char name[],const char value[])
    989: {
    990:   size_t         len;
    991:   int            N,n,i;
    992:   char           **names;
    993:   char           fullname[MAXOPTNAME] = "";

    996:   if (!options && !defaultoptions) {
    997:     PetscOptionsCreateDefault();if (ierr) return ierr;
    998:   }
    999:   options = options ? options : defaultoptions;

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

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

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

    1009:   if (options->prefixind > 0) {
    1010:     strncpy(fullname,options->prefix,sizeof(fullname));
    1011:     fullname[sizeof(fullname)-1] = 0;
    1012:     strncat(fullname,name,sizeof(fullname)-strlen(fullname)-1);
    1013:     fullname[sizeof(fullname)-1] = 0;
    1014:     name = fullname;
    1015:   }

    1017:   /* check against aliases */
    1018:   N = options->Naliases;
    1019:   for (i=0; i<N; i++) {
    1020:     int result = PetscOptNameCmp(options->aliases1[i],name);
    1021:     if (!result) { name = options->aliases2[i]; break; }
    1022:   }

    1024:   /* slow search */
    1025:   N = n = options->N;
    1026:   names = options->names;
    1027:   for (i=0; i<N; i++) {
    1028:     int result = PetscOptNameCmp(names[i],name);
    1029:     if (!result) {
    1030:       n = i; goto setvalue;
    1031:     } else if (result > 0) {
    1032:       n = i; break;
    1033:     }
    1034:   }
    1035:   if (N >= MAXOPTIONS) return PETSC_ERR_MEM;
    1036:   /* shift remaining values up 1 */
    1037:   for (i=N; i>n; i--) {
    1038:     options->names[i]  = options->names[i-1];
    1039:     options->values[i] = options->values[i-1];
    1040:     options->used[i]   = options->used[i-1];
    1041:   }
    1042:   options->names[n]  = NULL;
    1043:   options->values[n] = NULL;
    1044:   options->used[n]   = PETSC_FALSE;
    1045:   options->N++;

    1047:   /* destroy hash table */
    1048:   kh_destroy(HO,options->ht);
    1049:   options->ht = NULL;

    1051:   /* set new name */
    1052:   len = strlen(name);
    1053:   options->names[n] = (char*)malloc((len+1)*sizeof(char));
    1054:   if (!options->names[n]) return PETSC_ERR_MEM;
    1055:   strcpy(options->names[n],name);

    1057: setvalue:
    1058:   /* set new value */
    1059:   if (options->values[n]) free(options->values[n]);
    1060:   len = value ? strlen(value) : 0;
    1061:   if (len) {
    1062:     options->values[n] = (char*)malloc((len+1)*sizeof(char));
    1063:     if (!options->values[n]) return PETSC_ERR_MEM;
    1064:     strcpy(options->values[n],value);
    1065:   } else {
    1066:     options->values[n] = NULL;
    1067:   }

    1069:   PetscOptionsMonitor(options,name,value?value:"");if (ierr) return ierr;
    1070:   return 0;
    1071: }

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

    1077:    Logically Collective

    1079:    Input Parameter:
    1080: +  options - options database, use NULL for the default global database
    1081: -  name - name of option, this SHOULD have the - prepended

    1083:    Level: intermediate

    1085:    The collectivity of this routine is complex; only the MPI processes that call this routine will
    1086:    have the affect of these options. If some processes that create objects call this routine and others do
    1087:    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
    1088:    on different ranks.

    1090: .seealso: PetscOptionsInsert()
    1091: @*/
    1092: PetscErrorCode PetscOptionsClearValue(PetscOptions options,const char name[])
    1093: {
    1094:   int            N,n,i;
    1095:   char           **names;

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

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

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

    1108:   /* slow search */
    1109:   N = n = options->N;
    1110:   names = options->names;
    1111:   for (i=0; i<N; i++) {
    1112:     int result = PetscOptNameCmp(names[i],name);
    1113:     if (!result) {
    1114:       n = i; break;
    1115:     } else if (result > 0) {
    1116:       n = N; break;
    1117:     }
    1118:   }
    1119:   if (n == N) return(0); /* it was not present */

    1121:   /* remove name and value */
    1122:   if (options->names[n])  free(options->names[n]);
    1123:   if (options->values[n]) free(options->values[n]);
    1124:   /* shift remaining values down 1 */
    1125:   for (i=n; i<N-1; i++) {
    1126:     options->names[i]  = options->names[i+1];
    1127:     options->values[i] = options->values[i+1];
    1128:     options->used[i]   = options->used[i+1];
    1129:   }
    1130:   options->N--;

    1132:   /* destroy hash table */
    1133:   kh_destroy(HO,options->ht);
    1134:   options->ht = NULL;

    1136:   PetscOptionsMonitor(options,name,NULL);
    1137:   return(0);
    1138: }

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

    1143:    Not Collective

    1145:    Input Parameters:
    1146: +  options - options database, use NULL for the default global database
    1147: .  pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
    1148: -  name - name of option, this SHOULD have the "-" prepended

    1150:    Output Parameters:
    1151: +  value - the option value (optional, not used for all options)
    1152: -  set - whether the option is set (optional)

    1154:    Notes:
    1155:    Each process may find different values or no value depending on how options were inserted into the database

    1157:    Level: developer

    1159: .seealso: PetscOptionsSetValue(), PetscOptionsClearValue()
    1160: @*/
    1161: PetscErrorCode PetscOptionsFindPair(PetscOptions options,const char pre[],const char name[],const char *value[],PetscBool *set)
    1162: {
    1163:   char           buf[MAXOPTNAME];
    1164:   PetscBool      usehashtable = PETSC_TRUE;
    1165:   PetscBool      matchnumbers = PETSC_TRUE;

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

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

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

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

    1194:   if (!options->ht && usehashtable) {
    1195:     int i,ret;
    1196:     khiter_t it;
    1197:     khash_t(HO) *ht;
    1198:     ht = kh_init(HO);
    1199:     if (PetscUnlikely(!ht)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
    1200:     ret = kh_resize(HO,ht,options->N*2); /* twice the required size to reduce risk of collisions */
    1201:     if (PetscUnlikely(ret)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
    1202:     for (i=0; i<options->N; i++) {
    1203:       it = kh_put(HO,ht,options->names[i],&ret);
    1204:       if (PetscUnlikely(ret != 1)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
    1205:       kh_val(ht,it) = i;
    1206:     }
    1207:     options->ht = ht;
    1208:   }

    1210:   if (usehashtable)
    1211:   { /* fast search */
    1212:     khash_t(HO) *ht = options->ht;
    1213:     khiter_t it = kh_get(HO,ht,name);
    1214:     if (it != kh_end(ht)) {
    1215:       int i = kh_val(ht,it);
    1216:       options->used[i]  = PETSC_TRUE;
    1217:       if (value) *value = options->values[i];
    1218:       if (set)   *set   = PETSC_TRUE;
    1219:       return(0);
    1220:     }
    1221:   } else
    1222:   { /* slow search */
    1223:     int i, N = options->N;
    1224:     for (i=0; i<N; i++) {
    1225:       int result = PetscOptNameCmp(options->names[i],name);
    1226:       if (!result) {
    1227:         options->used[i]  = PETSC_TRUE;
    1228:         if (value) *value = options->values[i];
    1229:         if (set)   *set   = PETSC_TRUE;
    1230:         return(0);
    1231:       } else if (result > 0) {
    1232:         break;
    1233:       }
    1234:     }
    1235:   }

    1237:   /*
    1238:    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
    1239:    Maybe this special lookup mode should be enabled on request with a push/pop API.
    1240:    The feature of matching _%d_ used sparingly in the codebase.
    1241:    */
    1242:   if (matchnumbers) {
    1243:     int i,j,cnt = 0,locs[16],loce[16];
    1244:     /* determine the location and number of all _%d_ in the key */
    1245:     for (i=0; name[i]; i++) {
    1246:       if (name[i] == '_') {
    1247:         for (j=i+1; name[j]; j++) {
    1248:           if (name[j] >= '0' && name[j] <= '9') continue;
    1249:           if (name[j] == '_' && j > i+1) { /* found a number */
    1250:             locs[cnt]   = i+1;
    1251:             loce[cnt++] = j+1;
    1252:           }
    1253:           i = j-1;
    1254:           break;
    1255:         }
    1256:       }
    1257:     }
    1258:     for (i=0; i<cnt; i++) {
    1259:       PetscBool found;
    1260:       char      opt[MAXOPTNAME+1] = "-", tmp[MAXOPTNAME];
    1261:       PetscStrncpy(tmp,name,PetscMin((size_t)(locs[i]+1),sizeof(tmp)));
    1262:       PetscStrlcat(opt,tmp,sizeof(opt));
    1263:       PetscStrlcat(opt,name+loce[i],sizeof(opt));
    1264:       PetscOptionsFindPair(options,NULL,opt,value,&found);
    1265:       if (found) {if (set) *set = PETSC_TRUE; return(0);}
    1266:     }
    1267:   }

    1269:   if (set) *set = PETSC_FALSE;
    1270:   return(0);
    1271: }

    1273: /* Check whether any option begins with pre+name */
    1274: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options,const char pre[], const char name[],const char *value[],PetscBool *set)
    1275: {
    1276:   char           buf[MAXOPTNAME];
    1277:   int            numCnt = 0, locs[16],loce[16];

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

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

    1287:   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
    1288:   if (pre && pre[0]) {
    1289:     char *ptr = buf;
    1290:     if (name[0] == '-') { *ptr++ = '-';  name++; }
    1291:     PetscStrncpy(ptr,pre,sizeof(buf)+(size_t)(ptr-buf));
    1292:     PetscStrlcat(buf,name,sizeof(buf));
    1293:     name = buf;
    1294:   }

    1296: #if defined(PETSC_USE_DEBUG)
    1297:   {
    1298:     PetscBool valid;
    1299:     char      key[MAXOPTNAME+1] = "-";
    1300:     PetscStrncpy(key+1,name,sizeof(key)-1);
    1301:     PetscOptionsValidKey(key,&valid);
    1302:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
    1303:   }
    1304: #endif

    1306:   /* determine the location and number of all _%d_ in the key */
    1307:   {
    1308:     int i,j;
    1309:     for (i=0; name[i]; i++) {
    1310:       if (name[i] == '_') {
    1311:         for (j=i+1; name[j]; j++) {
    1312:           if (name[j] >= '0' && name[j] <= '9') continue;
    1313:           if (name[j] == '_' && j > i+1) { /* found a number */
    1314:             locs[numCnt]   = i+1;
    1315:             loce[numCnt++] = j+1;
    1316:           }
    1317:           i = j-1;
    1318:           break;
    1319:         }
    1320:       }
    1321:     }
    1322:   }

    1324:   { /* slow search */
    1325:     int       c, i;
    1326:     size_t    len;
    1327:     PetscBool match;

    1329:     for (c = -1; c < numCnt; ++c) {
    1330:       char opt[MAXOPTNAME+1] = "", tmp[MAXOPTNAME];

    1332:       if (c < 0) {
    1333:         PetscStrcpy(opt,name);
    1334:       } else {
    1335:         PetscStrncpy(tmp,name,PetscMin((size_t)(locs[c]+1),sizeof(tmp)));
    1336:         PetscStrlcat(opt,tmp,sizeof(opt));
    1337:         PetscStrlcat(opt,name+loce[c],sizeof(opt));
    1338:       }
    1339:       PetscStrlen(opt,&len);
    1340:       for (i=0; i<options->N; i++) {
    1341:         PetscStrncmp(options->names[i],opt,len,&match);
    1342:         if (match) {
    1343:           options->used[i]  = PETSC_TRUE;
    1344:           if (value) *value = options->values[i];
    1345:           if (set)   *set   = PETSC_TRUE;
    1346:           return(0);
    1347:         }
    1348:       }
    1349:     }
    1350:   }

    1352:   if (set) *set = PETSC_FALSE;
    1353:   return(0);
    1354: }

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

    1359:    Not Collective

    1361:    Input Parameters:
    1362: +  options - options database, use NULL for default global database
    1363: .  pre - the option prefix (may be NULL)
    1364: .  name - the option name one is seeking
    1365: -  mess - error message (may be NULL)

    1367:    Level: advanced

    1369: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
    1370:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1371:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1372:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1373:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1374:           PetscOptionsFList(), PetscOptionsEList()
    1375: @*/
    1376: PetscErrorCode PetscOptionsReject(PetscOptions options,const char pre[],const char name[],const char mess[])
    1377: {
    1379:   PetscBool      flag = PETSC_FALSE;

    1382:   PetscOptionsHasName(options,pre,name,&flag);
    1383:   if (flag) {
    1384:     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);
    1385:     else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s",pre?pre:"",name+1);
    1386:   }
    1387:   return(0);
    1388: }

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

    1393:    Not Collective

    1395:    Input Parameters:
    1396: .  options - options database, use NULL for default global database

    1398:    Output Parameters:
    1399: .  set - PETSC_TRUE if found else PETSC_FALSE.

    1401:    Level: advanced

    1403: .seealso: PetscOptionsHasName()
    1404: @*/
    1405: PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set)
    1406: {
    1409:   options = options ? options : defaultoptions;
    1410:   *set = options->help;
    1411:   return(0);
    1412: }

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

    1418:    Not Collective

    1420:    Input Parameters:
    1421: +  options - options database, use NULL for default global database
    1422: .  pre - string to prepend to the name or NULL
    1423: -  name - the option one is seeking

    1425:    Output Parameters:
    1426: .  set - PETSC_TRUE if found else PETSC_FALSE.

    1428:    Level: beginner

    1430:    Notes:
    1431:    Name cannot be simply "-h".

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

    1435: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    1436:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    1437:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    1438:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    1439:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    1440:           PetscOptionsFList(), PetscOptionsEList()
    1441: @*/
    1442: PetscErrorCode PetscOptionsHasName(PetscOptions options,const char pre[],const char name[],PetscBool *set)
    1443: {
    1444:   const char     *value;
    1446:   PetscBool      flag;

    1449:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    1450:   if (set) *set = flag;
    1451:   return(0);
    1452: }

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

    1457:    Not Collective

    1459:    Input Parameter:
    1460: .  options - the options database, use NULL for the default global database

    1462:    Output Parameter:
    1463: .  copts - pointer where string pointer is stored

    1465:    Notes:
    1466:     The array and each entry in the array should be freed with PetscFree()
    1467:     Each process may have different values depending on how the options were inserted into the database

    1469:    Level: advanced

    1471: .seealso: PetscOptionsAllUsed(), PetscOptionsView(), PetscOptionsPush(), PetscOptionsPop()
    1472: @*/
    1473: PetscErrorCode PetscOptionsGetAll(PetscOptions options,char *copts[])
    1474: {
    1476:   PetscInt       i;
    1477:   size_t         len = 1,lent = 0;
    1478:   char           *coptions = NULL;

    1482:   options = options ? options : defaultoptions;
    1483:   /* count the length of the required string */
    1484:   for (i=0; i<options->N; i++) {
    1485:     PetscStrlen(options->names[i],&lent);
    1486:     len += 2 + lent;
    1487:     if (options->values[i]) {
    1488:       PetscStrlen(options->values[i],&lent);
    1489:       len += 1 + lent;
    1490:     }
    1491:   }
    1492:   PetscMalloc1(len,&coptions);
    1493:   coptions[0] = 0;
    1494:   for (i=0; i<options->N; i++) {
    1495:     PetscStrcat(coptions,"-");
    1496:     PetscStrcat(coptions,options->names[i]);
    1497:     PetscStrcat(coptions," ");
    1498:     if (options->values[i]) {
    1499:       PetscStrcat(coptions,options->values[i]);
    1500:       PetscStrcat(coptions," ");
    1501:     }
    1502:   }
    1503:   *copts = coptions;
    1504:   return(0);
    1505: }

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

    1510:    Not Collective

    1512:    Input Parameter:
    1513: +  options - options database, use NULL for default global database
    1514: -  name - string name of option

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

    1519:    Level: advanced

    1521:    Notes:
    1522:    The value returned may be different on each process and depends on which options have been processed
    1523:    on the given process

    1525: .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
    1526: @*/
    1527: PetscErrorCode PetscOptionsUsed(PetscOptions options,const char *name,PetscBool *used)
    1528: {
    1529:   PetscInt       i;

    1535:   options = options ? options : defaultoptions;
    1536:   *used = PETSC_FALSE;
    1537:   for (i=0; i<options->N; i++) {
    1538:     PetscStrcmp(options->names[i],name,used);
    1539:     if (*used) {
    1540:       *used = options->used[i];
    1541:       break;
    1542:     }
    1543:   }
    1544:   return(0);
    1545: }

    1547: /*@
    1548:    PetscOptionsAllUsed - Returns a count of the number of options in the
    1549:    database that have never been selected.

    1551:    Not Collective

    1553:    Input Parameter:
    1554: .  options - options database, use NULL for default global database

    1556:    Output Parameter:
    1557: .  N - count of options not used

    1559:    Level: advanced

    1561:    Notes:
    1562:    The value returned may be different on each process and depends on which options have been processed
    1563:    on the given process

    1565: .seealso: PetscOptionsView()
    1566: @*/
    1567: PetscErrorCode PetscOptionsAllUsed(PetscOptions options,PetscInt *N)
    1568: {
    1569:   PetscInt     i,n = 0;

    1573:   options = options ? options : defaultoptions;
    1574:   for (i=0; i<options->N; i++) {
    1575:     if (!options->used[i]) n++;
    1576:   }
    1577:   *N = n;
    1578:   return(0);
    1579: }

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

    1584:    Not Collective

    1586:    Input Parameter:
    1587: .  options - options database; use NULL for default global database

    1589:    Options Database Key:
    1590: .  -options_left - activates PetscOptionsAllUsed() within PetscFinalize()

    1592:    Notes:
    1593:       This is rarely used directly, it is called by PetscFinalize() in debug more or if -options_left
    1594:       is passed otherwise to help users determine possible mistakes in their usage of options. This
    1595:       only prints values on process zero of PETSC_COMM_WORLD. Other processes depending the objects
    1596:       used may have different options that are left unused.

    1598:    Level: advanced

    1600: .seealso: PetscOptionsAllUsed()
    1601: @*/
    1602: PetscErrorCode PetscOptionsLeft(PetscOptions options)
    1603: {
    1605:   PetscInt       i;
    1606:   PetscInt       cnt = 0;
    1607:   PetscOptions   toptions;

    1610:   toptions = options ? options : defaultoptions;
    1611:   for (i=0; i<toptions->N; i++) {
    1612:     if (!toptions->used[i]) {
    1613:       if (toptions->values[i]) {
    1614:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",toptions->names[i],toptions->values[i]);
    1615:       } else {
    1616:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",toptions->names[i]);
    1617:       }
    1618:     }
    1619:   }
    1620:   if (!options) {
    1621:     toptions = defaultoptions;
    1622:     while (toptions->previous) {
    1623:       cnt++;
    1624:       toptions = toptions->previous;
    1625:     }
    1626:     if (cnt) {
    1627:       PetscPrintf(PETSC_COMM_WORLD,"Option left: You may have forgotten some calls to PetscOptionsPop(),\n             PetscOptionsPop() has been called %D less times than PetscOptionsPush()\n",cnt);
    1628:     }
    1629:   }
    1630:   return(0);
    1631: }

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

    1636:    Not Collective

    1638:    Input Parameter:
    1639: .  options - options database, use NULL for default global database

    1641:    Output Parameter:
    1642: +  N - count of options not used
    1643: .  names - names of options not used
    1644: -  values - values of options not used

    1646:    Level: advanced

    1648:    Notes:
    1649:    Users should call PetscOptionsLeftRestore() to free the memory allocated in this routine
    1650:    Notes: The value returned may be different on each process and depends on which options have been processed
    1651:    on the given process

    1653: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft()
    1654: @*/
    1655: PetscErrorCode PetscOptionsLeftGet(PetscOptions options,PetscInt *N,char **names[],char **values[])
    1656: {
    1658:   PetscInt       i,n;

    1664:   options = options ? options : defaultoptions;

    1666:   /* The number of unused PETSc options */
    1667:   n = 0;
    1668:   for (i=0; i<options->N; i++) {
    1669:     if (!options->used[i]) n++;
    1670:   }
    1671:   if (N) { *N = n; }
    1672:   if (names)  { PetscMalloc1(n,names); }
    1673:   if (values) { PetscMalloc1(n,values); }

    1675:   n = 0;
    1676:   if (names || values) {
    1677:     for (i=0; i<options->N; i++) {
    1678:       if (!options->used[i]) {
    1679:         if (names)  (*names)[n]  = options->names[i];
    1680:         if (values) (*values)[n] = options->values[i];
    1681:         n++;
    1682:       }
    1683:     }
    1684:   }
    1685:   return(0);
    1686: }

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

    1691:    Not Collective

    1693:    Input Parameter:
    1694: +  options - options database, use NULL for default global database
    1695: .  names - names of options not used
    1696: -  values - values of options not used

    1698:    Level: advanced

    1700: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft(), PetscOptionsLeftGet()
    1701: @*/
    1702: PetscErrorCode PetscOptionsLeftRestore(PetscOptions options,PetscInt *N,char **names[],char **values[])
    1703: {

    1710:   if (N) { *N = 0; }
    1711:   if (names)  { PetscFree(*names); }
    1712:   if (values) { PetscFree(*values); }
    1713:   return(0);
    1714: }

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

    1719:    Collective on PETSC_COMM_WORLD

    1721:    Input Parameter:
    1722: .  options - options database, use NULL for default global database

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

    1731:    Notes:
    1732:    To see all options, run your program with the -help option

    1734:    Level: intermediate

    1736: @*/
    1737: PetscErrorCode PetscOptionsSetFromOptions(PetscOptions options)
    1738: {
    1739:   PetscBool      flgc = PETSC_FALSE,flgm;
    1741:   char           monfilename[PETSC_MAX_PATH_LEN];
    1742:   PetscViewer    monviewer;

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

    1748:      options = options ? options : defaultoptions;
    1749:   */
    1750:   PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for handling options","PetscOptions");
    1751:   PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);
    1752:   PetscOptionsBool("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",flgc,&flgc,NULL);
    1753:   PetscOptionsEnd();
    1754:   if (flgm) {
    1755:     PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);
    1756:     PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    1757:   }
    1758:   if (flgc) { PetscOptionsMonitorCancel(); }
    1759:   return(0);
    1760: }

    1762: /*@C
    1763:    PetscOptionsMonitorDefault - Print all options set value events.

    1765:    Logically Collective on ctx

    1767:    Input Parameters:
    1768: +  name  - option name string
    1769: .  value - option value string
    1770: -  ctx - an ASCII viewer

    1772:    Level: intermediate

    1774:    Notes:
    1775:      The first MPI rank in the PetscViewer viewer actually prints the values, other
    1776:      processes may have different values set

    1778: .seealso: PetscOptionsMonitorSet()
    1779: @*/
    1780: PetscErrorCode PetscOptionsMonitorDefault(const char name[],const char value[],void *ctx)
    1781: {
    1783:   PetscViewer    viewer = (PetscViewer)ctx;

    1786:   if (!value) {
    1787:     PetscViewerASCIIPrintf(viewer,"Removing option: %s\n",name,value);
    1788:   } else if (!value[0]) {
    1789:     PetscViewerASCIIPrintf(viewer,"Setting option: %s (no value)\n",name);
    1790:   } else {
    1791:     PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
    1792:   }
    1793:   return(0);
    1794: }

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

    1800:    Not Collective

    1802:    Input Parameters:
    1803: +  monitor - pointer to function (if this is NULL, it turns off monitoring
    1804: .  mctx    - [optional] context for private data for the
    1805:              monitor routine (use NULL if no context is desired)
    1806: -  monitordestroy - [optional] routine that frees monitor context
    1807:           (may be NULL)

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

    1812: +  name - option name string
    1813: .  value - option value string
    1814: -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()

    1816:    Options Database Keys:
    1817: +    -options_monitor    - sets PetscOptionsMonitorDefault()
    1818: -    -options_monitor_cancel - cancels all monitors that have
    1819:                           been hardwired into a code by
    1820:                           calls to PetscOptionsMonitorSet(), but
    1821:                           does not cancel those set via
    1822:                           the options database.

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

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

    1833:    Level: beginner

    1835: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
    1836: @*/
    1837: PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
    1838: {
    1839:   PetscOptions options = defaultoptions;

    1842:   if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
    1843:   options->monitor[options->numbermonitors]          = monitor;
    1844:   options->monitordestroy[options->numbermonitors]   = monitordestroy;
    1845:   options->monitorcontext[options->numbermonitors++] = (void*)mctx;
    1846:   return(0);
    1847: }

    1849: /*@
    1850:    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.

    1852:    Not Collective

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

    1859:    Level: intermediate

    1861: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
    1862: @*/
    1863: PetscErrorCode PetscOptionsMonitorCancel(void)
    1864: {
    1866:   PetscInt       i;
    1867:   PetscOptions   options = defaultoptions;

    1870:   for (i=0; i<options->numbermonitors; i++) {
    1871:     if (options->monitordestroy[i]) {
    1872:       (*options->monitordestroy[i])(&options->monitorcontext[i]);
    1873:     }
    1874:   }
    1875:   options->numbermonitors = 0;
    1876:   return(0);
    1877: }

    1879: /*
    1880:    PetscOptionsStringToBool - Converts string to PetscBool , handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
    1881: */
    1882: PetscErrorCode PetscOptionsStringToBool(const char value[],PetscBool *a)
    1883: {
    1884:   PetscBool      istrue,isfalse;
    1885:   size_t         len;

    1889:   PetscStrlen(value,&len);
    1890:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Character string of length zero has no logical value");
    1891:   PetscStrcasecmp(value,"TRUE",&istrue);
    1892:   if (istrue) {*a = PETSC_TRUE; return(0);}
    1893:   PetscStrcasecmp(value,"YES",&istrue);
    1894:   if (istrue) {*a = PETSC_TRUE; return(0);}
    1895:   PetscStrcasecmp(value,"1",&istrue);
    1896:   if (istrue) {*a = PETSC_TRUE; return(0);}
    1897:   PetscStrcasecmp(value,"on",&istrue);
    1898:   if (istrue) {*a = PETSC_TRUE; return(0);}
    1899:   PetscStrcasecmp(value,"FALSE",&isfalse);
    1900:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    1901:   PetscStrcasecmp(value,"NO",&isfalse);
    1902:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    1903:   PetscStrcasecmp(value,"0",&isfalse);
    1904:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    1905:   PetscStrcasecmp(value,"off",&isfalse);
    1906:   if (isfalse) {*a = PETSC_FALSE; return(0);}
    1907:   SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value);
    1908: }

    1910: /*
    1911:    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
    1912: */
    1913: PetscErrorCode PetscOptionsStringToInt(const char name[],PetscInt *a)
    1914: {
    1916:   size_t         len;
    1917:   PetscBool      decide,tdefault,mouse;

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

    1923:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
    1924:   if (!tdefault) {
    1925:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
    1926:   }
    1927:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
    1928:   if (!decide) {
    1929:     PetscStrcasecmp(name,"DECIDE",&decide);
    1930:   }
    1931:   PetscStrcasecmp(name,"mouse",&mouse);

    1933:   if (tdefault)    *a = PETSC_DEFAULT;
    1934:   else if (decide) *a = PETSC_DECIDE;
    1935:   else if (mouse)  *a = -1;
    1936:   else {
    1937:     char *endptr;
    1938:     long strtolval;

    1940:     strtolval = strtol(name,&endptr,10);
    1941:     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);

    1943: #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
    1944:     (void) strtolval;
    1945:     *a = atoll(name);
    1946: #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
    1947:     (void) strtolval;
    1948:     *a = _atoi64(name);
    1949: #else
    1950:     *a = (PetscInt)strtolval;
    1951: #endif
    1952:   }
    1953:   return(0);
    1954: }

    1956: #if defined(PETSC_USE_REAL___FLOAT128)
    1957: #include <quadmath.h>
    1958: #endif

    1960: static PetscErrorCode PetscStrtod(const char name[],PetscReal *a,char **endptr)
    1961: {
    1963: #if defined(PETSC_USE_REAL___FLOAT128)
    1964:   *a = strtoflt128(name,endptr);
    1965: #else
    1966:   *a = (PetscReal)strtod(name,endptr);
    1967: #endif
    1968:   return(0);
    1969: }

    1971: static PetscErrorCode PetscStrtoz(const char name[],PetscScalar *a,char **endptr,PetscBool *isImaginary)
    1972: {
    1973:   PetscBool      hasi = PETSC_FALSE;
    1974:   char           *ptr;
    1975:   PetscReal      strtoval;

    1979:   PetscStrtod(name,&strtoval,&ptr);
    1980:   if (ptr == name) {
    1981:     strtoval = 1.;
    1982:     hasi = PETSC_TRUE;
    1983:     if (name[0] == 'i') {
    1984:       ptr++;
    1985:     } else if (name[0] == '+' && name[1] == 'i') {
    1986:       ptr += 2;
    1987:     } else if (name[0] == '-' && name[1] == 'i') {
    1988:       strtoval = -1.;
    1989:       ptr += 2;
    1990:     }
    1991:   } else if (*ptr == 'i') {
    1992:     hasi = PETSC_TRUE;
    1993:     ptr++;
    1994:   }
    1995:   *endptr = ptr;
    1996:   *isImaginary = hasi;
    1997:   if (hasi) {
    1998: #if !defined(PETSC_USE_COMPLEX)
    1999:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s contains imaginary but complex not supported ",name);
    2000: #else
    2001:     *a = PetscCMPLX(0.,strtoval);
    2002: #endif
    2003:   } else {
    2004:     *a = strtoval;
    2005:   }
    2006:   return(0);
    2007: }

    2009: /*
    2010:    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
    2011: */
    2012: PetscErrorCode PetscOptionsStringToReal(const char name[],PetscReal *a)
    2013: {
    2014:   size_t         len;
    2015:   PetscBool      match;
    2016:   char           *endptr;

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

    2023:   PetscStrcasecmp(name,"PETSC_DEFAULT",&match);
    2024:   if (!match) {
    2025:     PetscStrcasecmp(name,"DEFAULT",&match);
    2026:   }
    2027:   if (match) {*a = PETSC_DEFAULT; return(0);}

    2029:   PetscStrcasecmp(name,"PETSC_DECIDE",&match);
    2030:   if (!match) {
    2031:     PetscStrcasecmp(name,"DECIDE",&match);
    2032:   }
    2033:   if (match) {*a = PETSC_DECIDE; return(0);}

    2035:   PetscStrtod(name,a,&endptr);
    2036:   if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value",name);
    2037:   return(0);
    2038: }

    2040: PetscErrorCode PetscOptionsStringToScalar(const char name[],PetscScalar *a)
    2041: {
    2042:   PetscBool      imag1;
    2043:   size_t         len;
    2044:   PetscScalar    val = 0.;
    2045:   char           *ptr = NULL;

    2049:   PetscStrlen(name,&len);
    2050:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
    2051:   PetscStrtoz(name,&val,&ptr,&imag1);
    2052: #if defined(PETSC_USE_COMPLEX)
    2053:   if ((size_t) (ptr - name) < len) {
    2054:     PetscBool   imag2;
    2055:     PetscScalar val2;

    2057:     PetscStrtoz(ptr,&val2,&ptr,&imag2);
    2058:     if (imag1 || !imag2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s: must specify imaginary component second",name);
    2059:     val = PetscCMPLX(PetscRealPart(val),PetscImaginaryPart(val2));
    2060:   }
    2061: #endif
    2062:   if ((size_t) (ptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
    2063:   *a = val;
    2064:   return(0);
    2065: }

    2067: /*@C
    2068:    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
    2069:             option in the database.

    2071:    Not Collective

    2073:    Input Parameters:
    2074: +  options - options database, use NULL for default global database
    2075: .  pre - the string to prepend to the name or NULL
    2076: -  name - the option one is seeking

    2078:    Output Parameter:
    2079: +  ivalue - the logical value to return
    2080: -  set - PETSC_TRUE  if found, else PETSC_FALSE

    2082:    Level: beginner

    2084:    Notes:
    2085:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
    2086:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

    2088:       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
    2089:      is equivalent to -requested_bool true

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

    2094: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    2095:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
    2096:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2097:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2098:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2099:           PetscOptionsFList(), PetscOptionsEList()
    2100: @*/
    2101: PetscErrorCode PetscOptionsGetBool(PetscOptions options,const char pre[],const char name[],PetscBool *ivalue,PetscBool *set)
    2102: {
    2103:   const char     *value;
    2104:   PetscBool      flag;

    2110:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    2111:   if (flag) {
    2112:     if (set) *set = PETSC_TRUE;
    2113:     if (!value) {
    2114:       if (ivalue) *ivalue = PETSC_TRUE;
    2115:     } else {
    2116:       PetscOptionsStringToBool(value, &flag);
    2117:       if (ivalue) *ivalue = flag;
    2118:     }
    2119:   } else {
    2120:     if (set) *set = PETSC_FALSE;
    2121:   }
    2122:   return(0);
    2123: }

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

    2128:    Not Collective

    2130:    Input Parameters:
    2131: +  options - options database, use NULL for default global database
    2132: .  pre - the string to prepend to the name or NULL
    2133: .  opt - option name
    2134: .  list - the possible choices (one of these must be selected, anything else is invalid)
    2135: -  ntext - number of choices

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

    2141:    Level: intermediate

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

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

    2149: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    2150:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2151:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2152:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2153:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2154:           PetscOptionsFList(), PetscOptionsEList()
    2155: @*/
    2156: PetscErrorCode PetscOptionsGetEList(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool *set)
    2157: {
    2159:   size_t         alen,len = 0, tlen = 0;
    2160:   char           *svalue;
    2161:   PetscBool      aset,flg = PETSC_FALSE;
    2162:   PetscInt       i;

    2166:   for (i=0; i<ntext; i++) {
    2167:     PetscStrlen(list[i],&alen);
    2168:     if (alen > len) len = alen;
    2169:     tlen += len + 1;
    2170:   }
    2171:   len += 5; /* a little extra space for user mistypes */
    2172:   PetscMalloc1(len,&svalue);
    2173:   PetscOptionsGetString(options,pre,opt,svalue,len,&aset);
    2174:   if (aset) {
    2175:     PetscEListFind(ntext,list,svalue,value,&flg);
    2176:     if (!flg) {
    2177:       char *avail,*pavl;

    2179:       PetscMalloc1(tlen,&avail);
    2180:       pavl = avail;
    2181:       for (i=0; i<ntext; i++) {
    2182:         PetscStrlen(list[i],&alen);
    2183:         PetscStrcpy(pavl,list[i]);
    2184:         pavl += alen;
    2185:         PetscStrcpy(pavl," ");
    2186:         pavl += 1;
    2187:       }
    2188:       PetscStrtolower(avail);
    2189:       SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s. Available options: %s",svalue,pre ? pre : "",opt+1,avail);
    2190:     }
    2191:     if (set) *set = PETSC_TRUE;
    2192:   } else if (set) *set = PETSC_FALSE;
    2193:   PetscFree(svalue);
    2194:   return(0);
    2195: }

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

    2200:    Not Collective

    2202:    Input Parameters:
    2203: +  options - options database, use NULL for default global database
    2204: .  pre - option prefix or NULL
    2205: .  opt - option name
    2206: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
    2207: -  defaultv - the default (current) value

    2209:    Output Parameter:
    2210: +  value - the  value to return
    2211: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2213:    Level: beginner

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

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

    2221: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
    2222:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    2223:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    2224:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2225:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2226:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2227:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
    2228: @*/
    2229: PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set)
    2230: {
    2232:   PetscInt       ntext = 0,tval;
    2233:   PetscBool      fset;

    2237:   while (list[ntext++]) {
    2238:     if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
    2239:   }
    2240:   if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
    2241:   ntext -= 3;
    2242:   PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset);
    2243:   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
    2244:   if (fset) *value = (PetscEnum)tval;
    2245:   if (set) *set = fset;
    2246:   return(0);
    2247: }

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

    2252:    Not Collective

    2254:    Input Parameters:
    2255: +  options - options database, use NULL for default global database
    2256: .  pre - the string to prepend to the name or NULL
    2257: -  name - the option one is seeking

    2259:    Output Parameter:
    2260: +  ivalue - the integer value to return
    2261: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2263:    Level: beginner

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

    2269: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    2270:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    2271:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    2272:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2273:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2274:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2275:           PetscOptionsFList(), PetscOptionsEList()
    2276: @*/
    2277: PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set)
    2278: {
    2279:   const char     *value;
    2281:   PetscBool      flag;

    2286:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    2287:   if (flag) {
    2288:     if (!value) {
    2289:       if (set) *set = PETSC_FALSE;
    2290:     } else {
    2291:       if (set) *set = PETSC_TRUE;
    2292:       PetscOptionsStringToInt(value,ivalue);
    2293:     }
    2294:   } else {
    2295:     if (set) *set = PETSC_FALSE;
    2296:   }
    2297:   return(0);
    2298: }

    2300: /*@C
    2301:    PetscOptionsGetReal - Gets the double precision value for a particular
    2302:    option in the database.

    2304:    Not Collective

    2306:    Input Parameters:
    2307: +  options - options database, use NULL for default global database
    2308: .  pre - string to prepend to each name or NULL
    2309: -  name - the option one is seeking

    2311:    Output Parameter:
    2312: +  dvalue - the double value to return
    2313: -  set - PETSC_TRUE if found, PETSC_FALSE if not found

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

    2319:    Level: beginner

    2321: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2322:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
    2323:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2324:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2325:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2326:           PetscOptionsFList(), PetscOptionsEList()
    2327: @*/
    2328: PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set)
    2329: {
    2330:   const char     *value;
    2331:   PetscBool      flag;

    2337:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    2338:   if (flag) {
    2339:     if (!value) {
    2340:       if (set) *set = PETSC_FALSE;
    2341:     } else {
    2342:       if (set) *set = PETSC_TRUE;
    2343:       PetscOptionsStringToReal(value,dvalue);
    2344:     }
    2345:   } else {
    2346:     if (set) *set = PETSC_FALSE;
    2347:   }
    2348:   return(0);
    2349: }

    2351: /*@C
    2352:    PetscOptionsGetScalar - Gets the scalar value for a particular
    2353:    option in the database.

    2355:    Not Collective

    2357:    Input Parameters:
    2358: +  options - options database, use NULL for default global database
    2359: .  pre - string to prepend to each name or NULL
    2360: -  name - the option one is seeking

    2362:    Output Parameter:
    2363: +  dvalue - the double value to return
    2364: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2366:    Level: beginner

    2368:    Usage:
    2369:    A complex number 2+3i must be specified with NO spaces

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

    2375: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2376:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2377:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2378:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2379:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2380:           PetscOptionsFList(), PetscOptionsEList()
    2381: @*/
    2382: PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set)
    2383: {
    2384:   const char     *value;
    2385:   PetscBool      flag;

    2391:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    2392:   if (flag) {
    2393:     if (!value) {
    2394:       if (set) *set = PETSC_FALSE;
    2395:     } else {
    2396: #if !defined(PETSC_USE_COMPLEX)
    2397:       PetscOptionsStringToReal(value,dvalue);
    2398: #else
    2399:       PetscOptionsStringToScalar(value,dvalue);
    2400: #endif
    2401:       if (set) *set = PETSC_TRUE;
    2402:     }
    2403:   } else { /* flag */
    2404:     if (set) *set = PETSC_FALSE;
    2405:   }
    2406:   return(0);
    2407: }

    2409: /*@C
    2410:    PetscOptionsGetString - Gets the string value for a particular option in
    2411:    the database.

    2413:    Not Collective

    2415:    Input Parameters:
    2416: +  options - options database, use NULL for default global database
    2417: .  pre - string to prepend to name or NULL
    2418: .  name - the option one is seeking
    2419: -  len - maximum length of the string including null termination

    2421:    Output Parameters:
    2422: +  string - location to copy string
    2423: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2425:    Level: beginner

    2427:    Fortran Note:
    2428:    The Fortran interface is slightly different from the C/C++
    2429:    interface (len is not used).  Sample usage in Fortran follows
    2430: .vb
    2431:       character *20    string
    2432:       PetscErrorCode   ierr
    2433:       PetscBool        set
    2434:       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
    2435: .ve

    2437:    Notes:
    2438:     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

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

    2443:     Note:
    2444:       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).

    2446: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    2447:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2448:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2449:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2450:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2451:           PetscOptionsFList(), PetscOptionsEList()
    2452: @*/
    2453: PetscErrorCode PetscOptionsGetString(PetscOptions options,const char pre[],const char name[],char string[],size_t len,PetscBool *set)
    2454: {
    2455:   const char     *value;
    2456:   PetscBool      flag;

    2462:   PetscOptionsFindPair(options,pre,name,&value,&flag);
    2463:   if (!flag) {
    2464:     if (set) *set = PETSC_FALSE;
    2465:   } else {
    2466:     if (set) *set = PETSC_TRUE;
    2467:     if (value) {
    2468:       PetscStrncpy(string,value,len);
    2469:     } else {
    2470:       PetscArrayzero(string,len);
    2471:     }
    2472:   }
    2473:   return(0);
    2474: }

    2476: char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[])
    2477: {
    2478:   const char     *value;
    2479:   PetscBool      flag;

    2483:   PetscOptionsFindPair(options,pre,name,&value,&flag);if (ierr) PetscFunctionReturn(NULL);
    2484:   if (flag) PetscFunctionReturn((char*)value);
    2485:   else PetscFunctionReturn(NULL);
    2486: }

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

    2493:    Not Collective

    2495:    Input Parameters:
    2496: +  options - options database, use NULL for default global database
    2497: .  pre - string to prepend to each name or NULL
    2498: .  name - the option one is seeking
    2499: -  nmax - maximum number of values to retrieve

    2501:    Output Parameter:
    2502: +  dvalue - the integer values to return
    2503: .  nmax - actual number of values retreived
    2504: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2506:    Level: beginner

    2508:    Notes:
    2509:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
    2510:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

    2512: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2513:           PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2514:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2515:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2516:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2517:           PetscOptionsFList(), PetscOptionsEList()
    2518: @*/
    2519: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set)
    2520: {
    2521:   const char     *svalue;
    2522:   char           *value;
    2524:   PetscInt       n = 0;
    2525:   PetscBool      flag;
    2526:   PetscToken     token;

    2533:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2534:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2535:   if (set) *set = PETSC_TRUE;
    2536:   PetscTokenCreate(svalue,',',&token);
    2537:   PetscTokenFind(token,&value);
    2538:   while (value && n < *nmax) {
    2539:     PetscOptionsStringToBool(value,dvalue);
    2540:     PetscTokenFind(token,&value);
    2541:     dvalue++;
    2542:     n++;
    2543:   }
    2544:   PetscTokenDestroy(&token);
    2545:   *nmax = n;
    2546:   return(0);
    2547: }

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

    2552:    Not Collective

    2554:    Input Parameters:
    2555: +  options - options database, use NULL for default global database
    2556: .  pre - option prefix or NULL
    2557: .  name - option name
    2558: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
    2559: -  nmax - maximum number of values to retrieve

    2561:    Output Parameters:
    2562: +  ivalue - the  enum values to return
    2563: .  nmax - actual number of values retreived
    2564: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2566:    Level: beginner

    2568:    Notes:
    2569:    The array must be passed as a comma separated list.

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

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

    2575: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
    2576:           PetscOptionsGetEnum(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    2577:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(),
    2578:           PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(),
    2579:           PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2580:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
    2581: @*/
    2582: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set)
    2583: {
    2584:   const char     *svalue;
    2585:   char           *value;
    2586:   PetscInt       n = 0;
    2587:   PetscEnum      evalue;
    2588:   PetscBool      flag;
    2589:   PetscToken     token;

    2598:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2599:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2600:   if (set) *set = PETSC_TRUE;
    2601:   PetscTokenCreate(svalue,',',&token);
    2602:   PetscTokenFind(token,&value);
    2603:   while (value && n < *nmax) {
    2604:     PetscEnumFind(list,value,&evalue,&flag);
    2605:     if (!flag) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
    2606:     ivalue[n++] = evalue;
    2607:     PetscTokenFind(token,&value);
    2608:   }
    2609:   PetscTokenDestroy(&token);
    2610:   *nmax = n;
    2611:   return(0);
    2612: }

    2614: /*@C
    2615:    PetscOptionsGetIntArray - Gets an array of integer values for a particular
    2616:    option in the database.

    2618:    Not Collective

    2620:    Input Parameters:
    2621: +  options - options database, use NULL for default global database
    2622: .  pre - string to prepend to each name or NULL
    2623: .  name - the option one is seeking
    2624: -  nmax - maximum number of values to retrieve

    2626:    Output Parameter:
    2627: +  ivalue - the integer values to return
    2628: .  nmax - actual number of values retreived
    2629: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2631:    Level: beginner

    2633:    Notes:
    2634:    The array can be passed as
    2635:    a comma separated list:                                 0,1,2,3,4,5,6,7
    2636:    a range (start-end+1):                                  0-8
    2637:    a range with given increment (start-end+1:inc):         0-7:2
    2638:    a combination of values and ranges separated by commas: 0,1-8,8-15:2

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

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

    2664:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2665:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2666:   if (set) *set = PETSC_TRUE;
    2667:   PetscTokenCreate(svalue,',',&token);
    2668:   PetscTokenFind(token,&value);
    2669:   while (value && n < *nmax) {
    2670:     /* look for form  d-D where d and D are integers */
    2671:     foundrange = PETSC_FALSE;
    2672:     PetscStrlen(value,&len);
    2673:     if (value[0] == '-') i=2;
    2674:     else i=1;
    2675:     for (;i<(int)len; i++) {
    2676:       if (value[i] == '-') {
    2677:         if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
    2678:         value[i] = 0;

    2680:         PetscOptionsStringToInt(value,&start);
    2681:         inc  = 1;
    2682:         j    = i+1;
    2683:         for (;j<(int)len; j++) {
    2684:           if (value[j] == ':') {
    2685:             value[j] = 0;

    2687:             PetscOptionsStringToInt(value+j+1,&inc);
    2688:             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);
    2689:             break;
    2690:           }
    2691:         }
    2692:         PetscOptionsStringToInt(value+i+1,&end);
    2693:         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);
    2694:         nvalues = (end-start)/inc + (end-start)%inc;
    2695:         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);
    2696:         for (;start<end; start+=inc) {
    2697:           *ivalue = start; ivalue++;n++;
    2698:         }
    2699:         foundrange = PETSC_TRUE;
    2700:         break;
    2701:       }
    2702:     }
    2703:     if (!foundrange) {
    2704:       PetscOptionsStringToInt(value,ivalue);
    2705:       ivalue++;
    2706:       n++;
    2707:     }
    2708:     PetscTokenFind(token,&value);
    2709:   }
    2710:   PetscTokenDestroy(&token);
    2711:   *nmax = n;
    2712:   return(0);
    2713: }

    2715: /*@C
    2716:    PetscOptionsGetRealArray - Gets an array of double precision values for a
    2717:    particular option in the database.  The values must be separated with
    2718:    commas with no intervening spaces.

    2720:    Not Collective

    2722:    Input Parameters:
    2723: +  options - options database, use NULL for default global database
    2724: .  pre - string to prepend to each name or NULL
    2725: .  name - the option one is seeking
    2726: -  nmax - maximum number of values to retrieve

    2728:    Output Parameters:
    2729: +  dvalue - the double values to return
    2730: .  nmax - actual number of values retreived
    2731: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2733:    Level: beginner

    2735: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2736:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    2737:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2738:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2739:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2740:           PetscOptionsFList(), PetscOptionsEList()
    2741: @*/
    2742: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set)
    2743: {
    2744:   const char     *svalue;
    2745:   char           *value;
    2747:   PetscInt       n = 0;
    2748:   PetscBool      flag;
    2749:   PetscToken     token;

    2756:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2757:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2758:   if (set) *set = PETSC_TRUE;
    2759:   PetscTokenCreate(svalue,',',&token);
    2760:   PetscTokenFind(token,&value);
    2761:   while (value && n < *nmax) {
    2762:     PetscOptionsStringToReal(value,dvalue++);
    2763:     PetscTokenFind(token,&value);
    2764:     n++;
    2765:   }
    2766:   PetscTokenDestroy(&token);
    2767:   *nmax = n;
    2768:   return(0);
    2769: }

    2771: /*@C
    2772:    PetscOptionsGetScalarArray - Gets an array of scalars for a
    2773:    particular option in the database.  The values must be separated with
    2774:    commas with no intervening spaces.

    2776:    Not Collective

    2778:    Input Parameters:
    2779: +  options - options database, use NULL for default global database
    2780: .  pre - string to prepend to each name or NULL
    2781: .  name - the option one is seeking
    2782: -  nmax - maximum number of values to retrieve

    2784:    Output Parameters:
    2785: +  dvalue - the scalar values to return
    2786: .  nmax - actual number of values retreived
    2787: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2789:    Level: beginner

    2791: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
    2792:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
    2793:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2794:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2795:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2796:           PetscOptionsFList(), PetscOptionsEList()
    2797: @*/
    2798: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set)
    2799: {
    2800:   const char     *svalue;
    2801:   char           *value;
    2803:   PetscInt       n = 0;
    2804:   PetscBool      flag;
    2805:   PetscToken     token;

    2812:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2813:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2814:   if (set) *set = PETSC_TRUE;
    2815:   PetscTokenCreate(svalue,',',&token);
    2816:   PetscTokenFind(token,&value);
    2817:   while (value && n < *nmax) {
    2818:     PetscOptionsStringToScalar(value,dvalue++);
    2819:     PetscTokenFind(token,&value);
    2820:     n++;
    2821:   }
    2822:   PetscTokenDestroy(&token);
    2823:   *nmax = n;
    2824:   return(0);
    2825: }

    2827: /*@C
    2828:    PetscOptionsGetStringArray - Gets an array of string values for a particular
    2829:    option in the database. The values must be separated with commas with
    2830:    no intervening spaces.

    2832:    Not Collective

    2834:    Input Parameters:
    2835: +  options - options database, use NULL for default global database
    2836: .  pre - string to prepend to name or NULL
    2837: .  name - the option one is seeking
    2838: -  nmax - maximum number of strings

    2840:    Output Parameter:
    2841: +  strings - location to copy strings
    2842: -  set - PETSC_TRUE if found, else PETSC_FALSE

    2844:    Level: beginner

    2846:    Notes:
    2847:    The user should pass in an array of pointers to char, to hold all the
    2848:    strings returned by this function.

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

    2853: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
    2854:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
    2855:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    2856:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    2857:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    2858:           PetscOptionsFList(), PetscOptionsEList()
    2859: @*/
    2860: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set)
    2861: {
    2862:   const char     *svalue;
    2863:   char           *value;
    2865:   PetscInt       n = 0;
    2866:   PetscBool      flag;
    2867:   PetscToken     token;

    2874:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
    2875:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
    2876:   if (set) *set = PETSC_TRUE;
    2877:   PetscTokenCreate(svalue,',',&token);
    2878:   PetscTokenFind(token,&value);
    2879:   while (value && n < *nmax) {
    2880:     PetscStrallocpy(value,&strings[n]);
    2881:     PetscTokenFind(token,&value);
    2882:     n++;
    2883:   }
    2884:   PetscTokenDestroy(&token);
    2885:   *nmax = n;
    2886:   return(0);
    2887: }

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

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

    2894:    Logically Collective

    2896:    Input Parameters:
    2897: +  pre - string to prepend to name or NULL
    2898: .  oldname - the old, deprecated option
    2899: .  newname - the new option, or NULL if option is purely removed
    2900: .  version - a string describing the version of first deprecation, e.g. "3.9"
    2901: -  info - additional information string, or NULL.

    2903:    Options Database Keys:
    2904: . -options_suppress_deprecated_warnings - do not print deprecation warnings

    2906:    Notes:
    2907:    Must be called between PetscOptionsBegin() (or PetscObjectOptionsBegin()) and PetscOptionsEnd().
    2908:    Only the proces of rank zero that owns the PetscOptionsItems are argument (managed by PetscOptionsBegin() or
    2909:    PetscObjectOptionsBegin() prints the information
    2910:    If newname is provided, the old option is replaced. Otherwise, it remains
    2911:    in the options database.
    2912:    If an option is not replaced, the info argument should be used to advise the user
    2913:    on how to proceed.
    2914:    There is a limit on the length of the warning printed, so very long strings
    2915:    provided as info may be truncated.

    2917:    Level: developer

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

    2921: @*/
    2922: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[])
    2923: {
    2924:   PetscErrorCode     ierr;
    2925:   PetscBool          found,quiet;
    2926:   const char         *value;
    2927:   const char * const quietopt="-options_suppress_deprecated_warnings";
    2928:   char               msg[4096];
    2929:   char               *prefix = NULL;
    2930:   PetscOptions       options = NULL;
    2931:   MPI_Comm           comm = PETSC_COMM_SELF;

    2936:   if (PetscOptionsObject) {
    2937:     prefix  = PetscOptionsObject->prefix;
    2938:     options = PetscOptionsObject->options;
    2939:     comm    = PetscOptionsObject->comm;
    2940:   }
    2941:   PetscOptionsFindPair(options,prefix,oldname,&value,&found);
    2942:   if (found) {
    2943:     if (newname) {
    2944:       if (prefix) {
    2945:         PetscOptionsPrefixPush(options,prefix);
    2946:       }
    2947:       PetscOptionsSetValue(options,newname,value);
    2948:       if (prefix) {
    2949:         PetscOptionsPrefixPop(options);
    2950:       }
    2951:       PetscOptionsClearValue(options,oldname);
    2952:     }
    2953:     quiet = PETSC_FALSE;
    2954:     PetscOptionsGetBool(options,NULL,quietopt,&quiet,NULL);
    2955:     if (!quiet) {
    2956:       PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option ");
    2957:       PetscStrcat(msg,oldname);
    2958:       PetscStrcat(msg," is deprecated as of version ");
    2959:       PetscStrcat(msg,version);
    2960:       PetscStrcat(msg," and will be removed in a future release.");
    2961:       if (newname) {
    2962:         PetscStrcat(msg," Please use the option ");
    2963:         PetscStrcat(msg,newname);
    2964:         PetscStrcat(msg," instead.");
    2965:       }
    2966:       if (info) {
    2967:         PetscStrcat(msg," ");
    2968:         PetscStrcat(msg,info);
    2969:       }
    2970:       PetscStrcat(msg," (Silence this warning with ");
    2971:       PetscStrcat(msg,quietopt);
    2972:       PetscStrcat(msg,")\n");
    2973:       PetscPrintf(comm,msg);
    2974:     }
    2975:   }
    2976:   return(0);
    2977: }