xref: /petsc/src/sys/objects/aoptions.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795)
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 Notes:
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 scalar 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    Notes:
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: This cannot check for invalid selection because of things like MATAIJ that are not included in the list
1131 
1132 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1133           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1134           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1135           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1136           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1137           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsEnum()`
1138 M*/
1139 
1140 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) {
1141   PetscOptionItem amsopt;
1142   PetscBool       lset;
1143 
1144   PetscFunctionBegin;
1145   if (!PetscOptionsObject->count) {
1146     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt));
1147     /* must use system malloc since SAWs may free this */
1148     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
1149     amsopt->flist = list;
1150   }
1151   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, len, &lset));
1152   if (set) *set = lset;
1153   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1154     PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, PetscOptionsObject->prefix, opt, ltext, man, list, currentvalue, lset && value ? value : currentvalue));
1155   }
1156   PetscFunctionReturn(0);
1157 }
1158 
1159 /*MC
1160      PetscOptionsEList - Puts a list of option values that a single one may be selected from
1161 
1162    Logically Collective on the communicator passed in PetscOptionsBegin()
1163 
1164    Synopsis:
1165    #include "petscsys.h"
1166    PetscErrorCode  PetscOptionsEList(const char opt[],const char ltext[],const char man[],const char *const *list,PetscInt ntext,const char currentvalue[],PetscInt *value,PetscBool  *set)
1167 
1168    Input Parameters:
1169 +  opt - option name
1170 .  ltext - short string that describes the option
1171 .  man - manual page with additional information on option
1172 .  list - the possible choices (one of these must be selected, anything else is invalid)
1173 .  ntext - number of choices
1174 -  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with
1175 $                 PetscOptionsElist(..., obj->value,&value,&flg);
1176 $                 if (flg) {
1177 
1178    Output Parameters:
1179 +  value - the index of the value to return
1180 -  set - PETSC_TRUE if found, else PETSC_FALSE
1181 
1182    Level: intermediate
1183 
1184    Notes:
1185     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1186 
1187          If the user does not supply the option at all value is NOT changed. Thus
1188           you should ALWAYS initialize value if you access it without first checking if the set flag is true.
1189 
1190    See PetscOptionsFList() for when the choices are given in a PetscFunctionList()
1191 
1192 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1193           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1194           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1195           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1196           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1197           `PetscOptionsFList()`, `PetscOptionsEnum()`
1198 M*/
1199 
1200 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) {
1201   PetscInt        i;
1202   PetscOptionItem amsopt;
1203   PetscBool       lset;
1204 
1205   PetscFunctionBegin;
1206   if (!PetscOptionsObject->count) {
1207     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt));
1208     /* must use system malloc since SAWs may free this */
1209     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
1210     PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list));
1211     amsopt->nlist = ntext;
1212   }
1213   PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, list, ntext, value, &lset));
1214   if (set) *set = lset;
1215   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1216     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));
1217     for (i = 0; i < ntext; i++) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " %s", list[i]));
1218     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " (%s)\n", ManSection(man)));
1219   }
1220   PetscFunctionReturn(0);
1221 }
1222 
1223 /*MC
1224      PetscOptionsBoolGroupBegin - First in a series of logical queries on the options database for
1225        which at most a single value can be true.
1226 
1227    Logically Collective on the communicator passed in PetscOptionsBegin()
1228 
1229    Synopsis:
1230    #include "petscsys.h"
1231    PetscErrorCode PetscOptionsBoolGroupBegin(const char opt[],const char text[],const char man[],PetscBool  *flg)
1232 
1233    Input Parameters:
1234 +  opt - option name
1235 .  text - short string that describes the option
1236 -  man - manual page with additional information on option
1237 
1238    Output Parameter:
1239 .  flg - whether that option was set or not
1240 
1241    Level: intermediate
1242 
1243    Notes:
1244     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1245 
1246    Must be followed by 0 or more PetscOptionsBoolGroup()s and PetscOptionsBoolGroupEnd()
1247 
1248 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1249           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1250           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1251           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1252           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1253           `PetscOptionsFList()`, `PetscOptionsEList()`
1254 M*/
1255 
1256 PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) {
1257   PetscOptionItem amsopt;
1258 
1259   PetscFunctionBegin;
1260   if (!PetscOptionsObject->count) {
1261     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1262     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
1263 
1264     *(PetscBool *)amsopt->data = PETSC_FALSE;
1265   }
1266   *flg = PETSC_FALSE;
1267   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, flg, NULL));
1268   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1269     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  Pick at most one of -------------\n"));
1270     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, text, ManSection(man)));
1271   }
1272   PetscFunctionReturn(0);
1273 }
1274 
1275 /*MC
1276      PetscOptionsBoolGroup - One in a series of logical queries on the options database for
1277        which at most a single value can be true.
1278 
1279    Logically Collective on the communicator passed in PetscOptionsBegin()
1280 
1281    Synopsis:
1282    #include "petscsys.h"
1283    PetscErrorCode PetscOptionsBoolGroup(const char opt[],const char text[],const char man[],PetscBool  *flg)
1284 
1285    Input Parameters:
1286 +  opt - option name
1287 .  text - short string that describes the option
1288 -  man - manual page with additional information on option
1289 
1290    Output Parameter:
1291 .  flg - PETSC_TRUE if found, else PETSC_FALSE
1292 
1293    Level: intermediate
1294 
1295    Notes:
1296     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1297 
1298    Must follow a PetscOptionsBoolGroupBegin() and preceded a PetscOptionsBoolGroupEnd()
1299 
1300 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1301           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1302           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1303           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1304           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1305           `PetscOptionsFList()`, `PetscOptionsEList()`
1306 M*/
1307 
1308 PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) {
1309   PetscOptionItem amsopt;
1310 
1311   PetscFunctionBegin;
1312   if (!PetscOptionsObject->count) {
1313     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1314     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
1315 
1316     *(PetscBool *)amsopt->data = PETSC_FALSE;
1317   }
1318   *flg = PETSC_FALSE;
1319   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, flg, NULL));
1320   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1321     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, text, ManSection(man)));
1322   }
1323   PetscFunctionReturn(0);
1324 }
1325 
1326 /*MC
1327      PetscOptionsBoolGroupEnd - Last in a series of logical queries on the options database for
1328        which at most a single value can be true.
1329 
1330    Logically Collective on the communicator passed in PetscOptionsBegin()
1331 
1332    Synopsis:
1333    #include "petscsys.h"
1334    PetscErrorCode PetscOptionsBoolGroupEnd(const char opt[],const char text[],const char man[],PetscBool  *flg)
1335 
1336    Input Parameters:
1337 +  opt - option name
1338 .  text - short string that describes the option
1339 -  man - manual page with additional information on option
1340 
1341    Output Parameter:
1342 .  flg - PETSC_TRUE if found, else PETSC_FALSE
1343 
1344    Level: intermediate
1345 
1346    Notes:
1347     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1348 
1349    Must follow a PetscOptionsBoolGroupBegin()
1350 
1351 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1352           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1353           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1354           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1355           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1356           `PetscOptionsFList()`, `PetscOptionsEList()`
1357 M*/
1358 
1359 PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) {
1360   PetscOptionItem amsopt;
1361 
1362   PetscFunctionBegin;
1363   if (!PetscOptionsObject->count) {
1364     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1365     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
1366 
1367     *(PetscBool *)amsopt->data = PETSC_FALSE;
1368   }
1369   *flg = PETSC_FALSE;
1370   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, flg, NULL));
1371   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1372     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, text, ManSection(man)));
1373   }
1374   PetscFunctionReturn(0);
1375 }
1376 
1377 /*MC
1378    PetscOptionsBool - Determines if a particular option is in the database with a true or false
1379 
1380    Logically Collective on the communicator passed in PetscOptionsBegin()
1381 
1382    Synopsis:
1383    #include "petscsys.h"
1384    PetscErrorCode PetscOptionsBool(const char opt[],const char text[],const char man[],PetscBool currentvalue,PetscBool  *flg,PetscBool  *set)
1385 
1386    Input Parameters:
1387 +  opt - option name
1388 .  text - short string that describes the option
1389 .  man - manual page with additional information on option
1390 -  currentvalue - the current value
1391 
1392    Output Parameters:
1393 +  flg - PETSC_TRUE or PETSC_FALSE
1394 -  set - PETSC_TRUE if found, else PETSC_FALSE
1395 
1396    Notes:
1397        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1398        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
1399 
1400       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
1401      is equivalent to -requested_bool true
1402 
1403        If the user does not supply the option at all flg is NOT changed. Thus
1404      you should ALWAYS initialize the flg if you access it without first checking if the set flag is true.
1405 
1406     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1407 
1408    Level: beginner
1409 
1410 .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1411           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
1412           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1413           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1414           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1415           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1416           `PetscOptionsFList()`, `PetscOptionsEList()`
1417 M*/
1418 
1419 PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set) {
1420   PetscBool       iset;
1421   PetscOptionItem amsopt;
1422 
1423   PetscFunctionBegin;
1424   if (!PetscOptionsObject->count) {
1425     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1426     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
1427 
1428     *(PetscBool *)amsopt->data = currentvalue;
1429   }
1430   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, flg, &iset));
1431   if (set) *set = iset;
1432   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1433     const char *v = PetscBools[currentvalue], *vn = PetscBools[iset && flg ? *flg : currentvalue];
1434     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <%s : %s> %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, v, vn, text, ManSection(man)));
1435   }
1436   PetscFunctionReturn(0);
1437 }
1438 
1439 /*MC
1440    PetscOptionsRealArray - Gets an array of double values for a particular
1441    option in the database. The values must be separated with commas with
1442    no intervening spaces.
1443 
1444    Logically Collective on the communicator passed in PetscOptionsBegin()
1445 
1446    Synopsis:
1447    #include "petscsys.h"
1448    PetscErrorCode PetscOptionsRealArray(const char opt[],const char text[],const char man[],PetscReal value[],PetscInt *n,PetscBool  *set)
1449 
1450    Input Parameters:
1451 +  opt - the option one is seeking
1452 .  text - short string describing option
1453 .  man - manual page for option
1454 -  n - maximum number of values that value has room for
1455 
1456    Output Parameters:
1457 +  value - location to copy values
1458 .  n - actual number of values found
1459 -  set - PETSC_TRUE if found, else PETSC_FALSE
1460 
1461    Level: beginner
1462 
1463    Notes:
1464    The user should pass in an array of doubles
1465 
1466    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1467 
1468 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1469           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1470           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1471           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1472           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1473           `PetscOptionsFList()`, `PetscOptionsEList()`
1474 M*/
1475 
1476 PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set) {
1477   PetscInt        i;
1478   PetscOptionItem amsopt;
1479 
1480   PetscFunctionBegin;
1481   if (!PetscOptionsObject->count) {
1482     PetscReal *vals;
1483 
1484     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt));
1485     PetscCall(PetscMalloc((*n) * sizeof(PetscReal), &amsopt->data));
1486     vals = (PetscReal *)amsopt->data;
1487     for (i = 0; i < *n; i++) vals[i] = value[i];
1488     amsopt->arraylength = *n;
1489   }
1490   PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, n, set));
1491   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1492     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%g", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, (double)value[0]));
1493     for (i = 1; i < *n; i++) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, ",%g", (double)value[i]));
1494     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, ">: %s (%s)\n", text, ManSection(man)));
1495   }
1496   PetscFunctionReturn(0);
1497 }
1498 
1499 /*MC
1500    PetscOptionsScalarArray - Gets an array of Scalar values for a particular
1501    option in the database. The values must be separated with commas with
1502    no intervening spaces.
1503 
1504    Logically Collective on the communicator passed in PetscOptionsBegin()
1505 
1506    Synopsis:
1507    #include "petscsys.h"
1508    PetscErrorCode PetscOptionsScalarArray(const char opt[],const char text[],const char man[],PetscScalar value[],PetscInt *n,PetscBool  *set)
1509 
1510    Input Parameters:
1511 +  opt - the option one is seeking
1512 .  text - short string describing option
1513 .  man - manual page for option
1514 -  n - maximum number of values allowed in the value array
1515 
1516    Output Parameters:
1517 +  value - location to copy values
1518 .  n - actual number of values found
1519 -  set - PETSC_TRUE if found, else PETSC_FALSE
1520 
1521    Level: beginner
1522 
1523    Notes:
1524    The user should pass in an array of doubles
1525 
1526    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1527 
1528 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1529           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1530           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1531           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1532           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1533           `PetscOptionsFList()`, `PetscOptionsEList()`
1534 M*/
1535 
1536 PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set) {
1537   PetscInt        i;
1538   PetscOptionItem amsopt;
1539 
1540   PetscFunctionBegin;
1541   if (!PetscOptionsObject->count) {
1542     PetscScalar *vals;
1543 
1544     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt));
1545     PetscCall(PetscMalloc((*n) * sizeof(PetscScalar), &amsopt->data));
1546     vals = (PetscScalar *)amsopt->data;
1547     for (i = 0; i < *n; i++) vals[i] = value[i];
1548     amsopt->arraylength = *n;
1549   }
1550   PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, n, set));
1551   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1552     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%g+%gi", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0])));
1553     for (i = 1; i < *n; i++) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i])));
1554     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, ">: %s (%s)\n", text, ManSection(man)));
1555   }
1556   PetscFunctionReturn(0);
1557 }
1558 
1559 /*MC
1560    PetscOptionsIntArray - Gets an array of integers for a particular
1561    option in the database.
1562 
1563    Logically Collective on the communicator passed in PetscOptionsBegin()
1564 
1565    Synopsis:
1566    #include "petscsys.h"
1567    PetscErrorCode PetscOptionsIntArray(const char opt[],const char text[],const char man[],PetscInt value[],PetscInt *n,PetscBool  *set)
1568 
1569    Input Parameters:
1570 +  opt - the option one is seeking
1571 .  text - short string describing option
1572 .  man - manual page for option
1573 -  n - maximum number of values
1574 
1575    Output Parameters:
1576 +  value - location to copy values
1577 .  n - actual number of values found
1578 -  set - PETSC_TRUE if found, else PETSC_FALSE
1579 
1580    Level: beginner
1581 
1582    Notes:
1583    The array can be passed as
1584    a comma separated list:                                 0,1,2,3,4,5,6,7
1585    a range (start-end+1):                                  0-8
1586    a range with given increment (start-end+1:inc):         0-7:2
1587    a combination of values and ranges separated by commas: 0,1-8,8-15:2
1588 
1589    There must be no intervening spaces between the values.
1590 
1591    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1592 
1593 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1594           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1595           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1596           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1597           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1598           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsRealArray()`
1599 M*/
1600 
1601 PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set) {
1602   PetscInt        i;
1603   PetscOptionItem amsopt;
1604 
1605   PetscFunctionBegin;
1606   if (!PetscOptionsObject->count) {
1607     PetscInt *vals;
1608 
1609     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt));
1610     PetscCall(PetscMalloc1(*n, (PetscInt **)&amsopt->data));
1611     vals = (PetscInt *)amsopt->data;
1612     for (i = 0; i < *n; i++) vals[i] = value[i];
1613     amsopt->arraylength = *n;
1614   }
1615   PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, n, set));
1616   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1617     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%" PetscInt_FMT, PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, value[0]));
1618     for (i = 1; i < *n; i++) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, ",%" PetscInt_FMT, value[i]));
1619     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, ">: %s (%s)\n", text, ManSection(man)));
1620   }
1621   PetscFunctionReturn(0);
1622 }
1623 
1624 /*MC
1625    PetscOptionsStringArray - Gets an array of string values for a particular
1626    option in the database. The values must be separated with commas with
1627    no intervening spaces.
1628 
1629    Logically Collective on the communicator passed in PetscOptionsBegin()
1630 
1631    Synopsis:
1632    #include "petscsys.h"
1633    PetscErrorCode PetscOptionsStringArray(const char opt[],const char text[],const char man[],char *value[],PetscInt *nmax,PetscBool  *set)
1634 
1635    Input Parameters:
1636 +  opt - the option one is seeking
1637 .  text - short string describing option
1638 .  man - manual page for option
1639 -  nmax - maximum number of strings
1640 
1641    Output Parameters:
1642 +  value - location to copy strings
1643 .  nmax - actual number of strings found
1644 -  set - PETSC_TRUE if found, else PETSC_FALSE
1645 
1646    Level: beginner
1647 
1648    Notes:
1649    The user should pass in an array of pointers to char, to hold all the
1650    strings returned by this function.
1651 
1652    The user is responsible for deallocating the strings that are
1653    returned. The Fortran interface for this routine is not supported.
1654 
1655    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1656 
1657 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1658           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1659           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1660           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1661           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1662           `PetscOptionsFList()`, `PetscOptionsEList()`
1663 M*/
1664 
1665 PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set) {
1666   PetscOptionItem amsopt;
1667 
1668   PetscFunctionBegin;
1669   if (!PetscOptionsObject->count) {
1670     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt));
1671     PetscCall(PetscMalloc1(*nmax, (char **)&amsopt->data));
1672 
1673     amsopt->arraylength = *nmax;
1674   }
1675   PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, nmax, set));
1676   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1677     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <string1,string2,...>: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, text, ManSection(man)));
1678   }
1679   PetscFunctionReturn(0);
1680 }
1681 
1682 /*MC
1683    PetscOptionsBoolArray - Gets an array of logical values (true or false) for a particular
1684    option in the database. The values must be separated with commas with
1685    no intervening spaces.
1686 
1687    Logically Collective on the communicator passed in PetscOptionsBegin()
1688 
1689    Synopsis:
1690    #include "petscsys.h"
1691    PetscErrorCode PetscOptionsBoolArray(const char opt[],const char text[],const char man[],PetscBool value[],PetscInt *n,PetscBool *set)
1692 
1693    Input Parameters:
1694 +  opt - the option one is seeking
1695 .  text - short string describing option
1696 .  man - manual page for option
1697 -  n - maximum number of values allowed in the value array
1698 
1699    Output Parameters:
1700 +  value - location to copy values
1701 .  n - actual number of values found
1702 -  set - PETSC_TRUE if found, else PETSC_FALSE
1703 
1704    Level: beginner
1705 
1706    Notes:
1707    The user should pass in an array of doubles
1708 
1709    Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1710 
1711 .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1712           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1713           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1714           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1715           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1716           `PetscOptionsFList()`, `PetscOptionsEList()`
1717 M*/
1718 
1719 PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set) {
1720   PetscInt        i;
1721   PetscOptionItem amsopt;
1722 
1723   PetscFunctionBegin;
1724   if (!PetscOptionsObject->count) {
1725     PetscBool *vals;
1726 
1727     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt));
1728     PetscCall(PetscMalloc1(*n, (PetscBool **)&amsopt->data));
1729     vals = (PetscBool *)amsopt->data;
1730     for (i = 0; i < *n; i++) vals[i] = value[i];
1731     amsopt->arraylength = *n;
1732   }
1733   PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, n, set));
1734   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1735     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%d", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, value[0]));
1736     for (i = 1; i < *n; i++) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, ",%d", value[i]));
1737     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, ">: %s (%s)\n", text, ManSection(man)));
1738   }
1739   PetscFunctionReturn(0);
1740 }
1741 
1742 /*MC
1743    PetscOptionsViewer - Gets a viewer appropriate for the type indicated by the user
1744 
1745    Logically Collective on the communicator passed in PetscOptionsBegin()
1746 
1747    Synopsis:
1748    #include "petscsys.h"
1749    PetscErrorCode PetscOptionsViewer(const char opt[],const char text[],const char man[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool *set)
1750 
1751    Input Parameters:
1752 +  opt - option name
1753 .  text - short string that describes the option
1754 -  man - manual page with additional information on option
1755 
1756    Output Parameters:
1757 +  viewer - the viewer
1758 .  format - the PetscViewerFormat requested by the user, pass NULL if not needed
1759 -  set - PETSC_TRUE if found, else PETSC_FALSE
1760 
1761    Level: beginner
1762 
1763    Notes:
1764     Must be between a PetscOptionsBegin() and a PetscOptionsEnd()
1765 
1766    See PetscOptionsGetViewer() for the format of the supplied viewer and its options
1767 
1768 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1769           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
1770           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
1771           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1772           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1773           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1774           `PetscOptionsFList()`, `PetscOptionsEList()`
1775 M*/
1776 
1777 PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set) {
1778   PetscOptionItem amsopt;
1779 
1780   PetscFunctionBegin;
1781   if (!PetscOptionsObject->count) {
1782     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
1783     /* must use system malloc since SAWs may free this */
1784     PetscCall(PetscStrdup("", (char **)&amsopt->data));
1785   }
1786   PetscCall(PetscOptionsGetViewer(PetscOptionsObject->comm, PetscOptionsObject->options, PetscOptionsObject->prefix, opt, viewer, format, set));
1787   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1788     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%s>: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, "", text, ManSection(man)));
1789   }
1790   PetscFunctionReturn(0);
1791 }
1792