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
ManSection(const char * str)10 static const char *ManSection(const char *str)
11 {
12 return str ? str : "None";
13 }
14
Prefix(const char * str)15 static const char *Prefix(const char *str)
16 {
17 return str ? str : "";
18 }
19
ShouldPrintHelp(const PetscOptionItems opts)20 static int ShouldPrintHelp(const PetscOptionItems opts)
21 {
22 return opts->printhelp && opts->count == 1 && !opts->alreadyprinted;
23 }
24
25 /*
26 Keep a linked list of options that have been posted and we are waiting for
27 user selection. See the manual page for PetscOptionsBegin()
28
29 Eventually we'll attach this beast to a MPI_Comm
30 */
31
32 /*
33 Handles setting up the data structure in a call to PetscOptionsBegin()
34 */
PetscOptionsBegin_Private(PetscOptionItems PetscOptionsObject,MPI_Comm comm,const char prefix[],const char title[],const char mansec[])35 PetscErrorCode PetscOptionsBegin_Private(PetscOptionItems PetscOptionsObject, MPI_Comm comm, const char prefix[], const char title[], const char mansec[])
36 {
37 PetscFunctionBegin;
38 if (prefix) PetscAssertPointer(prefix, 3);
39 PetscAssertPointer(title, 4);
40 if (mansec) PetscAssertPointer(mansec, 5);
41 if (!PetscOptionsObject->alreadyprinted) {
42 if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
43 PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, prefix, title, &PetscOptionsObject->alreadyprinted));
44 }
45 PetscOptionsObject->next = NULL;
46 PetscOptionsObject->comm = comm;
47 PetscOptionsObject->changedmethod = PETSC_FALSE;
48
49 PetscCall(PetscStrallocpy(prefix, &PetscOptionsObject->prefix));
50 PetscCall(PetscStrallocpy(title, &PetscOptionsObject->title));
51
52 PetscCall(PetscOptionsHasHelp(PetscOptionsObject->options, &PetscOptionsObject->printhelp));
53 if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\n%s:\n", title));
54 PetscFunctionReturn(PETSC_SUCCESS);
55 }
56
57 /*
58 Handles setting up the data structure in a call to PetscObjectOptionsBegin()
59 */
PetscObjectOptionsBegin_Private(PetscObject obj,PetscOptionItems PetscOptionsObject)60 PetscErrorCode PetscObjectOptionsBegin_Private(PetscObject obj, PetscOptionItems PetscOptionsObject)
61 {
62 char title[256];
63 PetscBool flg;
64
65 PetscFunctionBegin;
66 PetscAssertPointer(PetscOptionsObject, 2);
67 PetscValidHeader(obj, 1);
68 PetscOptionsObject->object = obj;
69 PetscOptionsObject->alreadyprinted = obj->optionsprinted;
70
71 PetscCall(PetscStrcmp(obj->description, obj->class_name, &flg));
72 if (flg) PetscCall(PetscSNPrintf(title, sizeof(title), "%s options", obj->class_name));
73 else PetscCall(PetscSNPrintf(title, sizeof(title), "%s (%s) options", obj->description, obj->class_name));
74 PetscCall(PetscOptionsBegin_Private(PetscOptionsObject, obj->comm, obj->prefix, title, obj->mansec));
75 PetscFunctionReturn(PETSC_SUCCESS);
76 }
77
78 /*
79 Handles adding another option to the list of options within this particular PetscOptionsBegin() PetscOptionsEnd()
80 */
PetscOptionItemCreate_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscOptionType t,PetscOptionItem * amsopt)81 static PetscErrorCode PetscOptionItemCreate_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscOptionType t, PetscOptionItem *amsopt)
82 {
83 PetscBool valid;
84
85 PetscFunctionBegin;
86 PetscCall(PetscOptionsValidKey(opt, &valid));
87 PetscCheck(valid, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "The option '%s' is not a valid key", opt);
88
89 PetscCall(PetscNew(amsopt));
90 (*amsopt)->next = NULL;
91 (*amsopt)->set = PETSC_FALSE;
92 (*amsopt)->type = t;
93 (*amsopt)->data = NULL;
94
95 PetscCall(PetscStrallocpy(text, &(*amsopt)->text));
96 PetscCall(PetscStrallocpy(opt, &(*amsopt)->option));
97 PetscCall(PetscStrallocpy(man, &(*amsopt)->man));
98
99 {
100 PetscOptionItem cur = PetscOptionsObject->next;
101
102 while (cur->next) cur = cur->next;
103 cur->next = *amsopt;
104 }
105 PetscFunctionReturn(PETSC_SUCCESS);
106 }
107
108 /*
109 This is needed because certain strings may be freed by SAWs, hence we cannot use PetscStrallocpy()
110 */
PetscStrdup(const char s[],char * t[])111 static PetscErrorCode PetscStrdup(const char s[], char *t[])
112 {
113 char *tmp = NULL;
114
115 PetscFunctionBegin;
116 if (s) {
117 size_t len;
118
119 PetscCall(PetscStrlen(s, &len));
120 tmp = (char *)malloc((len + 1) * sizeof(*tmp));
121 PetscCheck(tmp, PETSC_COMM_SELF, PETSC_ERR_MEM, "No memory to duplicate string");
122 PetscCall(PetscArraycpy(tmp, s, len + 1));
123 }
124 *t = tmp;
125 PetscFunctionReturn(PETSC_SUCCESS);
126 }
127
128 #if defined(PETSC_HAVE_SAWS)
129 #include <petscviewersaws.h>
130
131 static int count = 0;
132
133 static const char *OptionsHeader = "<head>\n"
134 "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/jquery-1.9.1.js\"></script>\n"
135 "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/SAWs.js\"></script>\n"
136 "<script type=\"text/javascript\" src=\"js/PETSc.js\"></script>\n"
137 "<script>\n"
138 "jQuery(document).ready(function() {\n"
139 "PETSc.getAndDisplayDirectory(null,\"#variablesInfo\")\n"
140 "})\n"
141 "</script>\n"
142 "</head>\n";
143
144 /* Determines the size and style of the scroll region where PETSc options selectable from users are displayed */
145 static const char *OptionsBodyBottom = "<div id=\"variablesInfo\" style=\"background-color:lightblue;height:auto;max-height:500px;overflow:scroll;\"></div>\n<br>\n</body>";
146
147 /*
148 PetscOptionsSAWsInput - Presents all the PETSc Options processed by the program so the user may change them at runtime using the SAWs
149
150 Bugs:
151 + All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
152 . Internal strings have arbitrary length and string copies are not checked that they fit into string space
153 - Only works for PetscInt == int, PetscReal == double etc
154
155 */
PetscOptionsSAWsInput(PetscOptionItems PetscOptionsObject)156 static PetscErrorCode PetscOptionsSAWsInput(PetscOptionItems PetscOptionsObject)
157 {
158 PetscOptionItem next = PetscOptionsObject->next;
159 static int mancount = 0;
160 char options[16];
161 PetscBool changedmethod = PETSC_FALSE;
162 PetscBool stopasking = PETSC_FALSE;
163 char manname[16], textname[16];
164 char dir[1024];
165
166 PetscFunctionBegin;
167 /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */
168 PetscCall(PetscSNPrintf(options, PETSC_STATIC_ARRAY_LENGTH(options), "Options_%d", count++));
169
170 PetscOptionsObject->pprefix = PetscOptionsObject->prefix; /* SAWs will change this, so cannot pass prefix directly */
171
172 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "_title"));
173 PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->title, 1, SAWs_READ, SAWs_STRING));
174 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "prefix"));
175 PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->pprefix, 1, SAWs_READ, SAWs_STRING));
176 PetscCallSAWs(SAWs_Register, ("/PETSc/Options/ChangedMethod", &changedmethod, 1, SAWs_WRITE, SAWs_BOOLEAN));
177 PetscCallSAWs(SAWs_Register, ("/PETSc/Options/StopAsking", &stopasking, 1, SAWs_WRITE, SAWs_BOOLEAN));
178
179 while (next) {
180 PetscCall(PetscSNPrintf(manname, PETSC_STATIC_ARRAY_LENGTH(manname), "_man_%d", mancount));
181 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", manname));
182 PetscCallSAWs(SAWs_Register, (dir, &next->man, 1, SAWs_READ, SAWs_STRING));
183 PetscCall(PetscSNPrintf(textname, PETSC_STATIC_ARRAY_LENGTH(textname), "_text_%d", mancount++));
184 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", textname));
185 PetscCallSAWs(SAWs_Register, (dir, &next->text, 1, SAWs_READ, SAWs_STRING));
186
187 switch (next->type) {
188 case OPTION_HEAD:
189 break;
190 case OPTION_INT_ARRAY:
191 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
192 PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_INT));
193 break;
194 case OPTION_REAL_ARRAY:
195 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
196 PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_DOUBLE));
197 break;
198 case OPTION_INT:
199 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
200 PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_INT));
201 break;
202 case OPTION_REAL:
203 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
204 PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_DOUBLE));
205 break;
206 case OPTION_BOOL:
207 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
208 PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_BOOLEAN));
209 break;
210 case OPTION_BOOL_ARRAY:
211 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
212 PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_BOOLEAN));
213 break;
214 case OPTION_STRING:
215 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
216 PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
217 break;
218 case OPTION_STRING_ARRAY:
219 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
220 PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_STRING));
221 break;
222 case OPTION_FLIST: {
223 PetscInt ntext;
224 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
225 PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
226 PetscCall(PetscFunctionListGet(next->flist, (const char ***)&next->edata, &ntext));
227 PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
228 } break;
229 case OPTION_ELIST: {
230 PetscInt ntext = next->nlist;
231 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
232 PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
233 PetscCall(PetscMalloc1(ntext + 1, (char ***)&next->edata));
234 PetscCall(PetscMemcpy(next->edata, next->list, ntext * sizeof(char *)));
235 PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
236 } break;
237 default:
238 break;
239 }
240 next = next->next;
241 }
242
243 /* wait until accessor has unlocked the memory */
244 PetscCallSAWs(SAWs_Push_Header, ("index.html", OptionsHeader));
245 PetscCallSAWs(SAWs_Push_Body, ("index.html", 2, OptionsBodyBottom));
246 PetscCall(PetscSAWsBlock());
247 PetscCallSAWs(SAWs_Pop_Header, ("index.html"));
248 PetscCallSAWs(SAWs_Pop_Body, ("index.html", 2));
249
250 /* determine if any values have been set in GUI */
251 next = PetscOptionsObject->next;
252 while (next) {
253 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
254 PetscCallSAWs(SAWs_Selected, (dir, (int *)&next->set));
255 next = next->next;
256 }
257
258 /* reset counter to -2; this updates the screen with the new options for the selected method */
259 if (changedmethod) PetscOptionsObject->count = -2;
260
261 if (stopasking) {
262 PetscOptionsPublish = PETSC_FALSE;
263 PetscOptionsObject->count = 0; //do not ask for same thing again
264 }
265
266 PetscCallSAWs(SAWs_Delete, ("/PETSc/Options"));
267 PetscFunctionReturn(PETSC_SUCCESS);
268 }
269 #else
270 /*
271 PetscScanString - Gets user input via stdin from process and broadcasts to all processes
272
273 Collective
274
275 Input Parameters:
276 + commm - communicator for the broadcast, must be PETSC_COMM_WORLD
277 . n - length of the string, must be the same on all processes
278 - str - location to store input
279
280 Bugs:
281 . Assumes process 0 of the given communicator has access to stdin
282
283 */
PetscScanString(MPI_Comm comm,size_t n,char str[])284 static PetscErrorCode PetscScanString(MPI_Comm comm, size_t n, char str[])
285 {
286 PetscMPIInt rank, nm;
287
288 PetscFunctionBegin;
289 PetscCallMPI(MPI_Comm_rank(comm, &rank));
290 if (rank == 0) {
291 char c = (char)getchar();
292 size_t i = 0;
293
294 while (c != '\n' && i < n - 1) {
295 str[i++] = c;
296 c = (char)getchar();
297 }
298 str[i] = '\0';
299 }
300 PetscCall(PetscMPIIntCast(n, &nm));
301 PetscCallMPI(MPI_Bcast(str, nm, MPI_CHAR, 0, comm));
302 PetscFunctionReturn(PETSC_SUCCESS);
303 }
304
305 /*
306 PetscOptionsGetFromTextInput - Presents all the PETSc Options processed by the program so the user may change them at runtime
307
308 Notes:
309 this isn't really practical, it is just to demonstrate the principle
310
311 A carriage return indicates no change from the default; but this like -ksp_monitor <stdout> the default is actually not stdout the default
312 is to do nothing so to get it to use stdout you need to type stdout. This is kind of bug?
313
314 Bugs:
315 + All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
316 . Internal strings have arbitrary length and string copies are not checked that they fit into string space
317 - Only works for PetscInt == int, PetscReal == double etc
318
319 Developer Notes:
320 Normally the GUI that presents the options the user and retrieves the values would be running in a different
321 address space and communicating with the PETSc program
322
323 */
PetscOptionsGetFromTextInput(PetscOptionItems PetscOptionsObject)324 static PetscErrorCode PetscOptionsGetFromTextInput(PetscOptionItems PetscOptionsObject)
325 {
326 PetscOptionItem next = PetscOptionsObject->next;
327 char str[512];
328 PetscBool bid;
329 PetscReal ir, *valr;
330 PetscInt *vald;
331
332 PetscFunctionBegin;
333 PetscCall((*PetscPrintf)(PETSC_COMM_WORLD, "%s --------------------\n", PetscOptionsObject->title));
334 while (next) {
335 switch (next->type) {
336 case OPTION_HEAD:
337 break;
338 case OPTION_INT_ARRAY:
339 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
340 vald = (PetscInt *)next->data;
341 for (PetscInt i = 0; i < next->arraylength; i++) {
342 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT, vald[i]));
343 if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
344 }
345 PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
346 PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
347 if (str[0]) {
348 PetscToken token;
349 PetscInt n = 0, nmax = next->arraylength, *dvalue = (PetscInt *)next->data, start, end;
350 size_t len;
351 const char *value;
352 PetscBool foundrange;
353
354 next->set = PETSC_TRUE;
355 value = str;
356 PetscCall(PetscTokenCreate(value, ',', &token));
357 PetscCall(PetscTokenFind(token, &value));
358 while (n < nmax) {
359 char *ivalue;
360 PetscInt i;
361
362 if (!value) break;
363 PetscCall(PetscStrallocpy(value, &ivalue));
364
365 /* look for form d-D where d and D are integers */
366 foundrange = PETSC_FALSE;
367 PetscCall(PetscStrlen(ivalue, &len));
368 if (ivalue[0] == '-') i = 2;
369 else i = 1;
370 for (; i < (PetscInt)len; i++) {
371 if (ivalue[i] == '-') {
372 PetscCheck(i != (PetscInt)(len - 1), PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, ivalue);
373 ivalue[i] = 0;
374 PetscCall(PetscOptionsStringToInt(ivalue, &start));
375 PetscCall(PetscOptionsStringToInt(ivalue + i + 1, &end));
376 PetscCheck(end > start, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, %s-%s cannot have decreasing list", n, ivalue, ivalue + i + 1);
377 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);
378 for (; start < end; start++) {
379 *dvalue = start;
380 dvalue++;
381 n++;
382 }
383 foundrange = PETSC_TRUE;
384 break;
385 }
386 }
387 if (!foundrange) {
388 PetscCall(PetscOptionsStringToInt(ivalue, dvalue));
389 dvalue++;
390 n++;
391 }
392 PetscCall(PetscFree(ivalue));
393 PetscCall(PetscTokenFind(token, &value));
394 }
395 PetscCall(PetscTokenDestroy(&token));
396 }
397 break;
398 case OPTION_REAL_ARRAY:
399 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
400 valr = (PetscReal *)next->data;
401 for (PetscInt i = 0; i < next->arraylength; i++) {
402 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i]));
403 if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
404 }
405 PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
406 PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
407 if (str[0]) {
408 PetscToken token;
409 PetscInt n = 0, nmax = next->arraylength;
410 PetscReal *dvalue = (PetscReal *)next->data;
411 const char *value;
412
413 next->set = PETSC_TRUE;
414 value = str;
415 PetscCall(PetscTokenCreate(value, ',', &token));
416 PetscCall(PetscTokenFind(token, &value));
417 while (n < nmax) {
418 if (!value) break;
419 PetscCall(PetscOptionsStringToReal(value, dvalue));
420 dvalue++;
421 n++;
422 PetscCall(PetscTokenFind(token, &value));
423 }
424 PetscCall(PetscTokenDestroy(&token));
425 }
426 break;
427 case OPTION_INT:
428 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%d>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(int *)next->data, next->text, next->man));
429 PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
430 if (str[0]) {
431 #if defined(PETSC_SIZEOF_LONG_LONG)
432 long long lid;
433 sscanf(str, "%lld", &lid);
434 PetscCheck(lid <= PETSC_INT_MAX && lid >= PETSC_INT_MIN, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %lld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid);
435 #else
436 long lid;
437 sscanf(str, "%ld", &lid);
438 PetscCheck(lid <= PETSC_INT_MAX && lid >= PETSC_INT_MIN, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %ld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid);
439 #endif
440
441 next->set = PETSC_TRUE;
442 *((PetscInt *)next->data) = (PetscInt)lid;
443 }
444 break;
445 case OPTION_REAL:
446 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%g>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(double *)next->data, next->text, next->man));
447 PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
448 if (str[0]) {
449 #if defined(PETSC_USE_REAL_SINGLE)
450 sscanf(str, "%e", &ir);
451 #elif defined(PETSC_USE_REAL___FP16)
452 float irtemp;
453 sscanf(str, "%e", &irtemp);
454 ir = irtemp;
455 #elif defined(PETSC_USE_REAL_DOUBLE)
456 sscanf(str, "%le", &ir);
457 #elif defined(PETSC_USE_REAL___FLOAT128)
458 ir = strtoflt128(str, 0);
459 #else
460 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type");
461 #endif
462 next->set = PETSC_TRUE;
463 *((PetscReal *)next->data) = ir;
464 }
465 break;
466 case OPTION_BOOL:
467 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));
468 PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
469 if (str[0]) {
470 PetscCall(PetscOptionsStringToBool(str, &bid));
471 next->set = PETSC_TRUE;
472 *((PetscBool *)next->data) = bid;
473 }
474 break;
475 case OPTION_STRING:
476 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%s>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, (char *)next->data, next->text, next->man));
477 PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
478 if (str[0]) {
479 next->set = PETSC_TRUE;
480 /* must use system malloc since SAWs may free this */
481 PetscCall(PetscStrdup(str, (char **)&next->data));
482 }
483 break;
484 case OPTION_FLIST:
485 PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data));
486 PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
487 if (str[0]) {
488 PetscOptionsObject->changedmethod = PETSC_TRUE;
489 next->set = PETSC_TRUE;
490 /* must use system malloc since SAWs may free this */
491 PetscCall(PetscStrdup(str, (char **)&next->data));
492 }
493 break;
494 default:
495 break;
496 }
497 next = next->next;
498 }
499 PetscFunctionReturn(PETSC_SUCCESS);
500 }
501 #endif
502
PetscOptionsEnd_Private(PetscOptionItems PetscOptionsObject)503 PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems PetscOptionsObject)
504 {
505 PetscOptionItem next, last;
506
507 PetscFunctionBegin;
508 if (PetscOptionsObject->next) {
509 if (!PetscOptionsObject->count) {
510 #if defined(PETSC_HAVE_SAWS)
511 PetscCall(PetscOptionsSAWsInput(PetscOptionsObject));
512 #else
513 PetscCall(PetscOptionsGetFromTextInput(PetscOptionsObject));
514 #endif
515 }
516 }
517
518 PetscCall(PetscFree(PetscOptionsObject->title));
519
520 /* reset counter to -2; this updates the screen with the new options for the selected method */
521 if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2;
522 /* reset alreadyprinted flag */
523 PetscOptionsObject->alreadyprinted = PETSC_FALSE;
524 if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE;
525 PetscOptionsObject->object = NULL;
526
527 while ((next = PetscOptionsObject->next)) {
528 const PetscOptionType type = next->type;
529 const size_t arraylength = next->arraylength;
530 void *data = next->data;
531
532 if (next->set) {
533 char option[256], value[1024], tmp[32];
534
535 if (PetscOptionsObject->prefix) {
536 PetscCall(PetscStrncpy(option, "-", sizeof(option)));
537 PetscCall(PetscStrlcat(option, PetscOptionsObject->prefix, sizeof(option)));
538 PetscCall(PetscStrlcat(option, next->option + 1, sizeof(option)));
539 } else {
540 PetscCall(PetscStrncpy(option, next->option, sizeof(option)));
541 }
542
543 switch (type) {
544 case OPTION_HEAD:
545 break;
546 case OPTION_INT_ARRAY:
547 PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%" PetscInt_FMT, ((PetscInt *)data)[0]));
548 for (size_t j = 1; j < arraylength; ++j) {
549 PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%" PetscInt_FMT, ((PetscInt *)data)[j]));
550 PetscCall(PetscStrlcat(value, ",", sizeof(value)));
551 PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
552 }
553 break;
554 case OPTION_INT:
555 PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%" PetscInt_FMT, *(PetscInt *)data));
556 break;
557 case OPTION_REAL:
558 PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)*(PetscReal *)data));
559 break;
560 case OPTION_REAL_ARRAY:
561 PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)((PetscReal *)data)[0]));
562 for (size_t j = 1; j < arraylength; ++j) {
563 PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g", (double)((PetscReal *)data)[j]));
564 PetscCall(PetscStrlcat(value, ",", sizeof(value)));
565 PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
566 }
567 break;
568 case OPTION_SCALAR_ARRAY:
569 PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[0]), (double)PetscImaginaryPart(((PetscScalar *)data)[0])));
570 for (size_t j = 1; j < arraylength; ++j) {
571 PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[j]), (double)PetscImaginaryPart(((PetscScalar *)data)[j])));
572 PetscCall(PetscStrlcat(value, ",", sizeof(value)));
573 PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
574 }
575 break;
576 case OPTION_BOOL:
577 PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", *(int *)data));
578 break;
579 case OPTION_BOOL_ARRAY:
580 PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscBool *)data)[0]));
581 for (size_t j = 1; j < arraylength; ++j) {
582 PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscBool *)data)[j]));
583 PetscCall(PetscStrlcat(value, ",", sizeof(value)));
584 PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
585 }
586 break;
587 case OPTION_FLIST: // fall-through
588 case OPTION_ELIST: // fall-through
589 case OPTION_STRING:
590 PetscCall(PetscStrncpy(value, (char *)data, sizeof(value)));
591 break;
592 case OPTION_STRING_ARRAY:
593 PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%s", ((char **)data)[0]));
594 for (size_t j = 1; j < arraylength; j++) {
595 PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%s", ((char **)data)[j]));
596 PetscCall(PetscStrlcat(value, ",", sizeof(value)));
597 PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
598 }
599 break;
600 }
601 PetscCall(PetscOptionsSetValue(PetscOptionsObject->options, option, value));
602 }
603 if (type == OPTION_ELIST) PetscCall(PetscStrNArrayDestroy(next->nlist, (char ***)&next->list));
604 PetscCall(PetscFree(next->text));
605 PetscCall(PetscFree(next->option));
606 PetscCall(PetscFree(next->man));
607 PetscCall(PetscFree(next->edata));
608
609 if (type == OPTION_STRING || type == OPTION_FLIST || type == OPTION_ELIST) {
610 free(data);
611 } else {
612 // use next->data instead of data because PetscFree() sets it to NULL
613 PetscCall(PetscFree(next->data));
614 }
615
616 last = next;
617 PetscOptionsObject->next = next->next;
618 PetscCall(PetscFree(last));
619 }
620 PetscCall(PetscFree(PetscOptionsObject->prefix));
621 PetscOptionsObject->next = NULL;
622 PetscFunctionReturn(PETSC_SUCCESS);
623 }
624
GetListLength(const char * const * list,PetscInt * len)625 static PetscErrorCode GetListLength(const char *const *list, PetscInt *len)
626 {
627 PetscInt retlen = 0;
628
629 PetscFunctionBegin;
630 PetscAssertPointer(len, 2);
631 while (list[retlen]) {
632 PetscAssertPointer(list[retlen], 1);
633 PetscCheck(++retlen < 50, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "List argument appears to be wrong or have more than 50 entries");
634 }
635 PetscCheck(retlen > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least 2 entries: typename and type prefix");
636 /* drop item name and prefix*/
637 *len = retlen - 2;
638 PetscFunctionReturn(PETSC_SUCCESS);
639 }
640
PetscOptionsEnum_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],const char * const * list,PetscEnum currentvalue,PetscEnum * value,PetscBool * set)641 PetscErrorCode PetscOptionsEnum_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum currentvalue, PetscEnum *value, PetscBool *set)
642 {
643 PetscInt ntext = 0;
644 PetscInt tval;
645 PetscBool tflg;
646
647 PetscFunctionBegin;
648 PetscAssertPointer(opt, 2);
649 PetscAssertPointer(list, 5);
650 PetscAssertPointer(value, 7);
651 if (set) PetscAssertPointer(set, 8);
652 PetscCall(GetListLength(list, &ntext));
653 PetscCall(PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[(int)currentvalue], &tval, &tflg));
654 /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
655 if (tflg) *value = (PetscEnum)tval;
656 if (set) *set = tflg;
657 PetscFunctionReturn(PETSC_SUCCESS);
658 }
659
PetscOptionsEnumArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],const char * const * list,PetscEnum value[],PetscInt * n,PetscBool * set)660 PetscErrorCode PetscOptionsEnumArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum value[], PetscInt *n, PetscBool *set)
661 {
662 PetscInt nlist = 0;
663 const char *prefix = PetscOptionsObject->prefix;
664
665 PetscFunctionBegin;
666 PetscAssertPointer(opt, 2);
667 PetscAssertPointer(list, 5);
668 PetscAssertPointer(value, 6);
669 PetscAssertPointer(n, 7);
670 PetscCheck(*n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") must be > 0", *n);
671 if (set) PetscAssertPointer(set, 8);
672 PetscCall(GetListLength(list, &nlist));
673 const PetscInt nin = *n;
674 PetscCall(PetscOptionsGetEnumArray(PetscOptionsObject->options, prefix, opt, list, value, n, set));
675 if (ShouldPrintHelp(PetscOptionsObject) && nin) {
676 const MPI_Comm comm = PetscOptionsObject->comm;
677 const PetscInt nv = *n;
678
679 PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%s", Prefix(prefix), opt + 1, list[value[0]]));
680 for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%s", list[value[i]]));
681 PetscCall((*PetscHelpPrintf)(comm, ">: %s (choose from)", text));
682 for (PetscInt i = 0; i < nlist; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
683 PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
684 }
685 PetscFunctionReturn(PETSC_SUCCESS);
686 }
687
PetscOptionsInt_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt currentvalue,PetscInt * value,PetscBool * set,PetscInt lb,PetscInt ub)688 PetscErrorCode PetscOptionsInt_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *set, PetscInt lb, PetscInt ub)
689 {
690 const char *prefix = PetscOptionsObject->prefix;
691 const PetscOptions options = PetscOptionsObject->options;
692 PetscBool wasset;
693
694 PetscFunctionBegin;
695 PetscAssertPointer(opt, 2);
696 PetscAssertPointer(value, 6);
697 if (set) PetscAssertPointer(set, 7);
698 PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, currentvalue, lb);
699 PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, currentvalue, ub);
700 if (!PetscOptionsObject->count) {
701 PetscOptionItem amsopt;
702
703 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt));
704 PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data));
705 *(PetscInt *)amsopt->data = currentvalue;
706
707 PetscCall(PetscOptionsGetInt(options, prefix, opt, ¤tvalue, &wasset));
708 if (wasset) *(PetscInt *)amsopt->data = currentvalue;
709 }
710 PetscCall(PetscOptionsGetInt(options, prefix, opt, value, &wasset));
711 PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, *value, lb);
712 PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, *value, ub);
713 if (set) *set = wasset;
714 if (ShouldPrintHelp(PetscOptionsObject)) {
715 PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %" PetscInt_FMT " : formerly %" PetscInt_FMT ">: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? *value : currentvalue, currentvalue, text, ManSection(man)));
716 }
717 PetscFunctionReturn(PETSC_SUCCESS);
718 }
719
PetscOptionsMPIInt_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscMPIInt currentvalue,PetscMPIInt * value,PetscBool * set,PetscMPIInt lb,PetscMPIInt ub)720 PetscErrorCode PetscOptionsMPIInt_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscMPIInt currentvalue, PetscMPIInt *value, PetscBool *set, PetscMPIInt lb, PetscMPIInt ub)
721 {
722 const char *prefix = PetscOptionsObject->prefix;
723 const PetscOptions options = PetscOptionsObject->options;
724 PetscBool wasset;
725
726 PetscFunctionBegin;
727 PetscAssertPointer(opt, 2);
728 PetscAssertPointer(value, 6);
729 if (set) PetscAssertPointer(set, 7);
730 PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d less than allowed bound %d", currentvalue, lb);
731 PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d greater than allowed bound %d", currentvalue, ub);
732 if (!PetscOptionsObject->count) {
733 PetscOptionItem amsopt;
734
735 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt));
736 PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data));
737 *(PetscMPIInt *)amsopt->data = currentvalue;
738
739 PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, ¤tvalue, &wasset));
740 if (wasset) *(PetscMPIInt *)amsopt->data = currentvalue;
741 }
742 PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, value, &wasset));
743 PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d less than allowed bound %d", *value, lb);
744 PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d greater than allowed bound %d", *value, ub);
745 if (set) *set = wasset;
746 if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %d : formerly %d>: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? *value : currentvalue, currentvalue, text, ManSection(man)));
747 PetscFunctionReturn(PETSC_SUCCESS);
748 }
749
PetscOptionsString_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],const char currentvalue[],char value[],size_t len,PetscBool * set)750 PetscErrorCode PetscOptionsString_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], const char currentvalue[], char value[], size_t len, PetscBool *set)
751 {
752 const char *prefix = PetscOptionsObject->prefix;
753 PetscBool lset;
754
755 PetscFunctionBegin;
756 PetscAssertPointer(opt, 2);
757 PetscAssertPointer(value, 6);
758 if (set) PetscAssertPointer(set, 8);
759 if (!PetscOptionsObject->count) {
760 PetscOptionItem amsopt;
761
762 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
763 /* must use system malloc since SAWs may free this */
764 PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
765 }
766 PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
767 if (set) *set = lset;
768 if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %s : formerly %s>: %s (%s)\n", Prefix(prefix), opt + 1, lset ? value : currentvalue, currentvalue, text, ManSection(man)));
769 PetscFunctionReturn(PETSC_SUCCESS);
770 }
771
PetscOptionsReal_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscReal currentvalue,PetscReal * value,PetscBool * set,PetscReal lb,PetscReal ub)772 PetscErrorCode PetscOptionsReal_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal currentvalue, PetscReal *value, PetscBool *set, PetscReal lb, PetscReal ub)
773 {
774 const char *prefix = PetscOptionsObject->prefix;
775 const PetscOptions options = PetscOptionsObject->options;
776 PetscBool wasset;
777
778 PetscFunctionBegin;
779 PetscAssertPointer(opt, 2);
780 PetscAssertPointer(value, 6);
781 if (set) PetscAssertPointer(set, 7);
782 PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g less than allowed bound %g", (double)currentvalue, (double)lb);
783 PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g greater than allowed bound %g", (double)currentvalue, (double)ub);
784 if (!PetscOptionsObject->count) {
785 PetscOptionItem amsopt;
786
787 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt));
788 PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data));
789 *(PetscReal *)amsopt->data = currentvalue;
790
791 PetscCall(PetscOptionsGetReal(options, prefix, opt, ¤tvalue, &wasset));
792 if (wasset) *(PetscReal *)amsopt->data = currentvalue;
793 }
794 PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &wasset));
795 PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %g less than allowed bound %g", (double)*value, (double)lb);
796 PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %g greater than allowed bound %g", (double)*value, (double)ub);
797 if (set) *set = wasset;
798 if (ShouldPrintHelp(PetscOptionsObject)) {
799 PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %g : formerly %g>: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? (double)*value : (double)currentvalue, (double)currentvalue, text, ManSection(man)));
800 }
801 PetscFunctionReturn(PETSC_SUCCESS);
802 }
803
PetscOptionsScalar_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscScalar currentvalue,PetscScalar * value,PetscBool * set)804 PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set)
805 {
806 PetscFunctionBegin;
807 #if !defined(PETSC_USE_COMPLEX)
808 PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set));
809 #else
810 PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set));
811 #endif
812 PetscFunctionReturn(PETSC_SUCCESS);
813 }
814
PetscOptionsName_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool * flg)815 PetscErrorCode PetscOptionsName_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
816 {
817 const char *prefix = PetscOptionsObject->prefix;
818
819 PetscFunctionBegin;
820 PetscAssertPointer(opt, 2);
821 PetscAssertPointer(flg, 5);
822 if (!PetscOptionsObject->count) {
823 PetscOptionItem amsopt;
824
825 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
826 PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
827
828 *(PetscBool *)amsopt->data = PETSC_FALSE;
829 }
830 PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg));
831 if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
832 PetscFunctionReturn(PETSC_SUCCESS);
833 }
834
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)835 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)
836 {
837 const char *prefix = PetscOptionsObject->prefix;
838 PetscBool lset;
839
840 PetscFunctionBegin;
841 PetscAssertPointer(opt, 2);
842 PetscAssertPointer(value, 7);
843 if (set) PetscAssertPointer(set, 9);
844 if (!PetscOptionsObject->count) {
845 PetscOptionItem amsopt;
846
847 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt));
848 /* must use system malloc since SAWs may free this */
849 PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
850 amsopt->flist = list;
851 }
852 PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
853 if (set) *set = lset;
854 if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue));
855 PetscFunctionReturn(PETSC_SUCCESS);
856 }
857
858 #ifdef __cplusplus
859 #include <type_traits>
860 #endif
861
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)862 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)
863 {
864 const char *prefix = PetscOptionsObject->prefix;
865 PetscBool lset;
866
867 PetscFunctionBegin;
868 PetscAssertPointer(opt, 2);
869 PetscAssertPointer(value, 8);
870 if (set) PetscAssertPointer(set, 9);
871 if (!PetscOptionsObject->count) {
872 PetscOptionItem amsopt;
873
874 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt));
875 /* must use system malloc since SAWs may free this */
876 PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
877 PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list));
878 PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX);
879 #ifdef __cplusplus
880 static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, "");
881 #endif
882 amsopt->nlist = (char)ntext;
883 }
884 PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset));
885 if (set) *set = lset;
886 if (ShouldPrintHelp(PetscOptionsObject)) {
887 const MPI_Comm comm = PetscOptionsObject->comm;
888
889 PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext));
890 for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
891 PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
892 }
893 PetscFunctionReturn(PETSC_SUCCESS);
894 }
895
PetscOptionsBoolGroupBegin_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool * flg)896 PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
897 {
898 const char *prefix = PetscOptionsObject->prefix;
899
900 PetscFunctionBegin;
901 PetscAssertPointer(opt, 2);
902 PetscAssertPointer(flg, 5);
903 if (!PetscOptionsObject->count) {
904 PetscOptionItem amsopt;
905
906 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
907 PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
908
909 *(PetscBool *)amsopt->data = PETSC_FALSE;
910 }
911 *flg = PETSC_FALSE;
912 PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
913 if (ShouldPrintHelp(PetscOptionsObject)) {
914 const MPI_Comm comm = PetscOptionsObject->comm;
915
916 PetscCall((*PetscHelpPrintf)(comm, " Pick at most one of -------------\n"));
917 PetscCall((*PetscHelpPrintf)(comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
918 }
919 PetscFunctionReturn(PETSC_SUCCESS);
920 }
921
PetscOptionsBoolGroup_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool * flg)922 PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
923 {
924 const char *prefix = PetscOptionsObject->prefix;
925
926 PetscFunctionBegin;
927 PetscAssertPointer(opt, 2);
928 PetscAssertPointer(flg, 5);
929 if (!PetscOptionsObject->count) {
930 PetscOptionItem amsopt;
931
932 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
933 PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
934
935 *(PetscBool *)amsopt->data = PETSC_FALSE;
936 }
937 *flg = PETSC_FALSE;
938 PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
939 if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
940 PetscFunctionReturn(PETSC_SUCCESS);
941 }
942
PetscOptionsBoolGroupEnd_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool * flg)943 PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
944 {
945 const char *prefix = PetscOptionsObject->prefix;
946
947 PetscFunctionBegin;
948 PetscAssertPointer(opt, 2);
949 PetscAssertPointer(flg, 5);
950 if (!PetscOptionsObject->count) {
951 PetscOptionItem amsopt;
952
953 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
954 PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
955
956 *(PetscBool *)amsopt->data = PETSC_FALSE;
957 }
958 *flg = PETSC_FALSE;
959 PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
960 if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
961 PetscFunctionReturn(PETSC_SUCCESS);
962 }
963
PetscOptionsBool_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool currentvalue,PetscBool * flg,PetscBool * set)964 PetscErrorCode PetscOptionsBool_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set)
965 {
966 const char *prefix = PetscOptionsObject->prefix;
967 PetscBool iset;
968
969 PetscFunctionBegin;
970 PetscAssertPointer(opt, 2);
971 PetscAssertPointer(flg, 6);
972 if (set) PetscAssertPointer(set, 7);
973 if (!PetscOptionsObject->count) {
974 PetscOptionItem amsopt;
975
976 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
977 PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
978
979 *(PetscBool *)amsopt->data = currentvalue;
980 }
981 PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset));
982 if (set) *set = iset;
983 if (ShouldPrintHelp(PetscOptionsObject)) {
984 const char *curvalue = PetscBools[currentvalue];
985
986 PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %s : formerly %s> %s (%s)\n", Prefix(prefix), opt + 1, iset ? PetscBools[*flg] : curvalue, curvalue, text, ManSection(man)));
987 }
988 PetscFunctionReturn(PETSC_SUCCESS);
989 }
990
PetscOptionsBool3_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool3 currentvalue,PetscBool3 * flg,PetscBool * set)991 PetscErrorCode PetscOptionsBool3_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool3 currentvalue, PetscBool3 *flg, PetscBool *set)
992 {
993 const char *prefix = PetscOptionsObject->prefix;
994 PetscBool iset;
995
996 PetscFunctionBegin;
997 PetscAssertPointer(opt, 2);
998 PetscAssertPointer(flg, 6);
999 if (set) PetscAssertPointer(set, 7);
1000 PetscCall(PetscOptionsGetBool3(PetscOptionsObject->options, prefix, opt, flg, &iset));
1001 if (set) *set = iset;
1002 if (ShouldPrintHelp(PetscOptionsObject)) {
1003 const char *curvalue = PetscBool3s[currentvalue];
1004
1005 PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %s : formerly %s> %s (%s)\n", Prefix(prefix), opt + 1, iset ? PetscBools[*flg] : curvalue, curvalue, text, ManSection(man)));
1006 }
1007 PetscFunctionReturn(PETSC_SUCCESS);
1008 }
1009
PetscOptionsRealArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscReal value[],PetscInt * n,PetscBool * set)1010 PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set)
1011 {
1012 const char *prefix = PetscOptionsObject->prefix;
1013
1014 PetscFunctionBegin;
1015 PetscAssertPointer(opt, 2);
1016 PetscAssertPointer(n, 6);
1017 PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
1018 if (*n) PetscAssertPointer(value, 5);
1019 if (set) PetscAssertPointer(set, 7);
1020 if (!PetscOptionsObject->count) {
1021 const PetscInt nv = *n;
1022 PetscReal *vals;
1023 PetscOptionItem amsopt;
1024
1025 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt));
1026 PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
1027 for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
1028 amsopt->arraylength = nv;
1029 amsopt->data = vals;
1030 }
1031 const PetscInt nin = *n;
1032 PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1033 if (ShouldPrintHelp(PetscOptionsObject) && nin) {
1034 const PetscInt nv = *n;
1035 const MPI_Comm comm = PetscOptionsObject->comm;
1036
1037 PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0]));
1038 for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i]));
1039 PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1040 }
1041 PetscFunctionReturn(PETSC_SUCCESS);
1042 }
1043
PetscOptionsScalarArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscScalar value[],PetscInt * n,PetscBool * set)1044 PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set)
1045 {
1046 const char *prefix = PetscOptionsObject->prefix;
1047
1048 PetscFunctionBegin;
1049 PetscAssertPointer(opt, 2);
1050 PetscAssertPointer(n, 6);
1051 PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
1052 if (*n) PetscAssertPointer(value, 5);
1053 if (set) PetscAssertPointer(set, 7);
1054 if (!PetscOptionsObject->count) {
1055 const PetscInt nv = *n;
1056 PetscOptionItem amsopt;
1057 PetscScalar *vals;
1058
1059 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt));
1060 PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
1061 for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
1062 amsopt->arraylength = nv;
1063 amsopt->data = vals;
1064 }
1065 const PetscInt nin = *n;
1066 PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1067 if (ShouldPrintHelp(PetscOptionsObject) && nin) {
1068 const PetscInt nv = *n;
1069 const MPI_Comm comm = PetscOptionsObject->comm;
1070
1071 PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0])));
1072 for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i])));
1073 PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1074 }
1075 PetscFunctionReturn(PETSC_SUCCESS);
1076 }
1077
PetscOptionsIntArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt value[],PetscInt * n,PetscBool * set)1078 PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set)
1079 {
1080 const char *prefix = PetscOptionsObject->prefix;
1081
1082 PetscFunctionBegin;
1083 PetscAssertPointer(opt, 2);
1084 PetscAssertPointer(n, 6);
1085 PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
1086 if (*n) PetscAssertPointer(value, 5);
1087 if (set) PetscAssertPointer(set, 7);
1088 if (!PetscOptionsObject->count) {
1089 const PetscInt nv = *n;
1090 PetscInt *vals;
1091 PetscOptionItem amsopt;
1092
1093 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt));
1094 PetscCall(PetscMalloc1(nv, &vals));
1095 for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
1096 amsopt->arraylength = nv;
1097 amsopt->data = vals;
1098 }
1099 const PetscInt nin = *n;
1100 PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1101 if (ShouldPrintHelp(PetscOptionsObject) && nin) {
1102 const PetscInt nv = *n;
1103 const MPI_Comm comm = PetscOptionsObject->comm;
1104
1105 PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0]));
1106 for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i]));
1107 PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1108 }
1109 PetscFunctionReturn(PETSC_SUCCESS);
1110 }
1111
PetscOptionsStringArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],char * value[],PetscInt * nmax,PetscBool * set)1112 PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set)
1113 {
1114 const char *prefix = PetscOptionsObject->prefix;
1115
1116 PetscFunctionBegin;
1117 PetscAssertPointer(opt, 2);
1118 PetscAssertPointer(nmax, 6);
1119 PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax);
1120 if (*nmax) PetscAssertPointer(value, 5);
1121 if (set) PetscAssertPointer(set, 7);
1122 if (!PetscOptionsObject->count) {
1123 const PetscInt nmaxv = *nmax;
1124 PetscOptionItem amsopt;
1125
1126 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt));
1127 PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data));
1128 amsopt->arraylength = nmaxv;
1129 }
1130 const PetscInt nin = *nmax;
1131 PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set));
1132 if (ShouldPrintHelp(PetscOptionsObject) && nin) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
1133 PetscFunctionReturn(PETSC_SUCCESS);
1134 }
1135
PetscOptionsBoolArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool value[],PetscInt * n,PetscBool * set)1136 PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set)
1137 {
1138 const char *prefix = PetscOptionsObject->prefix;
1139
1140 PetscFunctionBegin;
1141 PetscAssertPointer(opt, 2);
1142 PetscAssertPointer(n, 6);
1143 PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
1144 if (*n) PetscAssertPointer(value, 5);
1145 if (set) PetscAssertPointer(set, 7);
1146 if (!PetscOptionsObject->count) {
1147 const PetscInt nv = *n;
1148 PetscBool *vals;
1149 PetscOptionItem amsopt;
1150
1151 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt));
1152 PetscCall(PetscMalloc1(nv, &vals));
1153 for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
1154 amsopt->arraylength = nv;
1155 amsopt->data = vals;
1156 }
1157 const PetscInt nin = *n;
1158 PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1159 if (ShouldPrintHelp(PetscOptionsObject) && nin) {
1160 const PetscInt nv = *n;
1161 const MPI_Comm comm = PetscOptionsObject->comm;
1162
1163 PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%d", Prefix(prefix), opt + 1, value[0]));
1164 for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i]));
1165 PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1166 }
1167 PetscFunctionReturn(PETSC_SUCCESS);
1168 }
1169
1170 /*MC
1171 PetscOptionsViewer - Creates a viewer appropriate for the type indicated by the user
1172
1173 Synopsis:
1174 #include <petscviewer.h>
1175 PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
1176
1177 Logically Collective on the communicator passed in `PetscOptionsBegin()`
1178
1179 Input Parameters:
1180 + opt - option name
1181 . text - short string that describes the option
1182 - man - manual page with additional information on option
1183
1184 Output Parameters:
1185 + viewer - the viewer
1186 . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed
1187 - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
1188
1189 Level: beginner
1190
1191 Notes:
1192 Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`
1193
1194 See `PetscOptionsCreateViewer()` for the format of the supplied viewer and its options
1195
1196 .seealso: `PetscOptionsCreateViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1197 `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
1198 `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1199 `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1200 `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1201 `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1202 `PetscOptionsFList()`, `PetscOptionsEList()`
1203 M*/
PetscOptionsViewer_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscViewer * viewer,PetscViewerFormat * format,PetscBool * set)1204 PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
1205 {
1206 const MPI_Comm comm = PetscOptionsObject->comm;
1207 const char *prefix = PetscOptionsObject->prefix;
1208
1209 PetscFunctionBegin;
1210 PetscAssertPointer(opt, 2);
1211 PetscAssertPointer(viewer, 5);
1212 if (format) PetscAssertPointer(format, 6);
1213 if (set) PetscAssertPointer(set, 7);
1214 if (!PetscOptionsObject->count) {
1215 PetscOptionItem amsopt;
1216
1217 PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
1218 /* must use system malloc since SAWs may free this */
1219 PetscCall(PetscStrdup("", (char **)&amsopt->data));
1220 }
1221 PetscCall(PetscOptionsCreateViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set));
1222 if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man)));
1223 PetscFunctionReturn(PETSC_SUCCESS);
1224 }
1225