Actual source code: aoptions.c

  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.

  5: */

  7: #include <petsc/private/petscimpl.h>
  8: #include <petscviewer.h>

 10: #define ManSection(str) ((str) ? (str) : "None")

 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()

 16:     Eventually we'll attach this beast to a MPI_Comm
 17: */

 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;
 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;

 36:   PetscCall(PetscStrallocpy(prefix, &PetscOptionsObject->prefix));
 37:   PetscCall(PetscStrallocpy(title, &PetscOptionsObject->title));

 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: }

 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;

 54:   PetscFunctionBegin;
 57:   PetscOptionsObject->object         = obj;
 58:   PetscOptionsObject->alreadyprinted = obj->optionsprinted;

 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: }

 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;

 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);

 79:   PetscCall(PetscNew(amsopt));
 80:   (*amsopt)->next = NULL;
 81:   (*amsopt)->set  = PETSC_FALSE;
 82:   (*amsopt)->type = t;
 83:   (*amsopt)->data = NULL;

 85:   PetscCall(PetscStrallocpy(text, &(*amsopt)->text));
 86:   PetscCall(PetscStrallocpy(opt, &(*amsopt)->option));
 87:   PetscCall(PetscStrallocpy(man, &(*amsopt)->man));

 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: }

 98: /*
 99:     PetscScanString -  Gets user input via stdin from process and broadcasts to all processes

101:     Collective

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

108:     Bugs:
109: .   Assumes process 0 of the given communicator has access to stdin

111: */
112: static PetscErrorCode PetscScanString(MPI_Comm comm, size_t n, char str[])
113: {
114:   PetscMPIInt rank, nm;

116:   PetscFunctionBegin;
117:   PetscCallMPI(MPI_Comm_rank(comm, &rank));
118:   if (rank == 0) {
119:     char   c = (char)getchar();
120:     size_t i = 0;

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: }

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;

140:   PetscFunctionBegin;
141:   if (s) {
142:     size_t len;

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: }

153: /*
154:     PetscOptionsGetFromTextInput - Presents all the PETSc Options processed by the program so the user may change them at runtime

156:     Notes:
157:     this isn't really practical, it is just to demonstrate the principle

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?

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

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

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;

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;

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;

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;

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

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: }

346: #if defined(PETSC_HAVE_SAWS)
347: #include <petscviewersaws.h>

349: static int count = 0;

351: PetscErrorCode PetscOptionsSAWsDestroy(void)
352: {
353:   PetscFunctionBegin;
354:   PetscFunctionReturn(PETSC_SUCCESS);
355: }

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";

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>";

371: /*
372:     PetscOptionsSAWsInput - Presents all the PETSc Options processed by the program so the user may change them at runtime using the SAWs

374:     Bugs:
375: +    All processes must traverse through the exact same set of option queries do 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

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];

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++));

394:   PetscOptionsObject->pprefix = PetscOptionsObject->prefix; /* SAWs will change this, so cannot pass prefix directly */

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));

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));

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:   }

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));

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:   }

482:   /* reset counter to -2; this updates the screen with the new options for the selected method */
483:   if (changedmethod) PetscOptionsObject->count = -2;

485:   if (stopasking) {
486:     PetscOptionsPublish       = PETSC_FALSE;
487:     PetscOptionsObject->count = 0; //do not ask for same thing again
488:   }

490:   PetscCallSAWs(SAWs_Delete, ("/PETSc/Options"));
491:   PetscFunctionReturn(PETSC_SUCCESS);
492: }
493: #endif

495: PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems *PetscOptionsObject)
496: {
497:   PetscOptionItem last;
498:   char            option[256], value[1024], tmp[32];
499:   size_t          j;

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:   }

512:   PetscCall(PetscFree(PetscOptionsObject->title));

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;

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)));

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));

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:     }

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: }

614: /*MC
615:    PetscOptionsEnum - Gets the enum value for a particular option in the database.

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)

621:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

636:    Output Parameters:
637: +  value - the  value to return
638: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

640:    Level: beginner

642:    Notes:
643:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

645:           list is usually something like `PCASMTypes` or some other predefined list of enum names

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`.

650:           The `currentvalue` passed into this routine does not get transferred to the output `value` variable automatically.

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*/

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;

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: }

678: /*MC
679:    PetscOptionsEnumArray - Gets an array of enum values for a particular
680:    option in the database.

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)

686:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

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`

700:    Level: beginner

702:    Notes:
703:    The array must be passed as a comma separated list.

705:    There must be no intervening spaces between the values.

707:    Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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;

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: }

747: /*MC
748:    PetscOptionsBoundedInt - Gets an integer value greater than or equal a given bound for a particular option in the database.

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)

754:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

772:    Output Parameters:
773: +  value - the integer value to return
774: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

776:    Level: beginner

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`.

782:     The `currentvalue` passed into this routine does not get transferred to the output `value` variable automatically.

784:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

795: /*MC
796:    PetscOptionsRangeInt - Gets an integer value within a range of values for a particular option in the database.

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)

802:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

818:    Output Parameters:
819: +  value - the integer value to return
820: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

822:    Level: beginner

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`.

828:     The `currentvalue` passed into this routine does not get transferred to the output `value` variable automatically.

830:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

841: /*MC
842:    PetscOptionsInt - Gets the integer value for a particular option in the database.

844:    Synopsis:
845:    #include "petscsys.h"
846:    PetscErrorCode  PetscOptionsInt(const char opt[],const char text[],const char man[],PetscInt currentvalue,PetscInt *value,PetscBool *flg))

848:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

862:    Output Parameters:
863: +  value - the integer value to return
864: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

866:    Level: beginner

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`.

872:     The `currentvalue` passed into this routine does not get transferred to the output `value` variable automatically.

874:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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;

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;

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: }

911: /*MC
912:    PetscOptionsString - Gets the string value for a particular option in the database.

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)

918:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

927:    Output Parameters:
928: +  value - the value to return
929: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

931:    Level: beginner

933:    Notes:
934:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

936:    If the user provided no string (for example `-optionname` `-someotheroption`) `flg` is set to `PETSC_TRUE` (and the string is filled with nulls).

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`.

941:           The `currentvalue` passed into this routine does not get transferred to the output `value` variable automatically.

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*/

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;

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: }

971: /*MC
972:    PetscOptionsReal - Gets the `PetscReal` value for a particular option in the database.

974:    Synopsis:
975:    #include "petscsys.h"
976:    PetscErrorCode  PetscOptionsReal(const char opt[],const char text[],const char man[],PetscReal currentvalue,PetscReal *value,PetscBool  *set)

978:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

992:    Output Parameters:
993: +  value - the value to return
994: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

996:    Level: beginner

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`.

1002:     The `currentvalue` passed into this routine does not get transferred to the output `value` variable automatically.

1004:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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;

1020:   PetscFunctionBegin;
1021:   if (!PetscOptionsObject->count) {
1022:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt));
1023:     PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data));

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 <%g : %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: }

1035: /*MC
1036:    PetscOptionsScalar - Gets the `PetscScalar` value for a particular option in the database.

1038:    Synopsis:
1039:    #include "petscsys.h"
1040:    PetscErrorCode PetscOptionsScalar(const char opt[],const char text[],const char man[],PetscScalar currentvalue,PetscScalar *value,PetscBool  *set)

1042:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

1056:    Output Parameters:
1057: +  value - the value to return
1058: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1060:    Level: beginner

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`.

1066:     The `currentvalue` passed into this routine does not get transferred to the output `value` variable automatically.

1068:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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: }

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.

1094:    Synopsis:
1095:    #include "petscsys.h"
1096:    PetscErrorCode PetscOptionsName(const char opt[],const char text[],const char man[],PetscBool  *flg)

1098:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

1100:    Input Parameters:
1101: +  opt - option name
1102: .  text - short string that describes the option
1103: -  man - manual page with additional information on option

1105:    Output Parameter:
1106: .  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1108:    Level: beginner

1110:    Note:
1111:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

1122: PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1123: {
1124:   PetscOptionItem amsopt;

1126:   PetscFunctionBegin;
1127:   if (!PetscOptionsObject->count) {
1128:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1129:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

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: }

1140: /*MC
1141:      PetscOptionsFList - Puts a list of option values that a single one may be selected from

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)

1147:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

1161:    Output Parameters:
1162: +  value - the value to return
1163: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1165:    Level: intermediate

1167:    Notes:
1168:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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`.

1173:           The `currentvalue` passed into this routine does not get transferred to the output `value` variable automatically.

1175:    See `PetscOptionsEList()` for when the choices are given in a string array

1177:    To get a listing of all currently specified options,
1178:     see `PetscOptionsView()` or `PetscOptionsGetAll()`

1180:    Developer Note:
1181:    This cannot check for invalid selection because of things like `MATAIJ` that are not included in the list

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*/

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;

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: }

1211: /*MC
1212:      PetscOptionsEList - Puts a list of option values that a single one may be selected from

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)

1218:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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) {

1231:    Output Parameters:
1232: +  value - the index of the value to return
1233: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1235:    Level: intermediate

1237:    Notes:
1238:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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`.

1243:    See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList()`

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*/

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;

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: }

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.

1281:    Synopsis:
1282:    #include "petscsys.h"
1283:    PetscErrorCode PetscOptionsBoolGroupBegin(const char opt[],const char text[],const char man[],PetscBool  *flg)

1285:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

1287:    Input Parameters:
1288: +  opt - option name
1289: .  text - short string that describes the option
1290: -  man - manual page with additional information on option

1292:    Output Parameter:
1293: .  flg - whether that option was set or not

1295:    Level: intermediate

1297:    Notes:
1298:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1300:    Must be followed by 0 or more `PetscOptionsBoolGroup()`s and `PetscOptionsBoolGroupEnd()`

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*/

1310: PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1311: {
1312:   PetscOptionItem amsopt;

1314:   PetscFunctionBegin;
1315:   if (!PetscOptionsObject->count) {
1316:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1317:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

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: }

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.

1334:    Synopsis:
1335:    #include "petscsys.h"
1336:    PetscErrorCode PetscOptionsBoolGroup(const char opt[],const char text[],const char man[],PetscBool  *flg)

1338:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

1340:    Input Parameters:
1341: +  opt - option name
1342: .  text - short string that describes the option
1343: -  man - manual page with additional information on option

1345:    Output Parameter:
1346: .  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1348:    Level: intermediate

1350:    Notes:
1351:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1353:    Must follow a `PetscOptionsBoolGroupBegin()` and preceded a `PetscOptionsBoolGroupEnd()`

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*/

1363: PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1364: {
1365:   PetscOptionItem amsopt;

1367:   PetscFunctionBegin;
1368:   if (!PetscOptionsObject->count) {
1369:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1370:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

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: }

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.

1386:    Synopsis:
1387:    #include "petscsys.h"
1388:    PetscErrorCode PetscOptionsBoolGroupEnd(const char opt[],const char text[],const char man[],PetscBool  *flg)

1390:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

1392:    Input Parameters:
1393: +  opt - option name
1394: .  text - short string that describes the option
1395: -  man - manual page with additional information on option

1397:    Output Parameter:
1398: .  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1400:    Level: intermediate

1402:    Notes:
1403:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1405:    Must follow a `PetscOptionsBoolGroupBegin()`

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*/

1415: PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1416: {
1417:   PetscOptionItem amsopt;

1419:   PetscFunctionBegin;
1420:   if (!PetscOptionsObject->count) {
1421:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1422:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

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: }

1434: /*MC
1435:    PetscOptionsBool - Determines if a particular option is in the database with a true or false

1437:    Synopsis:
1438:    #include "petscsys.h"
1439:    PetscErrorCode PetscOptionsBool(const char opt[],const char text[],const char man[],PetscBool currentvalue,PetscBool  *flg,PetscBool  *set)

1441:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

1449:    Output Parameters:
1450: +  flg -` PETSC_TRUE` or `PETSC_FALSE`
1451: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1453:    Level: beginner

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`

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`

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`.

1465:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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;

1481:   PetscFunctionBegin;
1482:   if (!PetscOptionsObject->count) {
1483:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1484:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

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[currentvalue], *vn = PetscBools[iset && flg ? *flg : currentvalue];
1492:     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <%s : %s> %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, v, vn, text, ManSection(man)));
1493:   }
1494:   PetscFunctionReturn(PETSC_SUCCESS);
1495: }

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.

1502:    Synopsis:
1503:    #include "petscsys.h"
1504:    PetscErrorCode PetscOptionsRealArray(const char opt[],const char text[],const char man[],PetscReal value[],PetscInt *n,PetscBool  *set)

1506:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

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`

1519:    Level: beginner

1521:    Note:
1522:    Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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;

1537:   PetscFunctionBegin;
1538:   if (!PetscOptionsObject->count) {
1539:     PetscReal *vals;

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: }

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.

1561:    Synopsis:
1562:    #include "petscsys.h"
1563:    PetscErrorCode PetscOptionsScalarArray(const char opt[],const char text[],const char man[],PetscScalar value[],PetscInt *n,PetscBool  *set)

1565:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

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`

1578:    Level: beginner

1580:    Note:
1581:    Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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;

1596:   PetscFunctionBegin;
1597:   if (!PetscOptionsObject->count) {
1598:     PetscScalar *vals;

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: }

1615: /*MC
1616:    PetscOptionsIntArray - Gets an array of integers for a particular
1617:    option in the database.

1619:    Synopsis:
1620:    #include "petscsys.h"
1621:    PetscErrorCode PetscOptionsIntArray(const char opt[],const char text[],const char man[],PetscInt value[],PetscInt *n,PetscBool  *set)

1623:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

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`

1636:    Level: beginner

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

1645:    There must be no intervening spaces between the values.

1647:    Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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;

1662:   PetscFunctionBegin;
1663:   if (!PetscOptionsObject->count) {
1664:     PetscInt *vals;

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: }

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.

1686:    Synopsis:
1687:    #include "petscsys.h"
1688:    PetscErrorCode PetscOptionsStringArray(const char opt[],const char text[],const char man[],char *value[],PetscInt *nmax,PetscBool  *set)

1690:    Logically Collective on the communicator passed in `PetscOptionsBegin()`; No Fortran Support

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

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`

1703:    Level: beginner

1705:    Notes:
1706:    The user should pass in an array of pointers to char, to hold all the
1707:    strings returned by this function.

1709:    The user is responsible for deallocating the strings that are
1710:    returned.

1712:    Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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;

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));

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: }

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.

1745:    Synopsis:
1746:    #include "petscsys.h"
1747:    PetscErrorCode PetscOptionsBoolArray(const char opt[],const char text[],const char man[],PetscBool value[],PetscInt *n,PetscBool *set)

1749:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

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

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`

1762:    Level: beginner

1764:    Notes:
1765:    The user should pass in an array of `PetscBool`

1767:    Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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*/

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;

1782:   PetscFunctionBegin;
1783:   if (!PetscOptionsObject->count) {
1784:     PetscBool *vals;

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: }

1801: /*MC
1802:    PetscOptionsViewer - Gets a viewer appropriate for the type indicated by the user

1804:    Synopsis:
1805:    #include "petscsys.h"
1806:    PetscErrorCode PetscOptionsViewer(const char opt[],const char text[],const char man[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool *set)

1808:    Logically Collective on the communicator passed in `PetscOptionsBegin()`

1810:    Input Parameters:
1811: +  opt - option name
1812: .  text - short string that describes the option
1813: -  man - manual page with additional information on option

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`

1820:    Level: beginner

1822:    Notes:
1823:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1825:    See `PetscOptionsGetViewer()` for the format of the supplied viewer and its options

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*/

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;

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: }