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