xref: /petsc/src/sys/objects/options.c (revision bbd56ea5790821d2a217d362e8e9710702952333)
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       ierr = PetscMPIIntCast(len,&acnt);CHKERRQ(ierr);
458       ierr = PetscStrlen(vstring,&len);CHKERRQ(ierr);
459       ierr = PetscMPIIntCast(len,&cnt);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   PetscFunctionReturn(0);
657 }
658 
659 #undef __FUNCT__
660 #define __FUNCT__ "PetscOptionsView"
661 /*@C
662    PetscOptionsView - Prints the options that have been loaded. This is
663    useful for debugging purposes.
664 
665    Logically Collective on PetscViewer
666 
667    Input Parameter:
668 .  viewer - must be an PETSCVIEWERASCII viewer
669 
670    Options Database Key:
671 .  -options_table - Activates PetscOptionsView() within PetscFinalize()
672 
673    Level: advanced
674 
675    Concepts: options database^printing
676 
677 .seealso: PetscOptionsAllUsed()
678 @*/
679 PetscErrorCode  PetscOptionsView(PetscViewer viewer)
680 {
681   PetscErrorCode ierr;
682   PetscInt       i;
683   PetscBool      isascii;
684 
685   PetscFunctionBegin;
686   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
687   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
688   if (!isascii) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Only supports ASCII viewer");
689 
690   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
691   if (options->N) {
692     ierr = PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");CHKERRQ(ierr);
693   } else {
694     ierr = PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");CHKERRQ(ierr);
695   }
696   for (i=0; i<options->N; i++) {
697     if (options->values[i]) {
698       ierr = PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);CHKERRQ(ierr);
699     } else {
700       ierr = PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);CHKERRQ(ierr);
701     }
702   }
703   if (options->N) {
704     ierr = PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");CHKERRQ(ierr);
705   }
706   PetscFunctionReturn(0);
707 }
708 
709 #undef __FUNCT__
710 #define __FUNCT__ "PetscOptionsGetAll"
711 /*@C
712    PetscOptionsGetAll - Lists all the options the program was run with in a single string.
713 
714    Not Collective
715 
716    Output Parameter:
717 .  copts - pointer where string pointer is stored
718 
719    Notes: the array and each entry in the array should be freed with PetscFree()
720 
721    Level: advanced
722 
723    Concepts: options database^listing
724 
725 .seealso: PetscOptionsAllUsed(), PetscOptionsView()
726 @*/
727 PetscErrorCode  PetscOptionsGetAll(char *copts[])
728 {
729   PetscErrorCode ierr;
730   PetscInt       i;
731   size_t         len = 1,lent = 0;
732   char           *coptions = PETSC_NULL;
733 
734   PetscFunctionBegin;
735   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
736 
737   /* count the length of the required string */
738   for (i=0; i<options->N; i++) {
739     ierr = PetscStrlen(options->names[i],&lent);CHKERRQ(ierr);
740     len += 2 + lent;
741     if (options->values[i]) {
742       ierr = PetscStrlen(options->values[i],&lent);CHKERRQ(ierr);
743       len += 1 + lent;
744     }
745   }
746   ierr = PetscMalloc(len*sizeof(char),&coptions);CHKERRQ(ierr);
747   coptions[0] = 0;
748   for (i=0; i<options->N; i++) {
749     ierr = PetscStrcat(coptions,"-");CHKERRQ(ierr);
750     ierr = PetscStrcat(coptions,options->names[i]);CHKERRQ(ierr);
751     ierr = PetscStrcat(coptions," ");CHKERRQ(ierr);
752     if (options->values[i]) {
753       ierr = PetscStrcat(coptions,options->values[i]);CHKERRQ(ierr);
754       ierr = PetscStrcat(coptions," ");CHKERRQ(ierr);
755     }
756   }
757   *copts = coptions;
758   PetscFunctionReturn(0);
759 }
760 
761 #undef __FUNCT__
762 #define __FUNCT__ "PetscOptionsPrefixPush"
763 /*@
764    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
765 
766    Not Collective, but prefix will only be applied on calling ranks
767 
768    Input Parameter:
769 .  prefix - The string to append to the existing prefix
770 
771    Options Database Keys:
772  +   -prefix_push <some_prefix_> - push the given prefix
773  -   -prefix_pop - pop the last prefix
774 
775    Notes:
776    It is common to use this in conjunction with -options_file as in
777 
778  $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
779 
780    where the files no longer require all options to be prefixed with -system2_.
781 
782 Level: advanced
783 
784 .seealso: PetscOptionsPrefixPop()
785 @*/
786 PetscErrorCode  PetscOptionsPrefixPush(const char prefix[])
787 {
788   PetscErrorCode ierr;
789   size_t n;
790   PetscInt start;
791   char buf[2048];
792   PetscBool  key;
793 
794   PetscFunctionBegin;
795   PetscValidCharPointer(prefix,1);
796   /* Want to check validity of the key using PetscOptionsValidKey(), which requires that the first character is a '-' */
797   buf[0] = '-';
798   ierr = PetscStrncpy(buf+1,prefix,sizeof(buf) - 1);CHKERRQ(ierr);
799   buf[sizeof(buf) - 1] = 0;
800   ierr = PetscOptionsValidKey(buf,&key);CHKERRQ(ierr);
801   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);
802 
803   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
804   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);
805   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
806   ierr = PetscStrlen(prefix,&n);CHKERRQ(ierr);
807   if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
808   ierr = PetscMemcpy(options->prefix+start,prefix,n+1);CHKERRQ(ierr);
809   options->prefixstack[options->prefixind++] = start+n;
810   PetscFunctionReturn(0);
811 }
812 
813 #undef __FUNCT__
814 #define __FUNCT__ "PetscOptionsPrefixPop"
815 /*@
816    PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details
817 
818    Not  Collective, but prefix will only be popped on calling ranks
819 
820    Level: advanced
821 
822 .seealso: PetscOptionsPrefixPush()
823 @*/
824 PetscErrorCode  PetscOptionsPrefixPop(void)
825 {
826   PetscInt offset;
827 
828   PetscFunctionBegin;
829   if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
830   options->prefixind--;
831   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
832   options->prefix[offset] = 0;
833   PetscFunctionReturn(0);
834 }
835 
836 #undef __FUNCT__
837 #define __FUNCT__ "PetscOptionsClear"
838 /*@C
839     PetscOptionsClear - Removes all options form the database leaving it empty.
840 
841    Level: developer
842 
843 .seealso: PetscOptionsInsert()
844 @*/
845 PetscErrorCode  PetscOptionsClear(void)
846 {
847   PetscInt i;
848 
849   PetscFunctionBegin;
850   if (!options) PetscFunctionReturn(0);
851   for (i=0; i<options->N; i++) {
852     if (options->names[i])  free(options->names[i]);
853     if (options->values[i]) free(options->values[i]);
854   }
855   for (i=0; i<options->Naliases; i++) {
856     free(options->aliases1[i]);
857     free(options->aliases2[i]);
858   }
859   options->prefix[0] = 0;
860   options->prefixind = 0;
861   options->N        = 0;
862   options->Naliases = 0;
863   PetscFunctionReturn(0);
864 }
865 
866 #undef __FUNCT__
867 #define __FUNCT__ "PetscOptionsDestroy"
868 /*@C
869     PetscOptionsDestroy - Destroys the option database.
870 
871     Note:
872     Since PetscOptionsDestroy() is called by PetscFinalize(), the user
873     typically does not need to call this routine.
874 
875    Level: developer
876 
877 .seealso: PetscOptionsInsert()
878 @*/
879 PetscErrorCode  PetscOptionsDestroy(void)
880 {
881   PetscErrorCode ierr;
882 
883   PetscFunctionBegin;
884   if (!options) PetscFunctionReturn(0);
885   ierr = PetscOptionsClear();CHKERRQ(ierr);
886   free(options);
887   options = 0;
888   PetscFunctionReturn(0);
889 }
890 
891 #undef __FUNCT__
892 #define __FUNCT__ "PetscOptionsSetValue"
893 /*@C
894    PetscOptionsSetValue - Sets an option name-value pair in the options
895    database, overriding whatever is already present.
896 
897    Not collective, but setting values on certain processors could cause problems
898    for parallel objects looking for options.
899 
900    Input Parameters:
901 +  name - name of option, this SHOULD have the - prepended
902 -  value - the option value (not used for all options)
903 
904    Level: intermediate
905 
906    Note:
907    Only some options have values associated with them, such as
908    -ksp_rtol tol.  Other options stand alone, such as -ksp_monitor.
909 
910   Concepts: options database^adding option
911 
912 .seealso: PetscOptionsInsert()
913 @*/
914 PetscErrorCode  PetscOptionsSetValue(const char iname[],const char value[])
915 {
916   size_t         len;
917   PetscErrorCode ierr;
918   PetscInt       N,n,i;
919   char           **names;
920   char           fullname[2048];
921   const char     *name = iname;
922   PetscBool      gt,match;
923 
924   PetscFunctionBegin;
925   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
926 
927   /* this is so that -h and -hel\p are equivalent (p4 does not like -help)*/
928   ierr = PetscStrcasecmp(name,"-h",&match);CHKERRQ(ierr);
929   if (match) name = "-help";
930 
931   name++; /* skip starting hyphen */
932   if (options->prefixind > 0) {
933     ierr = PetscStrncpy(fullname,options->prefix,sizeof(fullname));CHKERRQ(ierr);
934     ierr = PetscStrncat(fullname,name,sizeof(fullname));CHKERRQ(ierr);
935     name = fullname;
936   }
937 
938   /* check against aliases */
939   N = options->Naliases;
940   for (i=0; i<N; i++) {
941     ierr = PetscStrcasecmp(options->aliases1[i],name,&match);CHKERRQ(ierr);
942     if (match) {
943       name = options->aliases2[i];
944       break;
945     }
946   }
947 
948   N     = options->N;
949   n     = N;
950   names = options->names;
951 
952   for (i=0; i<N; i++) {
953     ierr = PetscStrcasecmp(names[i],name,&match);CHKERRQ(ierr);
954     ierr  = PetscStrgrt(names[i],name,&gt);CHKERRQ(ierr);
955     if (match) {
956       if (options->values[i]) free(options->values[i]);
957       ierr = PetscStrlen(value,&len);CHKERRQ(ierr);
958       if (len) {
959         options->values[i] = (char*)malloc((len+1)*sizeof(char));
960         ierr = PetscStrcpy(options->values[i],value);CHKERRQ(ierr);
961       } else { options->values[i] = 0;}
962       PetscOptionsMonitor(name,value);
963       PetscFunctionReturn(0);
964     } else if (gt) {
965       n = i;
966       break;
967     }
968   }
969   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);
970 
971   /* shift remaining values down 1 */
972   for (i=N; i>n; i--) {
973     options->names[i]  = options->names[i-1];
974     options->values[i] = options->values[i-1];
975     options->used[i]   = options->used[i-1];
976   }
977   /* insert new name and value */
978   ierr = PetscStrlen(name,&len);CHKERRQ(ierr);
979   options->names[n] = (char*)malloc((len+1)*sizeof(char));
980   ierr = PetscStrcpy(options->names[n],name);CHKERRQ(ierr);
981   ierr = PetscStrlen(value,&len);CHKERRQ(ierr);
982   if (len) {
983     options->values[n] = (char*)malloc((len+1)*sizeof(char));
984     ierr = PetscStrcpy(options->values[n],value);CHKERRQ(ierr);
985   } else {options->values[n] = 0;}
986   options->used[n] = PETSC_FALSE;
987   options->N++;
988   PetscOptionsMonitor(name,value);
989   PetscFunctionReturn(0);
990 }
991 
992 #undef __FUNCT__
993 #define __FUNCT__ "PetscOptionsClearValue"
994 /*@C
995    PetscOptionsClearValue - Clears an option name-value pair in the options
996    database, overriding whatever is already present.
997 
998    Not Collective, but setting values on certain processors could cause problems
999    for parallel objects looking for options.
1000 
1001    Input Parameter:
1002 .  name - name of option, this SHOULD have the - prepended
1003 
1004    Level: intermediate
1005 
1006    Concepts: options database^removing option
1007 .seealso: PetscOptionsInsert()
1008 @*/
1009 PetscErrorCode  PetscOptionsClearValue(const char iname[])
1010 {
1011   PetscErrorCode ierr;
1012   PetscInt       N,n,i;
1013   char           **names,*name=(char*)iname;
1014   PetscBool      gt,match;
1015 
1016   PetscFunctionBegin;
1017   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);
1018   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
1019 
1020   name++;
1021 
1022   N     = options->N; n = 0;
1023   names = options->names;
1024 
1025   for (i=0; i<N; i++) {
1026     ierr  = PetscStrcasecmp(names[i],name,&match);CHKERRQ(ierr);
1027     ierr  = PetscStrgrt(names[i],name,&gt);CHKERRQ(ierr);
1028     if (match) {
1029       if (options->names[i])  free(options->names[i]);
1030       if (options->values[i]) free(options->values[i]);
1031       PetscOptionsMonitor(name,"");
1032       break;
1033     } else if (gt) {
1034       PetscFunctionReturn(0); /* it was not listed */
1035     }
1036     n++;
1037   }
1038   if (n == N) PetscFunctionReturn(0); /* it was not listed */
1039 
1040   /* shift remaining values down 1 */
1041   for (i=n; i<N-1; i++) {
1042     options->names[i]  = options->names[i+1];
1043     options->values[i] = options->values[i+1];
1044     options->used[i]   = options->used[i+1];
1045   }
1046   options->N--;
1047   PetscFunctionReturn(0);
1048 }
1049 
1050 #undef __FUNCT__
1051 #define __FUNCT__ "PetscOptionsSetAlias"
1052 /*@C
1053    PetscOptionsSetAlias - Makes a key and alias for another key
1054 
1055    Not Collective, but setting values on certain processors could cause problems
1056    for parallel objects looking for options.
1057 
1058    Input Parameters:
1059 +  inewname - the alias
1060 -  ioldname - the name that alias will refer to
1061 
1062    Level: advanced
1063 
1064 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1065            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
1066           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1067           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1068           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1069           PetscOptionsList(), PetscOptionsEList()
1070 @*/
1071 PetscErrorCode  PetscOptionsSetAlias(const char inewname[],const char ioldname[])
1072 {
1073   PetscErrorCode ierr;
1074   PetscInt       n = options->Naliases;
1075   size_t         len;
1076   char           *newname = (char *)inewname,*oldname = (char*)ioldname;
1077 
1078   PetscFunctionBegin;
1079   if (newname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliased must have -: Instead %s",newname);
1080   if (oldname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliasee must have -: Instead %s",oldname);
1081   if (n >= MAXALIASES) {
1082     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);
1083   }
1084 
1085   newname++; oldname++;
1086   ierr = PetscStrlen(newname,&len);CHKERRQ(ierr);
1087   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
1088   ierr = PetscStrcpy(options->aliases1[n],newname);CHKERRQ(ierr);
1089   ierr = PetscStrlen(oldname,&len);CHKERRQ(ierr);
1090   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
1091   ierr = PetscStrcpy(options->aliases2[n],oldname);CHKERRQ(ierr);
1092   options->Naliases++;
1093   PetscFunctionReturn(0);
1094 }
1095 
1096 #undef __FUNCT__
1097 #define __FUNCT__ "PetscOptionsFindPair_Private"
1098 PetscErrorCode PetscOptionsFindPair_Private(const char pre[],const char name[],char *value[],PetscBool  *flg)
1099 {
1100   PetscErrorCode ierr;
1101   PetscInt       i,N;
1102   size_t         len;
1103   char           **names,tmp[256];
1104   PetscBool      match;
1105 
1106   PetscFunctionBegin;
1107   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
1108   N = options->N;
1109   names = options->names;
1110 
1111   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);
1112 
1113   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1114   if (pre) {
1115     char *ptr = tmp;
1116     const char *namep = name;
1117     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
1118     if (name[1] == '-') {
1119       *ptr++ = '-';
1120       namep++;
1121     }
1122     ierr = PetscStrncpy(ptr,pre,tmp+sizeof(tmp)-ptr);CHKERRQ(ierr);
1123     tmp[sizeof(tmp)-1] = 0;
1124     ierr = PetscStrlen(tmp,&len);CHKERRQ(ierr);
1125     ierr = PetscStrncat(tmp,namep+1,sizeof(tmp)-len-1);CHKERRQ(ierr);
1126   } else {
1127     ierr = PetscStrncpy(tmp,name+1,sizeof(tmp));CHKERRQ(ierr);
1128     tmp[sizeof(tmp)-1] = 0;
1129   }
1130 #if defined(PETSC_USE_DEBUG)
1131   {
1132     PetscBool valid;
1133     char key[sizeof(tmp)+1] = "-";
1134     ierr = PetscMemcpy(key+1,tmp,sizeof(tmp));CHKERRQ(ierr);
1135     ierr = PetscOptionsValidKey(key,&valid);CHKERRQ(ierr);
1136     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1137   }
1138 #endif
1139 
1140   /* slow search */
1141   *flg = PETSC_FALSE;
1142   for (i=0; i<N; i++) {
1143     ierr = PetscStrcasecmp(names[i],tmp,&match);CHKERRQ(ierr);
1144     if (match) {
1145        *value           = options->values[i];
1146        options->used[i] = PETSC_TRUE;
1147        *flg             = PETSC_TRUE;
1148        break;
1149      }
1150   }
1151   if (!*flg) {
1152     PetscInt j,cnt = 0,locs[16],loce[16];
1153     size_t   n;
1154     ierr = PetscStrlen(tmp,&n);CHKERRQ(ierr);
1155     /* determine the location and number of all _%d_ in the key */
1156     for (i=0; i< (PetscInt)n; i++) {
1157       if (tmp[i] == '_') {
1158         for (j=i+1; j< (PetscInt)n; j++) {
1159           if (tmp[j] >= '0' && tmp[j] <= '9') continue;
1160           if (tmp[j] == '_' && j > i+1) { /* found a number */
1161             locs[cnt]   = i+1;
1162             loce[cnt++] = j+1;
1163           }
1164           break;
1165         }
1166       }
1167     }
1168     if (cnt) {
1169       char tmp2[256];
1170       for (i=0; i<cnt; i++) {
1171         ierr = PetscStrcpy(tmp2,"-");CHKERRQ(ierr);
1172         ierr = PetscStrncat(tmp2,tmp,locs[i]);CHKERRQ(ierr);
1173         ierr = PetscStrcat(tmp2,tmp+loce[i]);CHKERRQ(ierr);
1174         ierr = PetscOptionsFindPair_Private(PETSC_NULL,tmp2,value,flg);CHKERRQ(ierr);
1175         if (*flg) break;
1176       }
1177     }
1178   }
1179   PetscFunctionReturn(0);
1180 }
1181 
1182 #undef __FUNCT__
1183 #define __FUNCT__ "PetscOptionsFindPairPrefix_Private"
1184 PetscErrorCode PetscOptionsFindPairPrefix_Private(const char pre[], const char name[], char *value[], PetscBool *flg)
1185 {
1186   PetscErrorCode ierr;
1187   PetscInt       i,N;
1188   size_t         len;
1189   char           **names,tmp[256];
1190   PetscBool      match;
1191 
1192   PetscFunctionBegin;
1193   if (!options) {ierr = PetscOptionsInsert(0,0,0);CHKERRQ(ierr);}
1194   N = options->N;
1195   names = options->names;
1196 
1197   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);
1198 
1199   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1200   if (pre) {
1201     char *ptr = tmp;
1202     const char *namep = name;
1203     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
1204     if (name[1] == '-') {
1205       *ptr++ = '-';
1206       namep++;
1207     }
1208     ierr = PetscStrncpy(ptr,pre,tmp+sizeof(tmp)-ptr);CHKERRQ(ierr);
1209     tmp[sizeof(tmp)-1] = 0;
1210     ierr = PetscStrlen(tmp,&len);CHKERRQ(ierr);
1211     ierr = PetscStrncat(tmp,namep+1,sizeof(tmp)-len-1);CHKERRQ(ierr);
1212   } else {
1213     ierr = PetscStrncpy(tmp,name+1,sizeof(tmp));CHKERRQ(ierr);
1214     tmp[sizeof(tmp)-1] = 0;
1215   }
1216 #if defined(PETSC_USE_DEBUG)
1217   {
1218     PetscBool valid;
1219     char key[sizeof(tmp)+1] = "-";
1220     ierr = PetscMemcpy(key+1,tmp,sizeof(tmp));CHKERRQ(ierr);
1221     ierr = PetscOptionsValidKey(key,&valid);CHKERRQ(ierr);
1222     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1223   }
1224 #endif
1225 
1226   /* slow search */
1227   *flg = PETSC_FALSE;
1228   ierr = PetscStrlen(tmp,&len);CHKERRQ(ierr);
1229   for (i = 0; i < N; ++i) {
1230     ierr = PetscStrncmp(names[i], tmp, len, &match);CHKERRQ(ierr);
1231     if (match) {
1232       if (value) *value = options->values[i];
1233       options->used[i]  = PETSC_TRUE;
1234       if (flg)   *flg   = PETSC_TRUE;
1235       break;
1236     }
1237   }
1238   PetscFunctionReturn(0);
1239 }
1240 
1241 #undef __FUNCT__
1242 #define __FUNCT__ "PetscOptionsReject"
1243 /*@C
1244    PetscOptionsReject - Generates an error if a certain option is given.
1245 
1246    Not Collective, but setting values on certain processors could cause problems
1247    for parallel objects looking for options.
1248 
1249    Input Parameters:
1250 +  name - the option one is seeking
1251 -  mess - error message (may be PETSC_NULL)
1252 
1253    Level: advanced
1254 
1255    Concepts: options database^rejecting option
1256 
1257 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1258            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1259           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1260           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1261           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1262           PetscOptionsList(), PetscOptionsEList()
1263 @*/
1264 PetscErrorCode  PetscOptionsReject(const char name[],const char mess[])
1265 {
1266   PetscErrorCode ierr;
1267   PetscBool      flag = PETSC_FALSE;
1268 
1269   PetscFunctionBegin;
1270   ierr = PetscOptionsHasName(PETSC_NULL,name,&flag);CHKERRQ(ierr);
1271   if (flag) {
1272     if (mess) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s with %s",name,mess);
1273     else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s",name);
1274   }
1275   PetscFunctionReturn(0);
1276 }
1277 
1278 #undef __FUNCT__
1279 #define __FUNCT__ "PetscOptionsHasName"
1280 /*@C
1281    PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or boolean, even
1282                       its value is set to false.
1283 
1284    Not Collective
1285 
1286    Input Parameters:
1287 +  name - the option one is seeking
1288 -  pre - string to prepend to the name or PETSC_NULL
1289 
1290    Output Parameters:
1291 .  set - PETSC_TRUE if found else PETSC_FALSE.
1292 
1293    Level: beginner
1294 
1295    Concepts: options database^has option name
1296 
1297    Notes: Name cannot be simply -h
1298 
1299           In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.
1300 
1301 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1302            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1303           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1304           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1305           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1306           PetscOptionsList(), PetscOptionsEList()
1307 @*/
1308 PetscErrorCode  PetscOptionsHasName(const char pre[],const char name[],PetscBool  *set)
1309 {
1310   char           *value;
1311   PetscErrorCode ierr;
1312   PetscBool      flag;
1313 
1314   PetscFunctionBegin;
1315   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1316   if (set) *set = flag;
1317   PetscFunctionReturn(0);
1318 }
1319 
1320 #undef __FUNCT__
1321 #define __FUNCT__ "PetscOptionsGetInt"
1322 /*@C
1323    PetscOptionsGetInt - Gets the integer value for a particular option in the database.
1324 
1325    Not Collective
1326 
1327    Input Parameters:
1328 +  pre - the string to prepend to the name or PETSC_NULL
1329 -  name - the option one is seeking
1330 
1331    Output Parameter:
1332 +  ivalue - the integer value to return
1333 -  set - PETSC_TRUE if found, else PETSC_FALSE
1334 
1335    Level: beginner
1336 
1337    Concepts: options database^has int
1338 
1339 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1340           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1341           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1342           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1343           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1344           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1345           PetscOptionsList(), PetscOptionsEList()
1346 @*/
1347 PetscErrorCode  PetscOptionsGetInt(const char pre[],const char name[],PetscInt *ivalue,PetscBool  *set)
1348 {
1349   char           *value;
1350   PetscErrorCode ierr;
1351   PetscBool      flag;
1352 
1353   PetscFunctionBegin;
1354   PetscValidCharPointer(name,2);
1355   PetscValidIntPointer(ivalue,3);
1356   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1357   if (flag) {
1358     if (!value) {if (set) *set = PETSC_FALSE;}
1359     else {
1360       if (set) *set = PETSC_TRUE;
1361       ierr = PetscOptionsStringToInt(value,ivalue);CHKERRQ(ierr);
1362     }
1363   } else {
1364     if (set) *set = PETSC_FALSE;
1365   }
1366   PetscFunctionReturn(0);
1367 }
1368 
1369 #undef __FUNCT__
1370 #define __FUNCT__ "PetscOptionsGetEList"
1371 /*@C
1372      PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
1373 
1374    Not Collective
1375 
1376    Input Parameters:
1377 +  pre - the string to prepend to the name or PETSC_NULL
1378 .  opt - option name
1379 .  list - the possible choices
1380 .  ntext - number of choices
1381 
1382    Output Parameter:
1383 +  value - the index of the value to return (defaults to zero if the option name is given but choice is listed)
1384 -  set - PETSC_TRUE if found, else PETSC_FALSE
1385 
1386    Level: intermediate
1387 
1388    See PetscOptionsList() for when the choices are given in a PetscFunctionList()
1389 
1390    Concepts: options database^list
1391 
1392 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1393            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1394           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1395           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1396           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1397           PetscOptionsList(), PetscOptionsEList()
1398 @*/
1399 PetscErrorCode  PetscOptionsGetEList(const char pre[],const char opt[],const char *const*list,PetscInt ntext,PetscInt *value,PetscBool  *set)
1400 {
1401   PetscErrorCode ierr;
1402   size_t         alen,len = 0;
1403   char           *svalue;
1404   PetscBool      aset,flg = PETSC_FALSE;
1405   PetscInt       i;
1406 
1407   PetscFunctionBegin;
1408   for (i=0; i<ntext; i++) {
1409     ierr = PetscStrlen(list[i],&alen);CHKERRQ(ierr);
1410     if (alen > len) len = alen;
1411   }
1412   len += 5; /* a little extra space for user mistypes */
1413   ierr = PetscMalloc(len*sizeof(char),&svalue);CHKERRQ(ierr);
1414   ierr = PetscOptionsGetString(pre,opt,svalue,len,&aset);CHKERRQ(ierr);
1415   if (aset) {
1416     if (set) *set = PETSC_TRUE;
1417     for (i=0; i<ntext; i++) {
1418       ierr = PetscStrcasecmp(svalue,list[i],&flg);CHKERRQ(ierr);
1419       if (flg || !svalue[0]) {
1420         flg    = PETSC_TRUE;
1421         *value = i;
1422         break;
1423       }
1424     }
1425     if (!flg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre?pre:"",opt+1);
1426   } else if (set) {
1427     *set = PETSC_FALSE;
1428   }
1429   ierr = PetscFree(svalue);CHKERRQ(ierr);
1430   PetscFunctionReturn(0);
1431 }
1432 
1433 #undef __FUNCT__
1434 #define __FUNCT__ "PetscOptionsGetEnum"
1435 /*@C
1436    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
1437 
1438    Not Collective
1439 
1440    Input Parameters:
1441 +  pre - option prefix or PETSC_NULL
1442 .  opt - option name
1443 .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
1444 -  defaultv - the default (current) value
1445 
1446    Output Parameter:
1447 +  value - the  value to return
1448 -  set - PETSC_TRUE if found, else PETSC_FALSE
1449 
1450    Level: beginner
1451 
1452    Concepts: options database
1453 
1454    Notes: Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1455 
1456           list is usually something like PCASMTypes or some other predefined list of enum names
1457 
1458 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1459           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1460           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1461           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1462           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1463           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1464           PetscOptionsList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
1465 @*/
1466 PetscErrorCode  PetscOptionsGetEnum(const char pre[],const char opt[],const char *const*list,PetscEnum *value,PetscBool  *set)
1467 {
1468   PetscErrorCode ierr;
1469   PetscInt       ntext = 0,tval;
1470   PetscBool      fset;
1471 
1472   PetscFunctionBegin;
1473   while (list[ntext++]) {
1474     if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
1475   }
1476   if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1477   ntext -= 3;
1478   ierr = PetscOptionsGetEList(pre,opt,list,ntext,&tval,&fset);CHKERRQ(ierr);
1479   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
1480   if (fset) *value = (PetscEnum)tval;
1481   if (set) *set = fset;
1482   PetscFunctionReturn(0);
1483 }
1484 
1485 #undef __FUNCT__
1486 #define __FUNCT__ "PetscOptionsGetBool"
1487 /*@C
1488    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
1489             option in the database.
1490 
1491    Not Collective
1492 
1493    Input Parameters:
1494 +  pre - the string to prepend to the name or PETSC_NULL
1495 -  name - the option one is seeking
1496 
1497    Output Parameter:
1498 +  ivalue - the logical value to return
1499 -  set - PETSC_TRUE  if found, else PETSC_FALSE
1500 
1501    Level: beginner
1502 
1503    Notes:
1504        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1505        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
1506 
1507        If the user does not supply the option (as either true or false) ivalue is NOT changed. Thus
1508      you NEED TO ALWAYS initialize the ivalue.
1509 
1510    Concepts: options database^has logical
1511 
1512 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1513           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
1514           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1515           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1516           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1517           PetscOptionsList(), PetscOptionsEList()
1518 @*/
1519 PetscErrorCode  PetscOptionsGetBool(const char pre[],const char name[],PetscBool  *ivalue,PetscBool  *set)
1520 {
1521   char           *value;
1522   PetscBool      flag;
1523   PetscErrorCode ierr;
1524 
1525   PetscFunctionBegin;
1526   PetscValidCharPointer(name,2);
1527   PetscValidIntPointer(ivalue,3);
1528   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1529   if (flag) {
1530     if (set) *set = PETSC_TRUE;
1531     if (!value) {
1532       *ivalue = PETSC_TRUE;
1533     } else {
1534       ierr = PetscOptionsStringToBool(value, ivalue);CHKERRQ(ierr);
1535     }
1536   } else {
1537     if (set) *set = PETSC_FALSE;
1538   }
1539   PetscFunctionReturn(0);
1540 }
1541 
1542 #undef __FUNCT__
1543 #define __FUNCT__ "PetscOptionsGetBoolArray"
1544 /*@C
1545    PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
1546    option in the database.  The values must be separated with commas with
1547    no intervening spaces.
1548 
1549    Not Collective
1550 
1551    Input Parameters:
1552 +  pre - string to prepend to each name or PETSC_NULL
1553 .  name - the option one is seeking
1554 -  nmax - maximum number of values to retrieve
1555 
1556    Output Parameter:
1557 +  dvalue - the integer values to return
1558 .  nmax - actual number of values retreived
1559 -  set - PETSC_TRUE if found, else PETSC_FALSE
1560 
1561    Level: beginner
1562 
1563    Concepts: options database^array of ints
1564 
1565    Notes:
1566        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1567        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
1568 
1569 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1570            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1571           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1572           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1573           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1574           PetscOptionsList(), PetscOptionsEList()
1575 @*/
1576 PetscErrorCode  PetscOptionsGetBoolArray(const char pre[],const char name[],PetscBool  dvalue[],PetscInt *nmax,PetscBool  *set)
1577 {
1578   char           *value;
1579   PetscErrorCode ierr;
1580   PetscInt       n = 0;
1581   PetscBool      flag;
1582   PetscToken     token;
1583 
1584   PetscFunctionBegin;
1585   PetscValidCharPointer(name,2);
1586   PetscValidIntPointer(dvalue,3);
1587   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1588   if (!flag)  {if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
1589   if (!value) {if (set) *set = PETSC_TRUE; *nmax = 0; PetscFunctionReturn(0);}
1590 
1591   if (set) *set = PETSC_TRUE;
1592 
1593   ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
1594   ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1595   while (n < *nmax) {
1596     if (!value) break;
1597     ierr = PetscOptionsStringToBool(value,dvalue);CHKERRQ(ierr);
1598     ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1599     dvalue++;
1600     n++;
1601   }
1602   ierr  = PetscTokenDestroy(&token);CHKERRQ(ierr);
1603   *nmax = n;
1604   PetscFunctionReturn(0);
1605 }
1606 
1607 #undef __FUNCT__
1608 #define __FUNCT__ "PetscOptionsGetReal"
1609 /*@C
1610    PetscOptionsGetReal - Gets the double precision value for a particular
1611    option in the database.
1612 
1613    Not Collective
1614 
1615    Input Parameters:
1616 +  pre - string to prepend to each name or PETSC_NULL
1617 -  name - the option one is seeking
1618 
1619    Output Parameter:
1620 +  dvalue - the double value to return
1621 -  set - PETSC_TRUE if found, PETSC_FALSE if not found
1622 
1623    Note: if the option is given but no value is provided then set is given the value PETSC_FALSE
1624 
1625    Level: beginner
1626 
1627    Concepts: options database^has double
1628 
1629 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1630            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
1631           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1632           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1633           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1634           PetscOptionsList(), PetscOptionsEList()
1635 @*/
1636 PetscErrorCode  PetscOptionsGetReal(const char pre[],const char name[],PetscReal *dvalue,PetscBool  *set)
1637 {
1638   char           *value;
1639   PetscErrorCode ierr;
1640   PetscBool      flag;
1641 
1642   PetscFunctionBegin;
1643   PetscValidCharPointer(name,2);
1644   PetscValidRealPointer(dvalue,3);
1645   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1646   if (flag) {
1647     if (!value) {if (set) *set = PETSC_FALSE;}
1648     else        {if (set) *set = PETSC_TRUE; ierr = PetscOptionsStringToReal(value,dvalue);CHKERRQ(ierr);}
1649   } else {
1650     if (set) *set = PETSC_FALSE;
1651   }
1652   PetscFunctionReturn(0);
1653 }
1654 
1655 #undef __FUNCT__
1656 #define __FUNCT__ "PetscOptionsGetScalar"
1657 /*@C
1658    PetscOptionsGetScalar - Gets the scalar value for a particular
1659    option in the database.
1660 
1661    Not Collective
1662 
1663    Input Parameters:
1664 +  pre - string to prepend to each name or PETSC_NULL
1665 -  name - the option one is seeking
1666 
1667    Output Parameter:
1668 +  dvalue - the double value to return
1669 -  set - PETSC_TRUE if found, else PETSC_FALSE
1670 
1671    Level: beginner
1672 
1673    Usage:
1674    A complex number 2+3i can be specified as 2,3 at the command line.
1675    or a number 2.0e-10 - 3.3e-20 i  can be specified as 2.0e-10,-3.3e-20
1676 
1677    Note: if the option is given but no value is provided then set is given the value PETSC_FALSE
1678 
1679    Concepts: options database^has scalar
1680 
1681 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1682            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1683           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1684           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1685           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1686           PetscOptionsList(), PetscOptionsEList()
1687 @*/
1688 PetscErrorCode  PetscOptionsGetScalar(const char pre[],const char name[],PetscScalar *dvalue,PetscBool  *set)
1689 {
1690   char           *value;
1691   PetscBool      flag;
1692   PetscErrorCode ierr;
1693 
1694   PetscFunctionBegin;
1695   PetscValidCharPointer(name,2);
1696   PetscValidScalarPointer(dvalue,3);
1697   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1698   if (flag) {
1699     if (!value) {
1700       if (set) *set = PETSC_FALSE;
1701     } else {
1702 #if !defined(PETSC_USE_COMPLEX)
1703       ierr = PetscOptionsStringToReal(value,dvalue);CHKERRQ(ierr);
1704 #else
1705       PetscReal  re=0.0,im=0.0;
1706       PetscToken token;
1707       char       *tvalue = 0;
1708 
1709       ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
1710       ierr = PetscTokenFind(token,&tvalue);CHKERRQ(ierr);
1711       if (!tvalue) { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"unknown string specified\n"); }
1712       ierr    = PetscOptionsStringToReal(tvalue,&re);CHKERRQ(ierr);
1713       ierr    = PetscTokenFind(token,&tvalue);CHKERRQ(ierr);
1714       if (!tvalue) { /* Unknown separator used. using only real value */
1715         *dvalue = re;
1716       } else {
1717         ierr    = PetscOptionsStringToReal(tvalue,&im);CHKERRQ(ierr);
1718         *dvalue = re + PETSC_i*im;
1719       }
1720       ierr    = PetscTokenDestroy(&token);CHKERRQ(ierr);
1721 #endif
1722       if (set) *set    = PETSC_TRUE;
1723     }
1724   } else { /* flag */
1725     if (set) *set = PETSC_FALSE;
1726   }
1727   PetscFunctionReturn(0);
1728 }
1729 
1730 #undef __FUNCT__
1731 #define __FUNCT__ "PetscOptionsGetRealArray"
1732 /*@C
1733    PetscOptionsGetRealArray - Gets an array of double precision values for a
1734    particular option in the database.  The values must be separated with
1735    commas with no intervening spaces.
1736 
1737    Not Collective
1738 
1739    Input Parameters:
1740 +  pre - string to prepend to each name or PETSC_NULL
1741 .  name - the option one is seeking
1742 -  nmax - maximum number of values to retrieve
1743 
1744    Output Parameters:
1745 +  dvalue - the double value to return
1746 .  nmax - actual number of values retreived
1747 -  set - PETSC_TRUE if found, else PETSC_FALSE
1748 
1749    Level: beginner
1750 
1751    Concepts: options database^array of doubles
1752 
1753 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1754            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
1755           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1756           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1757           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1758           PetscOptionsList(), PetscOptionsEList()
1759 @*/
1760 PetscErrorCode  PetscOptionsGetRealArray(const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool  *set)
1761 {
1762   char           *value;
1763   PetscErrorCode ierr;
1764   PetscInt       n = 0;
1765   PetscBool      flag;
1766   PetscToken     token;
1767 
1768   PetscFunctionBegin;
1769   PetscValidCharPointer(name,2);
1770   PetscValidRealPointer(dvalue,3);
1771   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1772   if (!flag)  {if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
1773   if (!value) {if (set) *set = PETSC_TRUE; *nmax = 0; PetscFunctionReturn(0);}
1774 
1775   if (set) *set = PETSC_TRUE;
1776 
1777   ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
1778   ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1779   while (n < *nmax) {
1780     if (!value) break;
1781     ierr = PetscOptionsStringToReal(value,dvalue++);CHKERRQ(ierr);
1782     ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1783     n++;
1784   }
1785   ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
1786   *nmax = n;
1787   PetscFunctionReturn(0);
1788 }
1789 
1790 #undef __FUNCT__
1791 #define __FUNCT__ "PetscOptionsGetIntArray"
1792 /*@C
1793    PetscOptionsGetIntArray - Gets an array of integer values for a particular
1794    option in the database.
1795 
1796    Not Collective
1797 
1798    Input Parameters:
1799 +  pre - string to prepend to each name or PETSC_NULL
1800 .  name - the option one is seeking
1801 -  nmax - maximum number of values to retrieve
1802 
1803    Output Parameter:
1804 +  dvalue - the integer values to return
1805 .  nmax - actual number of values retreived
1806 -  set - PETSC_TRUE if found, else PETSC_FALSE
1807 
1808    Level: beginner
1809 
1810    Notes:
1811    The array can be passed as
1812    a comma seperated list:                                 0,1,2,3,4,5,6,7
1813    a range (start-end+1):                                  0-8
1814    a range with given increment (start-end+1:inc):         0-7:2
1815    a combination of values and ranges seperated by commas: 0,1-8,8-15:2
1816 
1817    There must be no intervening spaces between the values.
1818 
1819    Concepts: options database^array of ints
1820 
1821 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1822            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1823           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1824           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1825           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1826           PetscOptionsList(), PetscOptionsEList()
1827 @*/
1828 PetscErrorCode  PetscOptionsGetIntArray(const char pre[],const char name[],PetscInt dvalue[],PetscInt *nmax,PetscBool  *set)
1829 {
1830   char           *value;
1831   PetscErrorCode ierr;
1832   PetscInt       n = 0,i,j,start,end,inc,nvalues;
1833   size_t         len;
1834   PetscBool      flag,foundrange;
1835   PetscToken     token;
1836 
1837   PetscFunctionBegin;
1838   PetscValidCharPointer(name,2);
1839   PetscValidIntPointer(dvalue,3);
1840   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1841   if (!flag)  {if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
1842   if (!value) {if (set) *set = PETSC_TRUE; *nmax = 0; PetscFunctionReturn(0);}
1843 
1844   if (set) *set = PETSC_TRUE;
1845 
1846   ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
1847   ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
1848   while (n < *nmax) {
1849     if (!value) break;
1850 
1851     /* look for form  d-D where d and D are integers */
1852     foundrange = PETSC_FALSE;
1853     ierr      = PetscStrlen(value,&len);CHKERRQ(ierr);
1854     if (value[0] == '-') i=2;
1855     else i=1;
1856     for (;i<(int)len; i++) {
1857       if (value[i] == '-') {
1858         if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
1859         value[i] = 0;
1860         ierr     = PetscOptionsStringToInt(value,&start);CHKERRQ(ierr);
1861         inc = 1;
1862         j = i+1;
1863         for (;j<(int)len; j++) {
1864           if (value[j] == ':') {
1865             value[j] = 0;
1866             ierr = PetscOptionsStringToInt(value+j+1,&inc);CHKERRQ(ierr);
1867             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);
1868             break;
1869           }
1870         }
1871         ierr     = PetscOptionsStringToInt(value+i+1,&end);CHKERRQ(ierr);
1872         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);
1873         nvalues = (end-start)/inc + (end-start)%inc;
1874         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);
1875         for (;start<end; start+=inc) {
1876           *dvalue = start; dvalue++;n++;
1877         }
1878         foundrange = PETSC_TRUE;
1879         break;
1880       }
1881     }
1882     if (!foundrange) {
1883       ierr      = PetscOptionsStringToInt(value,dvalue);CHKERRQ(ierr);
1884       dvalue++;
1885       n++;
1886     }
1887     ierr      = PetscTokenFind(token,&value);CHKERRQ(ierr);
1888   }
1889   ierr      = PetscTokenDestroy(&token);CHKERRQ(ierr);
1890   *nmax = n;
1891   PetscFunctionReturn(0);
1892 }
1893 
1894 #undef __FUNCT__
1895 #define __FUNCT__ "PetscOptionsGetString"
1896 /*@C
1897    PetscOptionsGetString - Gets the string value for a particular option in
1898    the database.
1899 
1900    Not Collective
1901 
1902    Input Parameters:
1903 +  pre - string to prepend to name or PETSC_NULL
1904 .  name - the option one is seeking
1905 -  len - maximum length of the string including null termination
1906 
1907    Output Parameters:
1908 +  string - location to copy string
1909 -  set - PETSC_TRUE if found, else PETSC_FALSE
1910 
1911    Level: beginner
1912 
1913    Fortran Note:
1914    The Fortran interface is slightly different from the C/C++
1915    interface (len is not used).  Sample usage in Fortran follows
1916 .vb
1917       character *20 string
1918       integer   flg, ierr
1919       call PetscOptionsGetString(PETSC_NULL_CHARACTER,'-s',string,flg,ierr)
1920 .ve
1921 
1922    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
1923 
1924    Concepts: options database^string
1925 
1926     Note:
1927       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).
1928 
1929 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1930            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1931           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1932           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1933           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1934           PetscOptionsList(), PetscOptionsEList()
1935 @*/
1936 PetscErrorCode  PetscOptionsGetString(const char pre[],const char name[],char string[],size_t len,PetscBool  *set)
1937 {
1938   char           *value;
1939   PetscErrorCode ierr;
1940   PetscBool      flag;
1941 
1942   PetscFunctionBegin;
1943   PetscValidCharPointer(name,2);
1944   PetscValidCharPointer(string,3);
1945   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
1946   if (!flag) {
1947     if (set) *set = PETSC_FALSE;
1948   } else {
1949     if (set) *set = PETSC_TRUE;
1950     if (value) {
1951       ierr = PetscStrncpy(string,value,len);CHKERRQ(ierr);
1952       string[len-1] = 0;        /* Ensure that the string is NULL terminated */
1953     } else {
1954       ierr = PetscMemzero(string,len);CHKERRQ(ierr);
1955     }
1956   }
1957   PetscFunctionReturn(0);
1958 }
1959 
1960 #undef __FUNCT__
1961 #define __FUNCT__ "PetscOptionsGetStringMatlab"
1962 char* PetscOptionsGetStringMatlab(const char pre[],const char name[])
1963 {
1964   char           *value;
1965   PetscErrorCode ierr;
1966   PetscBool      flag;
1967 
1968   PetscFunctionBegin;
1969   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);if (ierr) PetscFunctionReturn(0);
1970   if (flag) PetscFunctionReturn(value);
1971   else PetscFunctionReturn(0);
1972 }
1973 
1974 
1975 #undef __FUNCT__
1976 #define __FUNCT__ "PetscOptionsGetStringArray"
1977 /*@C
1978    PetscOptionsGetStringArray - Gets an array of string values for a particular
1979    option in the database. The values must be separated with commas with
1980    no intervening spaces.
1981 
1982    Not Collective
1983 
1984    Input Parameters:
1985 +  pre - string to prepend to name or PETSC_NULL
1986 .  name - the option one is seeking
1987 -  nmax - maximum number of strings
1988 
1989    Output Parameter:
1990 +  strings - location to copy strings
1991 -  set - PETSC_TRUE if found, else PETSC_FALSE
1992 
1993    Level: beginner
1994 
1995    Notes:
1996    The user should pass in an array of pointers to char, to hold all the
1997    strings returned by this function.
1998 
1999    The user is responsible for deallocating the strings that are
2000    returned. The Fortran interface for this routine is not supported.
2001 
2002    Contributed by Matthew Knepley.
2003 
2004    Concepts: options database^array of strings
2005 
2006 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2007            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2008           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2009           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2010           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2011           PetscOptionsList(), PetscOptionsEList()
2012 @*/
2013 PetscErrorCode  PetscOptionsGetStringArray(const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool  *set)
2014 {
2015   char           *value;
2016   PetscErrorCode ierr;
2017   PetscInt       n;
2018   PetscBool      flag;
2019   PetscToken     token;
2020 
2021   PetscFunctionBegin;
2022   PetscValidCharPointer(name,2);
2023   PetscValidPointer(strings,3);
2024   ierr = PetscOptionsFindPair_Private(pre,name,&value,&flag);CHKERRQ(ierr);
2025   if (!flag)  {*nmax = 0; if (set) *set = PETSC_FALSE; PetscFunctionReturn(0);}
2026   if (!value) {*nmax = 0; if (set) *set = PETSC_FALSE;PetscFunctionReturn(0);}
2027   if (!*nmax) {if (set) *set = PETSC_FALSE;PetscFunctionReturn(0);}
2028   if (set) *set = PETSC_TRUE;
2029 
2030   ierr = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
2031   ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
2032   n = 0;
2033   while (n < *nmax) {
2034     if (!value) break;
2035     ierr = PetscStrallocpy(value,&strings[n]);CHKERRQ(ierr);
2036     ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
2037     n++;
2038   }
2039   ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
2040   *nmax = n;
2041   PetscFunctionReturn(0);
2042 }
2043 
2044 #undef __FUNCT__
2045 #define __FUNCT__ "PetscOptionsUsed"
2046 /*@C
2047    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
2048 
2049    Not Collective
2050 
2051    Input Parameter:
2052 .    option - string name of option
2053 
2054    Output Parameter:
2055 .   used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database
2056 
2057    Level: advanced
2058 
2059 .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
2060 @*/
2061 PetscErrorCode  PetscOptionsUsed(const char *option,PetscBool *used)
2062 {
2063   PetscInt       i;
2064   PetscErrorCode ierr;
2065 
2066   PetscFunctionBegin;
2067   *used = PETSC_FALSE;
2068   for (i=0; i<options->N; i++) {
2069     ierr = PetscStrcmp(options->names[i],option,used);CHKERRQ(ierr);
2070     if (*used) {
2071       *used = options->used[i];
2072       break;
2073     }
2074   }
2075   PetscFunctionReturn(0);
2076 }
2077 
2078 #undef __FUNCT__
2079 #define __FUNCT__ "PetscOptionsAllUsed"
2080 /*@C
2081    PetscOptionsAllUsed - Returns a count of the number of options in the
2082    database that have never been selected.
2083 
2084    Not Collective
2085 
2086    Output Parameter:
2087 .   N - count of options not used
2088 
2089    Level: advanced
2090 
2091 .seealso: PetscOptionsView()
2092 @*/
2093 PetscErrorCode  PetscOptionsAllUsed(PetscInt *N)
2094 {
2095   PetscInt i,n = 0;
2096 
2097   PetscFunctionBegin;
2098   for (i=0; i<options->N; i++) {
2099     if (!options->used[i]) { n++; }
2100   }
2101   *N = n;
2102   PetscFunctionReturn(0);
2103 }
2104 
2105 #undef __FUNCT__
2106 #define __FUNCT__ "PetscOptionsLeft"
2107 /*@
2108     PetscOptionsLeft - Prints to screen any options that were set and never used.
2109 
2110   Not collective
2111 
2112    Options Database Key:
2113 .  -options_left - Activates OptionsAllUsed() within PetscFinalize()
2114 
2115   Level: advanced
2116 
2117 .seealso: PetscOptionsAllUsed()
2118 @*/
2119 PetscErrorCode  PetscOptionsLeft(void)
2120 {
2121   PetscErrorCode ierr;
2122   PetscInt       i;
2123 
2124   PetscFunctionBegin;
2125   for (i=0; i<options->N; i++) {
2126     if (!options->used[i]) {
2127       if (options->values[i]) {
2128         ierr = PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",options->names[i],options->values[i]);CHKERRQ(ierr);
2129       } else {
2130         ierr = PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s no value \n",options->names[i]);CHKERRQ(ierr);
2131       }
2132     }
2133   }
2134   PetscFunctionReturn(0);
2135 }
2136 
2137 
2138 #undef __FUNCT__
2139 #define __FUNCT__ "PetscOptionsCreate"
2140 /*
2141     PetscOptionsCreate - Creates the empty options database.
2142 
2143 */
2144 PetscErrorCode  PetscOptionsCreate(void)
2145 {
2146   PetscErrorCode ierr;
2147 
2148   PetscFunctionBegin;
2149   options = (PetscOptionsTable*)malloc(sizeof(PetscOptionsTable));
2150   ierr    = PetscMemzero(options,sizeof(PetscOptionsTable));CHKERRQ(ierr);
2151   options->namegiven            = PETSC_FALSE;
2152   options->N                    = 0;
2153   options->Naliases             = 0;
2154   options->numbermonitors       = 0;
2155 
2156   PetscOptionsObject.prefix = PETSC_NULL;
2157   PetscOptionsObject.title  = PETSC_NULL;
2158   PetscFunctionReturn(0);
2159 }
2160 
2161 #undef __FUNCT__
2162 #define __FUNCT__ "PetscOptionsSetFromOptions"
2163 /*@
2164    PetscOptionsSetFromOptions - Sets various SNES and KSP parameters from user options.
2165 
2166    Collective on PETSC_COMM_WORLD
2167 
2168    Options Database Keys:
2169 +  -options_monitor <optional filename> - prints the names and values of all runtime options as they are set. The monitor functionality is not
2170                 available for options set through a file, environment variable, or on
2171                 the command line. Only options set after PetscInitialize completes will
2172                 be monitored.
2173 .  -options_monitor_cancel - cancel all options database monitors
2174 
2175    Notes:
2176    To see all options, run your program with the -help option or consult
2177    the <A href="../../docs/manual.pdf">users manual</A>..
2178 
2179    Level: intermediate
2180 
2181 .keywords: set, options, database
2182 @*/
2183 PetscErrorCode  PetscOptionsSetFromOptions(void)
2184 {
2185   PetscBool           flgc,flgm;
2186   PetscErrorCode      ierr;
2187   char                monfilename[PETSC_MAX_PATH_LEN];
2188   PetscViewer         monviewer;
2189 
2190   PetscFunctionBegin;
2191   ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","Options database options","PetscOptions");CHKERRQ(ierr);
2192     ierr = PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);CHKERRQ(ierr);
2193     ierr = PetscOptionsBool("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",PETSC_FALSE,&flgc,PETSC_NULL);CHKERRQ(ierr);
2194   ierr = PetscOptionsEnd();CHKERRQ(ierr);
2195   if (flgm) {
2196     ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);CHKERRQ(ierr);
2197     ierr = PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
2198   }
2199   if (flgc) { ierr = PetscOptionsMonitorCancel();CHKERRQ(ierr); }
2200   PetscFunctionReturn(0);
2201 }
2202 
2203 
2204 #undef __FUNCT__
2205 #define __FUNCT__ "PetscOptionsMonitorDefault"
2206 /*@C
2207    PetscOptionsMonitorDefault - Print all options set value events.
2208 
2209    Logically Collective on PETSC_COMM_WORLD
2210 
2211    Input Parameters:
2212 +  name  - option name string
2213 .  value - option value string
2214 -  dummy - unused monitor context
2215 
2216    Level: intermediate
2217 
2218 .keywords: PetscOptions, default, monitor
2219 
2220 .seealso: PetscOptionsMonitorSet()
2221 @*/
2222 PetscErrorCode  PetscOptionsMonitorDefault(const char name[], const char value[], void *dummy)
2223 {
2224   PetscErrorCode ierr;
2225   PetscViewer    viewer = (PetscViewer) dummy;
2226 
2227   PetscFunctionBegin;
2228   if (!viewer) {
2229     ierr = PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);CHKERRQ(ierr);
2230   }
2231   ierr = PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);CHKERRQ(ierr);
2232   PetscFunctionReturn(0);
2233 }
2234 
2235 #undef __FUNCT__
2236 #define __FUNCT__ "PetscOptionsMonitorSet"
2237 /*@C
2238    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
2239    modified the PETSc options database.
2240 
2241    Not collective
2242 
2243    Input Parameters:
2244 +  monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring
2245 .  mctx    - [optional] context for private data for the
2246              monitor routine (use PETSC_NULL if no context is desired)
2247 -  monitordestroy - [optional] routine that frees monitor context
2248           (may be PETSC_NULL)
2249 
2250    Calling Sequence of monitor:
2251 $     monitor (const char name[], const char value[], void *mctx)
2252 
2253 +  name - option name string
2254 .  value - option value string
2255 -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()
2256 
2257    Options Database Keys:
2258 +    -options_monitor    - sets PetscOptionsMonitorDefault()
2259 -    -options_monitor_cancel - cancels all monitors that have
2260                           been hardwired into a code by
2261                           calls to PetscOptionsMonitorSet(), but
2262                           does not cancel those set via
2263                           the options database.
2264 
2265    Notes:
2266    The default is to do nothing.  To print the name and value of options
2267    being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
2268    with a null monitoring context.
2269 
2270    Several different monitoring routines may be set by calling
2271    PetscOptionsMonitorSet() multiple times; all will be called in the
2272    order in which they were set.
2273 
2274    Level: beginner
2275 
2276 .keywords: PetscOptions, set, monitor
2277 
2278 .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
2279 @*/
2280 PetscErrorCode  PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
2281 {
2282   PetscFunctionBegin;
2283   if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
2284   options->monitor[options->numbermonitors]           = monitor;
2285   options->monitordestroy[options->numbermonitors]    = monitordestroy;
2286   options->monitorcontext[options->numbermonitors++]  = (void*)mctx;
2287   PetscFunctionReturn(0);
2288 }
2289 
2290 #undef __FUNCT__
2291 #define __FUNCT__ "PetscOptionsMonitorCancel"
2292 /*@
2293    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.
2294 
2295    Not collective
2296 
2297    Options Database Key:
2298 .  -options_monitor_cancel - Cancels all monitors that have
2299     been hardwired into a code by calls to PetscOptionsMonitorSet(),
2300     but does not cancel those set via the options database.
2301 
2302    Level: intermediate
2303 
2304 .keywords: PetscOptions, set, monitor
2305 
2306 .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
2307 @*/
2308 PetscErrorCode  PetscOptionsMonitorCancel(void)
2309 {
2310   PetscErrorCode ierr;
2311   PetscInt       i;
2312 
2313   PetscFunctionBegin;
2314   for (i=0; i<options->numbermonitors; i++) {
2315     if (options->monitordestroy[i]) {
2316       ierr = (*options->monitordestroy[i])(&options->monitorcontext[i]);CHKERRQ(ierr);
2317     }
2318   }
2319   options->numbermonitors = 0;
2320   PetscFunctionReturn(0);
2321 }
2322