xref: /petsc/src/sys/objects/aoptions.c (revision c4762a1b19cd2af06abeed90e8f9d34fb975dd94)
1 
2 
3 /*
4    Implements the higher-level options database querying methods. These are self-documenting and can attach at runtime to
5    GUI code to display the options and get values from the users.
6 
7 */
8 
9 #include <petsc/private/petscimpl.h>        /*I  "petscsys.h"   I*/
10 #include <petscviewer.h>
11 
12 #define ManSection(str) ((str) ? (str) : "None")
13 
14 /*
15     Keep a linked list of options that have been posted and we are waiting for
16    user selection. See the manual page for PetscOptionsBegin()
17 
18     Eventually we'll attach this beast to a MPI_Comm
19 */
20 
21 
22 /*
23     Handles setting up the data structure in a call to PetscOptionsBegin()
24 */
25 PetscErrorCode PetscOptionsBegin_Private(PetscOptionItems *PetscOptionsObject,MPI_Comm comm,const char prefix[],const char title[],const char mansec[])
26 {
27   PetscErrorCode ierr;
28 
29   PetscFunctionBegin;
30   if (!PetscOptionsObject->alreadyprinted) {
31     if (!PetscOptionsHelpPrintedSingleton) {
32       ierr = PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton);CHKERRQ(ierr);
33     }
34     ierr = PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton,prefix,title,&PetscOptionsObject->alreadyprinted);CHKERRQ(ierr);
35   }
36   PetscOptionsObject->next          = NULL;
37   PetscOptionsObject->comm          = comm;
38   PetscOptionsObject->changedmethod = PETSC_FALSE;
39 
40   ierr = PetscStrallocpy(prefix,&PetscOptionsObject->prefix);CHKERRQ(ierr);
41   ierr = PetscStrallocpy(title,&PetscOptionsObject->title);CHKERRQ(ierr);
42 
43   ierr = PetscOptionsHasHelp(PetscOptionsObject->options,&PetscOptionsObject->printhelp);CHKERRQ(ierr);
44   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1) {
45     if (!PetscOptionsObject->alreadyprinted) {
46       ierr = (*PetscHelpPrintf)(comm,"%s -------------------------------------------------\n",title);CHKERRQ(ierr);
47     }
48   }
49   PetscFunctionReturn(0);
50 }
51 
52 /*
53     Handles setting up the data structure in a call to PetscObjectOptionsBegin()
54 */
55 PetscErrorCode PetscObjectOptionsBegin_Private(PetscOptionItems *PetscOptionsObject,PetscObject obj)
56 {
57   PetscErrorCode ierr;
58   char           title[256];
59   PetscBool      flg;
60 
61   PetscFunctionBegin;
62   PetscValidHeader(obj,1);
63   PetscOptionsObject->object         = obj;
64   PetscOptionsObject->alreadyprinted = obj->optionsprinted;
65 
66   ierr = PetscStrcmp(obj->description,obj->class_name,&flg);CHKERRQ(ierr);
67   if (flg) {
68     ierr = PetscSNPrintf(title,sizeof(title),"%s options",obj->class_name);CHKERRQ(ierr);
69   } else {
70     ierr = PetscSNPrintf(title,sizeof(title),"%s (%s) options",obj->description,obj->class_name);CHKERRQ(ierr);
71   }
72   ierr = PetscOptionsBegin_Private(PetscOptionsObject,obj->comm,obj->prefix,title,obj->mansec);CHKERRQ(ierr);
73   PetscFunctionReturn(0);
74 }
75 
76 /*
77      Handles adding another option to the list of options within this particular PetscOptionsBegin() PetscOptionsEnd()
78 */
79 static int PetscOptionItemCreate_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscOptionType t,PetscOptionItem *amsopt)
80 {
81   int             ierr;
82   PetscOptionItem next;
83   PetscBool       valid;
84 
85   PetscFunctionBegin;
86   ierr = PetscOptionsValidKey(opt,&valid);CHKERRQ(ierr);
87   if (!valid) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_ARG_INCOMP,"The option '%s' is not a valid key",opt);
88 
89   ierr            = PetscNew(amsopt);CHKERRQ(ierr);
90   (*amsopt)->next = NULL;
91   (*amsopt)->set  = PETSC_FALSE;
92   (*amsopt)->type = t;
93   (*amsopt)->data = NULL;
94 
95   ierr = PetscStrallocpy(text,&(*amsopt)->text);CHKERRQ(ierr);
96   ierr = PetscStrallocpy(opt,&(*amsopt)->option);CHKERRQ(ierr);
97   ierr = PetscStrallocpy(man,&(*amsopt)->man);CHKERRQ(ierr);
98 
99   if (!PetscOptionsObject->next) PetscOptionsObject->next = *amsopt;
100   else {
101     next = PetscOptionsObject->next;
102     while (next->next) next = next->next;
103     next->next = *amsopt;
104   }
105   PetscFunctionReturn(0);
106 }
107 
108 /*
109     PetscScanString -  Gets user input via stdin from process and broadcasts to all processes
110 
111     Collective
112 
113    Input Parameters:
114 +     commm - communicator for the broadcast, must be PETSC_COMM_WORLD
115 .     n - length of the string, must be the same on all processes
116 -     str - location to store input
117 
118     Bugs:
119 .   Assumes process 0 of the given communicator has access to stdin
120 
121 */
122 static PetscErrorCode PetscScanString(MPI_Comm comm,size_t n,char str[])
123 {
124   size_t         i;
125   char           c;
126   PetscMPIInt    rank,nm;
127   PetscErrorCode ierr;
128 
129   PetscFunctionBegin;
130   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
131   if (!rank) {
132     c = (char) getchar();
133     i = 0;
134     while (c != '\n' && i < n-1) {
135       str[i++] = c;
136       c = (char)getchar();
137     }
138     str[i] = 0;
139   }
140   ierr = PetscMPIIntCast(n,&nm);CHKERRQ(ierr);
141   ierr = MPI_Bcast(str,nm,MPI_CHAR,0,comm);CHKERRQ(ierr);
142   PetscFunctionReturn(0);
143 }
144 
145 /*
146     This is needed because certain strings may be freed by SAWs, hence we cannot use PetscStrallocpy()
147 */
148 static PetscErrorCode  PetscStrdup(const char s[],char *t[])
149 {
150   PetscErrorCode ierr;
151   size_t         len;
152   char           *tmp = NULL;
153 
154   PetscFunctionBegin;
155   if (s) {
156     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
157     tmp = (char*) malloc((len+1)*sizeof(char));
158     if (!tmp) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"No memory to duplicate string");
159     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
160   }
161   *t = tmp;
162   PetscFunctionReturn(0);
163 }
164 
165 
166 /*
167     PetscOptionsGetFromTextInput - Presents all the PETSc Options processed by the program so the user may change them at runtime
168 
169     Notes:
170     this isn't really practical, it is just to demonstrate the principle
171 
172     A carriage return indicates no change from the default; but this like -ksp_monitor <stdout>  the default is actually not stdout the default
173     is to do nothing so to get it to use stdout you need to type stdout. This is kind of bug?
174 
175     Bugs:
176 +    All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
177 .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
178 -    Only works for PetscInt == int, PetscReal == double etc
179 
180     Developer Notes:
181     Normally the GUI that presents the options the user and retrieves the values would be running in a different
182      address space and communicating with the PETSc program
183 
184 */
185 PetscErrorCode PetscOptionsGetFromTextInput(PetscOptionItems *PetscOptionsObject)
186 {
187   PetscErrorCode  ierr;
188   PetscOptionItem next = PetscOptionsObject->next;
189   char            str[512];
190   PetscBool       bid;
191   PetscReal       ir,*valr;
192   PetscInt        *vald;
193   size_t          i;
194 
195   PetscFunctionBegin;
196   ierr = (*PetscPrintf)(PETSC_COMM_WORLD,"%s -------------------------------------------------\n",PetscOptionsObject->title);CHKERRQ(ierr);
197   while (next) {
198     switch (next->type) {
199     case OPTION_HEAD:
200       break;
201     case OPTION_INT_ARRAY:
202       ierr = PetscPrintf(PETSC_COMM_WORLD,"-%s%s <",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",next->option+1);CHKERRQ(ierr);
203       vald = (PetscInt*) next->data;
204       for (i=0; i<next->arraylength; i++) {
205         ierr = PetscPrintf(PETSC_COMM_WORLD,"%d",vald[i]);CHKERRQ(ierr);
206         if (i < next->arraylength-1) {
207           ierr = PetscPrintf(PETSC_COMM_WORLD,",");CHKERRQ(ierr);
208         }
209       }
210       ierr = PetscPrintf(PETSC_COMM_WORLD,">: %s (%s) ",next->text,next->man);CHKERRQ(ierr);
211       ierr = PetscScanString(PETSC_COMM_WORLD,512,str);CHKERRQ(ierr);
212       if (str[0]) {
213         PetscToken token;
214         PetscInt   n=0,nmax = next->arraylength,*dvalue = (PetscInt*)next->data,start,end;
215         size_t     len;
216         char       *value;
217         PetscBool  foundrange;
218 
219         next->set = PETSC_TRUE;
220         value     = str;
221         ierr      = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
222         ierr      = PetscTokenFind(token,&value);CHKERRQ(ierr);
223         while (n < nmax) {
224           if (!value) break;
225 
226           /* look for form  d-D where d and D are integers */
227           foundrange = PETSC_FALSE;
228           ierr       = PetscStrlen(value,&len);CHKERRQ(ierr);
229           if (value[0] == '-') i=2;
230           else i=1;
231           for (;i<len; i++) {
232             if (value[i] == '-') {
233               if (i == len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
234               value[i] = 0;
235               ierr     = PetscOptionsStringToInt(value,&start);CHKERRQ(ierr);
236               ierr     = PetscOptionsStringToInt(value+i+1,&end);CHKERRQ(ierr);
237               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);
238               if (n + end - start - 1 >= nmax) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry, not enough space in left in array (%D) to contain entire range from %D to %D",n,nmax-n,start,end);
239               for (; start<end; start++) {
240                 *dvalue = start; dvalue++;n++;
241               }
242               foundrange = PETSC_TRUE;
243               break;
244             }
245           }
246           if (!foundrange) {
247             ierr = PetscOptionsStringToInt(value,dvalue);CHKERRQ(ierr);
248             dvalue++;
249             n++;
250           }
251           ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
252         }
253         ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
254       }
255       break;
256     case OPTION_REAL_ARRAY:
257       ierr = PetscPrintf(PETSC_COMM_WORLD,"-%s%s <",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",next->option+1);CHKERRQ(ierr);
258       valr = (PetscReal*) next->data;
259       for (i=0; i<next->arraylength; i++) {
260         ierr = PetscPrintf(PETSC_COMM_WORLD,"%g",valr[i]);CHKERRQ(ierr);
261         if (i < next->arraylength-1) {
262           ierr = PetscPrintf(PETSC_COMM_WORLD,",");CHKERRQ(ierr);
263         }
264       }
265       ierr = PetscPrintf(PETSC_COMM_WORLD,">: %s (%s) ",next->text,next->man);CHKERRQ(ierr);
266       ierr = PetscScanString(PETSC_COMM_WORLD,512,str);CHKERRQ(ierr);
267       if (str[0]) {
268         PetscToken token;
269         PetscInt   n = 0,nmax = next->arraylength;
270         PetscReal  *dvalue = (PetscReal*)next->data;
271         char       *value;
272 
273         next->set = PETSC_TRUE;
274         value     = str;
275         ierr      = PetscTokenCreate(value,',',&token);CHKERRQ(ierr);
276         ierr      = PetscTokenFind(token,&value);CHKERRQ(ierr);
277         while (n < nmax) {
278           if (!value) break;
279           ierr = PetscOptionsStringToReal(value,dvalue);CHKERRQ(ierr);
280           dvalue++;
281           n++;
282           ierr = PetscTokenFind(token,&value);CHKERRQ(ierr);
283         }
284         ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
285       }
286       break;
287     case OPTION_INT:
288       ierr = PetscPrintf(PETSC_COMM_WORLD,"-%s%s <%d>: %s (%s) ",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",next->option+1,*(int*)next->data,next->text,next->man);CHKERRQ(ierr);
289       ierr = PetscScanString(PETSC_COMM_WORLD,512,str);CHKERRQ(ierr);
290       if (str[0]) {
291 #if defined(PETSC_SIZEOF_LONG_LONG)
292         long long lid;
293         sscanf(str,"%lld",&lid);
294         if (lid > PETSC_MAX_INT || lid < PETSC_MIN_INT) SETERRQ3(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Argument: -%s%s %lld",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",next->option+1,lid);
295 #else
296         long  lid;
297         sscanf(str,"%ld",&lid);
298         if (lid > PETSC_MAX_INT || lid < PETSC_MIN_INT) SETERRQ3(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Argument: -%s%s %ld",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",next->option+1,lid);
299 #endif
300 
301         next->set = PETSC_TRUE;
302         *((PetscInt*)next->data) = (PetscInt)lid;
303       }
304       break;
305     case OPTION_REAL:
306       ierr = PetscPrintf(PETSC_COMM_WORLD,"-%s%s <%g>: %s (%s) ",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",next->option+1,*(double*)next->data,next->text,next->man);CHKERRQ(ierr);
307       ierr = PetscScanString(PETSC_COMM_WORLD,512,str);CHKERRQ(ierr);
308       if (str[0]) {
309 #if defined(PETSC_USE_REAL_SINGLE)
310         sscanf(str,"%e",&ir);
311 #elif defined(PETSC_USE_REAL___FP16)
312         float irtemp;
313         sscanf(str,"%e",&irtemp);
314         ir = irtemp;
315 #elif defined(PETSC_USE_REAL_DOUBLE)
316         sscanf(str,"%le",&ir);
317 #elif defined(PETSC_USE_REAL___FLOAT128)
318         ir = strtoflt128(str,0);
319 #else
320         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unknown scalar type");
321 #endif
322         next->set                 = PETSC_TRUE;
323         *((PetscReal*)next->data) = ir;
324       }
325       break;
326     case OPTION_BOOL:
327       ierr = PetscPrintf(PETSC_COMM_WORLD,"-%s%s <%s>: %s (%s) ",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",next->option+1,*(PetscBool*)next->data ? "true": "false",next->text,next->man);CHKERRQ(ierr);
328       ierr = PetscScanString(PETSC_COMM_WORLD,512,str);CHKERRQ(ierr);
329       if (str[0]) {
330         ierr = PetscOptionsStringToBool(str,&bid);CHKERRQ(ierr);
331         next->set = PETSC_TRUE;
332         *((PetscBool*)next->data) = bid;
333       }
334       break;
335     case OPTION_STRING:
336       ierr = PetscPrintf(PETSC_COMM_WORLD,"-%s%s <%s>: %s (%s) ",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",next->option+1,(char*)next->data,next->text,next->man);CHKERRQ(ierr);
337       ierr = PetscScanString(PETSC_COMM_WORLD,512,str);CHKERRQ(ierr);
338       if (str[0]) {
339         next->set = PETSC_TRUE;
340         /* must use system malloc since SAWs may free this */
341         ierr = PetscStrdup(str,(char**)&next->data);CHKERRQ(ierr);
342       }
343       break;
344     case OPTION_FLIST:
345       ierr = PetscFunctionListPrintTypes(PETSC_COMM_WORLD,stdout,PetscOptionsObject->prefix,next->option,next->text,next->man,next->flist,(char*)next->data,(char*)next->data);CHKERRQ(ierr);
346       ierr = PetscScanString(PETSC_COMM_WORLD,512,str);CHKERRQ(ierr);
347       if (str[0]) {
348         PetscOptionsObject->changedmethod = PETSC_TRUE;
349         next->set = PETSC_TRUE;
350         /* must use system malloc since SAWs may free this */
351         ierr = PetscStrdup(str,(char**)&next->data);CHKERRQ(ierr);
352       }
353       break;
354     default:
355       break;
356     }
357     next = next->next;
358   }
359   PetscFunctionReturn(0);
360 }
361 
362 #if defined(PETSC_HAVE_SAWS)
363 #include <petscviewersaws.h>
364 
365 static int count = 0;
366 
367 PetscErrorCode PetscOptionsSAWsDestroy(void)
368 {
369   PetscFunctionBegin;
370   PetscFunctionReturn(0);
371 }
372 
373 static const char *OptionsHeader = "<head>\n"
374                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/jquery-1.9.1.js\"></script>\n"
375                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/SAWs.js\"></script>\n"
376                                    "<script type=\"text/javascript\" src=\"js/PETSc.js\"></script>\n"
377                                    "<script>\n"
378                                       "jQuery(document).ready(function() {\n"
379                                          "PETSc.getAndDisplayDirectory(null,\"#variablesInfo\")\n"
380                                       "})\n"
381                                   "</script>\n"
382                                   "</head>\n";
383 
384 /*  Determines the size and style of the scroll region where PETSc options selectable from users are displayed */
385 static const char *OptionsBodyBottom = "<div id=\"variablesInfo\" style=\"background-color:lightblue;height:auto;max-height:500px;overflow:scroll;\"></div>\n<br>\n</body>";
386 
387 /*
388     PetscOptionsSAWsInput - Presents all the PETSc Options processed by the program so the user may change them at runtime using the SAWs
389 
390     Bugs:
391 +    All processes must traverse through the exact same set of option queries do to the call to PetscScanString()
392 .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
393 -    Only works for PetscInt == int, PetscReal == double etc
394 
395 
396 */
397 PetscErrorCode PetscOptionsSAWsInput(PetscOptionItems *PetscOptionsObject)
398 {
399   PetscErrorCode  ierr;
400   PetscOptionItem next     = PetscOptionsObject->next;
401   static int      mancount = 0;
402   char            options[16];
403   PetscBool       changedmethod = PETSC_FALSE;
404   PetscBool       stopasking    = PETSC_FALSE;
405   char            manname[16],textname[16];
406   char            dir[1024];
407 
408   PetscFunctionBegin;
409   /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */
410   sprintf(options,"Options_%d",count++);
411 
412   PetscOptionsObject->pprefix = PetscOptionsObject->prefix; /* SAWs will change this, so cannot pass prefix directly */
413 
414   ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s","_title");CHKERRQ(ierr);
415   PetscStackCallSAWs(SAWs_Register,(dir,&PetscOptionsObject->title,1,SAWs_READ,SAWs_STRING));
416   ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s","prefix");CHKERRQ(ierr);
417   PetscStackCallSAWs(SAWs_Register,(dir,&PetscOptionsObject->pprefix,1,SAWs_READ,SAWs_STRING));
418   PetscStackCallSAWs(SAWs_Register,("/PETSc/Options/ChangedMethod",&changedmethod,1,SAWs_WRITE,SAWs_BOOLEAN));
419   PetscStackCallSAWs(SAWs_Register,("/PETSc/Options/StopAsking",&stopasking,1,SAWs_WRITE,SAWs_BOOLEAN));
420 
421   while (next) {
422     sprintf(manname,"_man_%d",mancount);
423     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",manname);CHKERRQ(ierr);
424     PetscStackCallSAWs(SAWs_Register,(dir,&next->man,1,SAWs_READ,SAWs_STRING));
425     sprintf(textname,"_text_%d",mancount++);
426     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",textname);CHKERRQ(ierr);
427     PetscStackCallSAWs(SAWs_Register,(dir,&next->text,1,SAWs_READ,SAWs_STRING));
428 
429     switch (next->type) {
430     case OPTION_HEAD:
431       break;
432     case OPTION_INT_ARRAY:
433     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
434       PetscStackCallSAWs(SAWs_Register,(dir,next->data,next->arraylength,SAWs_WRITE,SAWs_INT));
435       break;
436     case OPTION_REAL_ARRAY:
437     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
438       PetscStackCallSAWs(SAWs_Register,(dir,next->data,next->arraylength,SAWs_WRITE,SAWs_DOUBLE));
439       break;
440     case OPTION_INT:
441     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
442       PetscStackCallSAWs(SAWs_Register,(dir,next->data,1,SAWs_WRITE,SAWs_INT));
443       break;
444     case OPTION_REAL:
445     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
446       PetscStackCallSAWs(SAWs_Register,(dir,next->data,1,SAWs_WRITE,SAWs_DOUBLE));
447       break;
448     case OPTION_BOOL:
449     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
450       PetscStackCallSAWs(SAWs_Register,(dir,next->data,1,SAWs_WRITE,SAWs_BOOLEAN));
451       break;
452     case OPTION_BOOL_ARRAY:
453     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
454       PetscStackCallSAWs(SAWs_Register,(dir,next->data,next->arraylength,SAWs_WRITE,SAWs_BOOLEAN));
455       break;
456     case OPTION_STRING:
457     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
458       PetscStackCallSAWs(SAWs_Register,(dir,&next->data,1,SAWs_WRITE,SAWs_STRING));
459       break;
460     case OPTION_STRING_ARRAY:
461     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
462       PetscStackCallSAWs(SAWs_Register,(dir,next->data,next->arraylength,SAWs_WRITE,SAWs_STRING));
463       break;
464     case OPTION_FLIST:
465       {
466       PetscInt ntext;
467       ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
468       PetscStackCallSAWs(SAWs_Register,(dir,&next->data,1,SAWs_WRITE,SAWs_STRING));
469       ierr = PetscFunctionListGet(next->flist,(const char***)&next->edata,&ntext);CHKERRQ(ierr);
470       PetscStackCallSAWs(SAWs_Set_Legal_Variable_Values,(dir,ntext,next->edata));
471       }
472       break;
473     case OPTION_ELIST:
474       {
475       PetscInt ntext = next->nlist;
476       ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
477       PetscStackCallSAWs(SAWs_Register,(dir,&next->data,1,SAWs_WRITE,SAWs_STRING));
478       ierr = PetscMalloc1((ntext+1),(char***)&next->edata);CHKERRQ(ierr);
479       ierr = PetscMemcpy(next->edata,next->list,ntext*sizeof(char*));CHKERRQ(ierr);
480       PetscStackCallSAWs(SAWs_Set_Legal_Variable_Values,(dir,ntext,next->edata));
481       }
482       break;
483     default:
484       break;
485     }
486     next = next->next;
487   }
488 
489   /* wait until accessor has unlocked the memory */
490   PetscStackCallSAWs(SAWs_Push_Header,("index.html",OptionsHeader));
491   PetscStackCallSAWs(SAWs_Push_Body,("index.html",2,OptionsBodyBottom));
492   ierr = PetscSAWsBlock();CHKERRQ(ierr);
493   PetscStackCallSAWs(SAWs_Pop_Header,("index.html"));
494   PetscStackCallSAWs(SAWs_Pop_Body,("index.html",2));
495 
496   /* determine if any values have been set in GUI */
497   next = PetscOptionsObject->next;
498   while (next) {
499     ierr = PetscSNPrintf(dir,1024,"/PETSc/Options/%s",next->option);CHKERRQ(ierr);
500     PetscStackCallSAWs(SAWs_Selected,(dir,(int*)&next->set));
501     next = next->next;
502   }
503 
504   /* reset counter to -2; this updates the screen with the new options for the selected method */
505   if (changedmethod) PetscOptionsObject->count = -2;
506 
507   if (stopasking) {
508     PetscOptionsPublish      = PETSC_FALSE;
509     PetscOptionsObject->count = 0;//do not ask for same thing again
510   }
511 
512   PetscStackCallSAWs(SAWs_Delete,("/PETSc/Options"));
513   PetscFunctionReturn(0);
514 }
515 #endif
516 
517 PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems *PetscOptionsObject)
518 {
519   PetscErrorCode  ierr;
520   PetscOptionItem last;
521   char            option[256],value[1024],tmp[32];
522   size_t          j;
523 
524   PetscFunctionBegin;
525   if (PetscOptionsObject->next) {
526     if (!PetscOptionsObject->count) {
527 #if defined(PETSC_HAVE_SAWS)
528       ierr = PetscOptionsSAWsInput(PetscOptionsObject);CHKERRQ(ierr);
529 #else
530       ierr = PetscOptionsGetFromTextInput(PetscOptionsObject);CHKERRQ(ierr);
531 #endif
532     }
533   }
534 
535   ierr = PetscFree(PetscOptionsObject->title);CHKERRQ(ierr);
536 
537   /* reset counter to -2; this updates the screen with the new options for the selected method */
538   if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2;
539   /* reset alreadyprinted flag */
540   PetscOptionsObject->alreadyprinted = PETSC_FALSE;
541   if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE;
542   PetscOptionsObject->object = NULL;
543 
544   while (PetscOptionsObject->next) {
545     if (PetscOptionsObject->next->set) {
546       if (PetscOptionsObject->prefix) {
547         ierr = PetscStrcpy(option,"-");CHKERRQ(ierr);
548         ierr = PetscStrcat(option,PetscOptionsObject->prefix);CHKERRQ(ierr);
549         ierr = PetscStrcat(option,PetscOptionsObject->next->option+1);CHKERRQ(ierr);
550       } else {
551         ierr = PetscStrcpy(option,PetscOptionsObject->next->option);CHKERRQ(ierr);
552       }
553 
554       switch (PetscOptionsObject->next->type) {
555       case OPTION_HEAD:
556         break;
557       case OPTION_INT_ARRAY:
558         sprintf(value,"%d",(int)((PetscInt*)PetscOptionsObject->next->data)[0]);
559         for (j=1; j<PetscOptionsObject->next->arraylength; j++) {
560           sprintf(tmp,"%d",(int)((PetscInt*)PetscOptionsObject->next->data)[j]);
561           ierr = PetscStrcat(value,",");CHKERRQ(ierr);
562           ierr = PetscStrcat(value,tmp);CHKERRQ(ierr);
563         }
564         break;
565       case OPTION_INT:
566         sprintf(value,"%d",(int) *(PetscInt*)PetscOptionsObject->next->data);
567         break;
568       case OPTION_REAL:
569         sprintf(value,"%g",(double) *(PetscReal*)PetscOptionsObject->next->data);
570         break;
571       case OPTION_REAL_ARRAY:
572         sprintf(value,"%g",(double)((PetscReal*)PetscOptionsObject->next->data)[0]);
573         for (j=1; j<PetscOptionsObject->next->arraylength; j++) {
574           sprintf(tmp,"%g",(double)((PetscReal*)PetscOptionsObject->next->data)[j]);
575           ierr = PetscStrcat(value,",");CHKERRQ(ierr);
576           ierr = PetscStrcat(value,tmp);CHKERRQ(ierr);
577         }
578         break;
579       case OPTION_SCALAR_ARRAY:
580         sprintf(value,"%g+%gi",(double)PetscRealPart(((PetscScalar*)PetscOptionsObject->next->data)[0]),(double)PetscImaginaryPart(((PetscScalar*)PetscOptionsObject->next->data)[0]));
581         for (j=1; j<PetscOptionsObject->next->arraylength; j++) {
582           sprintf(tmp,"%g+%gi",(double)PetscRealPart(((PetscScalar*)PetscOptionsObject->next->data)[j]),(double)PetscImaginaryPart(((PetscScalar*)PetscOptionsObject->next->data)[j]));
583           ierr = PetscStrcat(value,",");CHKERRQ(ierr);
584           ierr = PetscStrcat(value,tmp);CHKERRQ(ierr);
585         }
586         break;
587       case OPTION_BOOL:
588         sprintf(value,"%d",*(int*)PetscOptionsObject->next->data);
589         break;
590       case OPTION_BOOL_ARRAY:
591         sprintf(value,"%d",(int)((PetscBool*)PetscOptionsObject->next->data)[0]);
592         for (j=1; j<PetscOptionsObject->next->arraylength; j++) {
593           sprintf(tmp,"%d",(int)((PetscBool*)PetscOptionsObject->next->data)[j]);
594           ierr = PetscStrcat(value,",");CHKERRQ(ierr);
595           ierr = PetscStrcat(value,tmp);CHKERRQ(ierr);
596         }
597         break;
598       case OPTION_FLIST:
599         ierr = PetscStrcpy(value,(char*)PetscOptionsObject->next->data);CHKERRQ(ierr);
600         break;
601       case OPTION_ELIST:
602         ierr = PetscStrcpy(value,(char*)PetscOptionsObject->next->data);CHKERRQ(ierr);
603         break;
604       case OPTION_STRING:
605         ierr = PetscStrcpy(value,(char*)PetscOptionsObject->next->data);CHKERRQ(ierr);
606         break;
607       case OPTION_STRING_ARRAY:
608         sprintf(value,"%s",((char**)PetscOptionsObject->next->data)[0]);
609         for (j=1; j<PetscOptionsObject->next->arraylength; j++) {
610           sprintf(tmp,"%s",((char**)PetscOptionsObject->next->data)[j]);
611           ierr = PetscStrcat(value,",");CHKERRQ(ierr);
612           ierr = PetscStrcat(value,tmp);CHKERRQ(ierr);
613         }
614         break;
615       }
616       ierr = PetscOptionsSetValue(PetscOptionsObject->options,option,value);CHKERRQ(ierr);
617     }
618     if (PetscOptionsObject->next->type == OPTION_ELIST) {
619       ierr = PetscStrNArrayDestroy(PetscOptionsObject->next->nlist,(char ***)&PetscOptionsObject->next->list);CHKERRQ(ierr);
620     }
621     ierr   = PetscFree(PetscOptionsObject->next->text);CHKERRQ(ierr);
622     ierr   = PetscFree(PetscOptionsObject->next->option);CHKERRQ(ierr);
623     ierr   = PetscFree(PetscOptionsObject->next->man);CHKERRQ(ierr);
624     ierr   = PetscFree(PetscOptionsObject->next->edata);CHKERRQ(ierr);
625 
626     if ((PetscOptionsObject->next->type == OPTION_STRING) || (PetscOptionsObject->next->type == OPTION_FLIST) || (PetscOptionsObject->next->type == OPTION_ELIST)){
627       free(PetscOptionsObject->next->data);
628     } else {
629       ierr   = PetscFree(PetscOptionsObject->next->data);CHKERRQ(ierr);
630     }
631 
632     last                    = PetscOptionsObject->next;
633     PetscOptionsObject->next = PetscOptionsObject->next->next;
634     ierr                    = PetscFree(last);CHKERRQ(ierr);
635   }
636   ierr = PetscFree(PetscOptionsObject->prefix);CHKERRQ(ierr);
637   PetscOptionsObject->next = NULL;
638   PetscFunctionReturn(0);
639 }
640 
641 /*MC
642    PetscOptionsEnum - Gets the enum value for a particular option in the database.
643 
644    Logically Collective on the communicator passed in PetscOptionsBegin()
645 
646    Synopsis:
647    #include "petscsys.h"
648    PetscErrorCode  PetscOptionsEnum(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],const char *const *list,PetscEnum currentvalue,PetscEnum *value,PetscBool  *set)
649 
650    Input Parameters:
651 +  opt - option name
652 .  text - short string that describes the option
653 .  man - manual page with additional information on option
654 .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
655 -  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
656 $                 PetscOptionsEnum(..., obj->value,&object->value,...) or
657 $                 value = defaultvalue
658 $                 PetscOptionsEnum(..., value,&value,&flg);
659 $                 if (flg) {
660 
661    Output Parameter:
662 +  value - the  value to return
663 -  set - PETSC_TRUE if found, else PETSC_FALSE
664 
665    Level: beginner
666 
667    Notes:
668     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
669 
670           list is usually something like PCASMTypes or some other predefined list of enum names
671 
672           If the user does not supply the option at all value is NOT changed. Thus
673           you should ALWAYS initialize value if you access it without first checking if the set flag is true.
674 
675           The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.
676 
677 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
678           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
679           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
680           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
681           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
682           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
683           PetscOptionsFList(), PetscOptionsEList()
684 M*/
685 
686 PetscErrorCode  PetscOptionsEnum_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],const char *const *list,PetscEnum currentvalue,PetscEnum *value,PetscBool  *set)
687 {
688   PetscErrorCode ierr;
689   PetscInt       ntext = 0;
690   PetscInt       tval;
691   PetscBool      tflg;
692 
693   PetscFunctionBegin;
694   while (list[ntext++]) {
695     if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
696   }
697   if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
698   ntext -= 3;
699   ierr   = PetscOptionsEList_Private(PetscOptionsObject,opt,text,man,list,ntext,list[currentvalue],&tval,&tflg);CHKERRQ(ierr);
700   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
701   if (tflg) *value = (PetscEnum)tval;
702   if (set)  *set   = tflg;
703   PetscFunctionReturn(0);
704 }
705 
706 /*MC
707    PetscOptionsEnumArray - Gets an array of enum values for a particular
708    option in the database.
709 
710    Logically Collective on the communicator passed in PetscOptionsBegin()
711 
712    Synopsis:
713    #include "petscsys.h"
714    PetscErrorCode  PetscOptionsEnumArray(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],const char *const *list,PetscEnum value[],PetscInt *n,PetscBool  *set)
715 
716    Input Parameters:
717 +  opt - the option one is seeking
718 .  text - short string describing option
719 .  man - manual page for option
720 .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
721 -  n - maximum number of values
722 
723    Output Parameter:
724 +  value - location to copy values
725 .  n - actual number of values found
726 -  set - PETSC_TRUE if found, else PETSC_FALSE
727 
728    Level: beginner
729 
730    Notes:
731    The array must be passed as a comma separated list.
732 
733    There must be no intervening spaces between the values.
734 
735    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
736 
737 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
738           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
739           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
740           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
741           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
742           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsRealArray()
743 M*/
744 
745 PetscErrorCode  PetscOptionsEnumArray_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],const char *const *list,PetscEnum value[],PetscInt *n,PetscBool  *set)
746 {
747   PetscInt        i,nlist = 0;
748   PetscOptionItem amsopt;
749   PetscErrorCode  ierr;
750 
751   PetscFunctionBegin;
752   while (list[nlist++]) if (nlist > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
753   if (nlist < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
754   nlist -= 3; /* drop enum name, prefix, and null termination */
755   if (0 && !PetscOptionsObject->count) { /* XXX Requires additional support */
756     PetscEnum *vals;
757     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_INT_ARRAY/*XXX OPTION_ENUM_ARRAY*/,&amsopt);CHKERRQ(ierr);
758     ierr = PetscStrNArrayallocpy(nlist,list,(char***)&amsopt->list);CHKERRQ(ierr);
759     amsopt->nlist = nlist;
760     ierr = PetscMalloc1(*n,(PetscEnum**)&amsopt->data);CHKERRQ(ierr);
761     amsopt->arraylength = *n;
762     vals = (PetscEnum*)amsopt->data;
763     for (i=0; i<*n; i++) vals[i] = value[i];
764   }
765   ierr = PetscOptionsGetEnumArray(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,list,value,n,set);CHKERRQ(ierr);
766   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
767     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <%s",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,list[value[0]]);CHKERRQ(ierr);
768     for (i=1; i<*n; i++) {ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,",%s",list[value[i]]);CHKERRQ(ierr);}
769     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,">: %s (choose from)",text);CHKERRQ(ierr);
770     for (i=0; i<nlist; i++) {ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm," %s",list[i]);CHKERRQ(ierr);}
771     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm," (%s)\n",ManSection(man));CHKERRQ(ierr);
772   }
773   PetscFunctionReturn(0);
774 }
775 
776 /*MC
777    PetscOptionsBoundedInt - Gets an integer value greater than or equal a given bound for a particular option in the database.
778 
779    Logically Collective on the communicator passed in PetscOptionsBegin()
780 
781    Synopsis:
782    #include "petscsys.h"
783    PetscErrorCode  PetscOptionsBoundInt(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt currentvalue,PetscInt *value,PetscBool *flg,PetscInt bound)
784 
785    Input Parameters:
786 +  opt - option name
787 .  text - short string that describes the option
788 .  man - manual page with additional information on option
789 .  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
790 $                 PetscOptionsInt(..., obj->value,&obj->value,...) or
791 $                 value = defaultvalue
792 $                 PetscOptionsInt(..., value,&value,&flg);
793 $                 if (flg) {
794 -  bound - the requested value should be greater than or equal this bound or an error is generated
795 
796    Output Parameter:
797 +  value - the integer value to return
798 -  flg - PETSC_TRUE if found, else PETSC_FALSE
799 
800    Notes:
801     If the user does not supply the option at all value is NOT changed. Thus
802     you should ALWAYS initialize value if you access it without first checking if the set flag is true.
803 
804     The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.
805 
806     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
807 
808    Level: beginner
809 
810 .seealso: PetscOptionsInt(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
811           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(), PetscOptionsRangeInt()
812           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
813           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
814           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
815           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
816           PetscOptionsFList(), PetscOptionsEList()
817 M*/
818 
819 /*MC
820    PetscOptionsRangeInt - Gets an integer value within a range of values for a particular option in the database.
821 
822    Logically Collective on the communicator passed in PetscOptionsBegin()
823 
824    Synopsis:
825    #include "petscsys.h"
826 PetscErrorCode  PetscOptionsRangeInt(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt currentvalue,PetscInt *value,PetscBool *flg,PetscInt lb,PetscInt ub)
827 
828    Input Parameters:
829 +  opt - option name
830 .  text - short string that describes the option
831 .  man - manual page with additional information on option
832 .  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
833 $                 PetscOptionsInt(..., obj->value,&obj->value,...) or
834 $                 value = defaultvalue
835 $                 PetscOptionsInt(..., value,&value,&flg);
836 $                 if (flg) {
837 .  lb - the lower bound, provided value must be greater than or equal to this value or an error is generated
838 -  ub - the upper bound, provided value must be less than or equal to this value or an error is generated
839 
840    Output Parameter:
841 +  value - the integer value to return
842 -  flg - PETSC_TRUE if found, else PETSC_FALSE
843 
844    Notes:
845     If the user does not supply the option at all value is NOT changed. Thus
846     you should ALWAYS initialize value if you access it without first checking if the set flag is true.
847 
848     The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.
849 
850     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
851 
852    Level: beginner
853 
854 .seealso: PetscOptionsInt(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
855           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(), PetscOptionsBoundedInt()
856           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
857           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
858           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
859           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
860           PetscOptionsFList(), PetscOptionsEList()
861 M*/
862 
863 /*MC
864    PetscOptionsInt - Gets the integer value for a particular option in the database.
865 
866    Logically Collective on the communicator passed in PetscOptionsBegin()
867 
868    Synopsis:
869    #include "petscsys.h"
870 PetscErrorCode  PetscOptionsInt(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt currentvalue,PetscInt *value,PetscBool *flg))
871 
872 
873    Input Parameters:
874 +  opt - option name
875 .  text - short string that describes the option
876 .  man - manual page with additional information on option
877 -  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
878 $                 PetscOptionsInt(..., obj->value,&obj->value,...) or
879 $                 value = defaultvalue
880 $                 PetscOptionsInt(..., value,&value,&flg);
881 $                 if (flg) {
882 
883    Output Parameter:
884 +  value - the integer value to return
885 -  flg - PETSC_TRUE if found, else PETSC_FALSE
886 
887    Notes:
888     If the user does not supply the option at all value is NOT changed. Thus
889     you should ALWAYS initialize value if you access it without first checking if the set flag is true.
890 
891     The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.
892 
893     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
894 
895    Level: beginner
896 
897 .seealso: PetscOptionsBoundedInt(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
898           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(), PetscOptionsRangeInt()
899           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
900           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
901           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
902           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
903           PetscOptionsFList(), PetscOptionsEList()
904 M*/
905 
906 PetscErrorCode  PetscOptionsInt_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt currentvalue,PetscInt *value,PetscBool  *set,PetscInt lb,PetscInt ub)
907 {
908   PetscErrorCode  ierr;
909   PetscOptionItem amsopt;
910   PetscBool       wasset;
911 
912   PetscFunctionBegin;
913   if (currentvalue < lb) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Current value %D less than allowed bound %D",currentvalue,lb);
914   if (currentvalue > ub) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Current value %D greater than allowed bound %D",currentvalue,ub);
915      if (!PetscOptionsObject->count) {
916     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_INT,&amsopt);CHKERRQ(ierr);
917     ierr = PetscMalloc(sizeof(PetscInt),&amsopt->data);CHKERRQ(ierr);
918     *(PetscInt*)amsopt->data = currentvalue;
919 
920     ierr = PetscOptionsGetInt(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,&currentvalue,&wasset);CHKERRQ(ierr);
921     if (wasset) {
922       *(PetscInt*)amsopt->data = currentvalue;
923     }
924   }
925   ierr = PetscOptionsGetInt(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,&wasset);CHKERRQ(ierr);
926   if (wasset && *value < lb) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Newly set value %D less than allowed bound %D",*value,lb);
927   if (wasset && *value > ub) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Newly set value %D greater than allowed bound %D",*value,ub);
928   if (set) *set = wasset;
929   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
930     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <now %D : formerly %D>: %s (%s)\n",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,wasset && value ? *value : currentvalue,currentvalue,text,ManSection(man));CHKERRQ(ierr);
931   }
932   PetscFunctionReturn(0);
933 }
934 
935 /*MC
936    PetscOptionsString - Gets the string value for a particular option in the database.
937 
938    Logically Collective on the communicator passed in PetscOptionsBegin()
939 
940    Synopsis:
941    #include "petscsys.h"
942    PetscErrorCode  PetscOptionsString(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],const char currentvalue[],char value[],size_t len,PetscBool  *set)
943 
944    Input Parameters:
945 +  opt - option name
946 .  text - short string that describes the option
947 .  man - manual page with additional information on option
948 .  currentvalue - the current value; caller is responsible for setting this value correctly. This is not used to set value
949 -  len - length of the result string including null terminator
950 
951    Output Parameter:
952 +  value - the value to return
953 -  flg - PETSC_TRUE if found, else PETSC_FALSE
954 
955    Level: beginner
956 
957    Notes:
958     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
959 
960    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).
961 
962           If the user does not supply the option at all value is NOT changed. Thus
963           you should ALWAYS initialize value if you access it without first checking if the set flag is true.
964 
965           The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.
966 
967 
968 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
969           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
970           PetscOptionsInt(), PetscOptionsReal(), PetscOptionsBool(),
971           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
972           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
973           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
974           PetscOptionsFList(), PetscOptionsEList()
975 M*/
976 
977 PetscErrorCode  PetscOptionsString_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],const char currentvalue[],char value[],size_t len,PetscBool  *set)
978 {
979   PetscErrorCode  ierr;
980   PetscOptionItem amsopt;
981   PetscBool       lset;
982 
983   PetscFunctionBegin;
984   if (!PetscOptionsObject->count) {
985     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_STRING,&amsopt);CHKERRQ(ierr);
986     /* must use system malloc since SAWs may free this */
987     ierr = PetscStrdup(currentvalue ? currentvalue : "",(char**)&amsopt->data);CHKERRQ(ierr);
988   }
989   ierr = PetscOptionsGetString(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,len,&lset);CHKERRQ(ierr);
990   if (set) *set = lset;
991   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
992     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <now %s : formerly %s>: %s (%s)\n",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,lset && value ? value : currentvalue,currentvalue,text,ManSection(man));CHKERRQ(ierr);
993   }
994   PetscFunctionReturn(0);
995 }
996 
997 /*MC
998    PetscOptionsReal - Gets the PetscReal value for a particular option in the database.
999 
1000    Logically Collective on the communicator passed in PetscOptionsBegin()
1001 
1002    Synopsis:
1003    #include "petscsys.h"
1004    PetscErrorCode  PetscOptionsReal(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscReal currentvalue,PetscReal *value,PetscBool  *set)
1005 
1006    Input Parameters:
1007 +  opt - option name
1008 .  text - short string that describes the option
1009 .  man - manual page with additional information on option
1010 -  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
1011 $                 PetscOptionsReal(..., obj->value,&obj->value,...) or
1012 $                 value = defaultvalue
1013 $                 PetscOptionsReal(..., value,&value,&flg);
1014 $                 if (flg) {
1015 
1016    Output Parameter:
1017 +  value - the value to return
1018 -  flg - PETSC_TRUE if found, else PETSC_FALSE
1019 
1020    Notes:
1021     If the user does not supply the option at all value is NOT changed. Thus
1022     you should ALWAYS initialize value if you access it without first checking if the set flag is true.
1023 
1024     The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.
1025 
1026     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1027 
1028    Level: beginner
1029 
1030 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1031           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1032           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1033           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1034           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1035           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1036           PetscOptionsFList(), PetscOptionsEList()
1037 M*/
1038 
1039 PetscErrorCode  PetscOptionsReal_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscReal currentvalue,PetscReal *value,PetscBool  *set)
1040 {
1041   PetscErrorCode  ierr;
1042   PetscOptionItem amsopt;
1043   PetscBool       lset;
1044 
1045   PetscFunctionBegin;
1046   if (!PetscOptionsObject->count) {
1047     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_REAL,&amsopt);CHKERRQ(ierr);
1048     ierr = PetscMalloc(sizeof(PetscReal),&amsopt->data);CHKERRQ(ierr);
1049 
1050     *(PetscReal*)amsopt->data = currentvalue;
1051   }
1052   ierr = PetscOptionsGetReal(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,&lset);CHKERRQ(ierr);
1053   if (set) *set = lset;
1054   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1055     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <%g : %g>: %s (%s)\n",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,lset && value ? (double)*value : (double) currentvalue,(double)currentvalue,text,ManSection(man));CHKERRQ(ierr);
1056   }
1057   PetscFunctionReturn(0);
1058 }
1059 
1060 /*MC
1061    PetscOptionsScalar - Gets the scalar value for a particular option in the database.
1062 
1063    Logically Collective on the communicator passed in PetscOptionsBegin()
1064 
1065    Synopsis:
1066    #include "petscsys.h"
1067    PetscErrorCode PetscOptionsScalar(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscScalar currentvalue,PetscScalar *value,PetscBool  *set)
1068 
1069    Input Parameters:
1070 +  opt - option name
1071 .  text - short string that describes the option
1072 .  man - manual page with additional information on option
1073 -  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
1074 $                 PetscOptionsScalar(..., obj->value,&obj->value,...) or
1075 $                 value = defaultvalue
1076 $                 PetscOptionsScalar(..., value,&value,&flg);
1077 $                 if (flg) {
1078 
1079 
1080    Output Parameter:
1081 +  value - the value to return
1082 -  flg - PETSC_TRUE if found, else PETSC_FALSE
1083 
1084    Notes:
1085     If the user does not supply the option at all value is NOT changed. Thus
1086     you should ALWAYS initialize value if you access it without first checking if the set flag is true.
1087 
1088     The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.
1089 
1090     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1091 
1092    Level: beginner
1093 
1094 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1095           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1096           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1097           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1098           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1099           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1100           PetscOptionsFList(), PetscOptionsEList()
1101 M*/
1102 
1103 PetscErrorCode  PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscScalar currentvalue,PetscScalar *value,PetscBool  *set)
1104 {
1105   PetscErrorCode ierr;
1106 
1107   PetscFunctionBegin;
1108 #if !defined(PETSC_USE_COMPLEX)
1109   ierr = PetscOptionsReal(opt,text,man,currentvalue,value,set);CHKERRQ(ierr);
1110 #else
1111   ierr = PetscOptionsGetScalar(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,set);CHKERRQ(ierr);
1112 #endif
1113   PetscFunctionReturn(0);
1114 }
1115 
1116 /*MC
1117    PetscOptionsName - Determines if a particular option has been set in the database. This returns true whether the option is a number, string or boolean, even
1118                       its value is set to false.
1119 
1120    Logically Collective on the communicator passed in PetscOptionsBegin()
1121 
1122    Synopsis:
1123    #include "petscsys.h"
1124    PetscErrorCode PetscOptionsName(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool  *flg)
1125 
1126    Input Parameters:
1127 +  opt - option name
1128 .  text - short string that describes the option
1129 -  man - manual page with additional information on option
1130 
1131    Output Parameter:
1132 .  flg - PETSC_TRUE if found, else PETSC_FALSE
1133 
1134    Level: beginner
1135 
1136    Notes:
1137     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1138 
1139 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1140           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1141           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1142           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1143           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1144           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1145           PetscOptionsFList(), PetscOptionsEList()
1146 M*/
1147 
1148 PetscErrorCode  PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool  *flg)
1149 {
1150   PetscErrorCode  ierr;
1151   PetscOptionItem amsopt;
1152 
1153   PetscFunctionBegin;
1154   if (!PetscOptionsObject->count) {
1155     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_BOOL,&amsopt);CHKERRQ(ierr);
1156     ierr = PetscMalloc(sizeof(PetscBool),&amsopt->data);CHKERRQ(ierr);
1157 
1158     *(PetscBool*)amsopt->data = PETSC_FALSE;
1159   }
1160   ierr = PetscOptionsHasName(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,flg);CHKERRQ(ierr);
1161   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1162     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s: %s (%s)\n",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,text,ManSection(man));CHKERRQ(ierr);
1163   }
1164   PetscFunctionReturn(0);
1165 }
1166 
1167 /*MC
1168      PetscOptionsFList - Puts a list of option values that a single one may be selected from
1169 
1170    Logically Collective on the communicator passed in PetscOptionsBegin()
1171 
1172    Synopsis:
1173    #include "petscsys.h"
1174    PetscErrorCode  PetscOptionsFList(PetscOptionItems *PetscOptionsObject,const char opt[],const char ltext[],const char man[],PetscFunctionList list,const char currentvalue[],char value[],size_t len,PetscBool  *set)
1175 
1176    Input Parameters:
1177 +  opt - option name
1178 .  text - short string that describes the option
1179 .  man - manual page with additional information on option
1180 .  list - the possible choices
1181 .  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with
1182 $                 PetscOptionsFlist(..., obj->value,value,len,&flg);
1183 $                 if (flg) {
1184 -  len - the length of the character array value
1185 
1186    Output Parameter:
1187 +  value - the value to return
1188 -  set - PETSC_TRUE if found, else PETSC_FALSE
1189 
1190    Level: intermediate
1191 
1192    Notes:
1193     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1194 
1195           If the user does not supply the option at all value is NOT changed. Thus
1196           you should ALWAYS initialize value if you access it without first checking if the set flag is true.
1197 
1198           The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.
1199 
1200    See PetscOptionsEList() for when the choices are given in a string array
1201 
1202    To get a listing of all currently specified options,
1203     see PetscOptionsView() or PetscOptionsGetAll()
1204 
1205    Developer Note: This cannot check for invalid selection because of things like MATAIJ that are not included in the list
1206 
1207 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1208            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1209           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1210           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1211           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1212           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsEnum()
1213 M*/
1214 
1215 PetscErrorCode  PetscOptionsFList_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char ltext[],const char man[],PetscFunctionList list,const char currentvalue[],char value[],size_t len,PetscBool  *set)
1216 {
1217   PetscErrorCode  ierr;
1218   PetscOptionItem amsopt;
1219   PetscBool       lset;
1220 
1221   PetscFunctionBegin;
1222   if (!PetscOptionsObject->count) {
1223     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,ltext,man,OPTION_FLIST,&amsopt);CHKERRQ(ierr);
1224     /* must use system malloc since SAWs may free this */
1225     ierr = PetscStrdup(currentvalue ? currentvalue : "",(char**)&amsopt->data);CHKERRQ(ierr);
1226     amsopt->flist = list;
1227   }
1228   ierr = PetscOptionsGetString(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,len,&lset);CHKERRQ(ierr);
1229   if (set) *set = lset;
1230   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1231     ierr = PetscFunctionListPrintTypes(PetscOptionsObject->comm,stdout,PetscOptionsObject->prefix,opt,ltext,man,list,currentvalue,lset && value ? value : currentvalue);CHKERRQ(ierr);
1232   }
1233   PetscFunctionReturn(0);
1234 }
1235 
1236 /*MC
1237      PetscOptionsEList - Puts a list of option values that a single one may be selected from
1238 
1239    Logically Collective on the communicator passed in PetscOptionsBegin()
1240 
1241    Synopsis:
1242    #include "petscsys.h"
1243    PetscErrorCode  PetscOptionsEList(PetscOptionItems *PetscOptionsObject,const char opt[],const char ltext[],const char man[],const char *const *list,PetscInt ntext,const char currentvalue[],PetscInt *value,PetscBool  *set)
1244 
1245    Input Parameters:
1246 +  opt - option name
1247 .  ltext - short string that describes the option
1248 .  man - manual page with additional information on option
1249 .  list - the possible choices (one of these must be selected, anything else is invalid)
1250 .  ntext - number of choices
1251 -  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with
1252 $                 PetscOptionsElist(..., obj->value,&value,&flg);
1253 $                 if (flg) {
1254 
1255 
1256    Output Parameter:
1257 +  value - the index of the value to return
1258 -  set - PETSC_TRUE if found, else PETSC_FALSE
1259 
1260    Level: intermediate
1261 
1262    Notes:
1263     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1264 
1265          If the user does not supply the option at all value is NOT changed. Thus
1266           you should ALWAYS initialize value if you access it without first checking if the set flag is true.
1267 
1268    See PetscOptionsFList() for when the choices are given in a PetscFunctionList()
1269 
1270 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1271            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1272           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1273           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1274           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1275           PetscOptionsFList(), PetscOptionsEnum()
1276 M*/
1277 
1278 PetscErrorCode  PetscOptionsEList_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char ltext[],const char man[],const char *const *list,PetscInt ntext,const char currentvalue[],PetscInt *value,PetscBool  *set)
1279 {
1280   PetscErrorCode  ierr;
1281   PetscInt        i;
1282   PetscOptionItem amsopt;
1283   PetscBool       lset;
1284 
1285   PetscFunctionBegin;
1286   if (!PetscOptionsObject->count) {
1287     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,ltext,man,OPTION_ELIST,&amsopt);CHKERRQ(ierr);
1288     /* must use system malloc since SAWs may free this */
1289     ierr = PetscStrdup(currentvalue ? currentvalue : "",(char**)&amsopt->data);CHKERRQ(ierr);
1290     ierr = PetscStrNArrayallocpy(ntext,list,(char***)&amsopt->list);CHKERRQ(ierr);
1291     amsopt->nlist = ntext;
1292   }
1293   ierr = PetscOptionsGetEList(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,list,ntext,value,&lset);CHKERRQ(ierr);
1294   if (set) *set = lset;
1295   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1296     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <now %s : formerly %s> %s (choose one of)",PetscOptionsObject->prefix?PetscOptionsObject->prefix:"",opt+1,lset && value ? list[*value] : currentvalue,currentvalue,ltext);CHKERRQ(ierr);
1297     for (i=0; i<ntext; i++) {
1298       ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm," %s",list[i]);CHKERRQ(ierr);
1299     }
1300     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm," (%s)\n",ManSection(man));CHKERRQ(ierr);
1301   }
1302   PetscFunctionReturn(0);
1303 }
1304 
1305 /*MC
1306      PetscOptionsBoolGroupBegin - First in a series of logical queries on the options database for
1307        which at most a single value can be true.
1308 
1309    Logically Collective on the communicator passed in PetscOptionsBegin()
1310 
1311    Synopsis:
1312    #include "petscsys.h"
1313    PetscErrorCode PetscOptionsBoolGroupBegin(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool  *flg)
1314 
1315    Input Parameters:
1316 +  opt - option name
1317 .  text - short string that describes the option
1318 -  man - manual page with additional information on option
1319 
1320    Output Parameter:
1321 .  flg - whether that option was set or not
1322 
1323    Level: intermediate
1324 
1325    Notes:
1326     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1327 
1328    Must be followed by 0 or more PetscOptionsBoolGroup()s and PetscOptionsBoolGroupEnd()
1329 
1330 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1331            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1332           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1333           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1334           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1335           PetscOptionsFList(), PetscOptionsEList()
1336 M*/
1337 
1338 PetscErrorCode  PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool  *flg)
1339 {
1340   PetscErrorCode  ierr;
1341   PetscOptionItem amsopt;
1342 
1343   PetscFunctionBegin;
1344   if (!PetscOptionsObject->count) {
1345     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_BOOL,&amsopt);CHKERRQ(ierr);
1346     ierr = PetscMalloc(sizeof(PetscBool),&amsopt->data);CHKERRQ(ierr);
1347 
1348     *(PetscBool*)amsopt->data = PETSC_FALSE;
1349   }
1350   *flg = PETSC_FALSE;
1351   ierr = PetscOptionsGetBool(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,flg,NULL);CHKERRQ(ierr);
1352   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1353     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  Pick at most one of -------------\n");CHKERRQ(ierr);
1354     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"    -%s%s: %s (%s)\n",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,text,ManSection(man));CHKERRQ(ierr);
1355   }
1356   PetscFunctionReturn(0);
1357 }
1358 
1359 /*MC
1360      PetscOptionsBoolGroup - One in a series of logical queries on the options database for
1361        which at most a single value can be true.
1362 
1363    Logically Collective on the communicator passed in PetscOptionsBegin()
1364 
1365    Synopsis:
1366    #include "petscsys.h"
1367    PetscErrorCode PetscOptionsBoolGroup(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool  *flg)
1368 
1369    Input Parameters:
1370 +  opt - option name
1371 .  text - short string that describes the option
1372 -  man - manual page with additional information on option
1373 
1374    Output Parameter:
1375 .  flg - PETSC_TRUE if found, else PETSC_FALSE
1376 
1377    Level: intermediate
1378 
1379    Notes:
1380     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1381 
1382    Must follow a PetscOptionsBoolGroupBegin() and preceded a PetscOptionsBoolGroupEnd()
1383 
1384 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1385            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1386           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1387           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1388           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1389           PetscOptionsFList(), PetscOptionsEList()
1390 M*/
1391 
1392 PetscErrorCode  PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool  *flg)
1393 {
1394   PetscErrorCode  ierr;
1395   PetscOptionItem amsopt;
1396 
1397   PetscFunctionBegin;
1398   if (!PetscOptionsObject->count) {
1399     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_BOOL,&amsopt);CHKERRQ(ierr);
1400     ierr = PetscMalloc(sizeof(PetscBool),&amsopt->data);CHKERRQ(ierr);
1401 
1402     *(PetscBool*)amsopt->data = PETSC_FALSE;
1403   }
1404   *flg = PETSC_FALSE;
1405   ierr = PetscOptionsGetBool(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,flg,NULL);CHKERRQ(ierr);
1406   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1407     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"    -%s%s: %s (%s)\n",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,text,ManSection(man));CHKERRQ(ierr);
1408   }
1409   PetscFunctionReturn(0);
1410 }
1411 
1412 /*MC
1413      PetscOptionsBoolGroupEnd - Last in a series of logical queries on the options database for
1414        which at most a single value can be true.
1415 
1416    Logically Collective on the communicator passed in PetscOptionsBegin()
1417 
1418    Synopsis:
1419    #include "petscsys.h"
1420    PetscErrorCode PetscOptionsBoolGroupEnd(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool  *flg)
1421 
1422    Input Parameters:
1423 +  opt - option name
1424 .  text - short string that describes the option
1425 -  man - manual page with additional information on option
1426 
1427    Output Parameter:
1428 .  flg - PETSC_TRUE if found, else PETSC_FALSE
1429 
1430    Level: intermediate
1431 
1432    Notes:
1433     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1434 
1435    Must follow a PetscOptionsBoolGroupBegin()
1436 
1437 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1438            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1439           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1440           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1441           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1442           PetscOptionsFList(), PetscOptionsEList()
1443 M*/
1444 
1445 PetscErrorCode  PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool  *flg)
1446 {
1447   PetscErrorCode  ierr;
1448   PetscOptionItem amsopt;
1449 
1450   PetscFunctionBegin;
1451   if (!PetscOptionsObject->count) {
1452     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_BOOL,&amsopt);CHKERRQ(ierr);
1453     ierr = PetscMalloc(sizeof(PetscBool),&amsopt->data);CHKERRQ(ierr);
1454 
1455     *(PetscBool*)amsopt->data = PETSC_FALSE;
1456   }
1457   *flg = PETSC_FALSE;
1458   ierr = PetscOptionsGetBool(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,flg,NULL);CHKERRQ(ierr);
1459   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1460     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"    -%s%s: %s (%s)\n",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,text,ManSection(man));CHKERRQ(ierr);
1461   }
1462   PetscFunctionReturn(0);
1463 }
1464 
1465 /*MC
1466    PetscOptionsBool - Determines if a particular option is in the database with a true or false
1467 
1468    Logically Collective on the communicator passed in PetscOptionsBegin()
1469 
1470    Synopsis:
1471    #include "petscsys.h"
1472    PetscErrorCode PetscOptionsBool(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool currentvalue,PetscBool  *flg,PetscBool  *set)
1473 
1474    Input Parameters:
1475 +  opt - option name
1476 .  text - short string that describes the option
1477 .  man - manual page with additional information on option
1478 -  currentvalue - the current value
1479 
1480    Output Parameter:
1481 +  flg - PETSC_TRUE or PETSC_FALSE
1482 -  set - PETSC_TRUE if found, else PETSC_FALSE
1483 
1484    Notes:
1485        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1486        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
1487 
1488       If the option is given, but no value is provided, then flg and set are both given the value PETSC_TRUE. That is -requested_bool
1489      is equivalent to -requested_bool true
1490 
1491        If the user does not supply the option at all flg is NOT changed. Thus
1492      you should ALWAYS initialize the flg if you access it without first checking if the set flag is true.
1493 
1494     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1495 
1496    Level: beginner
1497 
1498 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1499           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1500           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1501           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1502           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1503           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1504           PetscOptionsFList(), PetscOptionsEList()
1505 M*/
1506 
1507 PetscErrorCode  PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool currentvalue,PetscBool  *flg,PetscBool  *set)
1508 {
1509   PetscErrorCode  ierr;
1510   PetscBool       iset;
1511   PetscOptionItem amsopt;
1512 
1513   PetscFunctionBegin;
1514   if (!PetscOptionsObject->count) {
1515     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_BOOL,&amsopt);CHKERRQ(ierr);
1516     ierr = PetscMalloc(sizeof(PetscBool),&amsopt->data);CHKERRQ(ierr);
1517 
1518     *(PetscBool*)amsopt->data = currentvalue;
1519   }
1520   ierr = PetscOptionsGetBool(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,flg,&iset);CHKERRQ(ierr);
1521   if (set) *set = iset;
1522   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1523     const char *v = PetscBools[currentvalue], *vn = PetscBools[iset && flg ? *flg : currentvalue];
1524     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s: <%s : %s> %s (%s)\n",PetscOptionsObject->prefix?PetscOptionsObject->prefix:"",opt+1,v,vn,text,ManSection(man));CHKERRQ(ierr);
1525   }
1526   PetscFunctionReturn(0);
1527 }
1528 
1529 /*MC
1530    PetscOptionsRealArray - Gets an array of double values for a particular
1531    option in the database. The values must be separated with commas with
1532    no intervening spaces.
1533 
1534    Logically Collective on the communicator passed in PetscOptionsBegin()
1535 
1536    Synopsis:
1537    #include "petscsys.h"
1538    PetscErrorCode PetscOptionsRealArray(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscReal value[],PetscInt *n,PetscBool  *set)
1539 
1540    Input Parameters:
1541 +  opt - the option one is seeking
1542 .  text - short string describing option
1543 .  man - manual page for option
1544 -  nmax - maximum number of values
1545 
1546    Output Parameter:
1547 +  value - location to copy values
1548 .  nmax - actual number of values found
1549 -  set - PETSC_TRUE if found, else PETSC_FALSE
1550 
1551    Level: beginner
1552 
1553    Notes:
1554    The user should pass in an array of doubles
1555 
1556    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1557 
1558 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1559            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1560           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1561           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1562           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1563           PetscOptionsFList(), PetscOptionsEList()
1564 M*/
1565 
1566 PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscReal value[],PetscInt *n,PetscBool  *set)
1567 {
1568   PetscErrorCode  ierr;
1569   PetscInt        i;
1570   PetscOptionItem amsopt;
1571 
1572   PetscFunctionBegin;
1573   if (!PetscOptionsObject->count) {
1574     PetscReal *vals;
1575 
1576     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_REAL_ARRAY,&amsopt);CHKERRQ(ierr);
1577     ierr = PetscMalloc((*n)*sizeof(PetscReal),&amsopt->data);CHKERRQ(ierr);
1578     vals = (PetscReal*)amsopt->data;
1579     for (i=0; i<*n; i++) vals[i] = value[i];
1580     amsopt->arraylength = *n;
1581   }
1582   ierr = PetscOptionsGetRealArray(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,n,set);CHKERRQ(ierr);
1583   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1584     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <%g",PetscOptionsObject->prefix?PetscOptionsObject->prefix:"",opt+1,(double)value[0]);CHKERRQ(ierr);
1585     for (i=1; i<*n; i++) {
1586       ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,",%g",(double)value[i]);CHKERRQ(ierr);
1587     }
1588     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,">: %s (%s)\n",text,ManSection(man));CHKERRQ(ierr);
1589   }
1590   PetscFunctionReturn(0);
1591 }
1592 
1593 /*MC
1594    PetscOptionsScalarArray - Gets an array of Scalar values for a particular
1595    option in the database. The values must be separated with commas with
1596    no intervening spaces.
1597 
1598    Logically Collective on the communicator passed in PetscOptionsBegin()
1599 
1600    Synopsis:
1601    #include "petscsys.h"
1602    PetscErrorCode PetscOptionsScalarArray(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscScalar value[],PetscInt *n,PetscBool  *set)
1603 
1604    Input Parameters:
1605 +  opt - the option one is seeking
1606 .  text - short string describing option
1607 .  man - manual page for option
1608 -  nmax - maximum number of values
1609 
1610    Output Parameter:
1611 +  value - location to copy values
1612 .  nmax - actual number of values found
1613 -  set - PETSC_TRUE if found, else PETSC_FALSE
1614 
1615    Level: beginner
1616 
1617    Notes:
1618    The user should pass in an array of doubles
1619 
1620    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1621 
1622 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1623           PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1624           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1625           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1626           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1627           PetscOptionsFList(), PetscOptionsEList()
1628 M*/
1629 
1630 PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscScalar value[],PetscInt *n,PetscBool  *set)
1631 {
1632   PetscErrorCode  ierr;
1633   PetscInt        i;
1634   PetscOptionItem amsopt;
1635 
1636   PetscFunctionBegin;
1637   if (!PetscOptionsObject->count) {
1638     PetscScalar *vals;
1639 
1640     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_SCALAR_ARRAY,&amsopt);CHKERRQ(ierr);
1641     ierr = PetscMalloc((*n)*sizeof(PetscScalar),&amsopt->data);CHKERRQ(ierr);
1642     vals = (PetscScalar*)amsopt->data;
1643     for (i=0; i<*n; i++) vals[i] = value[i];
1644     amsopt->arraylength = *n;
1645   }
1646   ierr = PetscOptionsGetScalarArray(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,n,set);CHKERRQ(ierr);
1647   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1648     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <%g+%gi",PetscOptionsObject->prefix?PetscOptionsObject->prefix:"",opt+1,(double)PetscRealPart(value[0]),(double)PetscImaginaryPart(value[0]));CHKERRQ(ierr);
1649     for (i=1; i<*n; i++) {
1650       ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,",%g+%gi",(double)PetscRealPart(value[i]),(double)PetscImaginaryPart(value[i]));CHKERRQ(ierr);
1651     }
1652     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,">: %s (%s)\n",text,ManSection(man));CHKERRQ(ierr);
1653   }
1654   PetscFunctionReturn(0);
1655 }
1656 
1657 /*MC
1658    PetscOptionsIntArray - Gets an array of integers for a particular
1659    option in the database.
1660 
1661    Logically Collective on the communicator passed in PetscOptionsBegin()
1662 
1663    Synopsis:
1664    #include "petscsys.h"
1665    PetscErrorCode PetscOptionsIntArray(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt value[],PetscInt *n,PetscBool  *set)
1666 
1667    Input Parameters:
1668 +  opt - the option one is seeking
1669 .  text - short string describing option
1670 .  man - manual page for option
1671 -  n - maximum number of values
1672 
1673    Output Parameter:
1674 +  value - location to copy values
1675 .  n - actual number of values found
1676 -  set - PETSC_TRUE if found, else PETSC_FALSE
1677 
1678    Level: beginner
1679 
1680    Notes:
1681    The array can be passed as
1682    a comma separated list:                                 0,1,2,3,4,5,6,7
1683    a range (start-end+1):                                  0-8
1684    a range with given increment (start-end+1:inc):         0-7:2
1685    a combination of values and ranges separated by commas: 0,1-8,8-15:2
1686 
1687    There must be no intervening spaces between the values.
1688 
1689    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1690 
1691 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1692            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1693           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1694           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1695           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1696           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsRealArray()
1697 M*/
1698 
1699 PetscErrorCode  PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt value[],PetscInt *n,PetscBool  *set)
1700 {
1701   PetscErrorCode ierr;
1702   PetscInt        i;
1703   PetscOptionItem amsopt;
1704 
1705   PetscFunctionBegin;
1706   if (!PetscOptionsObject->count) {
1707     PetscInt *vals;
1708 
1709     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_INT_ARRAY,&amsopt);CHKERRQ(ierr);
1710     ierr = PetscMalloc1(*n,(PetscInt**)&amsopt->data);CHKERRQ(ierr);
1711     vals = (PetscInt*)amsopt->data;
1712     for (i=0; i<*n; i++) vals[i] = value[i];
1713     amsopt->arraylength = *n;
1714   }
1715   ierr = PetscOptionsGetIntArray(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,n,set);CHKERRQ(ierr);
1716   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1717     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <%d",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,value[0]);CHKERRQ(ierr);
1718     for (i=1; i<*n; i++) {
1719       ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,",%d",value[i]);CHKERRQ(ierr);
1720     }
1721     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,">: %s (%s)\n",text,ManSection(man));CHKERRQ(ierr);
1722   }
1723   PetscFunctionReturn(0);
1724 }
1725 
1726 /*MC
1727    PetscOptionsStringArray - Gets an array of string values for a particular
1728    option in the database. The values must be separated with commas with
1729    no intervening spaces.
1730 
1731    Logically Collective on the communicator passed in PetscOptionsBegin()
1732 
1733    Synopsis:
1734    #include "petscsys.h"
1735    PetscErrorCode PetscOptionsStringArray(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],char *value[],PetscInt *nmax,PetscBool  *set)
1736 
1737    Input Parameters:
1738 +  opt - the option one is seeking
1739 .  text - short string describing option
1740 .  man - manual page for option
1741 -  nmax - maximum number of strings
1742 
1743    Output Parameter:
1744 +  value - location to copy strings
1745 .  nmax - actual number of strings found
1746 -  set - PETSC_TRUE if found, else PETSC_FALSE
1747 
1748    Level: beginner
1749 
1750    Notes:
1751    The user should pass in an array of pointers to char, to hold all the
1752    strings returned by this function.
1753 
1754    The user is responsible for deallocating the strings that are
1755    returned. The Fortran interface for this routine is not supported.
1756 
1757    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1758 
1759 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1760            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1761           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1762           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1763           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1764           PetscOptionsFList(), PetscOptionsEList()
1765 M*/
1766 
1767 PetscErrorCode  PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],char *value[],PetscInt *nmax,PetscBool  *set)
1768 {
1769   PetscErrorCode  ierr;
1770   PetscOptionItem amsopt;
1771 
1772   PetscFunctionBegin;
1773   if (!PetscOptionsObject->count) {
1774     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_STRING_ARRAY,&amsopt);CHKERRQ(ierr);
1775     ierr = PetscMalloc1(*nmax,(char**)&amsopt->data);CHKERRQ(ierr);
1776 
1777     amsopt->arraylength = *nmax;
1778   }
1779   ierr = PetscOptionsGetStringArray(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,nmax,set);CHKERRQ(ierr);
1780   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1781     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <string1,string2,...>: %s (%s)\n",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,text,ManSection(man));CHKERRQ(ierr);
1782   }
1783   PetscFunctionReturn(0);
1784 }
1785 
1786 /*MC
1787    PetscOptionsBoolArray - Gets an array of logical values (true or false) for a particular
1788    option in the database. The values must be separated with commas with
1789    no intervening spaces.
1790 
1791    Logically Collective on the communicator passed in PetscOptionsBegin()
1792 
1793    Synopsis:
1794    #include "petscsys.h"
1795    PetscErrorCode PetscOptionsBoolArray(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool value[],PetscInt *n,PetscBool *set)
1796 
1797    Input Parameters:
1798 +  opt - the option one is seeking
1799 .  text - short string describing option
1800 .  man - manual page for option
1801 -  nmax - maximum number of values
1802 
1803    Output Parameter:
1804 +  value - location to copy values
1805 .  nmax - actual number of values found
1806 -  set - PETSC_TRUE if found, else PETSC_FALSE
1807 
1808    Level: beginner
1809 
1810    Notes:
1811    The user should pass in an array of doubles
1812 
1813    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1814 
1815 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1816            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1817           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1818           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1819           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1820           PetscOptionsFList(), PetscOptionsEList()
1821 M*/
1822 
1823 PetscErrorCode  PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool value[],PetscInt *n,PetscBool *set)
1824 {
1825   PetscErrorCode   ierr;
1826   PetscInt         i;
1827   PetscOptionItem  amsopt;
1828 
1829   PetscFunctionBegin;
1830   if (!PetscOptionsObject->count) {
1831     PetscBool *vals;
1832 
1833     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_BOOL_ARRAY,&amsopt);CHKERRQ(ierr);
1834     ierr = PetscMalloc1(*n,(PetscBool**)&amsopt->data);CHKERRQ(ierr);
1835     vals = (PetscBool*)amsopt->data;
1836     for (i=0; i<*n; i++) vals[i] = value[i];
1837     amsopt->arraylength = *n;
1838   }
1839   ierr = PetscOptionsGetBoolArray(PetscOptionsObject->options,PetscOptionsObject->prefix,opt,value,n,set);CHKERRQ(ierr);
1840   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1841     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <%d",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,value[0]);CHKERRQ(ierr);
1842     for (i=1; i<*n; i++) {
1843       ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,",%d",value[i]);CHKERRQ(ierr);
1844     }
1845     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,">: %s (%s)\n",text,ManSection(man));CHKERRQ(ierr);
1846   }
1847   PetscFunctionReturn(0);
1848 }
1849 
1850 /*MC
1851    PetscOptionsViewer - Gets a viewer appropriate for the type indicated by the user
1852 
1853    Logically Collective on the communicator passed in PetscOptionsBegin()
1854 
1855    Synopsis:
1856    #include "petscsys.h"
1857    PetscErrorCode PetscOptionsViewer(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool  *set)
1858 
1859    Input Parameters:
1860 +  opt - option name
1861 .  text - short string that describes the option
1862 -  man - manual page with additional information on option
1863 
1864    Output Parameter:
1865 +  viewer - the viewer
1866 -  set - PETSC_TRUE if found, else PETSC_FALSE
1867 
1868    Level: beginner
1869 
1870    Notes:
1871     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1872 
1873    See PetscOptionsGetViewer() for the format of the supplied viewer and its options
1874 
1875 .seealso: PetscOptionsGetViewer(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1876           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1877           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1878           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1879           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1880           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1881           PetscOptionsFList(), PetscOptionsEList()
1882 M*/
1883 
1884 PetscErrorCode  PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject,const char opt[],const char text[],const char man[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool  *set)
1885 {
1886   PetscErrorCode  ierr;
1887   PetscOptionItem amsopt;
1888 
1889   PetscFunctionBegin;
1890   if (!PetscOptionsObject->count) {
1891     ierr = PetscOptionItemCreate_Private(PetscOptionsObject,opt,text,man,OPTION_STRING,&amsopt);CHKERRQ(ierr);
1892     /* must use system malloc since SAWs may free this */
1893     ierr = PetscStrdup("",(char**)&amsopt->data);CHKERRQ(ierr);
1894   }
1895   ierr = PetscOptionsGetViewer(PetscOptionsObject->comm,PetscOptionsObject->options,PetscOptionsObject->prefix,opt,viewer,format,set);CHKERRQ(ierr);
1896   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1897     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  -%s%s <%s>: %s (%s)\n",PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "",opt+1,"",text,ManSection(man));CHKERRQ(ierr);
1898   }
1899   PetscFunctionReturn(0);
1900 }
1901 
1902 /*@C
1903      PetscOptionsHead - Puts a heading before listing any more published options. Used, for example,
1904             in KSPSetFromOptions_GMRES().
1905 
1906    Logically Collective on the communicator passed in PetscOptionsBegin()
1907 
1908    Input Parameter:
1909 .   head - the heading text
1910 
1911 
1912    Level: intermediate
1913 
1914    Notes:
1915     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1916 
1917           Can be followed by a call to PetscOptionsTail() in the same function.
1918 
1919 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1920            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1921           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1922           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1923           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1924           PetscOptionsFList(), PetscOptionsEList()
1925 @*/
1926 PetscErrorCode  PetscOptionsHead(PetscOptionItems *PetscOptionsObject,const char head[])
1927 {
1928   PetscErrorCode ierr;
1929 
1930   PetscFunctionBegin;
1931   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1932     ierr = (*PetscHelpPrintf)(PetscOptionsObject->comm,"  %s\n",head);CHKERRQ(ierr);
1933   }
1934   PetscFunctionReturn(0);
1935 }
1936 
1937 
1938 
1939 
1940 
1941 
1942