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