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