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