Actual source code: options.c

petsc-3.12.5 2020-03-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(), PetscOptionDestroy(), PetscOptionsInsert(), PetscOptionsSetValue(),
201:           PetscOptionsLeft()

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

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

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

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

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

226:    Level: advanced

228: .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionDestroy(), PetscOptionsInsert(), PetscOptionsSetValue(),
229:           PetscOptionsLeft()

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

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

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

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

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

265:    Not collective

267:    Input Parameter:
268: .  key - string to check if valid

270:    Output Parameter:
271: .  valid - PETSC_TRUE if a valid key

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

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

293: /*@C
294:    PetscOptionsInsertString - Inserts options into the database from a string

296:    Logically Collective

298:    Input Parameter:
299: .  in_str - string that contains options separated by blanks

301:    Level: intermediate

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

308:    Contributed by Boyana Norris

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

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

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

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

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

389:      Collective

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


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

408:   Level: developer

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

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

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

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

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

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

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

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

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

538:   if (acnt) {
539:     PetscToken token;
540:     char       *first,*second;

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

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

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

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

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

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


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

625:    Collective on PETSC_COMM_WORLD

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

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

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

642:    Level: advanced

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


656:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

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

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

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

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

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

719:    Logically Collective on PetscViewer

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

725:    Options Database Key:
726: .  -options_view - Activates PetscOptionsView() within PetscFinalize()

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

732:    Level: advanced

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

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

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

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

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

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

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

793:    Logically Collective

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

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

803:    Notes:
804:    It is common to use this in conjunction with -options_file as in

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

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

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

815: Level: advanced

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

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

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

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

848:   Input Parameters:
849: .  options - options database, or NULL for the default global database

851:    Level: advanced

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

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

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

871:     Logically Collective

873:   Input Parameters:
874: .  options - options database, use NULL for the default global database

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

881:    Level: developer

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

889:   options = options ? options : defaultoptions;
890:   if (!options) return 0;

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

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

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

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

914: /*@C
915:    PetscOptionsSetAlias - Makes a key and alias for another key

917:    Logically Collective

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

924:    Level: advanced

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

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

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

951:   n = options->Naliases;
952:   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);

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

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

969:    Logically Collective

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

976:    Level: intermediate

978:    Note:
979:    This function can be called BEFORE PetscInitialize()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1079:    Logically Collective

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

1085:    Level: intermediate

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

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

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

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

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

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

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

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

1138:   PetscOptionsMonitor(options,name,NULL);
1139:   return(0);
1140: }

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

1145:    Not Collective

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

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

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

1159:    Level: developer

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

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

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

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

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

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

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

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

1271:   if (set) *set = PETSC_FALSE;
1272:   return(0);
1273: }

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

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

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

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

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

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

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

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

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

1354:   if (set) *set = PETSC_FALSE;
1355:   return(0);
1356: }

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

1361:    Not Collective

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

1369:    Level: advanced

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

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

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

1395:    Not Collective

1397:    Input Parameters:
1398: .  options - options database, use NULL for default global database

1400:    Output Parameters:
1401: .  set - PETSC_TRUE if found else PETSC_FALSE.

1403:    Level: advanced

1405: .seealso: PetscOptionsHasName()
1406: @*/
1407: PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set)
1408: {
1411:   options = options ? options : defaultoptions;
1412:   *set = options->help;
1413:   return(0);
1414: }

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

1420:    Not Collective

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

1427:    Output Parameters:
1428: .  set - PETSC_TRUE if found else PETSC_FALSE.

1430:    Level: beginner

1432:    Notes:
1433:    Name cannot be simply "-h".

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

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

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

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

1459:    Not Collective

1461:    Input Paramter:
1462: .  options - the options database, use NULL for the default global database

1464:    Output Parameter:
1465: .  copts - pointer where string pointer is stored

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

1471:    Level: advanced

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

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

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

1512:    Not Collective

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

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

1521:    Level: advanced

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

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

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

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

1553:    Not Collective

1555:    Input Parameter:
1556: .  options - options database, use NULL for default global database

1558:    Output Parameter:
1559: .  N - count of options not used

1561:    Level: advanced

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

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

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

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

1586:    Not Collective

1588:    Input Parameter:
1589: .  options - options database; use NULL for default global database

1591:    Options Database Key:
1592: .  -options_left - Activates OptionsAllUsed() within PetscFinalize()

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

1600:    Level: advanced

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

1612:   toptions = options ? options : defaultoptions;
1613:   for (i=0; i<toptions->N; i++) {
1614:     if (!toptions->used[i]) {
1615:       if (toptions->values[i]) {
1616:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",toptions->names[i],toptions->values[i]);
1617:       } else {
1618:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",toptions->names[i]);
1619:       }
1620:     }
1621:   }
1622:   if (!options) {
1623:     toptions = defaultoptions;
1624:     while (toptions->previous) {
1625:       cnt++;
1626:       toptions = toptions->previous;
1627:     }
1628:     if (cnt) {
1629:       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);
1630:     }
1631:   }
1632:   return(0);
1633: }

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

1638:    Not Collective

1640:    Input Parameter:
1641: .  options - options database, use NULL for default global database

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

1648:    Level: advanced

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

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

1666:   options = options ? options : defaultoptions;

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

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

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

1693:    Not Collective

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

1700:    Level: advanced

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

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

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

1721:    Collective on PETSC_COMM_WORLD

1723:    Input Parameter:
1724: .  options - options database, use NULL for default global database

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

1733:    Notes:
1734:    To see all options, run your program with the -help option

1736:    Level: intermediate

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

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

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

1764: /*@C
1765:    PetscOptionsMonitorDefault - Print all options set value events.

1767:    Logically Collective on ctx

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

1774:    Level: intermediate

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

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

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

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

1802:    Not Collective

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

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

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

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

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

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

1835:    Level: beginner

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

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

1851: /*@
1852:    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.

1854:    Not Collective

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

1861:    Level: intermediate

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

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

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

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

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

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

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

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

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

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

1958: #if defined(PETSC_USE_REAL___FLOAT128)
1959: #include <quadmath.h>
1960: #endif

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

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

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

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

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

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

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

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

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

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

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

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

2073:    Not Collective

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

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

2084:    Level: beginner

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

2090:       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
2091:      is equivalent to -requested_bool true

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

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

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

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

2130:    Not Collective

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

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

2143:    Level: intermediate

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

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

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

2168:   for (i=0; i<ntext; i++) {
2169:     PetscStrlen(list[i],&alen);
2170:     if (alen > len) len = alen;
2171:   }
2172:   len += 5; /* a little extra space for user mistypes */
2173:   PetscMalloc1(len,&svalue);
2174:   PetscOptionsGetString(options,pre,opt,svalue,len,&aset);
2175:   if (aset) {
2176:     PetscEListFind(ntext,list,svalue,value,&flg);
2177:     if (!flg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre ? pre : "",opt+1);
2178:     if (set) *set = PETSC_TRUE;
2179:   } else if (set) *set = PETSC_FALSE;
2180:   PetscFree(svalue);
2181:   return(0);
2182: }

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

2187:    Not Collective

2189:    Input Parameters:
2190: +  options - options database, use NULL for default global database
2191: .  pre - option prefix or NULL
2192: .  opt - option name
2193: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2194: -  defaultv - the default (current) value

2196:    Output Parameter:
2197: +  value - the  value to return
2198: -  set - PETSC_TRUE if found, else PETSC_FALSE

2200:    Level: beginner

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

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

2208: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2209:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2210:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2211:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2212:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2213:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2214:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2215: @*/
2216: PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set)
2217: {
2219:   PetscInt       ntext = 0,tval;
2220:   PetscBool      fset;

2224:   while (list[ntext++]) {
2225:     if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
2226:   }
2227:   if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
2228:   ntext -= 3;
2229:   PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset);
2230:   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2231:   if (fset) *value = (PetscEnum)tval;
2232:   if (set) *set = fset;
2233:   return(0);
2234: }

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

2239:    Not Collective

2241:    Input Parameters:
2242: +  options - options database, use NULL for default global database
2243: .  pre - the string to prepend to the name or NULL
2244: -  name - the option one is seeking

2246:    Output Parameter:
2247: +  ivalue - the integer value to return
2248: -  set - PETSC_TRUE if found, else PETSC_FALSE

2250:    Level: beginner

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

2256: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
2257:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2258:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2259:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2260:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2261:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2262:           PetscOptionsFList(), PetscOptionsEList()
2263: @*/
2264: PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set)
2265: {
2266:   const char     *value;
2268:   PetscBool      flag;

2273:   PetscOptionsFindPair(options,pre,name,&value,&flag);
2274:   if (flag) {
2275:     if (!value) {
2276:       if (set) *set = PETSC_FALSE;
2277:     } else {
2278:       if (set) *set = PETSC_TRUE;
2279:       PetscOptionsStringToInt(value,ivalue);
2280:     }
2281:   } else {
2282:     if (set) *set = PETSC_FALSE;
2283:   }
2284:   return(0);
2285: }

2287: /*@C
2288:    PetscOptionsGetReal - Gets the double precision value for a particular
2289:    option in the database.

2291:    Not Collective

2293:    Input Parameters:
2294: +  options - options database, use NULL for default global database
2295: .  pre - string to prepend to each name or NULL
2296: -  name - the option one is seeking

2298:    Output Parameter:
2299: +  dvalue - the double value to return
2300: -  set - PETSC_TRUE if found, PETSC_FALSE if not found

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

2306:    Level: beginner

2308: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2309:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
2310:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2311:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2312:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2313:           PetscOptionsFList(), PetscOptionsEList()
2314: @*/
2315: PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set)
2316: {
2317:   const char     *value;
2318:   PetscBool      flag;

2324:   PetscOptionsFindPair(options,pre,name,&value,&flag);
2325:   if (flag) {
2326:     if (!value) {
2327:       if (set) *set = PETSC_FALSE;
2328:     } else {
2329:       if (set) *set = PETSC_TRUE;
2330:       PetscOptionsStringToReal(value,dvalue);
2331:     }
2332:   } else {
2333:     if (set) *set = PETSC_FALSE;
2334:   }
2335:   return(0);
2336: }

2338: /*@C
2339:    PetscOptionsGetScalar - Gets the scalar value for a particular
2340:    option in the database.

2342:    Not Collective

2344:    Input Parameters:
2345: +  options - options database, use NULL for default global database
2346: .  pre - string to prepend to each name or NULL
2347: -  name - the option one is seeking

2349:    Output Parameter:
2350: +  dvalue - the double value to return
2351: -  set - PETSC_TRUE if found, else PETSC_FALSE

2353:    Level: beginner

2355:    Usage:
2356:    A complex number 2+3i must be specified with NO spaces

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

2362: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2363:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2364:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2365:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2366:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2367:           PetscOptionsFList(), PetscOptionsEList()
2368: @*/
2369: PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set)
2370: {
2371:   const char     *value;
2372:   PetscBool      flag;

2378:   PetscOptionsFindPair(options,pre,name,&value,&flag);
2379:   if (flag) {
2380:     if (!value) {
2381:       if (set) *set = PETSC_FALSE;
2382:     } else {
2383: #if !defined(PETSC_USE_COMPLEX)
2384:       PetscOptionsStringToReal(value,dvalue);
2385: #else
2386:       PetscOptionsStringToScalar(value,dvalue);
2387: #endif
2388:       if (set) *set = PETSC_TRUE;
2389:     }
2390:   } else { /* flag */
2391:     if (set) *set = PETSC_FALSE;
2392:   }
2393:   return(0);
2394: }

2396: /*@C
2397:    PetscOptionsGetString - Gets the string value for a particular option in
2398:    the database.

2400:    Not Collective

2402:    Input Parameters:
2403: +  options - options database, use NULL for default global database
2404: .  pre - string to prepend to name or NULL
2405: .  name - the option one is seeking
2406: -  len - maximum length of the string including null termination

2408:    Output Parameters:
2409: +  string - location to copy string
2410: -  set - PETSC_TRUE if found, else PETSC_FALSE

2412:    Level: beginner

2414:    Fortran Note:
2415:    The Fortran interface is slightly different from the C/C++
2416:    interface (len is not used).  Sample usage in Fortran follows
2417: .vb
2418:       character *20    string
2419:       PetscErrorCode   ierr
2420:       PetscBool        set
2421:       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2422: .ve

2424:    Notes:
2425:     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

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

2430:     Note:
2431:       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).

2433: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2434:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2435:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2436:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2437:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2438:           PetscOptionsFList(), PetscOptionsEList()
2439: @*/
2440: PetscErrorCode PetscOptionsGetString(PetscOptions options,const char pre[],const char name[],char string[],size_t len,PetscBool *set)
2441: {
2442:   const char     *value;
2443:   PetscBool      flag;

2449:   PetscOptionsFindPair(options,pre,name,&value,&flag);
2450:   if (!flag) {
2451:     if (set) *set = PETSC_FALSE;
2452:   } else {
2453:     if (set) *set = PETSC_TRUE;
2454:     if (value) {
2455:       PetscStrncpy(string,value,len);
2456:     } else {
2457:       PetscArrayzero(string,len);
2458:     }
2459:   }
2460:   return(0);
2461: }

2463: char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[])
2464: {
2465:   const char     *value;
2466:   PetscBool      flag;

2470:   PetscOptionsFindPair(options,pre,name,&value,&flag);if (ierr) return(0);
2471:   if (flag) PetscFunctionReturn((char*)value);
2472:   else return(0);
2473: }

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

2480:    Not Collective

2482:    Input Parameters:
2483: +  options - options database, use NULL for default global database
2484: .  pre - string to prepend to each name or NULL
2485: .  name - the option one is seeking
2486: -  nmax - maximum number of values to retrieve

2488:    Output Parameter:
2489: +  dvalue - the integer values to return
2490: .  nmax - actual number of values retreived
2491: -  set - PETSC_TRUE if found, else PETSC_FALSE

2493:    Level: beginner

2495:    Notes:
2496:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
2497:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

2499: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2500:           PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2501:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2502:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2503:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2504:           PetscOptionsFList(), PetscOptionsEList()
2505: @*/
2506: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set)
2507: {
2508:   const char     *svalue;
2509:   char           *value;
2511:   PetscInt       n = 0;
2512:   PetscBool      flag;
2513:   PetscToken     token;


2520:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2521:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2522:   if (set) *set = PETSC_TRUE;
2523:   PetscTokenCreate(svalue,',',&token);
2524:   PetscTokenFind(token,&value);
2525:   while (value && n < *nmax) {
2526:     PetscOptionsStringToBool(value,dvalue);
2527:     PetscTokenFind(token,&value);
2528:     dvalue++;
2529:     n++;
2530:   }
2531:   PetscTokenDestroy(&token);
2532:   *nmax = n;
2533:   return(0);
2534: }

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

2539:    Not Collective

2541:    Input Parameters:
2542: +  options - options database, use NULL for default global database
2543: .  pre - option prefix or NULL
2544: .  name - option name
2545: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2546: -  nmax - maximum number of values to retrieve

2548:    Output Parameters:
2549: +  ivalue - the  enum values to return
2550: .  nmax - actual number of values retreived
2551: -  set - PETSC_TRUE if found, else PETSC_FALSE

2553:    Level: beginner

2555:    Notes:
2556:    The array must be passed as a comma separated list.

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

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

2562: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2563:           PetscOptionsGetEnum(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2564:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(),
2565:           PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(),
2566:           PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2567:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2568: @*/
2569: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set)
2570: {
2571:   const char     *svalue;
2572:   char           *value;
2573:   PetscInt       n = 0;
2574:   PetscEnum      evalue;
2575:   PetscBool      flag;
2576:   PetscToken     token;


2585:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2586:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2587:   if (set) *set = PETSC_TRUE;
2588:   PetscTokenCreate(svalue,',',&token);
2589:   PetscTokenFind(token,&value);
2590:   while (value && n < *nmax) {
2591:     PetscEnumFind(list,value,&evalue,&flag);
2592:     if (!flag) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
2593:     ivalue[n++] = evalue;
2594:     PetscTokenFind(token,&value);
2595:   }
2596:   PetscTokenDestroy(&token);
2597:   *nmax = n;
2598:   return(0);
2599: }

2601: /*@C
2602:    PetscOptionsGetIntArray - Gets an array of integer values for a particular
2603:    option in the database.

2605:    Not Collective

2607:    Input Parameters:
2608: +  options - options database, use NULL for default global database
2609: .  pre - string to prepend to each name or NULL
2610: .  name - the option one is seeking
2611: -  nmax - maximum number of values to retrieve

2613:    Output Parameter:
2614: +  ivalue - the integer values to return
2615: .  nmax - actual number of values retreived
2616: -  set - PETSC_TRUE if found, else PETSC_FALSE

2618:    Level: beginner

2620:    Notes:
2621:    The array can be passed as
2622:    a comma separated list:                                 0,1,2,3,4,5,6,7
2623:    a range (start-end+1):                                  0-8
2624:    a range with given increment (start-end+1:inc):         0-7:2
2625:    a combination of values and ranges separated by commas: 0,1-8,8-15:2

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

2629: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2630:           PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2631:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2632:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2633:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2634:           PetscOptionsFList(), PetscOptionsEList()
2635: @*/
2636: PetscErrorCode PetscOptionsGetIntArray(PetscOptions options,const char pre[],const char name[],PetscInt ivalue[],PetscInt *nmax,PetscBool *set)
2637: {
2638:   const char     *svalue;
2639:   char           *value;
2641:   PetscInt       n = 0,i,j,start,end,inc,nvalues;
2642:   size_t         len;
2643:   PetscBool      flag,foundrange;
2644:   PetscToken     token;


2651:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2652:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2653:   if (set) *set = PETSC_TRUE;
2654:   PetscTokenCreate(svalue,',',&token);
2655:   PetscTokenFind(token,&value);
2656:   while (value && n < *nmax) {
2657:     /* look for form  d-D where d and D are integers */
2658:     foundrange = PETSC_FALSE;
2659:     PetscStrlen(value,&len);
2660:     if (value[0] == '-') i=2;
2661:     else i=1;
2662:     for (;i<(int)len; i++) {
2663:       if (value[i] == '-') {
2664:         if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
2665:         value[i] = 0;

2667:         PetscOptionsStringToInt(value,&start);
2668:         inc  = 1;
2669:         j    = i+1;
2670:         for (;j<(int)len; j++) {
2671:           if (value[j] == ':') {
2672:             value[j] = 0;

2674:             PetscOptionsStringToInt(value+j+1,&inc);
2675:             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);
2676:             break;
2677:           }
2678:         }
2679:         PetscOptionsStringToInt(value+i+1,&end);
2680:         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);
2681:         nvalues = (end-start)/inc + (end-start)%inc;
2682:         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);
2683:         for (;start<end; start+=inc) {
2684:           *ivalue = start; ivalue++;n++;
2685:         }
2686:         foundrange = PETSC_TRUE;
2687:         break;
2688:       }
2689:     }
2690:     if (!foundrange) {
2691:       PetscOptionsStringToInt(value,ivalue);
2692:       ivalue++;
2693:       n++;
2694:     }
2695:     PetscTokenFind(token,&value);
2696:   }
2697:   PetscTokenDestroy(&token);
2698:   *nmax = n;
2699:   return(0);
2700: }

2702: /*@C
2703:    PetscOptionsGetRealArray - Gets an array of double precision values for a
2704:    particular option in the database.  The values must be separated with
2705:    commas with no intervening spaces.

2707:    Not Collective

2709:    Input Parameters:
2710: +  options - options database, use NULL for default global database
2711: .  pre - string to prepend to each name or NULL
2712: .  name - the option one is seeking
2713: -  nmax - maximum number of values to retrieve

2715:    Output Parameters:
2716: +  dvalue - the double values to return
2717: .  nmax - actual number of values retreived
2718: -  set - PETSC_TRUE if found, else PETSC_FALSE

2720:    Level: beginner

2722: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2723:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2724:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2725:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2726:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2727:           PetscOptionsFList(), PetscOptionsEList()
2728: @*/
2729: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set)
2730: {
2731:   const char     *svalue;
2732:   char           *value;
2734:   PetscInt       n = 0;
2735:   PetscBool      flag;
2736:   PetscToken     token;


2743:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2744:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2745:   if (set) *set = PETSC_TRUE;
2746:   PetscTokenCreate(svalue,',',&token);
2747:   PetscTokenFind(token,&value);
2748:   while (value && n < *nmax) {
2749:     PetscOptionsStringToReal(value,dvalue++);
2750:     PetscTokenFind(token,&value);
2751:     n++;
2752:   }
2753:   PetscTokenDestroy(&token);
2754:   *nmax = n;
2755:   return(0);
2756: }

2758: /*@C
2759:    PetscOptionsGetScalarArray - Gets an array of scalars for a
2760:    particular option in the database.  The values must be separated with
2761:    commas with no intervening spaces.

2763:    Not Collective

2765:    Input Parameters:
2766: +  options - options database, use NULL for default global database
2767: .  pre - string to prepend to each name or NULL
2768: .  name - the option one is seeking
2769: -  nmax - maximum number of values to retrieve

2771:    Output Parameters:
2772: +  dvalue - the scalar values to return
2773: .  nmax - actual number of values retreived
2774: -  set - PETSC_TRUE if found, else PETSC_FALSE

2776:    Level: beginner

2778: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2779:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2780:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2781:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2782:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2783:           PetscOptionsFList(), PetscOptionsEList()
2784: @*/
2785: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set)
2786: {
2787:   const char     *svalue;
2788:   char           *value;
2790:   PetscInt       n = 0;
2791:   PetscBool      flag;
2792:   PetscToken     token;


2799:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2800:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2801:   if (set) *set = PETSC_TRUE;
2802:   PetscTokenCreate(svalue,',',&token);
2803:   PetscTokenFind(token,&value);
2804:   while (value && n < *nmax) {
2805:     PetscOptionsStringToScalar(value,dvalue++);
2806:     PetscTokenFind(token,&value);
2807:     n++;
2808:   }
2809:   PetscTokenDestroy(&token);
2810:   *nmax = n;
2811:   return(0);
2812: }

2814: /*@C
2815:    PetscOptionsGetStringArray - Gets an array of string values for a particular
2816:    option in the database. The values must be separated with commas with
2817:    no intervening spaces.

2819:    Not Collective

2821:    Input Parameters:
2822: +  options - options database, use NULL for default global database
2823: .  pre - string to prepend to name or NULL
2824: .  name - the option one is seeking
2825: -  nmax - maximum number of strings

2827:    Output Parameter:
2828: +  strings - location to copy strings
2829: -  set - PETSC_TRUE if found, else PETSC_FALSE

2831:    Level: beginner

2833:    Notes:
2834:    The user should pass in an array of pointers to char, to hold all the
2835:    strings returned by this function.

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

2840: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2841:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2842:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2843:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2844:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2845:           PetscOptionsFList(), PetscOptionsEList()
2846: @*/
2847: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set)
2848: {
2849:   const char     *svalue;
2850:   char           *value;
2852:   PetscInt       n = 0;
2853:   PetscBool      flag;
2854:   PetscToken     token;


2861:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2862:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2863:   if (set) *set = PETSC_TRUE;
2864:   PetscTokenCreate(svalue,',',&token);
2865:   PetscTokenFind(token,&value);
2866:   while (value && n < *nmax) {
2867:     PetscStrallocpy(value,&strings[n]);
2868:     PetscTokenFind(token,&value);
2869:     n++;
2870:   }
2871:   PetscTokenDestroy(&token);
2872:   *nmax = n;
2873:   return(0);
2874: }

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

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

2881:    Logically Collective

2883:    Input Parameters:
2884: +  pre - string to prepend to name or NULL
2885: .  oldname - the old, deprecated option
2886: .  newname - the new option, or NULL if option is purely removed
2887: .  version - a string describing the version of first deprecation, e.g. "3.9"
2888: -  info - additional information string, or NULL.

2890:    Options Database Keys:
2891: . -options_suppress_deprecated_warnings - do not print deprecation warnings

2893:    Notes:
2894:    Must be called between PetscOptionsBegin() (or PetscObjectOptionsBegin()) and PetscOptionsEnd().
2895:    Only the proces of rank zero that owns the PetscOptionsItems are argument (managed by PetscOptionsBegin() or
2896:    PetscObjectOptionsBegin() prints the information
2897:    If newname is provided, the old option is replaced. Otherwise, it remains
2898:    in the options database.
2899:    If an option is not replaced, the info argument should be used to advise the user
2900:    on how to proceed.
2901:    There is a limit on the length of the warning printed, so very long strings
2902:    provided as info may be truncated.

2904:    Level: developer

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

2908: @*/
2909: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[])
2910: {
2911:   PetscErrorCode     ierr;
2912:   PetscBool          found,quiet;
2913:   const char         *value;
2914:   const char * const quietopt="-options_suppress_deprecated_warnings";
2915:   char               msg[4096];


2921:   PetscOptionsFindPair(PetscOptionsObject->options,PetscOptionsObject->prefix,oldname,&value,&found);
2922:   if (found) {
2923:     if (newname) {
2924:       if (PetscOptionsObject->prefix) {
2925:         PetscOptionsPrefixPush(PetscOptionsObject->options,PetscOptionsObject->prefix);
2926:       }
2927:       PetscOptionsSetValue(PetscOptionsObject->options,newname,value);
2928:       if (PetscOptionsObject->prefix) {
2929:         PetscOptionsPrefixPop(PetscOptionsObject->options);
2930:       }
2931:       PetscOptionsClearValue(PetscOptionsObject->options,oldname);
2932:     }
2933:     quiet = PETSC_FALSE;
2934:     PetscOptionsGetBool(PetscOptionsObject->options,NULL,quietopt,&quiet,NULL);
2935:     if (!quiet) {
2936:       PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option ");
2937:       PetscStrcat(msg,oldname);
2938:       PetscStrcat(msg," is deprecated as of version ");
2939:       PetscStrcat(msg,version);
2940:       PetscStrcat(msg," and will be removed in a future release.");
2941:       if (newname) {
2942:         PetscStrcat(msg," Please use the option ");
2943:         PetscStrcat(msg,newname);
2944:         PetscStrcat(msg," instead.");
2945:       }
2946:       if (info) {
2947:         PetscStrcat(msg," ");
2948:         PetscStrcat(msg,info);
2949:       }
2950:       PetscStrcat(msg," (Silence this warning with ");
2951:       PetscStrcat(msg,quietopt);
2952:       PetscStrcat(msg,")\n");
2953:       PetscPrintf(PetscOptionsObject->comm,msg);
2954:     }
2955:   }
2956:   return(0);
2957: }