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: static const char *ManSection(const char *str)
 11: {
 12:   return str ? str : "None";
 13: }

 15: static const char *Prefix(const char *str)
 16: {
 17:   return str ? str : "";
 18: }

 20: static int ShouldPrintHelp(const PetscOptionItems *opts)
 21: {
 22:   return opts->printhelp && opts->count == 1 && !opts->alreadyprinted;
 23: }

 25: /*
 26:     Keep a linked list of options that have been posted and we are waiting for
 27:    user selection. See the manual page for PetscOptionsBegin()

 29:     Eventually we'll attach this beast to a MPI_Comm
 30: */

 32: /*
 33:     Handles setting up the data structure in a call to PetscOptionsBegin()
 34: */
 35: PetscErrorCode PetscOptionsBegin_Private(PetscOptionItems *PetscOptionsObject, MPI_Comm comm, const char prefix[], const char title[], const char mansec[])
 36: {
 37:   PetscFunctionBegin;
 38:   if (prefix) PetscAssertPointer(prefix, 3);
 39:   PetscAssertPointer(title, 4);
 40:   if (mansec) PetscAssertPointer(mansec, 5);
 41:   if (!PetscOptionsObject->alreadyprinted) {
 42:     if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
 43:     PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, prefix, title, &PetscOptionsObject->alreadyprinted));
 44:   }
 45:   PetscOptionsObject->next          = NULL;
 46:   PetscOptionsObject->comm          = comm;
 47:   PetscOptionsObject->changedmethod = PETSC_FALSE;

 49:   PetscCall(PetscStrallocpy(prefix, &PetscOptionsObject->prefix));
 50:   PetscCall(PetscStrallocpy(title, &PetscOptionsObject->title));

 52:   PetscCall(PetscOptionsHasHelp(PetscOptionsObject->options, &PetscOptionsObject->printhelp));
 53:   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\n%s:\n", title));
 54:   PetscFunctionReturn(PETSC_SUCCESS);
 55: }

 57: /*
 58:     Handles setting up the data structure in a call to PetscObjectOptionsBegin()
 59: */
 60: PetscErrorCode PetscObjectOptionsBegin_Private(PetscObject obj, PetscOptionItems *PetscOptionsObject)
 61: {
 62:   char      title[256];
 63:   PetscBool flg;

 65:   PetscFunctionBegin;
 66:   PetscAssertPointer(PetscOptionsObject, 2);
 68:   PetscOptionsObject->object         = obj;
 69:   PetscOptionsObject->alreadyprinted = obj->optionsprinted;

 71:   PetscCall(PetscStrcmp(obj->description, obj->class_name, &flg));
 72:   if (flg) PetscCall(PetscSNPrintf(title, sizeof(title), "%s options", obj->class_name));
 73:   else PetscCall(PetscSNPrintf(title, sizeof(title), "%s (%s) options", obj->description, obj->class_name));
 74:   PetscCall(PetscOptionsBegin_Private(PetscOptionsObject, obj->comm, obj->prefix, title, obj->mansec));
 75:   PetscFunctionReturn(PETSC_SUCCESS);
 76: }

 78: /*
 79:      Handles adding another option to the list of options within this particular PetscOptionsBegin() PetscOptionsEnd()
 80: */
 81: static PetscErrorCode PetscOptionItemCreate_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscOptionType t, PetscOptionItem *amsopt)
 82: {
 83:   PetscBool valid;

 85:   PetscFunctionBegin;
 86:   PetscCall(PetscOptionsValidKey(opt, &valid));
 87:   PetscCheck(valid, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "The option '%s' is not a valid key", opt);

 89:   PetscCall(PetscNew(amsopt));
 90:   (*amsopt)->next = NULL;
 91:   (*amsopt)->set  = PETSC_FALSE;
 92:   (*amsopt)->type = t;
 93:   (*amsopt)->data = NULL;

 95:   PetscCall(PetscStrallocpy(text, &(*amsopt)->text));
 96:   PetscCall(PetscStrallocpy(opt, &(*amsopt)->option));
 97:   PetscCall(PetscStrallocpy(man, &(*amsopt)->man));

 99:   {
100:     PetscOptionItem cur = PetscOptionsObject->next;

102:     while (cur->next) cur = cur->next;
103:     cur->next = *amsopt;
104:   }
105:   PetscFunctionReturn(PETSC_SUCCESS);
106: }

108: /*
109:     This is needed because certain strings may be freed by SAWs, hence we cannot use PetscStrallocpy()
110: */
111: static PetscErrorCode PetscStrdup(const char s[], char *t[])
112: {
113:   char *tmp = NULL;

115:   PetscFunctionBegin;
116:   if (s) {
117:     size_t len;

119:     PetscCall(PetscStrlen(s, &len));
120:     tmp = (char *)malloc((len + 1) * sizeof(*tmp));
121:     PetscCheck(tmp, PETSC_COMM_SELF, PETSC_ERR_MEM, "No memory to duplicate string");
122:     PetscCall(PetscArraycpy(tmp, s, len + 1));
123:   }
124:   *t = tmp;
125:   PetscFunctionReturn(PETSC_SUCCESS);
126: }

128: #if defined(PETSC_HAVE_SAWS)
129: #include <petscviewersaws.h>

131: static int count = 0;

133: PetscErrorCode PetscOptionsSAWsDestroy(void)
134: {
135:   PetscFunctionBegin;
136:   PetscFunctionReturn(PETSC_SUCCESS);
137: }

139: static const char *OptionsHeader = "<head>\n"
140:                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/jquery-1.9.1.js\"></script>\n"
141:                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/SAWs.js\"></script>\n"
142:                                    "<script type=\"text/javascript\" src=\"js/PETSc.js\"></script>\n"
143:                                    "<script>\n"
144:                                    "jQuery(document).ready(function() {\n"
145:                                    "PETSc.getAndDisplayDirectory(null,\"#variablesInfo\")\n"
146:                                    "})\n"
147:                                    "</script>\n"
148:                                    "</head>\n";

150: /*  Determines the size and style of the scroll region where PETSc options selectable from users are displayed */
151: static const char *OptionsBodyBottom = "<div id=\"variablesInfo\" style=\"background-color:lightblue;height:auto;max-height:500px;overflow:scroll;\"></div>\n<br>\n</body>";

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

156:     Bugs:
157: +    All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
158: .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
159: -    Only works for PetscInt == int, PetscReal == double etc

161: */
162: static PetscErrorCode PetscOptionsSAWsInput(PetscOptionItems *PetscOptionsObject)
163: {
164:   PetscOptionItem next     = PetscOptionsObject->next;
165:   static int      mancount = 0;
166:   char            options[16];
167:   PetscBool       changedmethod = PETSC_FALSE;
168:   PetscBool       stopasking    = PETSC_FALSE;
169:   char            manname[16], textname[16];
170:   char            dir[1024];

172:   PetscFunctionBegin;
173:   /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */
174:   PetscCall(PetscSNPrintf(options, PETSC_STATIC_ARRAY_LENGTH(options), "Options_%d", count++));

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

178:   PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "_title"));
179:   PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->title, 1, SAWs_READ, SAWs_STRING));
180:   PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "prefix"));
181:   PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->pprefix, 1, SAWs_READ, SAWs_STRING));
182:   PetscCallSAWs(SAWs_Register, ("/PETSc/Options/ChangedMethod", &changedmethod, 1, SAWs_WRITE, SAWs_BOOLEAN));
183:   PetscCallSAWs(SAWs_Register, ("/PETSc/Options/StopAsking", &stopasking, 1, SAWs_WRITE, SAWs_BOOLEAN));

185:   while (next) {
186:     PetscCall(PetscSNPrintf(manname, PETSC_STATIC_ARRAY_LENGTH(manname), "_man_%d", mancount));
187:     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", manname));
188:     PetscCallSAWs(SAWs_Register, (dir, &next->man, 1, SAWs_READ, SAWs_STRING));
189:     PetscCall(PetscSNPrintf(textname, PETSC_STATIC_ARRAY_LENGTH(textname), "_text_%d", mancount++));
190:     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", textname));
191:     PetscCallSAWs(SAWs_Register, (dir, &next->text, 1, SAWs_READ, SAWs_STRING));

193:     switch (next->type) {
194:     case OPTION_HEAD:
195:       break;
196:     case OPTION_INT_ARRAY:
197:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
198:       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_INT));
199:       break;
200:     case OPTION_REAL_ARRAY:
201:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
202:       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_DOUBLE));
203:       break;
204:     case OPTION_INT:
205:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
206:       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_INT));
207:       break;
208:     case OPTION_REAL:
209:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
210:       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_DOUBLE));
211:       break;
212:     case OPTION_BOOL:
213:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
214:       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_BOOLEAN));
215:       break;
216:     case OPTION_BOOL_ARRAY:
217:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
218:       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_BOOLEAN));
219:       break;
220:     case OPTION_STRING:
221:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
222:       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
223:       break;
224:     case OPTION_STRING_ARRAY:
225:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
226:       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_STRING));
227:       break;
228:     case OPTION_FLIST: {
229:       PetscInt ntext;
230:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
231:       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
232:       PetscCall(PetscFunctionListGet(next->flist, (const char ***)&next->edata, &ntext));
233:       PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
234:     } break;
235:     case OPTION_ELIST: {
236:       PetscInt ntext = next->nlist;
237:       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
238:       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
239:       PetscCall(PetscMalloc1((ntext + 1), (char ***)&next->edata));
240:       PetscCall(PetscMemcpy(next->edata, next->list, ntext * sizeof(char *)));
241:       PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
242:     } break;
243:     default:
244:       break;
245:     }
246:     next = next->next;
247:   }

249:   /* wait until accessor has unlocked the memory */
250:   PetscCallSAWs(SAWs_Push_Header, ("index.html", OptionsHeader));
251:   PetscCallSAWs(SAWs_Push_Body, ("index.html", 2, OptionsBodyBottom));
252:   PetscCall(PetscSAWsBlock());
253:   PetscCallSAWs(SAWs_Pop_Header, ("index.html"));
254:   PetscCallSAWs(SAWs_Pop_Body, ("index.html", 2));

256:   /* determine if any values have been set in GUI */
257:   next = PetscOptionsObject->next;
258:   while (next) {
259:     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
260:     PetscCallSAWs(SAWs_Selected, (dir, (int *)&next->set));
261:     next = next->next;
262:   }

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

267:   if (stopasking) {
268:     PetscOptionsPublish       = PETSC_FALSE;
269:     PetscOptionsObject->count = 0; //do not ask for same thing again
270:   }

272:   PetscCallSAWs(SAWs_Delete, ("/PETSc/Options"));
273:   PetscFunctionReturn(PETSC_SUCCESS);
274: }
275: #else
276: /*
277:     PetscScanString -  Gets user input via stdin from process and broadcasts to all processes

279:     Collective

281:    Input Parameters:
282: +     commm - communicator for the broadcast, must be PETSC_COMM_WORLD
283: .     n - length of the string, must be the same on all processes
284: -     str - location to store input

286:     Bugs:
287: .   Assumes process 0 of the given communicator has access to stdin

289: */
290: static PetscErrorCode PetscScanString(MPI_Comm comm, size_t n, char str[])
291: {
292:   PetscMPIInt rank, nm;

294:   PetscFunctionBegin;
295:   PetscCallMPI(MPI_Comm_rank(comm, &rank));
296:   if (rank == 0) {
297:     char   c = (char)getchar();
298:     size_t i = 0;

300:     while (c != '\n' && i < n - 1) {
301:       str[i++] = c;
302:       c        = (char)getchar();
303:     }
304:     str[i] = '\0';
305:   }
306:   PetscCall(PetscMPIIntCast(n, &nm));
307:   PetscCallMPI(MPI_Bcast(str, nm, MPI_CHAR, 0, comm));
308:   PetscFunctionReturn(PETSC_SUCCESS);
309: }

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

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

317:   A carriage return indicates no change from the default; but this like -ksp_monitor <stdout>  the default is actually not stdout the default
318:   is to do nothing so to get it to use stdout you need to type stdout. This is kind of bug?

320:   Bugs:
321: +    All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
322: .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
323: -    Only works for PetscInt == int, PetscReal == double etc

325:   Developer Notes:
326:   Normally the GUI that presents the options the user and retrieves the values would be running in a different
327:   address space and communicating with the PETSc program

329: */
330: static PetscErrorCode PetscOptionsGetFromTextInput(PetscOptionItems *PetscOptionsObject)
331: {
332:   PetscOptionItem next = PetscOptionsObject->next;
333:   char            str[512];
334:   PetscBool       bid;
335:   PetscReal       ir, *valr;
336:   PetscInt       *vald;
337:   size_t          i;

339:   PetscFunctionBegin;
340:   PetscCall((*PetscPrintf)(PETSC_COMM_WORLD, "%s --------------------\n", PetscOptionsObject->title));
341:   while (next) {
342:     switch (next->type) {
343:     case OPTION_HEAD:
344:       break;
345:     case OPTION_INT_ARRAY:
346:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
347:       vald = (PetscInt *)next->data;
348:       for (i = 0; i < next->arraylength; i++) {
349:         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT, vald[i]));
350:         if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
351:       }
352:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
353:       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
354:       if (str[0]) {
355:         PetscToken token;
356:         PetscInt   n = 0, nmax = next->arraylength, *dvalue = (PetscInt *)next->data, start, end;
357:         size_t     len;
358:         char      *value;
359:         PetscBool  foundrange;

361:         next->set = PETSC_TRUE;
362:         value     = str;
363:         PetscCall(PetscTokenCreate(value, ',', &token));
364:         PetscCall(PetscTokenFind(token, &value));
365:         while (n < nmax) {
366:           if (!value) break;

368:           /* look for form  d-D where d and D are integers */
369:           foundrange = PETSC_FALSE;
370:           PetscCall(PetscStrlen(value, &len));
371:           if (value[0] == '-') i = 2;
372:           else i = 1;
373:           for (; i < len; i++) {
374:             if (value[i] == '-') {
375:               PetscCheck(i != len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
376:               value[i] = 0;
377:               PetscCall(PetscOptionsStringToInt(value, &start));
378:               PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
379:               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);
380:               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);
381:               for (; start < end; start++) {
382:                 *dvalue = start;
383:                 dvalue++;
384:                 n++;
385:               }
386:               foundrange = PETSC_TRUE;
387:               break;
388:             }
389:           }
390:           if (!foundrange) {
391:             PetscCall(PetscOptionsStringToInt(value, dvalue));
392:             dvalue++;
393:             n++;
394:           }
395:           PetscCall(PetscTokenFind(token, &value));
396:         }
397:         PetscCall(PetscTokenDestroy(&token));
398:       }
399:       break;
400:     case OPTION_REAL_ARRAY:
401:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
402:       valr = (PetscReal *)next->data;
403:       for (i = 0; i < next->arraylength; i++) {
404:         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i]));
405:         if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
406:       }
407:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
408:       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
409:       if (str[0]) {
410:         PetscToken token;
411:         PetscInt   n = 0, nmax = next->arraylength;
412:         PetscReal *dvalue = (PetscReal *)next->data;
413:         char      *value;

415:         next->set = PETSC_TRUE;
416:         value     = str;
417:         PetscCall(PetscTokenCreate(value, ',', &token));
418:         PetscCall(PetscTokenFind(token, &value));
419:         while (n < nmax) {
420:           if (!value) break;
421:           PetscCall(PetscOptionsStringToReal(value, dvalue));
422:           dvalue++;
423:           n++;
424:           PetscCall(PetscTokenFind(token, &value));
425:         }
426:         PetscCall(PetscTokenDestroy(&token));
427:       }
428:       break;
429:     case OPTION_INT:
430:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%d>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(int *)next->data, next->text, next->man));
431:       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
432:       if (str[0]) {
433:   #if defined(PETSC_SIZEOF_LONG_LONG)
434:         long long lid;
435:         sscanf(str, "%lld", &lid);
436:         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);
437:   #else
438:         long lid;
439:         sscanf(str, "%ld", &lid);
440:         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);
441:   #endif

443:         next->set                 = PETSC_TRUE;
444:         *((PetscInt *)next->data) = (PetscInt)lid;
445:       }
446:       break;
447:     case OPTION_REAL:
448:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%g>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(double *)next->data, next->text, next->man));
449:       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
450:       if (str[0]) {
451:   #if defined(PETSC_USE_REAL_SINGLE)
452:         sscanf(str, "%e", &ir);
453:   #elif defined(PETSC_USE_REAL___FP16)
454:         float irtemp;
455:         sscanf(str, "%e", &irtemp);
456:         ir = irtemp;
457:   #elif defined(PETSC_USE_REAL_DOUBLE)
458:         sscanf(str, "%le", &ir);
459:   #elif defined(PETSC_USE_REAL___FLOAT128)
460:         ir = strtoflt128(str, 0);
461:   #else
462:         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type");
463:   #endif
464:         next->set                  = PETSC_TRUE;
465:         *((PetscReal *)next->data) = ir;
466:       }
467:       break;
468:     case OPTION_BOOL:
469:       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));
470:       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
471:       if (str[0]) {
472:         PetscCall(PetscOptionsStringToBool(str, &bid));
473:         next->set                  = PETSC_TRUE;
474:         *((PetscBool *)next->data) = bid;
475:       }
476:       break;
477:     case OPTION_STRING:
478:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%s>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, (char *)next->data, next->text, next->man));
479:       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
480:       if (str[0]) {
481:         next->set = PETSC_TRUE;
482:         /* must use system malloc since SAWs may free this */
483:         PetscCall(PetscStrdup(str, (char **)&next->data));
484:       }
485:       break;
486:     case OPTION_FLIST:
487:       PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data));
488:       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
489:       if (str[0]) {
490:         PetscOptionsObject->changedmethod = PETSC_TRUE;
491:         next->set                         = PETSC_TRUE;
492:         /* must use system malloc since SAWs may free this */
493:         PetscCall(PetscStrdup(str, (char **)&next->data));
494:       }
495:       break;
496:     default:
497:       break;
498:     }
499:     next = next->next;
500:   }
501:   PetscFunctionReturn(PETSC_SUCCESS);
502: }
503: #endif

505: PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems *PetscOptionsObject)
506: {
507:   PetscOptionItem next, last;

509:   PetscFunctionBegin;
510:   if (PetscOptionsObject->next) {
511:     if (!PetscOptionsObject->count) {
512: #if defined(PETSC_HAVE_SAWS)
513:       PetscCall(PetscOptionsSAWsInput(PetscOptionsObject));
514: #else
515:       PetscCall(PetscOptionsGetFromTextInput(PetscOptionsObject));
516: #endif
517:     }
518:   }

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

522:   /* reset counter to -2; this updates the screen with the new options for the selected method */
523:   if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2;
524:   /* reset alreadyprinted flag */
525:   PetscOptionsObject->alreadyprinted = PETSC_FALSE;
526:   if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE;
527:   PetscOptionsObject->object = NULL;

529:   while ((next = PetscOptionsObject->next)) {
530:     const PetscOptionType type        = next->type;
531:     const size_t          arraylength = next->arraylength;
532:     void                 *data        = next->data;

534:     if (next->set) {
535:       char option[256], value[1024], tmp[32];

537:       if (PetscOptionsObject->prefix) {
538:         PetscCall(PetscStrncpy(option, "-", sizeof(option)));
539:         PetscCall(PetscStrlcat(option, PetscOptionsObject->prefix, sizeof(option)));
540:         PetscCall(PetscStrlcat(option, next->option + 1, sizeof(option)));
541:       } else {
542:         PetscCall(PetscStrncpy(option, next->option, sizeof(option)));
543:       }

545:       switch (type) {
546:       case OPTION_HEAD:
547:         break;
548:       case OPTION_INT_ARRAY:
549:         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscInt *)data)[0]));
550:         for (size_t j = 1; j < arraylength; ++j) {
551:           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscInt *)data)[j]));
552:           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
553:           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
554:         }
555:         break;
556:       case OPTION_INT:
557:         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)*(PetscInt *)data));
558:         break;
559:       case OPTION_REAL:
560:         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)*(PetscReal *)data));
561:         break;
562:       case OPTION_REAL_ARRAY:
563:         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)((PetscReal *)data)[0]));
564:         for (size_t j = 1; j < arraylength; ++j) {
565:           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g", (double)((PetscReal *)data)[j]));
566:           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
567:           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
568:         }
569:         break;
570:       case OPTION_SCALAR_ARRAY:
571:         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[0]), (double)PetscImaginaryPart(((PetscScalar *)data)[0])));
572:         for (size_t j = 1; j < arraylength; ++j) {
573:           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[j]), (double)PetscImaginaryPart(((PetscScalar *)data)[j])));
574:           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
575:           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
576:         }
577:         break;
578:       case OPTION_BOOL:
579:         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", *(int *)data));
580:         break;
581:       case OPTION_BOOL_ARRAY:
582:         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscBool *)data)[0]));
583:         for (size_t j = 1; j < arraylength; ++j) {
584:           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscBool *)data)[j]));
585:           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
586:           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
587:         }
588:         break;
589:       case OPTION_FLIST: // fall-through
590:       case OPTION_ELIST: // fall-through
591:       case OPTION_STRING:
592:         PetscCall(PetscStrncpy(value, (char *)data, sizeof(value)));
593:         break;
594:       case OPTION_STRING_ARRAY:
595:         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%s", ((char **)data)[0]));
596:         for (size_t j = 1; j < arraylength; j++) {
597:           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%s", ((char **)data)[j]));
598:           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
599:           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
600:         }
601:         break;
602:       }
603:       PetscCall(PetscOptionsSetValue(PetscOptionsObject->options, option, value));
604:     }
605:     if (type == OPTION_ELIST) PetscCall(PetscStrNArrayDestroy(next->nlist, (char ***)&next->list));
606:     PetscCall(PetscFree(next->text));
607:     PetscCall(PetscFree(next->option));
608:     PetscCall(PetscFree(next->man));
609:     PetscCall(PetscFree(next->edata));

611:     if (type == OPTION_STRING || type == OPTION_FLIST || type == OPTION_ELIST) {
612:       free(data);
613:     } else {
614:       // use next->data instead of data because PetscFree() sets it to NULL
615:       PetscCall(PetscFree(next->data));
616:     }

618:     last                     = next;
619:     PetscOptionsObject->next = next->next;
620:     PetscCall(PetscFree(last));
621:   }
622:   PetscCall(PetscFree(PetscOptionsObject->prefix));
623:   PetscOptionsObject->next = NULL;
624:   PetscFunctionReturn(PETSC_SUCCESS);
625: }

627: static PetscErrorCode GetListLength(const char *const *list, PetscInt *len)
628: {
629:   PetscInt retlen = 0;

631:   PetscFunctionBegin;
632:   PetscAssertPointer(len, 2);
633:   while (list[retlen]) {
634:     PetscAssertPointer(list[retlen], 1);
635:     PetscCheck(++retlen < 50, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "List argument appears to be wrong or have more than 50 entries");
636:   }
637:   PetscCheck(retlen > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least 2 entries: typename and type prefix");
638:   /* drop item name and prefix*/
639:   *len = retlen - 2;
640:   PetscFunctionReturn(PETSC_SUCCESS);
641: }

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

646:   Synopsis:
647: #include <petscoptions.h>
648:   PetscErrorCode PetscOptionsEnum(const char opt[], const char text[], const char man[], const char *const *list, PetscEnum currentvalue, PetscEnum *value, PetscBool *set)

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

652:   Input Parameters:
653: + opt          - option name
654: . text         - short string that describes the option
655: . man          - manual page with additional information on option
656: . list         - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
657: - currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
658: .vb
659:                  PetscOptionsEnum(..., obj->value,&object->value,...) or
660:                  value = defaultvalue
661:                  PetscOptionsEnum(..., value,&value,&flg);
662:                  if (flg) {
663: .ve

665:   Output Parameters:
666: + value - the  value to return
667: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

669:   Level: beginner

671:   Notes:
672:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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

676:   If the user does not supply the option at all `value` is NOT changed. Thus
677:   you should ALWAYS initialize `value` if you access it without first checking if `set` is `PETSC_TRUE`.

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

681: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
682:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
683:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
684:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
685:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
686:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
687:           `PetscOptionsFList()`, `PetscOptionsEList()`
688: M*/
689: PetscErrorCode PetscOptionsEnum_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum currentvalue, PetscEnum *value, PetscBool *set)
690: {
691:   PetscInt  ntext = 0;
692:   PetscInt  tval;
693:   PetscBool tflg;

695:   PetscFunctionBegin;
696:   PetscAssertPointer(opt, 2);
697:   PetscAssertPointer(list, 5);
698:   PetscAssertPointer(value, 7);
699:   if (set) PetscAssertPointer(set, 8);
700:   PetscCall(GetListLength(list, &ntext));
701:   PetscCall(PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[currentvalue], &tval, &tflg));
702:   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
703:   if (tflg) *value = (PetscEnum)tval;
704:   if (set) *set = tflg;
705:   PetscFunctionReturn(PETSC_SUCCESS);
706: }

708: /*MC
709:   PetscOptionsEnumArray - Gets an array of enum values for a particular
710:   option in the database.

712:   Synopsis:
713: #include <petscoptions.h>
714:   PetscErrorCode PetscOptionsEnumArray(const char opt[], const char text[], const char man[], const char *const *list, PetscEnum value[], PetscInt *n, PetscBool *set)

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

718:   Input Parameters:
719: + opt  - the option one is seeking
720: . text - short string describing option
721: . man  - manual page for option
722: . list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
723: - n    - maximum number of values allowed in the value array

725:   Output Parameters:
726: + value - location to copy values
727: . n     - actual number of values found
728: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

730:   Level: beginner

732:   Notes:
733:   The array must be passed as a comma separated list.

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

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

739: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
740:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
741:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
742:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
743:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
744:           `PetscOptionsFList()`, `PetscOptionsEList()`
745: M*/
746: PetscErrorCode PetscOptionsEnumArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum value[], PetscInt *n, PetscBool *set)
747: {
748:   PetscInt    nlist  = 0;
749:   const char *prefix = PetscOptionsObject->prefix;

751:   PetscFunctionBegin;
752:   PetscAssertPointer(opt, 2);
753:   PetscAssertPointer(list, 5);
754:   PetscAssertPointer(value, 6);
755:   PetscAssertPointer(n, 7);
756:   PetscCheck(*n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") must be > 0", *n);
757:   if (set) PetscAssertPointer(set, 8);
758:   PetscCall(GetListLength(list, &nlist));
759:   PetscCall(PetscOptionsGetEnumArray(PetscOptionsObject->options, prefix, opt, list, value, n, set));
760:   if (ShouldPrintHelp(PetscOptionsObject)) {
761:     const MPI_Comm comm = PetscOptionsObject->comm;
762:     const PetscInt nv   = *n;

764:     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s", Prefix(prefix), opt + 1, list[value[0]]));
765:     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%s", list[value[i]]));
766:     PetscCall((*PetscHelpPrintf)(comm, ">: %s (choose from)", text));
767:     for (PetscInt i = 0; i < nlist; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
768:     PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
769:   }
770:   PetscFunctionReturn(PETSC_SUCCESS);
771: }

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

776:    Synopsis:
777: #include <petscoptions.h>
778:    PetscErrorCode  PetscOptionsBoundedInt(const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *flg, PetscInt bound)

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

782:    Input Parameters:
783: +  opt - option name
784: .  text - short string that describes the option
785: .  man - manual page with additional information on option
786: .  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
787: .vb
788:   PetscOptionsInt(..., obj->value,&obj->value,...)
789: .ve
790: or
791: .vb
792:   value = defaultvalue
793:   PetscOptionsInt(..., value,&value,&flg);
794:   if (flg) {
795: .ve
796: -  bound - the requested value should be greater than or equal this bound or an error is generated

798:    Output Parameters:
799: +  value - the integer value to return
800: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

802:    Level: beginner

804:    Notes:
805:     If the user does not supply the option at all `value` is NOT changed. Thus
806:     you should ALWAYS initialize `value` if you access it without first checking if `flg` is `PETSC_TRUE`.

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

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

812: .seealso: `PetscOptionsInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
813:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`, `PetscOptionsRangeInt()`
814:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
815:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
816:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
817:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
818:           `PetscOptionsFList()`, `PetscOptionsEList()`
819: M*/

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

824:    Synopsis:
825: #include <petscoptions.h>
826:    PetscErrorCode PetscOptionsRangeInt(const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *flg, PetscInt lb, PetscInt ub)

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

830:    Input Parameters:
831: +  opt - option name
832: .  text - short string that describes the option
833: .  man - manual page with additional information on option
834: .  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
835: .vb
836:                  PetscOptionsInt(..., obj->value,&obj->value,...) or
837:                  value = defaultvalue
838:                  PetscOptionsInt(..., value,&value,&flg);
839:                  if (flg) {
840: .ve
841: .  lb - the lower bound, provided value must be greater than or equal to this value or an error is generated
842: -  ub - the upper bound, provided value must be less than or equal to this value or an error is generated

844:    Output Parameters:
845: +  value - the integer value to return
846: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

848:    Level: beginner

850:    Notes:
851:     If the user does not supply the option at all `value` is NOT changed. Thus
852:     you should ALWAYS initialize `value` if you access it without first checking if `flg` is `PETSC_TRUE`.

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

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

858: .seealso: `PetscOptionsInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
859:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`, `PetscOptionsBoundedInt()`
860:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
861:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
862:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
863:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
864:           `PetscOptionsFList()`, `PetscOptionsEList()`
865: M*/

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

870:   Synopsis:
871: #include <petscoptions.h>
872:   PetscErrorCode PetscOptionsInt(const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *set)

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

876:   Input Parameters:
877: + opt          - option name
878: . text         - short string that describes the option
879: . man          - manual page with additional information on option
880: - currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
881: .vb
882:                  PetscOptionsInt(..., obj->value,&obj->value,...) or
883:                  value = defaultvalue
884:                  PetscOptionsInt(..., value,&value,&flg);
885:                  if (flg) {
886: .ve

888:   Output Parameters:
889: + value - the integer value to return
890: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

892:   Level: beginner

894:   Notes:
895:   If the user does not supply the option at all `value` is NOT changed. Thus
896:   you should ALWAYS initialize `value` if you access it without first checking if `flg` is `PETSC_TRUE`.

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

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

902: .seealso: `PetscOptionsBoundedInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
903:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`, `PetscOptionsRangeInt()`
904:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
905:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
906:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
907:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
908:           `PetscOptionsFList()`, `PetscOptionsEList()`
909: M*/
910: PetscErrorCode PetscOptionsInt_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *set, PetscInt lb, PetscInt ub)
911: {
912:   const char        *prefix  = PetscOptionsObject->prefix;
913:   const PetscOptions options = PetscOptionsObject->options;
914:   PetscBool          wasset;

916:   PetscFunctionBegin;
917:   PetscAssertPointer(opt, 2);
918:   PetscAssertPointer(value, 6);
919:   if (set) PetscAssertPointer(set, 7);
920:   PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, currentvalue, lb);
921:   PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, currentvalue, ub);
922:   if (!PetscOptionsObject->count) {
923:     PetscOptionItem amsopt;

925:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt));
926:     PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data));
927:     *(PetscInt *)amsopt->data = currentvalue;

929:     PetscCall(PetscOptionsGetInt(options, prefix, opt, &currentvalue, &wasset));
930:     if (wasset) *(PetscInt *)amsopt->data = currentvalue;
931:   }
932:   PetscCall(PetscOptionsGetInt(options, prefix, opt, value, &wasset));
933:   PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, *value, lb);
934:   PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, *value, ub);
935:   if (set) *set = wasset;
936:   if (ShouldPrintHelp(PetscOptionsObject)) {
937:     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <now %" PetscInt_FMT " : formerly %" PetscInt_FMT ">: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? *value : currentvalue, currentvalue, text, ManSection(man)));
938:   }
939:   PetscFunctionReturn(PETSC_SUCCESS);
940: }

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

945:   Synopsis:
946: #include <petscoptions.h>
947:   PetscErrorCode PetscOptionsString(const char opt[], const char text[], const char man[], const char currentvalue[], char value[], size_t len, PetscBool *set)

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

951:   Input Parameters:
952: + opt          - option name
953: . text         - short string that describes the option
954: . man          - manual page with additional information on option
955: . currentvalue - the current value; caller is responsible for setting this value correctly. This is not used to set value
956: - len          - length of the result string including null terminator

958:   Output Parameters:
959: + value - the value to return
960: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

962:   Level: beginner

964:   Notes:
965:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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

969:   If the user does not supply the option at all `value` is NOT changed. Thus
970:   you should ALWAYS initialize `value` if you access it without first checking if `flg` is `PETSC_TRUE`.

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

974: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
975:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
976:           `PetscOptionsInt()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
977:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
978:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
979:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
980:           `PetscOptionsFList()`, `PetscOptionsEList()`
981: M*/
982: PetscErrorCode PetscOptionsString_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char currentvalue[], char value[], size_t len, PetscBool *set)
983: {
984:   const char *prefix = PetscOptionsObject->prefix;
985:   PetscBool   lset;

987:   PetscFunctionBegin;
988:   PetscAssertPointer(opt, 2);
989:   PetscAssertPointer(value, 6);
990:   if (set) PetscAssertPointer(set, 8);
991:   if (!PetscOptionsObject->count) {
992:     PetscOptionItem amsopt;

994:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
995:     /* must use system malloc since SAWs may free this */
996:     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
997:   }
998:   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
999:   if (set) *set = lset;
1000:   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <now %s : formerly %s>: %s (%s)\n", Prefix(prefix), opt + 1, lset ? value : currentvalue, currentvalue, text, ManSection(man)));
1001:   PetscFunctionReturn(PETSC_SUCCESS);
1002: }

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

1007:   Synopsis:
1008: #include <petscoptions.h>
1009:   PetscErrorCode PetscOptionsReal(const char opt[], const char text[], const char man[], PetscReal currentvalue, PetscReal *value, PetscBool *set)

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

1013:   Input Parameters:
1014: + opt          - option name
1015: . text         - short string that describes the option
1016: . man          - manual page with additional information on option
1017: - currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
1018: .vb
1019:                  PetscOptionsReal(..., obj->value,&obj->value,...) or
1020:                  value = defaultvalue
1021:                  PetscOptionsReal(..., value,&value,&flg);
1022:                  if (flg) {
1023: .ve

1025:   Output Parameters:
1026: + value - the value to return
1027: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

1029:   Level: beginner

1031:   Notes:
1032:   If the user does not supply the option at all `value` is NOT changed. Thus
1033:   you should ALWAYS initialize `value` if you access it without first checking if `flg` is `PETSC_TRUE`.

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

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

1039: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1040:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
1041:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
1042:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1043:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1044:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1045:           `PetscOptionsFList()`, `PetscOptionsEList()`
1046: M*/
1047: PetscErrorCode PetscOptionsReal_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal currentvalue, PetscReal *value, PetscBool *set)
1048: {
1049:   const char *prefix = PetscOptionsObject->prefix;
1050:   PetscBool   lset;

1052:   PetscFunctionBegin;
1053:   PetscAssertPointer(opt, 2);
1054:   PetscAssertPointer(value, 6);
1055:   if (set) PetscAssertPointer(set, 7);
1056:   if (!PetscOptionsObject->count) {
1057:     PetscOptionItem amsopt;

1059:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt));
1060:     PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data));

1062:     *(PetscReal *)amsopt->data = currentvalue;
1063:   }
1064:   PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &lset));
1065:   if (set) *set = lset;
1066:   if (ShouldPrintHelp(PetscOptionsObject)) {
1067:     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <now %g : formerly %g>: %s (%s)\n", Prefix(prefix), opt + 1, lset ? (double)*value : (double)currentvalue, (double)currentvalue, text, ManSection(man)));
1068:   }
1069:   PetscFunctionReturn(PETSC_SUCCESS);
1070: }

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

1075:   Synopsis:
1076: #include <petscoptions.h>
1077:   PetscErrorCode PetscOptionsScalar(const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set)

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

1081:   Input Parameters:
1082: + opt          - option name
1083: . text         - short string that describes the option
1084: . man          - manual page with additional information on option
1085: - currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
1086: .vb
1087:                  PetscOptionsScalar(..., obj->value,&obj->value,...) or
1088:                  value = defaultvalue
1089:                  PetscOptionsScalar(..., value,&value,&flg);
1090:                  if (flg) {
1091: .ve

1093:   Output Parameters:
1094: + value - the value to return
1095: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

1097:   Level: beginner

1099:   Notes:
1100:   If the user does not supply the option at all `value` is NOT changed. Thus
1101:   you should ALWAYS initialize `value` if you access it without first checking if `flg` is `PETSC_TRUE`.

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

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

1107: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1108:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
1109:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
1110:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1111:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1112:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1113:           `PetscOptionsFList()`, `PetscOptionsEList()`
1114: M*/
1115: PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set)
1116: {
1117:   PetscFunctionBegin;
1118: #if !defined(PETSC_USE_COMPLEX)
1119:   PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set));
1120: #else
1121:   PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set));
1122: #endif
1123:   PetscFunctionReturn(PETSC_SUCCESS);
1124: }

1126: /*MC
1127:   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
1128:   its value is set to false.

1130:   Synopsis:
1131: #include <petscoptions.h>
1132:   PetscErrorCode PetscOptionsName(const char opt[], const char text[], const char man[], PetscBool *flg)

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

1136:   Input Parameters:
1137: + opt  - option name
1138: . text - short string that describes the option
1139: - man  - manual page with additional information on option

1141:   Output Parameter:
1142: . flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1144:   Level: beginner

1146:   Note:
1147:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1149: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1150:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
1151:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
1152:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1153:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1154:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1155:           `PetscOptionsFList()`, `PetscOptionsEList()`
1156: M*/
1157: PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1158: {
1159:   const char *prefix = PetscOptionsObject->prefix;

1161:   PetscFunctionBegin;
1162:   PetscAssertPointer(opt, 2);
1163:   PetscAssertPointer(flg, 5);
1164:   if (!PetscOptionsObject->count) {
1165:     PetscOptionItem amsopt;

1167:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1168:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

1170:     *(PetscBool *)amsopt->data = PETSC_FALSE;
1171:   }
1172:   PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg));
1173:   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
1174:   PetscFunctionReturn(PETSC_SUCCESS);
1175: }

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

1180:   Synopsis:
1181: #include <petscoptions.h>
1182:   PetscErrorCode PetscOptionsFList(const char opt[], const char ltext[], const char man[], PetscFunctionList list, const char currentvalue[], char value[], size_t len, PetscBool *set)

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

1186:   Input Parameters:
1187: + opt          - option name
1188: . ltext        - short string that describes the option
1189: . man          - manual page with additional information on option
1190: . list         - the possible choices
1191: . currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with
1192: .vb
1193:                  PetscOptionsFlist(..., obj->value,value,len,&flg);
1194:                  if (flg) {
1195: .ve
1196: - len          - the length of the character array value

1198:   Output Parameters:
1199: + value - the value to return
1200: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

1202:   Level: intermediate

1204:   Notes:
1205:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1207:   If the user does not supply the option at all `value` is NOT changed. Thus
1208:   you should ALWAYS initialize `value` if you access it without first checking if the `set` flag is `PETSC_TRUE`.

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

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

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

1217:   Developer Notes:
1218:   This cannot check for invalid selection because of things like `MATAIJ` that are not included in the list

1220: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1221:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1222:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1223:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1224:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1225:           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsEnum()`
1226: M*/
1227: 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)
1228: {
1229:   const char *prefix = PetscOptionsObject->prefix;
1230:   PetscBool   lset;

1232:   PetscFunctionBegin;
1233:   PetscAssertPointer(opt, 2);
1234:   PetscAssertPointer(value, 7);
1235:   if (set) PetscAssertPointer(set, 9);
1236:   if (!PetscOptionsObject->count) {
1237:     PetscOptionItem amsopt;

1239:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt));
1240:     /* must use system malloc since SAWs may free this */
1241:     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
1242:     amsopt->flist = list;
1243:   }
1244:   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
1245:   if (set) *set = lset;
1246:   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue));
1247:   PetscFunctionReturn(PETSC_SUCCESS);
1248: }

1250: #ifdef __cplusplus
1251:   #include <type_traits>
1252: #endif

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

1257:   Synopsis:
1258: #include <petscoptions.h>
1259:   PetscErrorCode PetscOptionsEList(const char opt[], const char ltext[], const char man[], const char *const *list, PetscInt ntext, const char currentvalue[], PetscInt *value, PetscBool *set)

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

1263:   Input Parameters:
1264: + opt          - option name
1265: . ltext        - short string that describes the option
1266: . man          - manual page with additional information on option
1267: . list         - the possible choices (one of these must be selected, anything else is invalid)
1268: . ntext        - number of choices
1269: - currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with
1270: .vb
1271:                  PetscOptionsEList(..., obj->value,&value,&flg);
1272: .ve                 if (flg) {

1274:   Output Parameters:
1275: + value - the index of the value to return
1276: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

1278:   Level: intermediate

1280:   Notes:
1281:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1283:   If the user does not supply the option at all `value` is NOT changed. Thus
1284:   you should ALWAYS initialize `value` if you access it without first checking if the `set` flag is `PETSC_TRUE`.

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

1288: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1289:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1290:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1291:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1292:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1293:           `PetscOptionsFList()`, `PetscOptionsEnum()`
1294: M*/
1295: 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)
1296: {
1297:   const char *prefix = PetscOptionsObject->prefix;
1298:   PetscBool   lset;

1300:   PetscFunctionBegin;
1301:   PetscAssertPointer(opt, 2);
1302:   PetscAssertPointer(value, 8);
1303:   if (set) PetscAssertPointer(set, 9);
1304:   if (!PetscOptionsObject->count) {
1305:     PetscOptionItem amsopt;

1307:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt));
1308:     /* must use system malloc since SAWs may free this */
1309:     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
1310:     PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list));
1311:     PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX);
1312: #ifdef __cplusplus
1313:     static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, "");
1314: #endif
1315:     amsopt->nlist = (char)ntext;
1316:   }
1317:   PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset));
1318:   if (set) *set = lset;
1319:   if (ShouldPrintHelp(PetscOptionsObject)) {
1320:     const MPI_Comm comm = PetscOptionsObject->comm;

1322:     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext));
1323:     for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
1324:     PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
1325:   }
1326:   PetscFunctionReturn(PETSC_SUCCESS);
1327: }

1329: /*MC
1330:   PetscOptionsBoolGroupBegin - First in a series of logical queries on the options database for
1331:   which at most a single value can be true.

1333:   Synopsis:
1334: #include <petscoptions.h>
1335:   PetscErrorCode PetscOptionsBoolGroupBegin(const char opt[], const char text[], const char man[], PetscBool *flg)

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

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

1344:   Output Parameter:
1345: . flg - whether that option was set or not

1347:   Level: intermediate

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

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

1354: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1355:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1356:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1357:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1358:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1359:           `PetscOptionsFList()`, `PetscOptionsEList()`
1360: M*/
1361: PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1362: {
1363:   const char *prefix = PetscOptionsObject->prefix;

1365:   PetscFunctionBegin;
1366:   PetscAssertPointer(opt, 2);
1367:   PetscAssertPointer(flg, 5);
1368:   if (!PetscOptionsObject->count) {
1369:     PetscOptionItem amsopt;

1371:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1372:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

1374:     *(PetscBool *)amsopt->data = PETSC_FALSE;
1375:   }
1376:   *flg = PETSC_FALSE;
1377:   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
1378:   if (ShouldPrintHelp(PetscOptionsObject)) {
1379:     const MPI_Comm comm = PetscOptionsObject->comm;

1381:     PetscCall((*PetscHelpPrintf)(comm, "  Pick at most one of -------------\n"));
1382:     PetscCall((*PetscHelpPrintf)(comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
1383:   }
1384:   PetscFunctionReturn(PETSC_SUCCESS);
1385: }

1387: /*MC
1388:   PetscOptionsBoolGroup - One in a series of logical queries on the options database for
1389:   which at most a single value can be true.

1391:   Synopsis:
1392: #include <petscoptions.h>
1393:   PetscErrorCode PetscOptionsBoolGroup(const char opt[], const char text[], const char man[], PetscBool *flg)

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

1397:   Input Parameters:
1398: + opt  - option name
1399: . text - short string that describes the option
1400: - man  - manual page with additional information on option

1402:   Output Parameter:
1403: . flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1405:   Level: intermediate

1407:   Notes:
1408:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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

1412: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1413:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1414:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1415:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1416:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1417:           `PetscOptionsFList()`, `PetscOptionsEList()`
1418: M*/
1419: PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1420: {
1421:   const char *prefix = PetscOptionsObject->prefix;

1423:   PetscFunctionBegin;
1424:   PetscAssertPointer(opt, 2);
1425:   PetscAssertPointer(flg, 5);
1426:   if (!PetscOptionsObject->count) {
1427:     PetscOptionItem amsopt;

1429:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1430:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

1432:     *(PetscBool *)amsopt->data = PETSC_FALSE;
1433:   }
1434:   *flg = PETSC_FALSE;
1435:   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
1436:   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
1437:   PetscFunctionReturn(PETSC_SUCCESS);
1438: }

1440: /*MC
1441:   PetscOptionsBoolGroupEnd - Last in a series of logical queries on the options database for
1442:   which at most a single value can be true.

1444:   Synopsis:
1445: #include <petscoptions.h>
1446:   PetscErrorCode PetscOptionsBoolGroupEnd(const char opt[], const char text[], const char man[], PetscBool  *flg)

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

1450:   Input Parameters:
1451: + opt  - option name
1452: . text - short string that describes the option
1453: - man  - manual page with additional information on option

1455:   Output Parameter:
1456: . flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1458:   Level: intermediate

1460:   Notes:
1461:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1463:   Must follow a `PetscOptionsBoolGroupBegin()`

1465: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1466:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1467:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1468:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1469:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1470:           `PetscOptionsFList()`, `PetscOptionsEList()`
1471: M*/
1472: PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1473: {
1474:   const char *prefix = PetscOptionsObject->prefix;

1476:   PetscFunctionBegin;
1477:   PetscAssertPointer(opt, 2);
1478:   PetscAssertPointer(flg, 5);
1479:   if (!PetscOptionsObject->count) {
1480:     PetscOptionItem amsopt;

1482:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1483:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

1485:     *(PetscBool *)amsopt->data = PETSC_FALSE;
1486:   }
1487:   *flg = PETSC_FALSE;
1488:   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
1489:   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
1490:   PetscFunctionReturn(PETSC_SUCCESS);
1491: }

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

1496:   Synopsis:
1497: #include <petscoptions.h>
1498:   PetscErrorCode PetscOptionsBool(const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set)

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

1502:   Input Parameters:
1503: + opt          - option name
1504: . text         - short string that describes the option
1505: . man          - manual page with additional information on option
1506: - currentvalue - the current value

1508:   Output Parameters:
1509: + flg - `PETSC_TRUE` or `PETSC_FALSE`
1510: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1512:   Level: beginner

1514:   Notes:
1515:   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`
1516:   FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`

1518:   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`
1519:   is equivalent to `-requested_bool true`

1521:   If the user does not supply the option at all `flg` is NOT changed. Thus
1522:   you should ALWAYS initialize the `flg` variable if you access it without first checking if the `set` flag is `PETSC_TRUE`.

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

1526: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1527:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
1528:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1529:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1530:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1531:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1532:           `PetscOptionsFList()`, `PetscOptionsEList()`
1533: M*/
1534: PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set)
1535: {
1536:   const char *prefix = PetscOptionsObject->prefix;
1537:   PetscBool   iset;

1539:   PetscFunctionBegin;
1540:   PetscAssertPointer(opt, 2);
1541:   PetscAssertPointer(flg, 6);
1542:   if (set) PetscAssertPointer(set, 7);
1543:   if (!PetscOptionsObject->count) {
1544:     PetscOptionItem amsopt;

1546:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
1547:     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));

1549:     *(PetscBool *)amsopt->data = currentvalue;
1550:   }
1551:   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset));
1552:   if (set) *set = iset;
1553:   if (ShouldPrintHelp(PetscOptionsObject)) {
1554:     const char *curvalue = PetscBools[currentvalue];

1556:     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <now %s : formerly %s> %s (%s)\n", Prefix(prefix), opt + 1, iset ? PetscBools[*flg] : curvalue, curvalue, text, ManSection(man)));
1557:   }
1558:   PetscFunctionReturn(PETSC_SUCCESS);
1559: }

1561: /*MC
1562:   PetscOptionsRealArray - Gets an array of double values for a particular
1563:   option in the database. The values must be separated with commas with
1564:   no intervening spaces.

1566:   Synopsis:
1567: #include <petscoptions.h>
1568:   PetscErrorCode PetscOptionsRealArray(const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set)

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

1572:   Input Parameters:
1573: + opt  - the option one is seeking
1574: . text - short string describing option
1575: . man  - manual page for option
1576: - n    - maximum number of values that value has room for

1578:   Output Parameters:
1579: + value - location to copy values
1580: . n     - actual number of values found
1581: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

1583:   Level: beginner

1585:   Note:
1586:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1588: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1589:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1590:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1591:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1592:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1593:           `PetscOptionsFList()`, `PetscOptionsEList()`
1594: M*/
1595: PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set)
1596: {
1597:   const char *prefix = PetscOptionsObject->prefix;

1599:   PetscFunctionBegin;
1600:   PetscAssertPointer(opt, 2);
1601:   PetscAssertPointer(n, 6);
1602:   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
1603:   if (*n) PetscAssertPointer(value, 5);
1604:   if (set) PetscAssertPointer(set, 7);
1605:   if (!PetscOptionsObject->count) {
1606:     const PetscInt  nv = *n;
1607:     PetscReal      *vals;
1608:     PetscOptionItem amsopt;

1610:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt));
1611:     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
1612:     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
1613:     amsopt->arraylength = nv;
1614:     amsopt->data        = vals;
1615:   }
1616:   PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1617:   if (ShouldPrintHelp(PetscOptionsObject)) {
1618:     const PetscInt nv   = *n;
1619:     const MPI_Comm comm = PetscOptionsObject->comm;

1621:     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0]));
1622:     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i]));
1623:     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1624:   }
1625:   PetscFunctionReturn(PETSC_SUCCESS);
1626: }

1628: /*MC
1629:   PetscOptionsScalarArray - Gets an array of `PetscScalar` values for a particular
1630:   option in the database. The values must be separated with commas with
1631:   no intervening spaces.

1633:   Synopsis:
1634: #include <petscoptions.h>
1635:   PetscErrorCode PetscOptionsScalarArray(const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set)

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

1639:   Input Parameters:
1640: + opt  - the option one is seeking
1641: . text - short string describing option
1642: . man  - manual page for option
1643: - n    - maximum number of values allowed in the value array

1645:   Output Parameters:
1646: + value - location to copy values
1647: . n     - actual number of values found
1648: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

1650:   Level: beginner

1652:   Note:
1653:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1655: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1656:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1657:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1658:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1659:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1660:           `PetscOptionsFList()`, `PetscOptionsEList()`
1661: M*/
1662: PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set)
1663: {
1664:   const char *prefix = PetscOptionsObject->prefix;

1666:   PetscFunctionBegin;
1667:   PetscAssertPointer(opt, 2);
1668:   PetscAssertPointer(n, 6);
1669:   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
1670:   if (*n) PetscAssertPointer(value, 5);
1671:   if (set) PetscAssertPointer(set, 7);
1672:   if (!PetscOptionsObject->count) {
1673:     const PetscInt  nv = *n;
1674:     PetscOptionItem amsopt;
1675:     PetscScalar    *vals;

1677:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt));
1678:     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
1679:     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
1680:     amsopt->arraylength = nv;
1681:     amsopt->data        = vals;
1682:   }
1683:   PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1684:   if (ShouldPrintHelp(PetscOptionsObject)) {
1685:     const PetscInt nv   = *n;
1686:     const MPI_Comm comm = PetscOptionsObject->comm;

1688:     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0])));
1689:     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i])));
1690:     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1691:   }
1692:   PetscFunctionReturn(PETSC_SUCCESS);
1693: }

1695: /*MC
1696:   PetscOptionsIntArray - Gets an array of integers for a particular
1697:   option in the database.

1699:   Synopsis:
1700: #include <petscoptions.h>
1701:   PetscErrorCode PetscOptionsIntArray(const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set)

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

1705:   Input Parameters:
1706: + opt  - the option one is seeking
1707: . text - short string describing option
1708: . man  - manual page for option
1709: - n    - maximum number of values

1711:   Output Parameters:
1712: + value - location to copy values
1713: . n     - actual number of values found
1714: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

1716:   Level: beginner

1718:   Notes:
1719:   The array can be passed as
1720: +   a comma separated list -                                  0,1,2,3,4,5,6,7
1721: .   a range (start\-end+1) -                                  0-8
1722: .   a range with given increment (start\-end+1:inc) -         0-7:2
1723: -   a combination of values and ranges separated by commas -  0,1-8,8-15:2

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

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

1729: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1730:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1731:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1732:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1733:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1734:           `PetscOptionsFList()`, `PetscOptionsEList()`
1735: M*/
1736: PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set)
1737: {
1738:   const char *prefix = PetscOptionsObject->prefix;

1740:   PetscFunctionBegin;
1741:   PetscAssertPointer(opt, 2);
1742:   PetscAssertPointer(n, 6);
1743:   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
1744:   if (*n) PetscAssertPointer(value, 5);
1745:   if (set) PetscAssertPointer(set, 7);
1746:   if (!PetscOptionsObject->count) {
1747:     const PetscInt  nv = *n;
1748:     PetscInt       *vals;
1749:     PetscOptionItem amsopt;

1751:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt));
1752:     PetscCall(PetscMalloc1(nv, &vals));
1753:     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
1754:     amsopt->arraylength = nv;
1755:     amsopt->data        = vals;
1756:   }
1757:   PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1758:   if (ShouldPrintHelp(PetscOptionsObject)) {
1759:     const PetscInt nv   = *n;
1760:     const MPI_Comm comm = PetscOptionsObject->comm;

1762:     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0]));
1763:     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i]));
1764:     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1765:   }
1766:   PetscFunctionReturn(PETSC_SUCCESS);
1767: }

1769: /*MC
1770:   PetscOptionsStringArray - Gets an array of string values for a particular
1771:   option in the database. The values must be separated with commas with
1772:   no intervening spaces.

1774:   Synopsis:
1775: #include <petscoptions.h>
1776:   PetscErrorCode PetscOptionsStringArray(const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool  *set)

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

1780:   Input Parameters:
1781: + opt  - the option one is seeking
1782: . text - short string describing option
1783: . man  - manual page for option
1784: - nmax - maximum number of strings

1786:   Output Parameters:
1787: + value - location to copy strings
1788: . nmax  - actual number of strings found
1789: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

1791:   Level: beginner

1793:   Notes:
1794:   The user should pass in an array of pointers to char, to hold all the
1795:   strings returned by this function.

1797:   The user is responsible for deallocating the strings that are
1798:   returned.

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

1802: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1803:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1804:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1805:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1806:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1807:           `PetscOptionsFList()`, `PetscOptionsEList()`
1808: M*/
1809: PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set)
1810: {
1811:   const char *prefix = PetscOptionsObject->prefix;

1813:   PetscFunctionBegin;
1814:   PetscAssertPointer(opt, 2);
1815:   PetscAssertPointer(nmax, 6);
1816:   PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax);
1817:   if (*nmax) PetscAssertPointer(value, 5);
1818:   if (set) PetscAssertPointer(set, 7);
1819:   if (!PetscOptionsObject->count) {
1820:     const PetscInt  nmaxv = *nmax;
1821:     PetscOptionItem amsopt;

1823:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt));
1824:     PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data));
1825:     amsopt->arraylength = nmaxv;
1826:   }
1827:   PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set));
1828:   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
1829:   PetscFunctionReturn(PETSC_SUCCESS);
1830: }

1832: /*MC
1833:   PetscOptionsBoolArray - Gets an array of logical values (true or false) for a particular
1834:   option in the database. The values must be separated with commas with
1835:   no intervening spaces.

1837:   Synopsis:
1838: #include <petscoptions.h>
1839:   PetscErrorCode PetscOptionsBoolArray(const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set)

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

1843:   Input Parameters:
1844: + opt  - the option one is seeking
1845: . text - short string describing option
1846: . man  - manual page for option
1847: - n    - maximum number of values allowed in the value array

1849:   Output Parameters:
1850: + value - location to copy values
1851: . n     - actual number of values found
1852: - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`

1854:   Level: beginner

1856:   Notes:
1857:   The user should pass in an array of `PetscBool`

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

1861: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1862:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1863:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1864:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1865:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1866:           `PetscOptionsFList()`, `PetscOptionsEList()`
1867: M*/
1868: PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set)
1869: {
1870:   const char *prefix = PetscOptionsObject->prefix;

1872:   PetscFunctionBegin;
1873:   PetscAssertPointer(opt, 2);
1874:   PetscAssertPointer(n, 6);
1875:   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
1876:   if (*n) PetscAssertPointer(value, 5);
1877:   if (set) PetscAssertPointer(set, 7);
1878:   if (!PetscOptionsObject->count) {
1879:     const PetscInt  nv = *n;
1880:     PetscBool      *vals;
1881:     PetscOptionItem amsopt;

1883:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt));
1884:     PetscCall(PetscMalloc1(nv, &vals));
1885:     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
1886:     amsopt->arraylength = nv;
1887:     amsopt->data        = vals;
1888:   }
1889:   PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1890:   if (ShouldPrintHelp(PetscOptionsObject)) {
1891:     const PetscInt nv   = *n;
1892:     const MPI_Comm comm = PetscOptionsObject->comm;

1894:     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%d", Prefix(prefix), opt + 1, value[0]));
1895:     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i]));
1896:     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1897:   }
1898:   PetscFunctionReturn(PETSC_SUCCESS);
1899: }

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

1904:   Synopsis:
1905: #include <petscviewer.h>
1906:   PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)

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

1910:   Input Parameters:
1911: + opt  - option name
1912: . text - short string that describes the option
1913: - man  - manual page with additional information on option

1915:   Output Parameters:
1916: + viewer - the viewer
1917: . format - the PetscViewerFormat requested by the user, pass NULL if not needed
1918: - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`

1920:   Level: beginner

1922:   Notes:
1923:   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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

1927: .seealso: `PetscOptionsGetViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1928:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
1929:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1930:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1931:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1932:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1933:           `PetscOptionsFList()`, `PetscOptionsEList()`
1934: M*/
1935: PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
1936: {
1937:   const MPI_Comm comm   = PetscOptionsObject->comm;
1938:   const char    *prefix = PetscOptionsObject->prefix;

1940:   PetscFunctionBegin;
1941:   PetscAssertPointer(opt, 2);
1942:   PetscAssertPointer(viewer, 5);
1943:   if (format) PetscAssertPointer(format, 6);
1944:   if (set) PetscAssertPointer(set, 7);
1945:   if (!PetscOptionsObject->count) {
1946:     PetscOptionItem amsopt;

1948:     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
1949:     /* must use system malloc since SAWs may free this */
1950:     PetscCall(PetscStrdup("", (char **)&amsopt->data));
1951:   }
1952:   PetscCall(PetscOptionsGetViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set));
1953:   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man)));
1954:   PetscFunctionReturn(PETSC_SUCCESS);
1955: }