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