Actual source code: options.c

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

105: static PetscOptions defaultoptions = NULL;


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

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

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

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

130:    Level: advanced

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

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

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

148:    Level: developer

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

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

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

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

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

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

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

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

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

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

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

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

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

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


227:    Level: intermediate

229:    Contributed by Boyana Norris

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

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

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

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

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

310:      Collective on MPI_Comm

312:   Input Parameter:
313: +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
314: .   options - options database, use NULL for default global database
315: .   file - name of file
316: -   require - if PETSC_TRUE will generate an error if the file does not exist


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

322:    Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
323:    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
324:    calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().

326:   Level: developer

328: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
329:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
330:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
331:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
332:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
333:           PetscOptionsFList(), PetscOptionsEList()

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

349:   MPI_Comm_rank(comm,&rank);
350:   if (!rank) {
351:     cnt        = 0;
352:     acnt       = 0;

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

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

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

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

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

442:   counts[0] = acnt;
443:   counts[1] = cnt;
444:   MPI_Bcast(counts,2,MPI_INT,0,comm);
445:   acnt = counts[0];
446:   cnt = counts[1];
447:   if (rank) {
448:     PetscMalloc1(2+acnt+cnt,&packed);
449:   }
450:   if (acnt || cnt) {
451:     MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm);
452:     astring = packed;
453:     vstring = packed + acnt + 1;
454:   }

456:   if (acnt) {
457:     PetscToken token;
458:     char       *first,*second;

460:     PetscTokenCreate(astring,' ',&token);
461:     PetscTokenFind(token,&first);
462:     while (first) {
463:       PetscTokenFind(token,&second);
464:       PetscOptionsSetAlias(options,first,second);
465:       PetscTokenFind(token,&first);
466:     }
467:     PetscTokenDestroy(&token);
468:   }

470:   if (cnt) {
471:     PetscOptionsInsertString(options,vstring);
472:   }
473:   PetscFree(packed);
474:   return(0);
475: }

477: static PetscErrorCode PetscOptionsInsertArgs(PetscOptions options,int argc,char *args[])
478: {
480:   int            left    = argc - 1;
481:   char           **eargs = args + 1;

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

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

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


539: /*@C
540:    PetscOptionsInsert - Inserts into the options database from the command line,
541:                    the environmental variable and a file.

543:    Input Parameters:
544: +  options - options database or NULL for the default global database
545: .  argc - count of number of command line arguments
546: .  args - the command line arguments
547: -  file - optional filename, defaults to ~username/.petscrc

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

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

558:    Level: advanced

560:    Concepts: options database^adding

562: .seealso: PetscOptionsDestroy(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
563:           PetscInitialize()
564: @*/
565: PetscErrorCode PetscOptionsInsert(PetscOptions options,int *argc,char ***args,const char file[])
566: {
568:   PetscMPIInt    rank;
569:   char           filename[PETSC_MAX_PATH_LEN];
570:   PetscBool      flag = PETSC_FALSE;


574:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

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

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

617: #if defined(PETSC_HAVE_YAML)
618:   {
619:     char      yaml_file[PETSC_MAX_PATH_LEN];
620:     PetscBool yaml_flg;
621:     PetscOptionsGetString(NULL,NULL,"-options_file_yaml",yaml_file,PETSC_MAX_PATH_LEN,&yaml_flg);
622:     if (yaml_flg) {
623:       PetscOptionsInsertFileYAML(PETSC_COMM_WORLD,yaml_file,PETSC_TRUE);
624:     }
625:   }
626: #endif

628:   /* insert command line options again because they take precedence over arguments in petscrc/environment */
629:   if (argc && args && *argc) {PetscOptionsInsertArgs(options,*argc,*args);}
630:   return(0);
631: }

633: /*@C
634:    PetscOptionsView - Prints the options that have been loaded. This is
635:    useful for debugging purposes.

637:    Logically Collective on PetscViewer

639:    Input Parameter:
640: -  options - options database, use NULL for default global database
641: +  viewer - must be an PETSCVIEWERASCII viewer

643:    Options Database Key:
644: .  -options_view - Activates PetscOptionsView() within PetscFinalize()

646:    Level: advanced

648:    Concepts: options database^printing

650: .seealso: PetscOptionsAllUsed()
651: @*/
652: PetscErrorCode PetscOptionsView(PetscOptions options,PetscViewer viewer)
653: {
655:   PetscInt       i;
656:   PetscBool      isascii;

660:   options = options ? options : defaultoptions;
661:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
662:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
663:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");

665:   if (!options->N) {
666:     PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");
667:     return(0);
668:   }

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

682: /*
683:    Called by error handlers to print options used in run
684: */
685: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
686: {
687:   PetscInt     i;
688:   PetscOptions options = defaultoptions;

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

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

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

711:    Input Parameter:
712: +  options - options database, or NULL for the default global database
713: -  prefix - The string to append to the existing prefix

715:    Options Database Keys:
716: +   -prefix_push <some_prefix_> - push the given prefix
717: -   -prefix_pop - pop the last prefix

719:    Notes:
720:    It is common to use this in conjunction with -options_file as in

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

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

726: Level: advanced

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

740:   options = options ? options : defaultoptions;
741:   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);
742:   key[0] = '-'; /* keys must start with '-' */
743:   PetscStrncpy(key+1,prefix,sizeof(key)-1);
744:   PetscOptionsValidKey(key,&valid);
745:   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);
746:   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
747:   PetscStrlen(prefix,&n);
748:   if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
749:   PetscMemcpy(options->prefix+start,prefix,n+1);
750:   options->prefixstack[options->prefixind++] = start+n;
751:   return(0);
752: }

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

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

759:   Input Parameters:
760: .  options - options database, or NULL for the default global database

762:    Level: advanced

764: .seealso: PetscOptionsPrefixPush()
765: @*/
766: PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
767: {
768:   PetscInt offset;

771:   options = options ? options : defaultoptions;
772:   if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
773:   options->prefixind--;
774:   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
775:   options->prefix[offset] = 0;
776:   return(0);
777: }

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

782:   Input Parameters:
783: .  options - options database, use NULL for the default global database

785:    Level: developer

787: .seealso: PetscOptionsInsert()
788: @*/
789: PetscErrorCode PetscOptionsClear(PetscOptions options)
790: {
791:   PetscInt i;

793:   options = options ? options : defaultoptions;
794:   if (!options) return 0;

796:   for (i=0; i<options->N; i++) {
797:     if (options->names[i])  free(options->names[i]);
798:     if (options->values[i]) free(options->values[i]);
799:   }
800:   options->N = 0;

802:   for (i=0; i<options->Naliases; i++) {
803:     free(options->aliases1[i]);
804:     free(options->aliases2[i]);
805:   }
806:   options->Naliases = 0;

808:   /* destroy hash table */
809:   kh_destroy(HO,options->ht);
810:   options->ht = NULL;

812:   options->prefixind = 0;
813:   options->prefix[0] = 0;
814:   options->help      = PETSC_FALSE;
815:   return 0;
816: }

818: /*@C
819:    PetscOptionsSetAlias - Makes a key and alias for another key

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

824:    Input Parameters:
825: +  options - options database, or NULL for default global database
826: .  newname - the alias
827: -  oldname - the name that alias will refer to

829:    Level: advanced

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

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

851:   n = options->Naliases;
852:   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);

854:   newname++; oldname++;
855:   PetscStrlen(newname,&len);
856:   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
857:   PetscStrcpy(options->aliases1[n],newname);
858:   PetscStrlen(oldname,&len);
859:   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
860:   PetscStrcpy(options->aliases2[n],oldname);
861:   options->Naliases++;
862:   return(0);
863: }

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

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

872:    Input Parameters:
873: +  options - options database, use NULL for the default global database
874: .  name - name of option, this SHOULD have the - prepended
875: -  value - the option value (not used for all options, so can be NULL)

877:    Level: intermediate

879:    Note:
880:    This function can be called BEFORE PetscInitialize()

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

884:    Concepts: options database^adding option

886: .seealso: PetscOptionsInsert(), PetscOptionsClearValue()
887: @*/
888: PetscErrorCode PetscOptionsSetValue(PetscOptions options,const char name[],const char value[])
889: {
890:   size_t         len;
891:   int            N,n,i;
892:   char           **names;
893:   char           fullname[MAXOPTNAME] = "";

896:   if (!options && !defaultoptions) {
897:     PetscOptionsCreateDefault();if (ierr) return ierr;
898:   }
899:   options = options ? options : defaultoptions;

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

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

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

909:   if (options->prefixind > 0) {
910:     strncpy(fullname,options->prefix,sizeof(fullname));
911:     fullname[sizeof(fullname)-1] = 0;
912:     strncat(fullname,name,sizeof(fullname)-strlen(fullname)-1);
913:     fullname[sizeof(fullname)-1] = 0;
914:     name = fullname;
915:   }

917:   /* check against aliases */
918:   N = options->Naliases;
919:   for (i=0; i<N; i++) {
920:     int result = PetscOptNameCmp(options->aliases1[i],name);
921:     if (!result) { name = options->aliases2[i]; break; }
922:   }

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

947:   /* destroy hash table */
948:   kh_destroy(HO,options->ht);
949:   options->ht = NULL;

951:   /* set new name */
952:   len = strlen(name);
953:   options->names[n] = (char*)malloc((len+1)*sizeof(char));
954:   if (!options->names[n]) return PETSC_ERR_MEM;
955:   strcpy(options->names[n],name);

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

969:   PetscOptionsMonitor(options,name,value?value:"");if (ierr) return ierr;
970:   return 0;
971: }

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

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

980:    Input Parameter:
981: +  options - options database, use NULL for the default global database
982: .  name - name of option, this SHOULD have the - prepended

984:    Level: intermediate

986:    Concepts: options database^removing option
987: .seealso: PetscOptionsInsert()
988: @*/
989: PetscErrorCode PetscOptionsClearValue(PetscOptions options,const char name[])
990: {
991:   int            N,n,i;
992:   char           **names;

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

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

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

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

1018:   /* remove name and value */
1019:   if (options->names[n])  free(options->names[n]);
1020:   if (options->values[n]) free(options->values[n]);
1021:   /* shift remaining values down 1 */
1022:   for (i=n; i<N-1; i++) {
1023:     options->names[i]  = options->names[i+1];
1024:     options->values[i] = options->values[i+1];
1025:     options->used[i]   = options->used[i+1];
1026:   }
1027:   options->N--;

1029:   /* destroy hash table */
1030:   kh_destroy(HO,options->ht);
1031:   options->ht = NULL;

1033:   PetscOptionsMonitor(options,name,NULL);
1034:   return(0);
1035: }

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

1040:    Not Collective

1042:    Input Parameters:
1043: +  options - options database, use NULL for the default global database
1044: .  pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
1045: -  name - name of option, this SHOULD have the "-" prepended

1047:    Output Parameters:
1048: +  value - the option value (optional, not used for all options)
1049: -  set - whether the option is set (optional)

1051:    Level: developer

1053:   Concepts: options database^getting option

1055: .seealso: PetscOptionsSetValue(), PetscOptionsClearValue()
1056: @*/
1057: PetscErrorCode PetscOptionsFindPair(PetscOptions options,const char pre[],const char name[],const char *value[],PetscBool *set)
1058: {
1059:   char           buf[MAXOPTNAME];
1060:   PetscBool      usehashtable = PETSC_TRUE;
1061:   PetscBool      matchnumbers = PETSC_TRUE;

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

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

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

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

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

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

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

1165:   if (set) *set = PETSC_FALSE;
1166:   return(0);
1167: }

1169: /* Check whether any option begins with pre+name */
1170: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options,const char pre[], const char name[],const char *value[],PetscBool *set)
1171: {
1172:   char           buf[MAXOPTNAME];
1173:   int            numCnt = 0, locs[16],loce[16];

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

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

1183:   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1184:   if (pre && pre[0]) {
1185:     char *ptr = buf;
1186:     if (name[0] == '-') { *ptr++ = '-';  name++; }
1187:     PetscStrncpy(ptr,pre,sizeof(buf)+(size_t)(ptr-buf));
1188:     PetscStrlcat(buf,name,sizeof(buf));
1189:     name = buf;
1190:   }

1192: #if defined(PETSC_USE_DEBUG)
1193:   {
1194:     PetscBool valid;
1195:     char      key[MAXOPTNAME+1] = "-";
1196:     PetscStrncpy(key+1,name,sizeof(key)-1);
1197:     PetscOptionsValidKey(key,&valid);
1198:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1199:   }
1200: #endif

1202:   /* determine the location and number of all _%d_ in the key */
1203:   {
1204:     int i,j;
1205:     for (i=0; name[i]; i++) {
1206:       if (name[i] == '_') {
1207:         for (j=i+1; name[j]; j++) {
1208:           if (name[j] >= '0' && name[j] <= '9') continue;
1209:           if (name[j] == '_' && j > i+1) { /* found a number */
1210:             locs[numCnt]   = i+1;
1211:             loce[numCnt++] = j+1;
1212:           }
1213:           i = j-1;
1214:           break;
1215:         }
1216:       }
1217:     }
1218:   }

1220:   { /* slow search */
1221:     int       c, i;
1222:     size_t    len;
1223:     PetscBool match;

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

1228:       if (c < 0) {
1229:         PetscStrcpy(opt,name);
1230:       } else {
1231:         PetscStrncpy(tmp,name,PetscMin((size_t)(locs[c]+1),sizeof(tmp)));
1232:         PetscStrlcat(opt,tmp,sizeof(opt));
1233:         PetscStrlcat(opt,name+loce[c],sizeof(opt));
1234:       }
1235:       PetscStrlen(opt,&len);
1236:       for (i=0; i<options->N; i++) {
1237:         PetscStrncmp(options->names[i],opt,len,&match);
1238:         if (match) {
1239:           options->used[i]  = PETSC_TRUE;
1240:           if (value) *value = options->values[i];
1241:           if (set)   *set   = PETSC_TRUE;
1242:           return(0);
1243:         }
1244:       }
1245:     }
1246:   }

1248:   if (set) *set = PETSC_FALSE;
1249:   return(0);
1250: }

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

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

1258:    Input Parameters:
1259: +  options - options database, use NULL for default global database
1260: .  pre - the option prefix (may be NULL)
1261: .  name - the option name one is seeking
1262: -  mess - error message (may be NULL)

1264:    Level: advanced

1266:    Concepts: options database^rejecting option

1268: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1269:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1270:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1271:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1272:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1273:           PetscOptionsFList(), PetscOptionsEList()
1274: @*/
1275: PetscErrorCode PetscOptionsReject(PetscOptions options,const char pre[],const char name[],const char mess[])
1276: {
1278:   PetscBool      flag = PETSC_FALSE;

1281:   PetscOptionsHasName(options,pre,name,&flag);
1282:   if (flag) {
1283:     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);
1284:     else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s",pre?pre:"",name+1);
1285:   }
1286:   return(0);
1287: }

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

1292:    Not Collective

1294:    Input Parameters:
1295: .  options - options database, use NULL for default global database

1297:    Output Parameters:
1298: .  set - PETSC_TRUE if found else PETSC_FALSE.

1300:    Level: advanced

1302:    Concepts: options database^help

1304: .seealso: PetscOptionsHasName()
1305: @*/
1306: PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set)
1307: {
1310:   options = options ? options : defaultoptions;
1311:   *set = options->help;
1312:   return(0);
1313: }

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

1319:    Not Collective

1321:    Input Parameters:
1322: +  options - options database, use NULL for default global database
1323: .  pre - string to prepend to the name or NULL
1324: -  name - the option one is seeking

1326:    Output Parameters:
1327: .  set - PETSC_TRUE if found else PETSC_FALSE.

1329:    Level: beginner

1331:    Concepts: options database^has option name

1333:    Notes:
1334:    Name cannot be simply "-h".

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

1338: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1339:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1340:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1341:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1342:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1343:           PetscOptionsFList(), PetscOptionsEList()
1344: @*/
1345: PetscErrorCode PetscOptionsHasName(PetscOptions options,const char pre[],const char name[],PetscBool *set)
1346: {
1347:   const char     *value;
1349:   PetscBool      flag;

1352:   PetscOptionsFindPair(options,pre,name,&value,&flag);
1353:   if (set) *set = flag;
1354:   return(0);
1355: }

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

1360:    Not Collective

1362:    Input Paramter:
1363: .  options - the options database, use NULL for the default global database

1365:    Output Parameter:
1366: .  copts - pointer where string pointer is stored

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

1371:    Level: advanced

1373:    Concepts: options database^listing

1375: .seealso: PetscOptionsAllUsed(), PetscOptionsView()
1376: @*/
1377: PetscErrorCode PetscOptionsGetAll(PetscOptions options,char *copts[])
1378: {
1380:   PetscInt       i;
1381:   size_t         len = 1,lent = 0;
1382:   char           *coptions = NULL;

1386:   options = options ? options : defaultoptions;
1387:   /* count the length of the required string */
1388:   for (i=0; i<options->N; i++) {
1389:     PetscStrlen(options->names[i],&lent);
1390:     len += 2 + lent;
1391:     if (options->values[i]) {
1392:       PetscStrlen(options->values[i],&lent);
1393:       len += 1 + lent;
1394:     }
1395:   }
1396:   PetscMalloc1(len,&coptions);
1397:   coptions[0] = 0;
1398:   for (i=0; i<options->N; i++) {
1399:     PetscStrcat(coptions,"-");
1400:     PetscStrcat(coptions,options->names[i]);
1401:     PetscStrcat(coptions," ");
1402:     if (options->values[i]) {
1403:       PetscStrcat(coptions,options->values[i]);
1404:       PetscStrcat(coptions," ");
1405:     }
1406:   }
1407:   *copts = coptions;
1408:   return(0);
1409: }

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

1414:    Not Collective

1416:    Input Parameter:
1417: +  options - options database, use NULL for default global database
1418: -  name - string name of option

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

1423:    Level: advanced

1425: .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
1426: @*/
1427: PetscErrorCode PetscOptionsUsed(PetscOptions options,const char *name,PetscBool *used)
1428: {
1429:   PetscInt       i;

1435:   options = options ? options : defaultoptions;
1436:   *used = PETSC_FALSE;
1437:   for (i=0; i<options->N; i++) {
1438:     PetscStrcmp(options->names[i],name,used);
1439:     if (*used) {
1440:       *used = options->used[i];
1441:       break;
1442:     }
1443:   }
1444:   return(0);
1445: }

1447: /*@
1448:    PetscOptionsAllUsed - Returns a count of the number of options in the
1449:    database that have never been selected.

1451:    Not Collective

1453:    Input Parameter:
1454: .  options - options database, use NULL for default global database

1456:    Output Parameter:
1457: .  N - count of options not used

1459:    Level: advanced

1461: .seealso: PetscOptionsView()
1462: @*/
1463: PetscErrorCode PetscOptionsAllUsed(PetscOptions options,PetscInt *N)
1464: {
1465:   PetscInt     i,n = 0;

1469:   options = options ? options : defaultoptions;
1470:   for (i=0; i<options->N; i++) {
1471:     if (!options->used[i]) n++;
1472:   }
1473:   *N = n;
1474:   return(0);
1475: }

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

1480:    Not Collective

1482:    Input Parameter:
1483: .  options - options database; use NULL for default global database

1485:    Options Database Key:
1486: .  -options_left - Activates OptionsAllUsed() within PetscFinalize()

1488:    Level: advanced

1490: .seealso: PetscOptionsAllUsed()
1491: @*/
1492: PetscErrorCode PetscOptionsLeft(PetscOptions options)
1493: {
1495:   PetscInt       i;

1498:   options = options ? options : defaultoptions;
1499:   for (i=0; i<options->N; i++) {
1500:     if (!options->used[i]) {
1501:       if (options->values[i]) {
1502:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",options->names[i],options->values[i]);
1503:       } else {
1504:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",options->names[i]);
1505:       }
1506:     }
1507:   }
1508:   return(0);
1509: }

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

1514:    Not Collective

1516:    Input Parameter:
1517: .  options - options database, use NULL for default global database

1519:    Output Parameter:
1520: .  N - count of options not used
1521: .  names - names of options not used
1522: .  values - values of options not used

1524:    Level: advanced

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

1529: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft()
1530: @*/
1531: PetscErrorCode PetscOptionsLeftGet(PetscOptions options,PetscInt *N,char **names[],char **values[])
1532: {
1534:   PetscInt       i,n;

1540:   options = options ? options : defaultoptions;

1542:   /* The number of unused PETSc options */
1543:   n = 0;
1544:   for (i=0; i<options->N; i++) {
1545:     if (!options->used[i]) n++;
1546:   }
1547:   if (N) { *N = n; }
1548:   if (names)  { PetscMalloc1(n,names); }
1549:   if (values) { PetscMalloc1(n,values); }

1551:   n = 0;
1552:   if (names || values) {
1553:     for (i=0; i<options->N; i++) {
1554:       if (!options->used[i]) {
1555:         if (names)  (*names)[n]  = options->names[i];
1556:         if (values) (*values)[n] = options->values[i];
1557:         n++;
1558:       }
1559:     }
1560:   }
1561:   return(0);
1562: }

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

1567:    Not Collective

1569:    Input Parameter:
1570: .  options - options database, use NULL for default global database
1571: .  names - names of options not used
1572: .  values - values of options not used

1574:    Level: advanced

1576: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft(), PetscOptionsLeftGet()
1577: @*/
1578: PetscErrorCode PetscOptionsLeftRestore(PetscOptions options,PetscInt *N,char **names[],char **values[])
1579: {

1586:   if (N) { *N = 0; }
1587:   if (names)  { PetscFree(*names); }
1588:   if (values) { PetscFree(*values); }
1589:   return(0);
1590: }

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

1595:    Collective on PETSC_COMM_WORLD

1597:    Input Parameter:
1598: .  options - options database, use NULL for default global database

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

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

1610:    Level: intermediate

1612: .keywords: set, options, database
1613: @*/
1614: PetscErrorCode PetscOptionsSetFromOptions(PetscOptions options)
1615: {
1616:   PetscBool      flgc = PETSC_FALSE,flgm;
1618:   char           monfilename[PETSC_MAX_PATH_LEN];
1619:   PetscViewer    monviewer;

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

1625:      options = options ? options : defaultoptions;
1626:   */
1627:   PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for handling options","PetscOptions");
1628:   PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);
1629:   PetscOptionsBool("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",flgc,&flgc,NULL);
1630:   PetscOptionsEnd();
1631:   if (flgm) {
1632:     PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);
1633:     PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
1634:   }
1635:   if (flgc) { PetscOptionsMonitorCancel(); }
1636:   return(0);
1637: }

1639: /*@C
1640:    PetscOptionsMonitorDefault - Print all options set value events.

1642:    Logically Collective on PETSC_COMM_WORLD

1644:    Input Parameters:
1645: +  name  - option name string
1646: .  value - option value string
1647: -  ctx - an ASCII viewer

1649:    Level: intermediate

1651: .keywords: PetscOptions, default, monitor

1653: .seealso: PetscOptionsMonitorSet()
1654: @*/
1655: PetscErrorCode PetscOptionsMonitorDefault(const char name[],const char value[],void *ctx)
1656: {
1658:   PetscViewer    viewer = (PetscViewer)ctx;

1661:   if (!value) {
1662:     PetscViewerASCIIPrintf(viewer,"Removing option: %s\n",name,value);
1663:   } else if (!value[0]) {
1664:     PetscViewerASCIIPrintf(viewer,"Setting option: %s (no value)\n",name);
1665:   } else {
1666:     PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
1667:   }
1668:   return(0);
1669: }

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

1675:    Not Collective

1677:    Input Parameters:
1678: +  monitor - pointer to function (if this is NULL, it turns off monitoring
1679: .  mctx    - [optional] context for private data for the
1680:              monitor routine (use NULL if no context is desired)
1681: -  monitordestroy - [optional] routine that frees monitor context
1682:           (may be NULL)

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

1687: +  name - option name string
1688: .  value - option value string
1689: -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()

1691:    Options Database Keys:
1692: +    -options_monitor    - sets PetscOptionsMonitorDefault()
1693: -    -options_monitor_cancel - cancels all monitors that have
1694:                           been hardwired into a code by
1695:                           calls to PetscOptionsMonitorSet(), but
1696:                           does not cancel those set via
1697:                           the options database.

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

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

1708:    Level: beginner

1710: .keywords: PetscOptions, set, monitor

1712: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
1713: @*/
1714: PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
1715: {
1716:   PetscOptions options = defaultoptions;

1719:   if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
1720:   options->monitor[options->numbermonitors]          = monitor;
1721:   options->monitordestroy[options->numbermonitors]   = monitordestroy;
1722:   options->monitorcontext[options->numbermonitors++] = (void*)mctx;
1723:   return(0);
1724: }

1726: /*@
1727:    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.

1729:    Not Collective

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

1736:    Level: intermediate

1738: .keywords: PetscOptions, set, monitor

1740: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
1741: @*/
1742: PetscErrorCode PetscOptionsMonitorCancel(void)
1743: {
1745:   PetscInt       i;
1746:   PetscOptions   options = defaultoptions;

1749:   for (i=0; i<options->numbermonitors; i++) {
1750:     if (options->monitordestroy[i]) {
1751:       (*options->monitordestroy[i])(&options->monitorcontext[i]);
1752:     }
1753:   }
1754:   options->numbermonitors = 0;
1755:   return(0);
1756: }

1758: /*
1759:    PetscOptionsStringToBool - Converts string to PetscBool , handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
1760: */
1761: PetscErrorCode PetscOptionsStringToBool(const char value[],PetscBool *a)
1762: {
1763:   PetscBool      istrue,isfalse;
1764:   size_t         len;

1768:   PetscStrlen(value,&len);
1769:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Character string of length zero has no logical value");
1770:   PetscStrcasecmp(value,"TRUE",&istrue);
1771:   if (istrue) {*a = PETSC_TRUE; return(0);}
1772:   PetscStrcasecmp(value,"YES",&istrue);
1773:   if (istrue) {*a = PETSC_TRUE; return(0);}
1774:   PetscStrcasecmp(value,"1",&istrue);
1775:   if (istrue) {*a = PETSC_TRUE; return(0);}
1776:   PetscStrcasecmp(value,"on",&istrue);
1777:   if (istrue) {*a = PETSC_TRUE; return(0);}
1778:   PetscStrcasecmp(value,"FALSE",&isfalse);
1779:   if (isfalse) {*a = PETSC_FALSE; return(0);}
1780:   PetscStrcasecmp(value,"NO",&isfalse);
1781:   if (isfalse) {*a = PETSC_FALSE; return(0);}
1782:   PetscStrcasecmp(value,"0",&isfalse);
1783:   if (isfalse) {*a = PETSC_FALSE; return(0);}
1784:   PetscStrcasecmp(value,"off",&isfalse);
1785:   if (isfalse) {*a = PETSC_FALSE; return(0);}
1786:   SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value);
1787: }

1789: /*
1790:    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
1791: */
1792: PetscErrorCode PetscOptionsStringToInt(const char name[],PetscInt *a)
1793: {
1795:   size_t         len;
1796:   PetscBool      decide,tdefault,mouse;

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

1802:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
1803:   if (!tdefault) {
1804:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
1805:   }
1806:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
1807:   if (!decide) {
1808:     PetscStrcasecmp(name,"DECIDE",&decide);
1809:   }
1810:   PetscStrcasecmp(name,"mouse",&mouse);

1812:   if (tdefault)    *a = PETSC_DEFAULT;
1813:   else if (decide) *a = PETSC_DECIDE;
1814:   else if (mouse)  *a = -1;
1815:   else {
1816:     char *endptr;
1817:     long strtolval;

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

1822: #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
1823:     (void) strtolval;
1824:     *a = atoll(name);
1825: #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
1826:     (void) strtolval;
1827:     *a = _atoi64(name);
1828: #else
1829:     *a = (PetscInt)strtolval;
1830: #endif
1831:   }
1832:   return(0);
1833: }

1835: #if defined(PETSC_USE_REAL___FLOAT128)
1836: #include <quadmath.h>
1837: #endif

1839: static PetscErrorCode PetscStrtod(const char name[],PetscReal *a,char **endptr)
1840: {
1842: #if defined(PETSC_USE_REAL___FLOAT128)
1843:   *a = strtoflt128(name,endptr);
1844: #else
1845:   *a = (PetscReal)strtod(name,endptr);
1846: #endif
1847:   return(0);
1848: }

1850: static PetscErrorCode PetscStrtoz(const char name[],PetscScalar *a,char **endptr,PetscBool *isImaginary)
1851: {
1852:   PetscBool      hasi = PETSC_FALSE;
1853:   char           *ptr;
1854:   PetscReal      strtoval;

1858:   PetscStrtod(name,&strtoval,&ptr);
1859:   if (ptr == name) {
1860:     strtoval = 1.;
1861:     hasi = PETSC_TRUE;
1862:     if (name[0] == 'i') {
1863:       ptr++;
1864:     } else if (name[0] == '+' && name[1] == 'i') {
1865:       ptr += 2;
1866:     } else if (name[0] == '-' && name[1] == 'i') {
1867:       strtoval = -1.;
1868:       ptr += 2;
1869:     }
1870:   } else if (*ptr == 'i') {
1871:     hasi = PETSC_TRUE;
1872:     ptr++;
1873:   }
1874:   *endptr = ptr;
1875:   *isImaginary = hasi;
1876:   if (hasi) {
1877: #if !defined(PETSC_USE_COMPLEX)
1878:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s contains imaginary but complex not supported ",name);
1879: #else
1880:     *a = PetscCMPLX(0.,strtoval);
1881: #endif
1882:   } else {
1883:     *a = strtoval;
1884:   }
1885:   return(0);
1886: }

1888: /*
1889:    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
1890: */
1891: PetscErrorCode PetscOptionsStringToReal(const char name[],PetscReal *a)
1892: {
1893:   size_t         len;
1894:   PetscBool      match;
1895:   char           *endptr;

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

1902:   PetscStrcasecmp(name,"PETSC_DEFAULT",&match);
1903:   if (!match) {
1904:     PetscStrcasecmp(name,"DEFAULT",&match);
1905:   }
1906:   if (match) {*a = PETSC_DEFAULT; return(0);}

1908:   PetscStrcasecmp(name,"PETSC_DECIDE",&match);
1909:   if (!match) {
1910:     PetscStrcasecmp(name,"DECIDE",&match);
1911:   }
1912:   if (match) {*a = PETSC_DECIDE; return(0);}

1914:   PetscStrtod(name,a,&endptr);
1915:   if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value",name);
1916:   return(0);
1917: }

1919: PetscErrorCode PetscOptionsStringToScalar(const char name[],PetscScalar *a)
1920: {
1921:   PetscBool      imag1;
1922:   size_t         len;
1923:   PetscScalar    val = 0.;
1924:   char           *ptr = NULL;

1928:   PetscStrlen(name,&len);
1929:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
1930:   PetscStrtoz(name,&val,&ptr,&imag1);
1931: #if defined(PETSC_USE_COMPLEX)
1932:   if ((size_t) (ptr - name) < len) {
1933:     PetscBool   imag2;
1934:     PetscScalar val2;

1936:     PetscStrtoz(ptr,&val2,&ptr,&imag2);
1937:     if (imag1 || !imag2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s: must specify imaginary component second",name);
1938:     val = PetscCMPLX(PetscRealPart(val),PetscImaginaryPart(val2));
1939:   }
1940: #endif
1941:   if ((size_t) (ptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
1942:   *a = val;
1943:   return(0);
1944: }

1946: /*@C
1947:    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
1948:             option in the database.

1950:    Not Collective

1952:    Input Parameters:
1953: +  options - options database, use NULL for default global database
1954: .  pre - the string to prepend to the name or NULL
1955: -  name - the option one is seeking

1957:    Output Parameter:
1958: +  ivalue - the logical value to return
1959: -  set - PETSC_TRUE  if found, else PETSC_FALSE

1961:    Level: beginner

1963:    Notes:
1964:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1965:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

1967:       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
1968:      is equivalent to -requested_bool true

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

1973:    Concepts: options database^has logical

1975: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1976:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
1977:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1978:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1979:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1980:           PetscOptionsFList(), PetscOptionsEList()
1981: @*/
1982: PetscErrorCode PetscOptionsGetBool(PetscOptions options,const char pre[],const char name[],PetscBool *ivalue,PetscBool *set)
1983: {
1984:   const char     *value;
1985:   PetscBool      flag;

1991:   PetscOptionsFindPair(options,pre,name,&value,&flag);
1992:   if (flag) {
1993:     if (set) *set = PETSC_TRUE;
1994:     if (!value) {
1995:       if (ivalue) *ivalue = PETSC_TRUE;
1996:     } else {
1997:       PetscOptionsStringToBool(value, &flag);
1998:       if (ivalue) *ivalue = flag;
1999:     }
2000:   } else {
2001:     if (set) *set = PETSC_FALSE;
2002:   }
2003:   return(0);
2004: }

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

2009:    Not Collective

2011:    Input Parameters:
2012: +  options - options database, use NULL for default global database
2013: .  pre - the string to prepend to the name or NULL
2014: .  opt - option name
2015: .  list - the possible choices (one of these must be selected, anything else is invalid)
2016: .  ntext - number of choices

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

2022:    Level: intermediate

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

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

2030:    Concepts: options database^list

2032: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2033:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2034:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2035:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2036:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2037:           PetscOptionsFList(), PetscOptionsEList()
2038: @*/
2039: PetscErrorCode PetscOptionsGetEList(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool *set)
2040: {
2042:   size_t         alen,len = 0;
2043:   char           *svalue;
2044:   PetscBool      aset,flg = PETSC_FALSE;
2045:   PetscInt       i;

2049:   for (i=0; i<ntext; i++) {
2050:     PetscStrlen(list[i],&alen);
2051:     if (alen > len) len = alen;
2052:   }
2053:   len += 5; /* a little extra space for user mistypes */
2054:   PetscMalloc1(len,&svalue);
2055:   PetscOptionsGetString(options,pre,opt,svalue,len,&aset);
2056:   if (aset) {
2057:     PetscEListFind(ntext,list,svalue,value,&flg);
2058:     if (!flg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre ? pre : "",opt+1);
2059:     if (set) *set = PETSC_TRUE;
2060:   } else if (set) *set = PETSC_FALSE;
2061:   PetscFree(svalue);
2062:   return(0);
2063: }

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

2068:    Not Collective

2070:    Input Parameters:
2071: +  options - options database, use NULL for default global database
2072: .  pre - option prefix or NULL
2073: .  opt - option name
2074: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2075: -  defaultv - the default (current) value

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

2081:    Level: beginner

2083:    Concepts: options database

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

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

2091: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2092:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2093:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2094:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2095:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2096:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2097:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2098: @*/
2099: PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set)
2100: {
2102:   PetscInt       ntext = 0,tval;
2103:   PetscBool      fset;

2107:   while (list[ntext++]) {
2108:     if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
2109:   }
2110:   if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
2111:   ntext -= 3;
2112:   PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset);
2113:   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2114:   if (fset) *value = (PetscEnum)tval;
2115:   if (set) *set = fset;
2116:   return(0);
2117: }

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

2122:    Not Collective

2124:    Input Parameters:
2125: +  options - options database, use NULL for default global database
2126: .  pre - the string to prepend to the name or NULL
2127: -  name - the option one is seeking

2129:    Output Parameter:
2130: +  ivalue - the integer value to return
2131: -  set - PETSC_TRUE if found, else PETSC_FALSE

2133:    Level: beginner

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

2139:    Concepts: options database^has int

2141: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
2142:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2143:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2144:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2145:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2146:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2147:           PetscOptionsFList(), PetscOptionsEList()
2148: @*/
2149: PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set)
2150: {
2151:   const char     *value;
2153:   PetscBool      flag;

2158:   PetscOptionsFindPair(options,pre,name,&value,&flag);
2159:   if (flag) {
2160:     if (!value) {
2161:       if (set) *set = PETSC_FALSE;
2162:     } else {
2163:       if (set) *set = PETSC_TRUE;
2164:       PetscOptionsStringToInt(value,ivalue);
2165:     }
2166:   } else {
2167:     if (set) *set = PETSC_FALSE;
2168:   }
2169:   return(0);
2170: }

2172: /*@C
2173:    PetscOptionsGetReal - Gets the double precision value for a particular
2174:    option in the database.

2176:    Not Collective

2178:    Input Parameters:
2179: +  options - options database, use NULL for default global database
2180: .  pre - string to prepend to each name or NULL
2181: -  name - the option one is seeking

2183:    Output Parameter:
2184: +  dvalue - the double value to return
2185: -  set - PETSC_TRUE if found, PETSC_FALSE if not found

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

2191:    Level: beginner

2193:    Concepts: options database^has double

2195: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2196:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
2197:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2198:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2199:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2200:           PetscOptionsFList(), PetscOptionsEList()
2201: @*/
2202: PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set)
2203: {
2204:   const char     *value;
2205:   PetscBool      flag;

2211:   PetscOptionsFindPair(options,pre,name,&value,&flag);
2212:   if (flag) {
2213:     if (!value) {
2214:       if (set) *set = PETSC_FALSE;
2215:     } else {
2216:       if (set) *set = PETSC_TRUE;
2217:       PetscOptionsStringToReal(value,dvalue);
2218:     }
2219:   } else {
2220:     if (set) *set = PETSC_FALSE;
2221:   }
2222:   return(0);
2223: }

2225: /*@C
2226:    PetscOptionsGetScalar - Gets the scalar value for a particular
2227:    option in the database.

2229:    Not Collective

2231:    Input Parameters:
2232: +  options - options database, use NULL for default global database
2233: .  pre - string to prepend to each name or NULL
2234: -  name - the option one is seeking

2236:    Output Parameter:
2237: +  dvalue - the double value to return
2238: -  set - PETSC_TRUE if found, else PETSC_FALSE

2240:    Level: beginner

2242:    Usage:
2243:    A complex number 2+3i must be specified with NO spaces

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

2249:    Concepts: options database^has scalar

2251: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2252:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2253:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2254:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2255:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2256:           PetscOptionsFList(), PetscOptionsEList()
2257: @*/
2258: PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set)
2259: {
2260:   const char     *value;
2261:   PetscBool      flag;

2267:   PetscOptionsFindPair(options,pre,name,&value,&flag);
2268:   if (flag) {
2269:     if (!value) {
2270:       if (set) *set = PETSC_FALSE;
2271:     } else {
2272: #if !defined(PETSC_USE_COMPLEX)
2273:       PetscOptionsStringToReal(value,dvalue);
2274: #else
2275:       PetscOptionsStringToScalar(value,dvalue);
2276: #endif
2277:       if (set) *set = PETSC_TRUE;
2278:     }
2279:   } else { /* flag */
2280:     if (set) *set = PETSC_FALSE;
2281:   }
2282:   return(0);
2283: }

2285: /*@C
2286:    PetscOptionsGetString - Gets the string value for a particular option in
2287:    the database.

2289:    Not Collective

2291:    Input Parameters:
2292: +  options - options database, use NULL for default global database
2293: .  pre - string to prepend to name or NULL
2294: .  name - the option one is seeking
2295: -  len - maximum length of the string including null termination

2297:    Output Parameters:
2298: +  string - location to copy string
2299: -  set - PETSC_TRUE if found, else PETSC_FALSE

2301:    Level: beginner

2303:    Fortran Note:
2304:    The Fortran interface is slightly different from the C/C++
2305:    interface (len is not used).  Sample usage in Fortran follows
2306: .vb
2307:       character *20    string
2308:       PetscErrorCode   ierr
2309:       PetscBool        set
2310:       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2311: .ve

2313:    Notes:
2314:     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

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

2319:    Concepts: options database^string

2321:     Note:
2322:       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).

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

2340:   PetscOptionsFindPair(options,pre,name,&value,&flag);
2341:   if (!flag) {
2342:     if (set) *set = PETSC_FALSE;
2343:   } else {
2344:     if (set) *set = PETSC_TRUE;
2345:     if (value) {
2346:       PetscStrncpy(string,value,len);
2347:     } else {
2348:       PetscMemzero(string,len);
2349:     }
2350:   }
2351:   return(0);
2352: }

2354: char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[])
2355: {
2356:   const char     *value;
2357:   PetscBool      flag;

2361:   PetscOptionsFindPair(options,pre,name,&value,&flag);if (ierr) return(0);
2362:   if (flag) PetscFunctionReturn((char*)value);
2363:   else return(0);
2364: }

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

2371:    Not Collective

2373:    Input Parameters:
2374: +  options - options database, use NULL for default global database
2375: .  pre - string to prepend to each name or NULL
2376: .  name - the option one is seeking
2377: -  nmax - maximum number of values to retrieve

2379:    Output Parameter:
2380: +  dvalue - the integer values to return
2381: .  nmax - actual number of values retreived
2382: -  set - PETSC_TRUE if found, else PETSC_FALSE

2384:    Level: beginner

2386:    Concepts: options database^array of ints

2388:    Notes:
2389:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
2390:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

2392: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2393:           PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2394:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2395:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2396:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2397:           PetscOptionsFList(), PetscOptionsEList()
2398: @*/
2399: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set)
2400: {
2401:   const char     *svalue;
2402:   char           *value;
2404:   PetscInt       n = 0;
2405:   PetscBool      flag;
2406:   PetscToken     token;


2413:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2414:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2415:   if (set) *set = PETSC_TRUE;
2416:   PetscTokenCreate(svalue,',',&token);
2417:   PetscTokenFind(token,&value);
2418:   while (value && n < *nmax) {
2419:     PetscOptionsStringToBool(value,dvalue);
2420:     PetscTokenFind(token,&value);
2421:     dvalue++;
2422:     n++;
2423:   }
2424:   PetscTokenDestroy(&token);
2425:   *nmax = n;
2426:   return(0);
2427: }

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

2432:    Not Collective

2434:    Input Parameters:
2435: +  options - options database, use NULL for default global database
2436: .  pre - option prefix or NULL
2437: .  name - option name
2438: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2439: -  nmax - maximum number of values to retrieve

2441:    Output Parameters:
2442: +  ivalue - the  enum values to return
2443: .  nmax - actual number of values retreived
2444: -  set - PETSC_TRUE if found, else PETSC_FALSE

2446:    Level: beginner

2448:    Concepts: options database

2450:    Notes:
2451:    The array must be passed as a comma separated list.

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

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

2457: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2458:           PetscOptionsGetEnum(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2459:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(),
2460:           PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(),
2461:           PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2462:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2463: @*/
2464: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set)
2465: {
2466:   const char     *svalue;
2467:   char           *value;
2468:   PetscInt       n = 0;
2469:   PetscEnum      evalue;
2470:   PetscBool      flag;
2471:   PetscToken     token;


2480:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2481:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2482:   if (set) *set = PETSC_TRUE;
2483:   PetscTokenCreate(svalue,',',&token);
2484:   PetscTokenFind(token,&value);
2485:   while (value && n < *nmax) {
2486:     PetscEnumFind(list,value,&evalue,&flag);
2487:     if (!flag) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
2488:     ivalue[n++] = evalue;
2489:     PetscTokenFind(token,&value);
2490:   }
2491:   PetscTokenDestroy(&token);
2492:   *nmax = n;
2493:   return(0);
2494: }

2496: /*@C
2497:    PetscOptionsGetIntArray - Gets an array of integer values for a particular
2498:    option in the database.

2500:    Not Collective

2502:    Input Parameters:
2503: +  options - options database, use NULL for default global database
2504: .  pre - string to prepend to each name or NULL
2505: .  name - the option one is seeking
2506: -  nmax - maximum number of values to retrieve

2508:    Output Parameter:
2509: +  ivalue - the integer values to return
2510: .  nmax - actual number of values retreived
2511: -  set - PETSC_TRUE if found, else PETSC_FALSE

2513:    Level: beginner

2515:    Notes:
2516:    The array can be passed as
2517:    a comma separated list:                                 0,1,2,3,4,5,6,7
2518:    a range (start-end+1):                                  0-8
2519:    a range with given increment (start-end+1:inc):         0-7:2
2520:    a combination of values and ranges separated by commas: 0,1-8,8-15:2

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

2524:    Concepts: options database^array of ints

2526: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2527:           PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2528:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2529:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2530:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2531:           PetscOptionsFList(), PetscOptionsEList()
2532: @*/
2533: PetscErrorCode PetscOptionsGetIntArray(PetscOptions options,const char pre[],const char name[],PetscInt ivalue[],PetscInt *nmax,PetscBool *set)
2534: {
2535:   const char     *svalue;
2536:   char           *value;
2538:   PetscInt       n = 0,i,j,start,end,inc,nvalues;
2539:   size_t         len;
2540:   PetscBool      flag,foundrange;
2541:   PetscToken     token;


2548:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2549:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2550:   if (set) *set = PETSC_TRUE;
2551:   PetscTokenCreate(svalue,',',&token);
2552:   PetscTokenFind(token,&value);
2553:   while (value && n < *nmax) {
2554:     /* look for form  d-D where d and D are integers */
2555:     foundrange = PETSC_FALSE;
2556:     PetscStrlen(value,&len);
2557:     if (value[0] == '-') i=2;
2558:     else i=1;
2559:     for (;i<(int)len; i++) {
2560:       if (value[i] == '-') {
2561:         if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
2562:         value[i] = 0;

2564:         PetscOptionsStringToInt(value,&start);
2565:         inc  = 1;
2566:         j    = i+1;
2567:         for (;j<(int)len; j++) {
2568:           if (value[j] == ':') {
2569:             value[j] = 0;

2571:             PetscOptionsStringToInt(value+j+1,&inc);
2572:             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);
2573:             break;
2574:           }
2575:         }
2576:         PetscOptionsStringToInt(value+i+1,&end);
2577:         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);
2578:         nvalues = (end-start)/inc + (end-start)%inc;
2579:         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);
2580:         for (;start<end; start+=inc) {
2581:           *ivalue = start; ivalue++;n++;
2582:         }
2583:         foundrange = PETSC_TRUE;
2584:         break;
2585:       }
2586:     }
2587:     if (!foundrange) {
2588:       PetscOptionsStringToInt(value,ivalue);
2589:       ivalue++;
2590:       n++;
2591:     }
2592:     PetscTokenFind(token,&value);
2593:   }
2594:   PetscTokenDestroy(&token);
2595:   *nmax = n;
2596:   return(0);
2597: }

2599: /*@C
2600:    PetscOptionsGetRealArray - Gets an array of double precision values for a
2601:    particular option in the database.  The values must be separated with
2602:    commas with no intervening spaces.

2604:    Not Collective

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

2612:    Output Parameters:
2613: +  dvalue - the double values to return
2614: .  nmax - actual number of values retreived
2615: -  set - PETSC_TRUE if found, else PETSC_FALSE

2617:    Level: beginner

2619:    Concepts: options database^array of doubles

2621: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2622:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2623:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2624:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2625:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2626:           PetscOptionsFList(), PetscOptionsEList()
2627: @*/
2628: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set)
2629: {
2630:   const char     *svalue;
2631:   char           *value;
2633:   PetscInt       n = 0;
2634:   PetscBool      flag;
2635:   PetscToken     token;


2642:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2643:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2644:   if (set) *set = PETSC_TRUE;
2645:   PetscTokenCreate(svalue,',',&token);
2646:   PetscTokenFind(token,&value);
2647:   while (value && n < *nmax) {
2648:     PetscOptionsStringToReal(value,dvalue++);
2649:     PetscTokenFind(token,&value);
2650:     n++;
2651:   }
2652:   PetscTokenDestroy(&token);
2653:   *nmax = n;
2654:   return(0);
2655: }

2657: /*@C
2658:    PetscOptionsGetScalarArray - Gets an array of scalars for a
2659:    particular option in the database.  The values must be separated with
2660:    commas with no intervening spaces.

2662:    Not Collective

2664:    Input Parameters:
2665: +  options - options database, use NULL for default global database
2666: .  pre - string to prepend to each name or NULL
2667: .  name - the option one is seeking
2668: -  nmax - maximum number of values to retrieve

2670:    Output Parameters:
2671: +  dvalue - the scalar values to return
2672: .  nmax - actual number of values retreived
2673: -  set - PETSC_TRUE if found, else PETSC_FALSE

2675:    Level: beginner

2677:    Concepts: options database^array of doubles

2679: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2680:           PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2681:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2682:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2683:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2684:           PetscOptionsFList(), PetscOptionsEList()
2685: @*/
2686: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set)
2687: {
2688:   const char     *svalue;
2689:   char           *value;
2691:   PetscInt       n = 0;
2692:   PetscBool      flag;
2693:   PetscToken     token;


2700:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2701:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2702:   if (set) *set = PETSC_TRUE;
2703:   PetscTokenCreate(svalue,',',&token);
2704:   PetscTokenFind(token,&value);
2705:   while (value && n < *nmax) {
2706:     PetscOptionsStringToScalar(value,dvalue++);
2707:     PetscTokenFind(token,&value);
2708:     n++;
2709:   }
2710:   PetscTokenDestroy(&token);
2711:   *nmax = n;
2712:   return(0);
2713: }

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

2720:    Not Collective

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

2728:    Output Parameter:
2729: +  strings - location to copy strings
2730: -  set - PETSC_TRUE if found, else PETSC_FALSE

2732:    Level: beginner

2734:    Notes:
2735:    The user should pass in an array of pointers to char, to hold all the
2736:    strings returned by this function.

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

2741:    Contributed by Matthew Knepley.

2743:    Concepts: options database^array of strings

2745: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2746:           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2747:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2748:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2749:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2750:           PetscOptionsFList(), PetscOptionsEList()
2751: @*/
2752: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set)
2753: {
2754:   const char     *svalue;
2755:   char           *value;
2757:   PetscInt       n = 0;
2758:   PetscBool      flag;
2759:   PetscToken     token;


2766:   PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2767:   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2768:   if (set) *set = PETSC_TRUE;
2769:   PetscTokenCreate(svalue,',',&token);
2770:   PetscTokenFind(token,&value);
2771:   while (value && n < *nmax) {
2772:     PetscStrallocpy(value,&strings[n]);
2773:     PetscTokenFind(token,&value);
2774:     n++;
2775:   }
2776:   PetscTokenDestroy(&token);
2777:   *nmax = n;
2778:   return(0);
2779: }

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

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

2786:    Not Collective

2788:    Input Parameters:
2789: +  pre - string to prepend to name or NULL
2790: .  oldname - the old, deprecated option
2791: .  newname - the new option, or NULL if option is purely removed
2792: .  version - a string describing the version of first deprecation, e.g. "3.9"
2793: -  info - additional information string, or NULL.

2795:    Options Database Keys:
2796: . -options_suppress_deprecated_warnings - do not print deprecation warnings

2798:    Notes:
2799:    Must be called between PetscOptionsBegin() and PetscOptionsEnd().
2800:    If newname is provided, the old option is replaced. Otherwise, it remains
2801:    in the options database.
2802:    If an option is not replaced, the info argument should be used to advise the user
2803:    on how to proceed.
2804:    There is a limit on the length of the warning printed, so very long strings
2805:    provided as info may be truncated.

2807:    Level: developer

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

2811: @*/
2812: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[])
2813: {
2814:   PetscErrorCode     ierr;
2815:   PetscBool          found,quiet;
2816:   const char         *value;
2817:   const char * const quietopt="-options_suppress_deprecated_warnings";
2818:   char               msg[4096];


2824:   PetscOptionsFindPair(PetscOptionsObject->options,PetscOptionsObject->prefix,oldname,&value,&found);
2825:   if (found) {
2826:     if (newname) {
2827:       if (PetscOptionsObject->prefix) {
2828:         PetscOptionsPrefixPush(PetscOptionsObject->options,PetscOptionsObject->prefix);
2829:       }
2830:       PetscOptionsSetValue(PetscOptionsObject->options,newname,value);
2831:       if (PetscOptionsObject->prefix) {
2832:         PetscOptionsPrefixPop(PetscOptionsObject->options);
2833:       }
2834:       PetscOptionsClearValue(PetscOptionsObject->options,oldname);
2835:     }
2836:     quiet = PETSC_FALSE;
2837:     PetscOptionsGetBool(PetscOptionsObject->options,NULL,quietopt,&quiet,NULL);
2838:     if (!quiet) {
2839:       PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option ");
2840:       PetscStrcat(msg,oldname);
2841:       PetscStrcat(msg," is deprecated as of version ");
2842:       PetscStrcat(msg,version);
2843:       PetscStrcat(msg," and will be removed in a future release.");
2844:       if (newname) {
2845:         PetscStrcat(msg," Please use the option ");
2846:         PetscStrcat(msg,newname);
2847:         PetscStrcat(msg," instead.");
2848:       }
2849:       if (info) {
2850:         PetscStrcat(msg," ");
2851:         PetscStrcat(msg,info);
2852:       }
2853:       PetscStrcat(msg," (Silence this warning with ");
2854:       PetscStrcat(msg,quietopt);
2855:       PetscStrcat(msg,")\n");
2856:       PetscPrintf(PetscOptionsObject->comm,msg);
2857:     }
2858:   }
2859:   return(0);
2860: }