xref: /petsc/src/sys/objects/options.c (revision 5fd668637986a8d8518383a9159eebc368e1d5b4)
1 
2 /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
3 #define PETSC_DESIRE_FEATURE_TEST_MACROS
4 
5 /*
6    These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
7    This provides the low-level interface, the high level interface is in aoptions.c
8 
9    Some routines use regular malloc and free because it cannot know  what malloc is requested with the
10    options database until it has already processed the input.
11 */
12 
13 #include <petscsys.h>        /*I  "petscsys.h"   I*/
14 #include <ctype.h>
15 #if defined(PETSC_HAVE_STDLIB_H)
16 #include <stdlib.h>
17 #endif
18 #if defined(PETSC_HAVE_MALLOC_H)
19 #include <malloc.h>
20 #endif
21 #if defined(PETSC_HAVE_SYS_PARAM_H)
22 #include <sys/param.h>
23 #endif
24 #if defined(PETSC_HAVE_YAML)
25 #include <yaml.h>
26 #endif
27 
28 /*
29     This table holds all the options set by the user. For simplicity, we use a static size database
30 */
31 #define MAXOPTIONS 512
32 #define MAXALIASES 25
33 #define MAXOPTIONSMONITORS 5
34 #define MAXPREFIXES 25
35 
36 typedef struct {
37   int            N,argc,Naliases;
38   char           **args,*names[MAXOPTIONS],*values[MAXOPTIONS];
39   char           *aliases1[MAXALIASES],*aliases2[MAXALIASES];
40   PetscBool      used[MAXOPTIONS];
41   PetscBool      namegiven;
42   char           programname[PETSC_MAX_PATH_LEN]; /* HP includes entire path in name */
43 
44   /* --------User (or default) routines (most return -1 on error) --------*/
45   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], void*); /* returns control to user after */
46   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void**);         /* */
47   void           *monitorcontext[MAXOPTIONSMONITORS];                  /* to pass arbitrary user data into monitor */
48   PetscInt       numbermonitors;                                       /* to, for instance, detect options being set */
49 
50   /* Prefixes */
51   PetscInt prefixind,prefixstack[MAXPREFIXES];
52   char prefix[2048];
53 } PetscOptionsTable;
54 
55 
56 static PetscOptionsTable      *options = 0;
57 extern PetscOptionsObjectType PetscOptionsObject;
58 
59 /*
60     Options events monitor
61 */
62 #define PetscOptionsMonitor(name,value)                                     \
63         { PetscErrorCode _ierr; PetscInt _i,_im = options->numbermonitors; \
64           for (_i=0; _i<_im; _i++) {\
65             _ierr = (*options->monitor[_i])(name, value, options->monitorcontext[_i]);CHKERRQ(_ierr); \
66           } \
67         }
68 
69 #undef __FUNCT__
70 #define __FUNCT__ "PetscOptionsStringToInt"
71 /*
72    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
73 */
74 PetscErrorCode  PetscOptionsStringToInt(const char name[],PetscInt *a)
75 {
76   PetscErrorCode ierr;
77   size_t         i,len;
78   PetscBool      decide,tdefault,mouse;
79 
80   PetscFunctionBegin;
81   ierr = PetscStrlen(name,&len);CHKERRQ(ierr);
82   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
83 
84   ierr = PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);CHKERRQ(ierr);
85   if (!tdefault) {
86     ierr = PetscStrcasecmp(name,"DEFAULT",&tdefault);CHKERRQ(ierr);
87   }
88   ierr = PetscStrcasecmp(name,"PETSC_DECIDE",&decide);CHKERRQ(ierr);
89   if (!decide) {
90     ierr = PetscStrcasecmp(name,"DECIDE",&decide);CHKERRQ(ierr);
91   }
92   ierr = PetscStrcasecmp(name,"mouse",&mouse);CHKERRQ(ierr);
93 
94   if (tdefault) {
95     *a = PETSC_DEFAULT;
96   } else if (decide) {
97     *a = PETSC_DECIDE;
98   } else if (mouse) {
99     *a = -1;
100   } else {
101     if (name[0] != '+' && name[0] != '-' && name[0] < '0' && name[0] > '9') {
102       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);
103     }
104     for (i=1; i<len; i++) {
105       if (name[i] < '0' || name[i] > '9') {
106         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);
107       }
108     }
109 
110 #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
111     *a = atoll(name);
112 #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
113     *a = _atoi64(name);
114 #else
115     *a = (PetscInt)atoi(name);
116 #endif
117   }
118   PetscFunctionReturn(0);
119 }
120 
121 #undef __FUNCT__
122 #define __FUNCT__ "PetscOptionsStringToReal"
123 /*
124    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
125 */
126 PetscErrorCode  PetscOptionsStringToReal(const char name[],PetscReal *a)
127 {
128   PetscErrorCode ierr;
129   size_t         len;
130   PetscBool      decide,tdefault;
131 
132   PetscFunctionBegin;
133   ierr = PetscStrlen(name,&len);CHKERRQ(ierr);
134   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
135 
136   ierr = PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);CHKERRQ(ierr);
137   if (!tdefault) {
138     ierr = PetscStrcasecmp(name,"DEFAULT",&tdefault);CHKERRQ(ierr);
139   }
140   ierr = PetscStrcasecmp(name,"PETSC_DECIDE",&decide);CHKERRQ(ierr);
141   if (!decide) {
142     ierr = PetscStrcasecmp(name,"DECIDE",&decide);CHKERRQ(ierr);
143   }
144 
145   if (tdefault) {
146     *a = PETSC_DEFAULT;
147   } else if (decide) {
148     *a = PETSC_DECIDE;
149   } else {
150     if (name[0] != '+' && name[0] != '-' && name[0] != '.' && name[0] < '0' && name[0] > '9') {
151       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
152     }
153     *a  = atof(name);
154   }
155   PetscFunctionReturn(0);
156 }
157 
158 #undef __FUNCT__
159 #define __FUNCT__ "PetscOptionsStringToBool"
160 /*
161    PetscOptionsStringToBool - Converts string to PetscBool , handles cases like "yes", "no", "true", "false", "0", "1"
162 */
163 PetscErrorCode  PetscOptionsStringToBool(const char value[], PetscBool  *a)
164 {
165   PetscBool      istrue, isfalse;
166   size_t         len;
167   PetscErrorCode ierr;
168 
169   PetscFunctionBegin;
170   ierr = PetscStrlen(value, &len);CHKERRQ(ierr);
171   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Character string of length zero has no logical value");
172   ierr = PetscStrcasecmp(value,"TRUE",&istrue);CHKERRQ(ierr);
173   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
174   ierr = PetscStrcasecmp(value,"YES",&istrue);CHKERRQ(ierr);
175   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
176   ierr = PetscStrcasecmp(value,"1",&istrue);CHKERRQ(ierr);
177   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
178   ierr = PetscStrcasecmp(value,"on",&istrue);CHKERRQ(ierr);
179   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
180   ierr = PetscStrcasecmp(value,"FALSE",&isfalse);CHKERRQ(ierr);
181   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
182   ierr = PetscStrcasecmp(value,"NO",&isfalse);CHKERRQ(ierr);
183   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
184   ierr = PetscStrcasecmp(value,"0",&isfalse);CHKERRQ(ierr);
185   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
186   ierr = PetscStrcasecmp(value,"off",&isfalse);CHKERRQ(ierr);
187   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
188   SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
189   PetscFunctionReturn(0);
190 }
191 
192 #undef __FUNCT__
193 #define __FUNCT__ "PetscGetProgramName"
194 /*@C
195     PetscGetProgramName - Gets the name of the running program.
196 
197     Not Collective
198 
199     Input Parameter:
200 .   len - length of the string name
201 
202     Output Parameter:
203 .   name - the name of the running program
204 
205    Level: advanced
206 
207     Notes:
208     The name of the program is copied into the user-provided character
209     array of length len.  On some machines the program name includes
210     its entire path, so one should generally set len >= PETSC_MAX_PATH_LEN.
211 @*/
212 PetscErrorCode  PetscGetProgramName(char name[],size_t len)
213 {
214   PetscErrorCode ierr;
215 
216   PetscFunctionBegin;
217   if (!options) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call PetscInitialize() first");
218   if (!options->namegiven) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to determine program name");
219   ierr = PetscStrncpy(name,options->programname,len);CHKERRQ(ierr);
220   PetscFunctionReturn(0);
221 }
222 
223 #undef __FUNCT__
224 #define __FUNCT__ "PetscSetProgramName"
225 PetscErrorCode  PetscSetProgramName(const char name[])
226 {
227   PetscErrorCode ierr;
228 
229   PetscFunctionBegin;
230   options->namegiven = PETSC_TRUE;
231   ierr  = PetscStrncpy(options->programname,name,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
232   PetscFunctionReturn(0);
233 }
234 
235 #undef __FUNCT__
236 #define __FUNCT__ "PetscOptionsValidKey"
237 /*@
238     PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
239 
240    Input Parameter:
241 .    in_str - string to check if valid
242 
243    Output Parameter:
244 .    key - PETSC_TRUE if a valid key
245 
246   Level: intermediate
247 
248 @*/
249 PetscErrorCode  PetscOptionsValidKey(const char in_str[],PetscBool  *key)
250 {
251   PetscFunctionBegin;
252   *key = PETSC_FALSE;
253   if (!in_str) PetscFunctionReturn(0);
254   if (in_str[0] != '-') PetscFunctionReturn(0);
255   if (in_str[1] == '-') in_str++;
256   if (!isalpha(in_str[1])) PetscFunctionReturn(0);
257   if ((!strncmp(in_str+1,"inf",3) || !strncmp(in_str+1,"INF",3)) && !(in_str[4] == '_' || isalnum(in_str[4]))) PetscFunctionReturn(0);
258   *key = PETSC_TRUE;
259   PetscFunctionReturn(0);
260 }
261 
262 #undef __FUNCT__
263 #define __FUNCT__ "PetscOptionsInsertString"
264 /*@C
265      PetscOptionsInsertString - Inserts options into the database from a string
266 
267      Not collective: but only processes that call this routine will set the options
268                      included in the string
269 
270   Input Parameter:
271 .   in_str - string that contains options separated by blanks
272 
273 
274   Level: intermediate
275 
276   Contributed by Boyana Norris
277 
278 .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
279           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
280           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
281           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
282           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
283           PetscOptionsList(), PetscOptionsEList(), PetscOptionsInsertFile()
284 
285 @*/
286 PetscErrorCode  PetscOptionsInsertString(const char in_str[])
287 {
288   char           *first,*second;
289   PetscErrorCode ierr;
290   PetscToken     token;
291   PetscBool      key,ispush,ispop;
292 
293   PetscFunctionBegin;
294   ierr = PetscTokenCreate(in_str,' ',&token);CHKERRQ(ierr);
295   ierr = PetscTokenFind(token,&first);CHKERRQ(ierr);
296   while (first) {
297     ierr = PetscStrcasecmp(first,"-prefix_push",&ispush);CHKERRQ(ierr);
298     ierr = PetscStrcasecmp(first,"-prefix_pop",&ispop);CHKERRQ(ierr);
299     ierr = PetscOptionsValidKey(first,&key);CHKERRQ(ierr);
300     if (ispush) {
301       ierr = PetscTokenFind(token,&second);CHKERRQ(ierr);
302       ierr = PetscOptionsPrefixPush(second);CHKERRQ(ierr);
303       ierr = PetscTokenFind(token,&first);CHKERRQ(ierr);
304     } else if (ispop) {
305       ierr = PetscOptionsPrefixPop();CHKERRQ(ierr);
306       ierr = PetscTokenFind(token,&first);CHKERRQ(ierr);
307     } else if (key) {
308       ierr = PetscTokenFind(token,&second);CHKERRQ(ierr);
309       ierr = PetscOptionsValidKey(second,&key);CHKERRQ(ierr);
310       if (!key) {
311         ierr = PetscOptionsSetValue(first,second);CHKERRQ(ierr);
312         ierr = PetscTokenFind(token,&first);CHKERRQ(ierr);
313       } else {
314         ierr  = PetscOptionsSetValue(first,PETSC_NULL);CHKERRQ(ierr);
315         first = second;
316       }
317     } else {
318       ierr = PetscTokenFind(token,&first);CHKERRQ(ierr);
319     }
320   }
321   ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
322   PetscFunctionReturn(0);
323 }
324 
325 /*
326     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
327 */
328 static char *Petscgetline(FILE * f)
329 {
330   size_t size = 0;
331   size_t len  = 0;
332   size_t last = 0;
333   char * buf  = PETSC_NULL;
334 
335   if (feof(f)) return 0;
336   do {
337     size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
338     buf = (char*)realloc((void *)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
339     /* Actually do the read. Note that fgets puts a terminal '\0' on the
340     end of the string, so we make sure we overwrite this */
341     if (!fgets(buf+len,size,f)) buf[len]=0;
342     PetscStrlen(buf,&len);
343     last = len - 1;
344   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
345   if (len) return buf;
346   free(buf);
347   return 0;
348 }
349 
350 
351 #undef __FUNCT__
352 #define __FUNCT__ "PetscOptionsInsertFile"
353 /*@C
354      PetscOptionsInsertFile - Inserts options into the database from a file.
355 
356      Collective on MPI_Comm
357 
358   Input Parameter:
359 +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
360 .   file - name of file
361 -   require - if PETSC_TRUE will generate an error if the file does not exist
362 
363 
364   Notes: Use  # for lines that are comments and which should be ignored.
365 
366   Level: developer
367 
368 .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
369           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
370           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
371           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
372           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
373           PetscOptionsList(), PetscOptionsEList()
374 
375 @*/
376 PetscErrorCode  PetscOptionsInsertFile(MPI_Comm comm,const char file[],PetscBool require)
377 {
378   char           *string,fname[PETSC_MAX_PATH_LEN],*first,*second,*third,*vstring = 0,*astring = 0;
379   PetscErrorCode ierr;
380   size_t         i,len;
381   FILE           *fd;
382   PetscToken     token;
383   int            err;
384   char           cmt[1]={'#'},*cmatch;
385   PetscMPIInt    rank,cnt=0,acnt=0;
386 
387   PetscFunctionBegin;
388   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
389   if (!rank) {
390     /* Warning: assume a maximum size for all options in a string */
391     ierr = PetscMalloc(128000*sizeof(char),&vstring);CHKERRQ(ierr);
392     vstring[0] = 0;
393     ierr = PetscMalloc(64000*sizeof(char),&astring);CHKERRQ(ierr);
394     astring[0] = 0;
395     cnt     = 0;
396     acnt    = 0;
397 
398     ierr = PetscFixFilename(file,fname);CHKERRQ(ierr);
399     fd   = fopen(fname,"r");
400     if (fd) {
401       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
402       ierr = PetscInfo1(0,"Opened options file %s\n",file);CHKERRQ(ierr);
403       while ((string = Petscgetline(fd))) {
404         /* eliminate comments from each line */
405         for (i=0; i<1; i++) {
406           ierr = PetscStrchr(string,cmt[i],&cmatch);CHKERRQ(ierr);
407           if (cmatch) *cmatch = 0;
408         }
409         ierr = PetscStrlen(string,&len);CHKERRQ(ierr);
410         /* replace tabs, ^M, \n with " " */
411         for (i=0; i<len; i++) {
412           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
413             string[i] = ' ';
414           }
415         }
416         ierr = PetscTokenCreate(string,' ',&token);CHKERRQ(ierr);
417         free(string);
418         ierr = PetscTokenFind(token,&first);CHKERRQ(ierr);
419         if (!first) {
420           goto destroy;
421         } else if (!first[0]) { /* if first token is empty spaces, redo first token */
422           ierr = PetscTokenFind(token,&first);CHKERRQ(ierr);
423         }
424         ierr = PetscTokenFind(token,&second);CHKERRQ(ierr);
425         if (!first) {
426           goto destroy;
427         } else if (first[0] == '-') {
428           /* warning: should be making sure we do not overfill vstring */
429           ierr = PetscStrcat(vstring,first);CHKERRQ(ierr);
430           ierr = PetscStrcat(vstring," ");CHKERRQ(ierr);
431           if (second) {
432             /* protect second with quotes in case it contains strings */
433             ierr = PetscStrcat(vstring,"\"");CHKERRQ(ierr);
434             ierr = PetscStrcat(vstring,second);CHKERRQ(ierr);
435             ierr = PetscStrcat(vstring,"\"");CHKERRQ(ierr);
436           }
437           ierr = PetscStrcat(vstring," ");CHKERRQ(ierr);
438         } else {
439           PetscBool  match;
440 
441           ierr = PetscStrcasecmp(first,"alias",&match);CHKERRQ(ierr);
442           if (match) {
443             ierr = PetscTokenFind(token,&third);CHKERRQ(ierr);
444             if (!third) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file:alias missing (%s)",second);
445             ierr = PetscStrcat(astring,second);CHKERRQ(ierr);
446             ierr = PetscStrcat(astring," ");CHKERRQ(ierr);
447             ierr = PetscStrcat(astring,third);CHKERRQ(ierr);
448             ierr = PetscStrcat(astring," ");CHKERRQ(ierr);
449           } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown statement in options file: (%s)",string);
450         }
451         destroy:
452         ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
453       }
454       err = fclose(fd);
455       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
456       ierr = PetscStrlen(astring,&len);CHKERRQ(ierr);
457       acnt = PetscMPIIntCast(len);CHKERRQ(ierr);
458       ierr = PetscStrlen(vstring,&len);CHKERRQ(ierr);
459       cnt  = PetscMPIIntCast(len);CHKERRQ(ierr);
460     } else if (require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open Options File %s",fname);
461   }
462 
463   ierr = MPI_Bcast(&acnt,1,MPI_INT,0,comm);CHKERRQ(ierr);
464   if (acnt) {
465     PetscToken token;
466     char       *first,*second;
467 
468     if (rank) {
469       ierr = PetscMalloc((acnt+1)*sizeof(char),&astring);CHKERRQ(ierr);
470     }
471     ierr = MPI_Bcast(astring,acnt,MPI_CHAR,0,comm);CHKERRQ(ierr);
472     astring[acnt] = 0;
473     ierr = PetscTokenCreate(astring,' ',&token);CHKERRQ(ierr);
474     ierr = PetscTokenFind(token,&first);CHKERRQ(ierr);
475     while (first) {
476       ierr = PetscTokenFind(token,&second);CHKERRQ(ierr);
477       ierr = PetscOptionsSetAlias(first,second);CHKERRQ(ierr);
478       ierr = PetscTokenFind(token,&first);CHKERRQ(ierr);
479     }
480     ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
481   }
482 
483   ierr = MPI_Bcast(&cnt,1,MPI_INT,0,comm);CHKERRQ(ierr);
484   if (cnt) {
485     if (rank) {
486       ierr = PetscMalloc((cnt+1)*sizeof(char),&vstring);CHKERRQ(ierr);
487     }
488     ierr = MPI_Bcast(vstring,cnt,MPI_CHAR,0,comm);CHKERRQ(ierr);
489     vstring[cnt] = 0;
490     ierr = PetscOptionsInsertString(vstring);CHKERRQ(ierr);
491   }
492   ierr = PetscFree(astring);CHKERRQ(ierr);
493   ierr = PetscFree(vstring);CHKERRQ(ierr);
494   PetscFunctionReturn(0);
495 }
496 
497 #undef __FUNCT__
498 #define __FUNCT__ "PetscOptionsInsertArgs_Private"
499 static PetscErrorCode PetscOptionsInsertArgs_Private(int argc,char *args[])
500 {
501   PetscErrorCode ierr;
502   int            left    = argc - 1;
503   char           **eargs = args + 1;
504 
505   PetscFunctionBegin;
506   while (left) {
507     PetscBool  isoptions_file,isprefixpush,isprefixpop,isp4,tisp4,isp4yourname,isp4rmrank,key;
508     ierr = PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);CHKERRQ(ierr);
509     ierr = PetscStrcasecmp(eargs[0],"-prefix_push",&isprefixpush);CHKERRQ(ierr);
510     ierr = PetscStrcasecmp(eargs[0],"-prefix_pop",&isprefixpop);CHKERRQ(ierr);
511     ierr = PetscStrcasecmp(eargs[0],"-p4pg",&isp4);CHKERRQ(ierr);
512     ierr = PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);CHKERRQ(ierr);
513     ierr = PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);CHKERRQ(ierr);
514     ierr = PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);CHKERRQ(ierr);
515     isp4 = (PetscBool) (isp4 || tisp4);
516     ierr = PetscStrcasecmp(eargs[0],"-np",&tisp4);CHKERRQ(ierr);
517     isp4 = (PetscBool) (isp4 || tisp4);
518     ierr = PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);CHKERRQ(ierr);
519     ierr = PetscOptionsValidKey(eargs[0],&key);CHKERRQ(ierr);
520 
521     if (!key) {
522       eargs++; left--;
523     } else if (isoptions_file) {
524       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
525       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
526       ierr = PetscOptionsInsertFile(PETSC_COMM_WORLD,eargs[1],PETSC_TRUE);CHKERRQ(ierr);
527       eargs += 2; left -= 2;
528     } else if (isprefixpush) {
529       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
530       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
531       ierr = PetscOptionsPrefixPush(eargs[1]);CHKERRQ(ierr);
532       eargs += 2; left -= 2;
533     } else if (isprefixpop) {
534       ierr = PetscOptionsPrefixPop();CHKERRQ(ierr);
535       eargs++; left--;
536 
537       /*
538        These are "bad" options that MPICH, etc put on the command line
539        we strip them out here.
540        */
541     } else if (tisp4 || isp4rmrank) {
542       eargs += 1; left -= 1;
543     } else if (isp4 || isp4yourname) {
544       eargs += 2; left -= 2;
545     } else {
546       PetscBool nextiskey = PETSC_FALSE;
547       if (left >= 2) {ierr = PetscOptionsValidKey(eargs[1],&nextiskey);CHKERRQ(ierr);}
548       if (left < 2 || nextiskey) {
549         ierr = PetscOptionsSetValue(eargs[0],PETSC_NULL);CHKERRQ(ierr);
550         eargs++; left--;
551       } else {
552         ierr = PetscOptionsSetValue(eargs[0],eargs[1]);CHKERRQ(ierr);
553         eargs += 2; left -= 2;
554       }
555     }
556   }
557   PetscFunctionReturn(0);
558 }
559 
560 
561 #undef __FUNCT__
562 #define __FUNCT__ "PetscOptionsInsert"
563 /*@C
564    PetscOptionsInsert - Inserts into the options database from the command line,
565                    the environmental variable and a file.
566 
567    Input Parameters:
568 +  argc - count of number of command line arguments
569 .  args - the command line arguments
570 -  file - optional filename, defaults to ~username/.petscrc
571 
572    Note:
573    Since PetscOptionsInsert() is automatically called by PetscInitialize(),
574    the user does not typically need to call this routine. PetscOptionsInsert()
575    can be called several times, adding additional entries into the database.
576 
577    Options Database Keys:
578 +   -options_monitor <optional filename> - print options names and values as they are set
579 .   -options_file <filename> - read options from a file
580 
581    Level: advanced
582 
583    Concepts: options database^adding
584 
585 .seealso: PetscOptionsDestroy_Private(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
586           PetscInitialize()
587 @*/
588 PetscErrorCode  PetscOptionsInsert(int *argc,char ***args,const char file[])
589 {
590   PetscErrorCode ierr;
591   PetscMPIInt    rank;
592   char           pfile[PETSC_MAX_PATH_LEN];
593   PetscBool      flag = PETSC_FALSE;
594 
595   PetscFunctionBegin;
596   if (!options) {
597     fprintf(stderr, "Options have not been enabled.\nYou might have forgotten to call PetscInitialize().\n");
598     MPI_Abort(MPI_COMM_WORLD, PETSC_ERR_SUP);
599   }
600   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
601 
602   options->argc     = (argc) ? *argc : 0;
603   options->args     = (args) ? *args : PETSC_NULL;
604 
605   if (file && file[0]) {
606     ierr = PetscOptionsInsertFile(PETSC_COMM_WORLD,file,PETSC_TRUE);CHKERRQ(ierr);
607   }
608   /*
609      We want to be able to give -skip_petscrc on the command line, but need to parse it first.  Since the command line
610      should take precedence, we insert it twice.  It would be sufficient to just scan for -skip_petscrc.
611   */
612   if (argc && args && *argc) {ierr = PetscOptionsInsertArgs_Private(*argc,*args);CHKERRQ(ierr);}
613   ierr = PetscOptionsGetBool(PETSC_NULL,"-skip_petscrc",&flag,PETSC_NULL);CHKERRQ(ierr);
614   if (!flag) {
615     ierr = PetscGetHomeDirectory(pfile,PETSC_MAX_PATH_LEN-16);CHKERRQ(ierr);
616     /* warning: assumes all processes have a home directory or none, but nothing in between */
617     if (pfile[0]) {
618       ierr = PetscStrcat(pfile,"/.petscrc");CHKERRQ(ierr);
619       ierr = PetscOptionsInsertFile(PETSC_COMM_WORLD,pfile,PETSC_FALSE);CHKERRQ(ierr);
620     }
621     ierr = PetscOptionsInsertFile(PETSC_COMM_WORLD,".petscrc",PETSC_FALSE);CHKERRQ(ierr);
622     ierr = PetscOptionsInsertFile(PETSC_COMM_WORLD,"petscrc",PETSC_FALSE);CHKERRQ(ierr);
623   }
624 
625   /* insert environmental options */
626   {
627     char   *eoptions = 0;
628     size_t len = 0;
629     if (!rank) {
630       eoptions = (char*)getenv("PETSC_OPTIONS");
631       ierr     = PetscStrlen(eoptions,&len);CHKERRQ(ierr);
632       ierr     = MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
633     } else {
634       ierr = MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
635       if (len) {
636         ierr = PetscMalloc((len+1)*sizeof(char*),&eoptions);CHKERRQ(ierr);
637       }
638     }
639     if (len) {
640       ierr = MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
641       if (rank) eoptions[len] = 0;
642       ierr = PetscOptionsInsertString(eoptions);CHKERRQ(ierr);
643       if (rank) {ierr = PetscFree(eoptions);CHKERRQ(ierr);}
644     }
645   }
646 
647 #if defined(PETSC_HAVE_YAML)
648   char yaml_file[PETSC_MAX_PATH_LEN];
649   PetscBool yaml_flg = PETSC_FALSE;
650   ierr = PetscOptionsGetString(PETSC_NULL,"-options_file_yaml",yaml_file,PETSC_MAX_PATH_LEN,&yaml_flg);CHKERRQ(ierr);
651   if (yaml_flg) ierr = PetscOptionsInsertFile_YAML(PETSC_COMM_WORLD,yaml_file,PETSC_TRUE);CHKERRQ(ierr);
652 #endif
653 
654   /* insert command line options again because they take precedence over arguments in petscrc/environment */
655   if (argc && args && *argc) {ierr = PetscOptionsInsertArgs_Private(*argc,*args);CHKERRQ(ierr);}
656 
657   PetscFunctionReturn(0);
658 }
659 
660 #undef __FUNCT__
661 #define __FUNCT__ "PetscOptionsView"
662 /*@C
663    PetscOptionsView - Prints the options that have been loaded. This is
664    useful for debugging purposes.
665 
666    Logically Collective on PetscViewer
667 
668    Input Parameter:
669 .  viewer - must be an PETSCVIEWERASCII viewer
670 
671    Options Database Key:
672 .  -options_table - Activates PetscOptionsView() within PetscFinalize()
673 
674    Level: advanced
675 
676    Concepts: options database^printing
677 
678 .seealso: PetscOptionsAllUsed()
679 @*/
680 PetscErrorCode  PetscOptionsView(PetscViewer viewer)
681 {
682   PetscErrorCode ierr;
683   PetscInt       i;
684   PetscBool      isascii;
685 
686   PetscFunctionBegin;
687   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
688   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
689   if (!isascii) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Only supports ASCII viewer");
690 
691   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
692   if (options->N) {
693     ierr = PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");CHKERRQ(ierr);
694   } else {
695     ierr = PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");CHKERRQ(ierr);
696   }
697   for (i=0; i<options->N; i++) {
698     if (options->values[i]) {
699       ierr = PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);CHKERRQ(ierr);
700     } else {
701       ierr = PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);CHKERRQ(ierr);
702     }
703   }
704   if (options->N) {
705     ierr = PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");CHKERRQ(ierr);
706   }
707   PetscFunctionReturn(0);
708 }
709 
710 #undef __FUNCT__
711 #define __FUNCT__ "PetscOptionsGetAll"
712 /*@C
713    PetscOptionsGetAll - Lists all the options the program was run with in a single string.
714 
715    Not Collective
716 
717    Output Parameter:
718 .  copts - pointer where string pointer is stored
719 
720    Notes: the array and each entry in the array should be freed with PetscFree()
721 
722    Level: advanced
723 
724    Concepts: options database^listing
725 
726 .seealso: PetscOptionsAllUsed(), PetscOptionsView()
727 @*/
728 PetscErrorCode  PetscOptionsGetAll(char *copts[])
729 {
730   PetscErrorCode ierr;
731   PetscInt       i;
732   size_t         len = 1,lent = 0;
733   char           *coptions = PETSC_NULL;
734 
735   PetscFunctionBegin;
736   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
737 
738   /* count the length of the required string */
739   for (i=0; i<options->N; i++) {
740     ierr = PetscStrlen(options->names[i],&lent);CHKERRQ(ierr);
741     len += 2 + lent;
742     if (options->values[i]) {
743       ierr = PetscStrlen(options->values[i],&lent);CHKERRQ(ierr);
744       len += 1 + lent;
745     }
746   }
747   ierr = PetscMalloc(len*sizeof(char),&coptions);CHKERRQ(ierr);
748   coptions[0] = 0;
749   for (i=0; i<options->N; i++) {
750     ierr = PetscStrcat(coptions,"-");CHKERRQ(ierr);
751     ierr = PetscStrcat(coptions,options->names[i]);CHKERRQ(ierr);
752     ierr = PetscStrcat(coptions," ");CHKERRQ(ierr);
753     if (options->values[i]) {
754       ierr = PetscStrcat(coptions,options->values[i]);CHKERRQ(ierr);
755       ierr = PetscStrcat(coptions," ");CHKERRQ(ierr);
756     }
757   }
758   *copts = coptions;
759   PetscFunctionReturn(0);
760 }
761 
762 #undef __FUNCT__
763 #define __FUNCT__ "PetscOptionsPrefixPush"
764 /*@
765    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
766 
767    Not Collective, but prefix will only be applied on calling ranks
768 
769    Input Parameter:
770 .  prefix - The string to append to the existing prefix
771 
772    Options Database Keys:
773  +   -prefix_push <some_prefix_> - push the given prefix
774  -   -prefix_pop - pop the last prefix
775 
776    Notes:
777    It is common to use this in conjunction with -options_file as in
778 
779  $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
780 
781    where the files no longer require all options to be prefixed with -system2_.
782 
783 Level: advanced
784 
785 .seealso: PetscOptionsPrefixPop()
786 @*/
787 PetscErrorCode  PetscOptionsPrefixPush(const char prefix[])
788 {
789   PetscErrorCode ierr;
790   size_t n;
791   PetscInt start;
792   char buf[2048];
793   PetscBool  key;
794 
795   PetscFunctionBegin;
796   PetscValidCharPointer(prefix,1);
797   /* Want to check validity of the key using PetscOptionsValidKey(), which requires that the first character is a '-' */
798   buf[0] = '-';
799   ierr = PetscStrncpy(buf+1,prefix,sizeof(buf) - 1);CHKERRQ(ierr);
800   buf[sizeof(buf) - 1] = 0;
801   ierr = PetscOptionsValidKey(buf,&key);CHKERRQ(ierr);
802   if (!key) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Given prefix \"%s\" not valid (the first character must be a letter, do not include leading '-')",prefix);
803 
804   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
805   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);
806   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
807   ierr = PetscStrlen(prefix,&n);CHKERRQ(ierr);
808   if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
809   ierr = PetscMemcpy(options->prefix+start,prefix,n+1);CHKERRQ(ierr);
810   options->prefixstack[options->prefixind++] = start+n;
811   PetscFunctionReturn(0);
812 }
813 
814 #undef __FUNCT__
815 #define __FUNCT__ "PetscOptionsPrefixPop"
816 /*@
817    PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details
818 
819    Not  Collective, but prefix will only be popped on calling ranks
820 
821    Level: advanced
822 
823 .seealso: PetscOptionsPrefixPush()
824 @*/
825 PetscErrorCode  PetscOptionsPrefixPop(void)
826 {
827   PetscInt offset;
828 
829   PetscFunctionBegin;
830   if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
831   options->prefixind--;
832   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
833   options->prefix[offset] = 0;
834   PetscFunctionReturn(0);
835 }
836 
837 #undef __FUNCT__
838 #define __FUNCT__ "PetscOptionsClear"
839 /*@C
840     PetscOptionsClear - Removes all options form the database leaving it empty.
841 
842    Level: developer
843 
844 .seealso: PetscOptionsInsert()
845 @*/
846 PetscErrorCode  PetscOptionsClear(void)
847 {
848   PetscInt i;
849 
850   PetscFunctionBegin;
851   if (!options) PetscFunctionReturn(0);
852   for (i=0; i<options->N; i++) {
853     if (options->names[i])  free(options->names[i]);
854     if (options->values[i]) free(options->values[i]);
855   }
856   for (i=0; i<options->Naliases; i++) {
857     free(options->aliases1[i]);
858     free(options->aliases2[i]);
859   }
860   options->prefix[0] = 0;
861   options->prefixind = 0;
862   options->N        = 0;
863   options->Naliases = 0;
864   PetscFunctionReturn(0);
865 }
866 
867 #undef __FUNCT__
868 #define __FUNCT__ "PetscOptionsDestroy"
869 /*@C
870     PetscOptionsDestroy - Destroys the option database.
871 
872     Note:
873     Since PetscOptionsDestroy() is called by PetscFinalize(), the user
874     typically does not need to call this routine.
875 
876    Level: developer
877 
878 .seealso: PetscOptionsInsert()
879 @*/
880 PetscErrorCode  PetscOptionsDestroy(void)
881 {
882   PetscErrorCode ierr;
883 
884   PetscFunctionBegin;
885   if (!options) PetscFunctionReturn(0);
886   ierr = PetscOptionsClear();CHKERRQ(ierr);
887   free(options);
888   options = 0;
889   PetscFunctionReturn(0);
890 }
891 
892 #undef __FUNCT__
893 #define __FUNCT__ "PetscOptionsSetValue"
894 /*@C
895    PetscOptionsSetValue - Sets an option name-value pair in the options
896    database, overriding whatever is already present.
897 
898    Not collective, but setting values on certain processors could cause problems
899    for parallel objects looking for options.
900 
901    Input Parameters:
902 +  name - name of option, this SHOULD have the - prepended
903 -  value - the option value (not used for all options)
904 
905    Level: intermediate
906 
907    Note:
908    Only some options have values associated with them, such as
909    -ksp_rtol tol.  Other options stand alone, such as -ksp_monitor.
910 
911   Concepts: options database^adding option
912 
913 .seealso: PetscOptionsInsert()
914 @*/
915 PetscErrorCode  PetscOptionsSetValue(const char iname[],const char value[])
916 {
917   size_t         len;
918   PetscErrorCode ierr;
919   PetscInt       N,n,i;
920   char           **names;
921   char           fullname[2048];
922   const char     *name = iname;
923   PetscBool      gt,match;
924 
925   PetscFunctionBegin;
926   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
927 
928   /* this is so that -h and -hel\p are equivalent (p4 does not like -help)*/
929   ierr = PetscStrcasecmp(name,"-h",&match);CHKERRQ(ierr);
930   if (match) name = "-help";
931 
932   name++; /* skip starting hyphen */
933   if (options->prefixind > 0) {
934     ierr = PetscStrncpy(fullname,options->prefix,sizeof(fullname));CHKERRQ(ierr);
935     ierr = PetscStrncat(fullname,name,sizeof(fullname));CHKERRQ(ierr);
936     name = fullname;
937   }
938 
939   /* check against aliases */
940   N = options->Naliases;
941   for (i=0; i<N; i++) {
942     ierr = PetscStrcasecmp(options->aliases1[i],name,&match);CHKERRQ(ierr);
943     if (match) {
944       name = options->aliases2[i];
945       break;
946     }
947   }
948 
949   N     = options->N;
950   n     = N;
951   names = options->names;
952 
953   for (i=0; i<N; i++) {
954     ierr = PetscStrcasecmp(names[i],name,&match);CHKERRQ(ierr);
955     ierr  = PetscStrgrt(names[i],name,&gt);CHKERRQ(ierr);
956     if (match) {
957       if (options->values[i]) free(options->values[i]);
958       ierr = PetscStrlen(value,&len);CHKERRQ(ierr);
959       if (len) {
960         options->values[i] = (char*)malloc((len+1)*sizeof(char));
961         ierr = PetscStrcpy(options->values[i],value);CHKERRQ(ierr);
962       } else { options->values[i] = 0;}
963       PetscOptionsMonitor(name,value);
964       PetscFunctionReturn(0);
965     } else if (gt) {
966       n = i;
967       break;
968     }
969   }
970   if (N >= MAXOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"No more room in option table, limit %d recompile \n src/sys/objects/options.c with larger value for MAXOPTIONS\n",MAXOPTIONS);
971 
972   /* shift remaining values down 1 */
973   for (i=N; i>n; i--) {
974     options->names[i]  = options->names[i-1];
975     options->values[i] = options->values[i-1];
976     options->used[i]   = options->used[i-1];
977   }
978   /* insert new name and value */
979   ierr = PetscStrlen(name,&len);CHKERRQ(ierr);
980   options->names[n] = (char*)malloc((len+1)*sizeof(char));
981   ierr = PetscStrcpy(options->names[n],name);CHKERRQ(ierr);
982   ierr = PetscStrlen(value,&len);CHKERRQ(ierr);
983   if (len) {
984     options->values[n] = (char*)malloc((len+1)*sizeof(char));
985     ierr = PetscStrcpy(options->values[n],value);CHKERRQ(ierr);
986   } else {options->values[n] = 0;}
987   options->used[n] = PETSC_FALSE;
988   options->N++;
989   PetscOptionsMonitor(name,value);
990   PetscFunctionReturn(0);
991 }
992 
993 #undef __FUNCT__
994 #define __FUNCT__ "PetscOptionsClearValue"
995 /*@C
996    PetscOptionsClearValue - Clears an option name-value pair in the options
997    database, overriding whatever is already present.
998 
999    Not Collective, but setting values on certain processors could cause problems
1000    for parallel objects looking for options.
1001 
1002    Input Parameter:
1003 .  name - name of option, this SHOULD have the - prepended
1004 
1005    Level: intermediate
1006 
1007    Concepts: options database^removing option
1008 .seealso: PetscOptionsInsert()
1009 @*/
1010 PetscErrorCode  PetscOptionsClearValue(const char iname[])
1011 {
1012   PetscErrorCode ierr;
1013   PetscInt       N,n,i;
1014   char           **names,*name=(char*)iname;
1015   PetscBool      gt,match;
1016 
1017   PetscFunctionBegin;
1018   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);
1019   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
1020 
1021   name++;
1022 
1023   N     = options->N; n = 0;
1024   names = options->names;
1025 
1026   for (i=0; i<N; i++) {
1027     ierr  = PetscStrcasecmp(names[i],name,&match);CHKERRQ(ierr);
1028     ierr  = PetscStrgrt(names[i],name,&gt);CHKERRQ(ierr);
1029     if (match) {
1030       if (options->names[i])  free(options->names[i]);
1031       if (options->values[i]) free(options->values[i]);
1032       PetscOptionsMonitor(name,"");
1033       break;
1034     } else if (gt) {
1035       PetscFunctionReturn(0); /* it was not listed */
1036     }
1037     n++;
1038   }
1039   if (n == N) PetscFunctionReturn(0); /* it was not listed */
1040 
1041   /* shift remaining values down 1 */
1042   for (i=n; i<N-1; i++) {
1043     options->names[i]  = options->names[i+1];
1044     options->values[i] = options->values[i+1];
1045     options->used[i]   = options->used[i+1];
1046   }
1047   options->N--;
1048   PetscFunctionReturn(0);
1049 }
1050 
1051 #undef __FUNCT__
1052 #define __FUNCT__ "PetscOptionsSetAlias"
1053 /*@C
1054    PetscOptionsSetAlias - Makes a key and alias for another key
1055 
1056    Not Collective, but setting values on certain processors could cause problems
1057    for parallel objects looking for options.
1058 
1059    Input Parameters:
1060 +  inewname - the alias
1061 -  ioldname - the name that alias will refer to
1062 
1063    Level: advanced
1064 
1065 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1066            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
1067           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1068           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1069           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1070           PetscOptionsList(), PetscOptionsEList()
1071 @*/
1072 PetscErrorCode  PetscOptionsSetAlias(const char inewname[],const char ioldname[])
1073 {
1074   PetscErrorCode ierr;
1075   PetscInt       n = options->Naliases;
1076   size_t         len;
1077   char           *newname = (char *)inewname,*oldname = (char*)ioldname;
1078 
1079   PetscFunctionBegin;
1080   if (newname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliased must have -: Instead %s",newname);
1081   if (oldname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliasee must have -: Instead %s",oldname);
1082   if (n >= MAXALIASES) {
1083     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);
1084   }
1085 
1086   newname++; oldname++;
1087   ierr = PetscStrlen(newname,&len);CHKERRQ(ierr);
1088   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
1089   ierr = PetscStrcpy(options->aliases1[n],newname);CHKERRQ(ierr);
1090   ierr = PetscStrlen(oldname,&len);CHKERRQ(ierr);
1091   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
1092   ierr = PetscStrcpy(options->aliases2[n],oldname);CHKERRQ(ierr);
1093   options->Naliases++;
1094   PetscFunctionReturn(0);
1095 }
1096 
1097 #undef __FUNCT__
1098 #define __FUNCT__ "PetscOptionsFindPair_Private"
1099 PetscErrorCode PetscOptionsFindPair_Private(const char pre[],const char name[],char *value[],PetscBool  *flg)
1100 {
1101   PetscErrorCode ierr;
1102   PetscInt       i,N;
1103   size_t         len;
1104   char           **names,tmp[256];
1105   PetscBool      match;
1106 
1107   PetscFunctionBegin;
1108   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
1109   N = options->N;
1110   names = options->names;
1111 
1112   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);
1113 
1114   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1115   if (pre) {
1116     char *ptr = tmp;
1117     const char *namep = name;
1118     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
1119     if (name[1] == '-') {
1120       *ptr++ = '-';
1121       namep++;
1122     }
1123     ierr = PetscStrncpy(ptr,pre,tmp+sizeof(tmp)-ptr);CHKERRQ(ierr);
1124     tmp[sizeof(tmp)-1] = 0;
1125     ierr = PetscStrlen(tmp,&len);CHKERRQ(ierr);
1126     ierr = PetscStrncat(tmp,namep+1,sizeof(tmp)-len-1);CHKERRQ(ierr);
1127   } else {
1128     ierr = PetscStrncpy(tmp,name+1,sizeof(tmp));CHKERRQ(ierr);
1129     tmp[sizeof(tmp)-1] = 0;
1130   }
1131 #if defined(PETSC_USE_DEBUG)
1132   {
1133     PetscBool valid;
1134     char key[sizeof(tmp)+1] = "-";
1135     ierr = PetscMemcpy(key+1,tmp,sizeof(tmp));CHKERRQ(ierr);
1136     ierr = PetscOptionsValidKey(key,&valid);CHKERRQ(ierr);
1137     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1138   }
1139 #endif
1140 
1141   /* slow search */
1142   *flg = PETSC_FALSE;
1143   for (i=0; i<N; i++) {
1144     ierr = PetscStrcasecmp(names[i],tmp,&match);CHKERRQ(ierr);
1145     if (match) {
1146        *value           = options->values[i];
1147        options->used[i] = PETSC_TRUE;
1148        *flg             = PETSC_TRUE;
1149        break;
1150      }
1151   }
1152   if (!*flg) {
1153     PetscInt j,cnt = 0,locs[16],loce[16];
1154     size_t   n;
1155     ierr = PetscStrlen(tmp,&n);CHKERRQ(ierr);
1156     /* determine the location and number of all _%d_ in the key */
1157     for (i=0; i< (PetscInt)n; i++) {
1158       if (tmp[i] == '_') {
1159         for (j=i+1; j< (PetscInt)n; j++) {
1160           if (tmp[j] >= '0' && tmp[j] <= '9') continue;
1161           if (tmp[j] == '_' && j > i+1) { /* found a number */
1162             locs[cnt]   = i+1;
1163             loce[cnt++] = j+1;
1164           }
1165           break;
1166         }
1167       }
1168     }
1169     if (cnt) {
1170       char tmp2[256];
1171       for (i=0; i<cnt; i++) {
1172         ierr = PetscStrcpy(tmp2,"-");CHKERRQ(ierr);
1173         ierr = PetscStrncat(tmp2,tmp,locs[i]);CHKERRQ(ierr);
1174         ierr = PetscStrcat(tmp2,tmp+loce[i]);CHKERRQ(ierr);
1175         ierr = PetscOptionsFindPair_Private(PETSC_NULL,tmp2,value,flg);CHKERRQ(ierr);
1176         if (*flg) break;
1177       }
1178     }
1179   }
1180   PetscFunctionReturn(0);
1181 }
1182 
1183 #undef __FUNCT__
1184 #define __FUNCT__ "PetscOptionsFindPairPrefix_Private"
1185 PetscErrorCode PetscOptionsFindPairPrefix_Private(const char pre[], const char name[], char *value[], PetscBool *flg)
1186 {
1187   PetscErrorCode ierr;
1188   PetscInt       i,N;
1189   size_t         len;
1190   char           **names,tmp[256];
1191   PetscBool      match;
1192 
1193   PetscFunctionBegin;
1194   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
1195   N = options->N;
1196   names = options->names;
1197 
1198   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);
1199 
1200   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1201   if (pre) {
1202     char *ptr = tmp;
1203     const char *namep = name;
1204     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
1205     if (name[1] == '-') {
1206       *ptr++ = '-';
1207       namep++;
1208     }
1209     ierr = PetscStrncpy(ptr,pre,tmp+sizeof(tmp)-ptr);CHKERRQ(ierr);
1210     tmp[sizeof(tmp)-1] = 0;
1211     ierr = PetscStrlen(tmp,&len);CHKERRQ(ierr);
1212     ierr = PetscStrncat(tmp,namep+1,sizeof(tmp)-len-1);CHKERRQ(ierr);
1213   } else {
1214     ierr = PetscStrncpy(tmp,name+1,sizeof(tmp));CHKERRQ(ierr);
1215     tmp[sizeof(tmp)-1] = 0;
1216   }
1217 #if defined(PETSC_USE_DEBUG)
1218   {
1219     PetscBool valid;
1220     char key[sizeof(tmp)+1] = "-";
1221     ierr = PetscMemcpy(key+1,tmp,sizeof(tmp));CHKERRQ(ierr);
1222     ierr = PetscOptionsValidKey(key,&valid);CHKERRQ(ierr);
1223     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1224   }
1225 #endif
1226 
1227   /* slow search */
1228   *flg = PETSC_FALSE;
1229   ierr = PetscStrlen(tmp,&len);CHKERRQ(ierr);
1230   for (i = 0; i < N; ++i) {
1231     ierr = PetscStrncmp(names[i], tmp, len, &match);CHKERRQ(ierr);
1232     if (match) {
1233       if (value) *value = options->values[i];
1234       options->used[i]  = PETSC_TRUE;
1235       if (flg)   *flg   = PETSC_TRUE;
1236       break;
1237     }
1238   }
1239   PetscFunctionReturn(0);
1240 }
1241 
1242 #undef __FUNCT__
1243 #define __FUNCT__ "PetscOptionsReject"
1244 /*@C
1245    PetscOptionsReject - Generates an error if a certain option is given.
1246 
1247    Not Collective, but setting values on certain processors could cause problems
1248    for parallel objects looking for options.
1249 
1250    Input Parameters:
1251 +  name - the option one is seeking
1252 -  mess - error message (may be PETSC_NULL)
1253 
1254    Level: advanced
1255 
1256    Concepts: options database^rejecting option
1257 
1258 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1259            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1260           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1261           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1262           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1263           PetscOptionsList(), PetscOptionsEList()
1264 @*/
1265 PetscErrorCode  PetscOptionsReject(const char name[],const char mess[])
1266 {
1267   PetscErrorCode ierr;
1268   PetscBool      flag = PETSC_FALSE;
1269 
1270   PetscFunctionBegin;
1271   ierr = PetscOptionsHasName(PETSC_NULL,name,&flag);CHKERRQ(ierr);
1272   if (flag) {
1273     if (mess) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s with %s",name,mess);
1274     else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s",name);
1275   }
1276   PetscFunctionReturn(0);
1277 }
1278 
1279 #undef __FUNCT__
1280 #define __FUNCT__ "PetscOptionsHasName"
1281 /*@C
1282    PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or boolean, even
1283                       its value is set to false.
1284 
1285    Not Collective
1286 
1287    Input Parameters:
1288 +  name - the option one is seeking
1289 -  pre - string to prepend to the name or PETSC_NULL
1290 
1291    Output Parameters:
1292 .  set - PETSC_TRUE if found else PETSC_FALSE.
1293 
1294    Level: beginner
1295 
1296    Concepts: options database^has option name
1297 
1298    Notes: Name cannot be simply -h
1299 
1300           In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.
1301 
1302 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1303            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1304           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1305           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1306           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1307           PetscOptionsList(), PetscOptionsEList()
1308 @*/
1309 PetscErrorCode  PetscOptionsHasName(const char pre[],const char name[],PetscBool  *set)
1310 {
1311   char           *value;
1312   PetscErrorCode ierr;
1313   PetscBool      flag;
1314 
1315   PetscFunctionBegin;
1316   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1317   if (set) *set = flag;
1318   PetscFunctionReturn(0);
1319 }
1320 
1321 #undef __FUNCT__
1322 #define __FUNCT__ "PetscOptionsGetInt"
1323 /*@C
1324    PetscOptionsGetInt - Gets the integer value for a particular option in the database.
1325 
1326    Not Collective
1327 
1328    Input Parameters:
1329 +  pre - the string to prepend to the name or PETSC_NULL
1330 -  name - the option one is seeking
1331 
1332    Output Parameter:
1333 +  ivalue - the integer value to return
1334 -  set - PETSC_TRUE if found, else PETSC_FALSE
1335 
1336    Level: beginner
1337 
1338    Concepts: options database^has int
1339 
1340 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1341           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1342           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1343           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1344           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1345           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1346           PetscOptionsList(), PetscOptionsEList()
1347 @*/
1348 PetscErrorCode  PetscOptionsGetInt(const char pre[],const char name[],PetscInt *ivalue,PetscBool  *set)
1349 {
1350   char           *value;
1351   PetscErrorCode ierr;
1352   PetscBool      flag;
1353 
1354   PetscFunctionBegin;
1355   PetscValidCharPointer(name,2);
1356   PetscValidIntPointer(ivalue,3);
1357   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1358   if (flag) {
1359     if (!value) {if (set) *set = PETSC_FALSE;}
1360     else {
1361       if (set) *set = PETSC_TRUE;
1362       ierr = PetscOptionsStringToInt(value,ivalue);CHKERRQ(ierr);
1363     }
1364   } else {
1365     if (set) *set = PETSC_FALSE;
1366   }
1367   PetscFunctionReturn(0);
1368 }
1369 
1370 #undef __FUNCT__
1371 #define __FUNCT__ "PetscOptionsGetEList"
1372 /*@C
1373      PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
1374 
1375    Not Collective
1376 
1377    Input Parameters:
1378 +  pre - the string to prepend to the name or PETSC_NULL
1379 .  opt - option name
1380 .  list - the possible choices
1381 .  ntext - number of choices
1382 
1383    Output Parameter:
1384 +  value - the index of the value to return (defaults to zero if the option name is given but choice is listed)
1385 -  set - PETSC_TRUE if found, else PETSC_FALSE
1386 
1387    Level: intermediate
1388 
1389    See PetscOptionsList() for when the choices are given in a PetscFunctionList()
1390 
1391    Concepts: options database^list
1392 
1393 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1394            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1395           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1396           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1397           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1398           PetscOptionsList(), PetscOptionsEList()
1399 @*/
1400 PetscErrorCode  PetscOptionsGetEList(const char pre[],const char opt[],const char *const*list,PetscInt ntext,PetscInt *value,PetscBool  *set)
1401 {
1402   PetscErrorCode ierr;
1403   size_t         alen,len = 0;
1404   char           *svalue;
1405   PetscBool      aset,flg = PETSC_FALSE;
1406   PetscInt       i;
1407 
1408   PetscFunctionBegin;
1409   for (i=0; i<ntext; i++) {
1410     ierr = PetscStrlen(list[i],&alen);CHKERRQ(ierr);
1411     if (alen > len) len = alen;
1412   }
1413   len += 5; /* a little extra space for user mistypes */
1414   ierr = PetscMalloc(len*sizeof(char),&svalue);CHKERRQ(ierr);
1415   ierr = PetscOptionsGetString(pre,opt,svalue,len,&aset);CHKERRQ(ierr);
1416   if (aset) {
1417     if (set) *set = PETSC_TRUE;
1418     for (i=0; i<ntext; i++) {
1419       ierr = PetscStrcasecmp(svalue,list[i],&flg);CHKERRQ(ierr);
1420       if (flg || !svalue[0]) {
1421         flg    = PETSC_TRUE;
1422         *value = i;
1423         break;
1424       }
1425     }
1426     if (!flg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre?pre:"",opt+1);
1427   } else if (set) {
1428     *set = PETSC_FALSE;
1429   }
1430   ierr = PetscFree(svalue);CHKERRQ(ierr);
1431   PetscFunctionReturn(0);
1432 }
1433 
1434 #undef __FUNCT__
1435 #define __FUNCT__ "PetscOptionsGetEnum"
1436 /*@C
1437    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
1438 
1439    Not Collective
1440 
1441    Input Parameters:
1442 +  pre - option prefix or PETSC_NULL
1443 .  opt - option name
1444 .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
1445 -  defaultv - the default (current) value
1446 
1447    Output Parameter:
1448 +  value - the  value to return
1449 -  set - PETSC_TRUE if found, else PETSC_FALSE
1450 
1451    Level: beginner
1452 
1453    Concepts: options database
1454 
1455    Notes: Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1456 
1457           list is usually something like PCASMTypes or some other predefined list of enum names
1458 
1459 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1460           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1461           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1462           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1463           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1464           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1465           PetscOptionsList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
1466 @*/
1467 PetscErrorCode  PetscOptionsGetEnum(const char pre[],const char opt[],const char *const*list,PetscEnum *value,PetscBool  *set)
1468 {
1469   PetscErrorCode ierr;
1470   PetscInt       ntext = 0,tval;
1471   PetscBool      fset;
1472 
1473   PetscFunctionBegin;
1474   while (list[ntext++]) {
1475     if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
1476   }
1477   if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1478   ntext -= 3;
1479   ierr = PetscOptionsGetEList(pre,opt,list,ntext,&tval,&fset);CHKERRQ(ierr);
1480   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
1481   if (fset) *value = (PetscEnum)tval;
1482   if (set) *set = fset;
1483   PetscFunctionReturn(0);
1484 }
1485 
1486 #undef __FUNCT__
1487 #define __FUNCT__ "PetscOptionsGetBool"
1488 /*@C
1489    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
1490             option in the database.
1491 
1492    Not Collective
1493 
1494    Input Parameters:
1495 +  pre - the string to prepend to the name or PETSC_NULL
1496 -  name - the option one is seeking
1497 
1498    Output Parameter:
1499 +  ivalue - the logical value to return
1500 -  set - PETSC_TRUE  if found, else PETSC_FALSE
1501 
1502    Level: beginner
1503 
1504    Notes:
1505        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1506        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
1507 
1508        If the user does not supply the option (as either true or false) ivalue is NOT changed. Thus
1509      you NEED TO ALWAYS initialize the ivalue.
1510 
1511    Concepts: options database^has logical
1512 
1513 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1514           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
1515           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1516           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1517           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1518           PetscOptionsList(), PetscOptionsEList()
1519 @*/
1520 PetscErrorCode  PetscOptionsGetBool(const char pre[],const char name[],PetscBool  *ivalue,PetscBool  *set)
1521 {
1522   char           *value;
1523   PetscBool      flag;
1524   PetscErrorCode ierr;
1525 
1526   PetscFunctionBegin;
1527   PetscValidCharPointer(name,2);
1528   PetscValidIntPointer(ivalue,3);
1529   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1530   if (flag) {
1531     if (set) *set = PETSC_TRUE;
1532     if (!value) {
1533       *ivalue = PETSC_TRUE;
1534     } else {
1535       ierr = PetscOptionsStringToBool(value, ivalue);CHKERRQ(ierr);
1536     }
1537   } else {
1538     if (set) *set = PETSC_FALSE;
1539   }
1540   PetscFunctionReturn(0);
1541 }
1542 
1543 #undef __FUNCT__
1544 #define __FUNCT__ "PetscOptionsGetBoolArray"
1545 /*@C
1546    PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
1547    option in the database.  The values must be separated with commas with
1548    no intervening spaces.
1549 
1550    Not Collective
1551 
1552    Input Parameters:
1553 +  pre - string to prepend to each name or PETSC_NULL
1554 .  name - the option one is seeking
1555 -  nmax - maximum number of values to retrieve
1556 
1557    Output Parameter:
1558 +  dvalue - the integer values to return
1559 .  nmax - actual number of values retreived
1560 -  set - PETSC_TRUE if found, else PETSC_FALSE
1561 
1562    Level: beginner
1563 
1564    Concepts: options database^array of ints
1565 
1566    Notes:
1567        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1568        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
1569 
1570 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1571            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1572           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1573           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1574           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1575           PetscOptionsList(), PetscOptionsEList()
1576 @*/
1577 PetscErrorCode  PetscOptionsGetBoolArray(const char pre[],const char name[],PetscBool  dvalue[],PetscInt *nmax,PetscBool  *set)
1578 {
1579   char           *value;
1580   PetscErrorCode ierr;
1581   PetscInt       n = 0;
1582   PetscBool      flag;
1583   PetscToken     token;
1584 
1585   PetscFunctionBegin;
1586   PetscValidCharPointer(name,2);
1587   PetscValidIntPointer(dvalue,3);
1588   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1589   if (!flag)  {if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
1590   if (!value) {if (set) *set = PETSC_TRUE; *nmax = 0; PetscFunctionReturn(0);}
1591 
1592   if (set) *set = PETSC_TRUE;
1593 
1594   ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
1595   ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1596   while (n < *nmax) {
1597     if (!value) break;
1598     ierr = PetscOptionsStringToBool(value,dvalue);CHKERRQ(ierr);
1599     ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1600     dvalue++;
1601     n++;
1602   }
1603   ierr  = PetscTokenDestroy(&token);CHKERRQ(ierr);
1604   *nmax = n;
1605   PetscFunctionReturn(0);
1606 }
1607 
1608 #undef __FUNCT__
1609 #define __FUNCT__ "PetscOptionsGetReal"
1610 /*@C
1611    PetscOptionsGetReal - Gets the double precision value for a particular
1612    option in the database.
1613 
1614    Not Collective
1615 
1616    Input Parameters:
1617 +  pre - string to prepend to each name or PETSC_NULL
1618 -  name - the option one is seeking
1619 
1620    Output Parameter:
1621 +  dvalue - the double value to return
1622 -  set - PETSC_TRUE if found, PETSC_FALSE if not found
1623 
1624    Note: if the option is given but no value is provided then set is given the value PETSC_FALSE
1625 
1626    Level: beginner
1627 
1628    Concepts: options database^has double
1629 
1630 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1631            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
1632           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1633           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1634           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1635           PetscOptionsList(), PetscOptionsEList()
1636 @*/
1637 PetscErrorCode  PetscOptionsGetReal(const char pre[],const char name[],PetscReal *dvalue,PetscBool  *set)
1638 {
1639   char           *value;
1640   PetscErrorCode ierr;
1641   PetscBool      flag;
1642 
1643   PetscFunctionBegin;
1644   PetscValidCharPointer(name,2);
1645   PetscValidRealPointer(dvalue,3);
1646   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1647   if (flag) {
1648     if (!value) {if (set) *set = PETSC_FALSE;}
1649     else        {if (set) *set = PETSC_TRUE; ierr = PetscOptionsStringToReal(value,dvalue);CHKERRQ(ierr);}
1650   } else {
1651     if (set) *set = PETSC_FALSE;
1652   }
1653   PetscFunctionReturn(0);
1654 }
1655 
1656 #undef __FUNCT__
1657 #define __FUNCT__ "PetscOptionsGetScalar"
1658 /*@C
1659    PetscOptionsGetScalar - Gets the scalar value for a particular
1660    option in the database.
1661 
1662    Not Collective
1663 
1664    Input Parameters:
1665 +  pre - string to prepend to each name or PETSC_NULL
1666 -  name - the option one is seeking
1667 
1668    Output Parameter:
1669 +  dvalue - the double value to return
1670 -  set - PETSC_TRUE if found, else PETSC_FALSE
1671 
1672    Level: beginner
1673 
1674    Usage:
1675    A complex number 2+3i can be specified as 2,3 at the command line.
1676    or a number 2.0e-10 - 3.3e-20 i  can be specified as 2.0e-10,-3.3e-20
1677 
1678    Note: if the option is given but no value is provided then set is given the value PETSC_FALSE
1679 
1680    Concepts: options database^has scalar
1681 
1682 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1683            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1684           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1685           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1686           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1687           PetscOptionsList(), PetscOptionsEList()
1688 @*/
1689 PetscErrorCode  PetscOptionsGetScalar(const char pre[],const char name[],PetscScalar *dvalue,PetscBool  *set)
1690 {
1691   char           *value;
1692   PetscBool      flag;
1693   PetscErrorCode ierr;
1694 
1695   PetscFunctionBegin;
1696   PetscValidCharPointer(name,2);
1697   PetscValidScalarPointer(dvalue,3);
1698   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1699   if (flag) {
1700     if (!value) {
1701       if (set) *set = PETSC_FALSE;
1702     } else {
1703 #if !defined(PETSC_USE_COMPLEX)
1704       ierr = PetscOptionsStringToReal(value,dvalue);CHKERRQ(ierr);
1705 #else
1706       PetscReal  re=0.0,im=0.0;
1707       PetscToken token;
1708       char       *tvalue = 0;
1709 
1710       ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
1711       ierr = PetscTokenFind(token,&tvalue);CHKERRQ(ierr);
1712       if (!tvalue) { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"unknown string specified\n"); }
1713       ierr    = PetscOptionsStringToReal(tvalue,&re);CHKERRQ(ierr);
1714       ierr    = PetscTokenFind(token,&tvalue);CHKERRQ(ierr);
1715       if (!tvalue) { /* Unknown separator used. using only real value */
1716         *dvalue = re;
1717       } else {
1718         ierr    = PetscOptionsStringToReal(tvalue,&im);CHKERRQ(ierr);
1719         *dvalue = re + PETSC_i*im;
1720       }
1721       ierr    = PetscTokenDestroy(&token);CHKERRQ(ierr);
1722 #endif
1723       if (set) *set    = PETSC_TRUE;
1724     }
1725   } else { /* flag */
1726     if (set) *set = PETSC_FALSE;
1727   }
1728   PetscFunctionReturn(0);
1729 }
1730 
1731 #undef __FUNCT__
1732 #define __FUNCT__ "PetscOptionsGetRealArray"
1733 /*@C
1734    PetscOptionsGetRealArray - Gets an array of double precision values for a
1735    particular option in the database.  The values must be separated with
1736    commas with no intervening spaces.
1737 
1738    Not Collective
1739 
1740    Input Parameters:
1741 +  pre - string to prepend to each name or PETSC_NULL
1742 .  name - the option one is seeking
1743 -  nmax - maximum number of values to retrieve
1744 
1745    Output Parameters:
1746 +  dvalue - the double value to return
1747 .  nmax - actual number of values retreived
1748 -  set - PETSC_TRUE if found, else PETSC_FALSE
1749 
1750    Level: beginner
1751 
1752    Concepts: options database^array of doubles
1753 
1754 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1755            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
1756           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1757           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1758           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1759           PetscOptionsList(), PetscOptionsEList()
1760 @*/
1761 PetscErrorCode  PetscOptionsGetRealArray(const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool  *set)
1762 {
1763   char           *value;
1764   PetscErrorCode ierr;
1765   PetscInt       n = 0;
1766   PetscBool      flag;
1767   PetscToken     token;
1768 
1769   PetscFunctionBegin;
1770   PetscValidCharPointer(name,2);
1771   PetscValidRealPointer(dvalue,3);
1772   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1773   if (!flag)  {if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
1774   if (!value) {if (set) *set = PETSC_TRUE; *nmax = 0; PetscFunctionReturn(0);}
1775 
1776   if (set) *set = PETSC_TRUE;
1777 
1778   ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
1779   ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1780   while (n < *nmax) {
1781     if (!value) break;
1782     ierr = PetscOptionsStringToReal(value,dvalue++);CHKERRQ(ierr);
1783     ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1784     n++;
1785   }
1786   ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
1787   *nmax = n;
1788   PetscFunctionReturn(0);
1789 }
1790 
1791 #undef __FUNCT__
1792 #define __FUNCT__ "PetscOptionsGetIntArray"
1793 /*@C
1794    PetscOptionsGetIntArray - Gets an array of integer values for a particular
1795    option in the database.
1796 
1797    Not Collective
1798 
1799    Input Parameters:
1800 +  pre - string to prepend to each name or PETSC_NULL
1801 .  name - the option one is seeking
1802 -  nmax - maximum number of values to retrieve
1803 
1804    Output Parameter:
1805 +  dvalue - the integer values to return
1806 .  nmax - actual number of values retreived
1807 -  set - PETSC_TRUE if found, else PETSC_FALSE
1808 
1809    Level: beginner
1810 
1811    Notes:
1812    The array can be passed as
1813    a comma seperated list:                                 0,1,2,3,4,5,6,7
1814    a range (start-end+1):                                  0-8
1815    a range with given increment (start-end+1:inc):         0-7:2
1816    a combination of values and ranges seperated by commas: 0,1-8,8-15:2
1817 
1818    There must be no intervening spaces between the values.
1819 
1820    Concepts: options database^array of ints
1821 
1822 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1823            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1824           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1825           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1826           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1827           PetscOptionsList(), PetscOptionsEList()
1828 @*/
1829 PetscErrorCode  PetscOptionsGetIntArray(const char pre[],const char name[],PetscInt dvalue[],PetscInt *nmax,PetscBool  *set)
1830 {
1831   char           *value;
1832   PetscErrorCode ierr;
1833   PetscInt       n = 0,i,j,start,end,inc,nvalues;
1834   size_t         len;
1835   PetscBool      flag,foundrange;
1836   PetscToken     token;
1837 
1838   PetscFunctionBegin;
1839   PetscValidCharPointer(name,2);
1840   PetscValidIntPointer(dvalue,3);
1841   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1842   if (!flag)  {if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
1843   if (!value) {if (set) *set = PETSC_TRUE; *nmax = 0; PetscFunctionReturn(0);}
1844 
1845   if (set) *set = PETSC_TRUE;
1846 
1847   ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
1848   ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1849   while (n < *nmax) {
1850     if (!value) break;
1851 
1852     /* look for form  d-D where d and D are integers */
1853     foundrange = PETSC_FALSE;
1854     ierr      = PetscStrlen(value,&len);CHKERRQ(ierr);
1855     if (value[0] == '-') i=2;
1856     else i=1;
1857     for (;i<(int)len; i++) {
1858       if (value[i] == '-') {
1859         if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
1860         value[i] = 0;
1861         ierr     = PetscOptionsStringToInt(value,&start);CHKERRQ(ierr);
1862         inc = 1;
1863         j = i+1;
1864         for (;j<(int)len; j++) {
1865           if (value[j] == ':') {
1866             value[j] = 0;
1867             ierr = PetscOptionsStringToInt(value+j+1,&inc);CHKERRQ(ierr);
1868             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);CHKERRQ(ierr);
1869             break;
1870           }
1871         }
1872         ierr     = PetscOptionsStringToInt(value+i+1,&end);CHKERRQ(ierr);
1873         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);
1874         nvalues = (end-start)/inc + (end-start)%inc;
1875         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);
1876         for (;start<end; start+=inc) {
1877           *dvalue = start; dvalue++;n++;
1878         }
1879         foundrange = PETSC_TRUE;
1880         break;
1881       }
1882     }
1883     if (!foundrange) {
1884       ierr      = PetscOptionsStringToInt(value,dvalue);CHKERRQ(ierr);
1885       dvalue++;
1886       n++;
1887     }
1888     ierr      = PetscTokenFind(token,&value);CHKERRQ(ierr);
1889   }
1890   ierr      = PetscTokenDestroy(&token);CHKERRQ(ierr);
1891   *nmax = n;
1892   PetscFunctionReturn(0);
1893 }
1894 
1895 #undef __FUNCT__
1896 #define __FUNCT__ "PetscOptionsGetString"
1897 /*@C
1898    PetscOptionsGetString - Gets the string value for a particular option in
1899    the database.
1900 
1901    Not Collective
1902 
1903    Input Parameters:
1904 +  pre - string to prepend to name or PETSC_NULL
1905 .  name - the option one is seeking
1906 -  len - maximum length of the string including null termination
1907 
1908    Output Parameters:
1909 +  string - location to copy string
1910 -  set - PETSC_TRUE if found, else PETSC_FALSE
1911 
1912    Level: beginner
1913 
1914    Fortran Note:
1915    The Fortran interface is slightly different from the C/C++
1916    interface (len is not used).  Sample usage in Fortran follows
1917 .vb
1918       character *20 string
1919       integer   flg, ierr
1920       call PetscOptionsGetString(PETSC_NULL_CHARACTER,'-s',string,flg,ierr)
1921 .ve
1922 
1923    Notes: if the option is given but no string is provided then an empty string is returned and set is given the value of PETSC_TRUE
1924 
1925    Concepts: options database^string
1926 
1927     Note:
1928       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).
1929 
1930 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1931            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1932           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1933           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1934           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1935           PetscOptionsList(), PetscOptionsEList()
1936 @*/
1937 PetscErrorCode  PetscOptionsGetString(const char pre[],const char name[],char string[],size_t len,PetscBool  *set)
1938 {
1939   char           *value;
1940   PetscErrorCode ierr;
1941   PetscBool      flag;
1942 
1943   PetscFunctionBegin;
1944   PetscValidCharPointer(name,2);
1945   PetscValidCharPointer(string,3);
1946   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1947   if (!flag) {
1948     if (set) *set = PETSC_FALSE;
1949   } else {
1950     if (set) *set = PETSC_TRUE;
1951     if (value) {
1952       ierr = PetscStrncpy(string,value,len);CHKERRQ(ierr);
1953       string[len-1] = 0;        /* Ensure that the string is NULL terminated */
1954     } else {
1955       ierr = PetscMemzero(string,len);CHKERRQ(ierr);
1956     }
1957   }
1958   PetscFunctionReturn(0);
1959 }
1960 
1961 #undef __FUNCT__
1962 #define __FUNCT__ "PetscOptionsGetStringMatlab"
1963 char* PetscOptionsGetStringMatlab(const char pre[],const char name[])
1964 {
1965   char           *value;
1966   PetscErrorCode ierr;
1967   PetscBool      flag;
1968 
1969   PetscFunctionBegin;
1970   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);if (ierr) PetscFunctionReturn(0);
1971   if (flag) PetscFunctionReturn(value);
1972   else PetscFunctionReturn(0);
1973 }
1974 
1975 
1976 #undef __FUNCT__
1977 #define __FUNCT__ "PetscOptionsGetStringArray"
1978 /*@C
1979    PetscOptionsGetStringArray - Gets an array of string values for a particular
1980    option in the database. The values must be separated with commas with
1981    no intervening spaces.
1982 
1983    Not Collective
1984 
1985    Input Parameters:
1986 +  pre - string to prepend to name or PETSC_NULL
1987 .  name - the option one is seeking
1988 -  nmax - maximum number of strings
1989 
1990    Output Parameter:
1991 +  strings - location to copy strings
1992 -  set - PETSC_TRUE if found, else PETSC_FALSE
1993 
1994    Level: beginner
1995 
1996    Notes:
1997    The user should pass in an array of pointers to char, to hold all the
1998    strings returned by this function.
1999 
2000    The user is responsible for deallocating the strings that are
2001    returned. The Fortran interface for this routine is not supported.
2002 
2003    Contributed by Matthew Knepley.
2004 
2005    Concepts: options database^array of strings
2006 
2007 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2008            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2009           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2010           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2011           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2012           PetscOptionsList(), PetscOptionsEList()
2013 @*/
2014 PetscErrorCode  PetscOptionsGetStringArray(const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool  *set)
2015 {
2016   char           *value;
2017   PetscErrorCode ierr;
2018   PetscInt       n;
2019   PetscBool      flag;
2020   PetscToken     token;
2021 
2022   PetscFunctionBegin;
2023   PetscValidCharPointer(name,2);
2024   PetscValidPointer(strings,3);
2025   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
2026   if (!flag)  {*nmax = 0; if (set) *set = PETSC_FALSE; PetscFunctionReturn(0);}
2027   if (!value) {*nmax = 0; if (set) *set = PETSC_FALSE;PetscFunctionReturn(0);}
2028   if (!*nmax) {if (set) *set = PETSC_FALSE;PetscFunctionReturn(0);}
2029   if (set) *set = PETSC_TRUE;
2030 
2031   ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
2032   ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
2033   n = 0;
2034   while (n < *nmax) {
2035     if (!value) break;
2036     ierr = PetscStrallocpy(value,&strings[n]);CHKERRQ(ierr);
2037     ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
2038     n++;
2039   }
2040   ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
2041   *nmax = n;
2042   PetscFunctionReturn(0);
2043 }
2044 
2045 #undef __FUNCT__
2046 #define __FUNCT__ "PetscOptionsUsed"
2047 /*@C
2048    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
2049 
2050    Not Collective
2051 
2052    Input Parameter:
2053 .    option - string name of option
2054 
2055    Output Parameter:
2056 .   used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database
2057 
2058    Level: advanced
2059 
2060 .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
2061 @*/
2062 PetscErrorCode  PetscOptionsUsed(const char *option,PetscBool *used)
2063 {
2064   PetscInt       i;
2065   PetscErrorCode ierr;
2066 
2067   PetscFunctionBegin;
2068   *used = PETSC_FALSE;
2069   for (i=0; i<options->N; i++) {
2070     ierr = PetscStrcmp(options->names[i],option,used);CHKERRQ(ierr);
2071     if (*used) {
2072       *used = options->used[i];
2073       break;
2074     }
2075   }
2076   PetscFunctionReturn(0);
2077 }
2078 
2079 #undef __FUNCT__
2080 #define __FUNCT__ "PetscOptionsAllUsed"
2081 /*@C
2082    PetscOptionsAllUsed - Returns a count of the number of options in the
2083    database that have never been selected.
2084 
2085    Not Collective
2086 
2087    Output Parameter:
2088 .   N - count of options not used
2089 
2090    Level: advanced
2091 
2092 .seealso: PetscOptionsView()
2093 @*/
2094 PetscErrorCode  PetscOptionsAllUsed(PetscInt *N)
2095 {
2096   PetscInt i,n = 0;
2097 
2098   PetscFunctionBegin;
2099   for (i=0; i<options->N; i++) {
2100     if (!options->used[i]) { n++; }
2101   }
2102   *N = n;
2103   PetscFunctionReturn(0);
2104 }
2105 
2106 #undef __FUNCT__
2107 #define __FUNCT__ "PetscOptionsLeft"
2108 /*@
2109     PetscOptionsLeft - Prints to screen any options that were set and never used.
2110 
2111   Not collective
2112 
2113    Options Database Key:
2114 .  -options_left - Activates OptionsAllUsed() within PetscFinalize()
2115 
2116   Level: advanced
2117 
2118 .seealso: PetscOptionsAllUsed()
2119 @*/
2120 PetscErrorCode  PetscOptionsLeft(void)
2121 {
2122   PetscErrorCode ierr;
2123   PetscInt       i;
2124 
2125   PetscFunctionBegin;
2126   for (i=0; i<options->N; i++) {
2127     if (!options->used[i]) {
2128       if (options->values[i]) {
2129         ierr = PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",options->names[i],options->values[i]);CHKERRQ(ierr);
2130       } else {
2131         ierr = PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s no value \n",options->names[i]);CHKERRQ(ierr);
2132       }
2133     }
2134   }
2135   PetscFunctionReturn(0);
2136 }
2137 
2138 
2139 #undef __FUNCT__
2140 #define __FUNCT__ "PetscOptionsCreate"
2141 /*
2142     PetscOptionsCreate - Creates the empty options database.
2143 
2144 */
2145 PetscErrorCode  PetscOptionsCreate(void)
2146 {
2147   PetscErrorCode ierr;
2148 
2149   PetscFunctionBegin;
2150   options = (PetscOptionsTable*)malloc(sizeof(PetscOptionsTable));
2151   ierr    = PetscMemzero(options,sizeof(PetscOptionsTable));CHKERRQ(ierr);
2152   options->namegiven            = PETSC_FALSE;
2153   options->N                    = 0;
2154   options->Naliases             = 0;
2155   options->numbermonitors       = 0;
2156 
2157   PetscOptionsObject.prefix = PETSC_NULL;
2158   PetscOptionsObject.title  = PETSC_NULL;
2159 
2160   PetscFunctionReturn(0);
2161 }
2162 
2163 #undef __FUNCT__
2164 #define __FUNCT__ "PetscOptionsSetFromOptions"
2165 /*@
2166    PetscOptionsSetFromOptions - Sets various SNES and KSP parameters from user options.
2167 
2168    Collective on PETSC_COMM_WORLD
2169 
2170    Options Database Keys:
2171 +  -options_monitor <optional filename> - prints the names and values of all runtime options as they are set. The monitor functionality is not
2172                 available for options set through a file, environment variable, or on
2173                 the command line. Only options set after PetscInitialize completes will
2174                 be monitored.
2175 .  -options_monitor_cancel - cancel all options database monitors
2176 
2177    Notes:
2178    To see all options, run your program with the -help option or consult
2179    the <A href="../../docs/manual.pdf">users manual</A>..
2180 
2181    Level: intermediate
2182 
2183 .keywords: set, options, database
2184 @*/
2185 PetscErrorCode  PetscOptionsSetFromOptions(void)
2186 {
2187   PetscBool           flgc,flgm;
2188   PetscErrorCode      ierr;
2189   char                monfilename[PETSC_MAX_PATH_LEN];
2190   PetscViewer         monviewer;
2191 
2192   PetscFunctionBegin;
2193   ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","Options database options","PetscOptions");CHKERRQ(ierr);
2194     ierr = PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);CHKERRQ(ierr);
2195     ierr = PetscOptionsBool("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",PETSC_FALSE,&flgc,PETSC_NULL);CHKERRQ(ierr);
2196   ierr = PetscOptionsEnd();CHKERRQ(ierr);
2197   if (flgm) {
2198     ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);CHKERRQ(ierr);
2199     ierr = PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
2200   }
2201   if (flgc) { ierr = PetscOptionsMonitorCancel();CHKERRQ(ierr); }
2202   PetscFunctionReturn(0);
2203 }
2204 
2205 
2206 #undef __FUNCT__
2207 #define __FUNCT__ "PetscOptionsMonitorDefault"
2208 /*@C
2209    PetscOptionsMonitorDefault - Print all options set value events.
2210 
2211    Logically Collective on PETSC_COMM_WORLD
2212 
2213    Input Parameters:
2214 +  name  - option name string
2215 .  value - option value string
2216 -  dummy - unused monitor context
2217 
2218    Level: intermediate
2219 
2220 .keywords: PetscOptions, default, monitor
2221 
2222 .seealso: PetscOptionsMonitorSet()
2223 @*/
2224 PetscErrorCode  PetscOptionsMonitorDefault(const char name[], const char value[], void *dummy)
2225 {
2226   PetscErrorCode ierr;
2227   PetscViewer    viewer = (PetscViewer) dummy;
2228 
2229   PetscFunctionBegin;
2230   if (!viewer) {
2231     ierr = PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);CHKERRQ(ierr);
2232   }
2233   ierr = PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);CHKERRQ(ierr);
2234   PetscFunctionReturn(0);
2235 }
2236 
2237 #undef __FUNCT__
2238 #define __FUNCT__ "PetscOptionsMonitorSet"
2239 /*@C
2240    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
2241    modified the PETSc options database.
2242 
2243    Not collective
2244 
2245    Input Parameters:
2246 +  monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring
2247 .  mctx    - [optional] context for private data for the
2248              monitor routine (use PETSC_NULL if no context is desired)
2249 -  monitordestroy - [optional] routine that frees monitor context
2250           (may be PETSC_NULL)
2251 
2252    Calling Sequence of monitor:
2253 $     monitor (const char name[], const char value[], void *mctx)
2254 
2255 +  name - option name string
2256 .  value - option value string
2257 -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()
2258 
2259    Options Database Keys:
2260 +    -options_monitor    - sets PetscOptionsMonitorDefault()
2261 -    -options_monitor_cancel - cancels all monitors that have
2262                           been hardwired into a code by
2263                           calls to PetscOptionsMonitorSet(), but
2264                           does not cancel those set via
2265                           the options database.
2266 
2267    Notes:
2268    The default is to do nothing.  To print the name and value of options
2269    being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
2270    with a null monitoring context.
2271 
2272    Several different monitoring routines may be set by calling
2273    PetscOptionsMonitorSet() multiple times; all will be called in the
2274    order in which they were set.
2275 
2276    Level: beginner
2277 
2278 .keywords: PetscOptions, set, monitor
2279 
2280 .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
2281 @*/
2282 PetscErrorCode  PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
2283 {
2284   PetscFunctionBegin;
2285   if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
2286   options->monitor[options->numbermonitors]           = monitor;
2287   options->monitordestroy[options->numbermonitors]    = monitordestroy;
2288   options->monitorcontext[options->numbermonitors++]  = (void*)mctx;
2289   PetscFunctionReturn(0);
2290 }
2291 
2292 #undef __FUNCT__
2293 #define __FUNCT__ "PetscOptionsMonitorCancel"
2294 /*@
2295    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.
2296 
2297    Not collective
2298 
2299    Options Database Key:
2300 .  -options_monitor_cancel - Cancels all monitors that have
2301     been hardwired into a code by calls to PetscOptionsMonitorSet(),
2302     but does not cancel those set via the options database.
2303 
2304    Level: intermediate
2305 
2306 .keywords: PetscOptions, set, monitor
2307 
2308 .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
2309 @*/
2310 PetscErrorCode  PetscOptionsMonitorCancel(void)
2311 {
2312   PetscErrorCode ierr;
2313   PetscInt       i;
2314 
2315   PetscFunctionBegin;
2316   for (i=0; i<options->numbermonitors; i++) {
2317     if (options->monitordestroy[i]) {
2318       ierr = (*options->monitordestroy[i])(&options->monitorcontext[i]);CHKERRQ(ierr);
2319     }
2320   }
2321   options->numbermonitors = 0;
2322   PetscFunctionReturn(0);
2323 }
2324