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