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