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