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