Actual source code: aoptions.c

  1: /*
  2:    Implements the higher-level options database querying methods. These are self-documenting and can attach at runtime to
  3:    GUI code to display the options and get values from the users.

  5: */

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

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

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

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

 19: /*
 20:     Handles setting up the data structure in a call to PetscOptionsBegin()
 21: */
 22: PetscErrorCode PetscOptionsBegin_Private(PetscOptionItems *PetscOptionsObject, MPI_Comm comm, const char prefix[], const char title[], const char mansec[])
 23: {
 27:   if (!PetscOptionsObject->alreadyprinted) {
 28:     if (!PetscOptionsHelpPrintedSingleton) PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton);
 29:     PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, prefix, title, &PetscOptionsObject->alreadyprinted);
 30:   }
 31:   PetscOptionsObject->next          = NULL;
 32:   PetscOptionsObject->comm          = comm;
 33:   PetscOptionsObject->changedmethod = PETSC_FALSE;

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

 38:   PetscOptionsHasHelp(PetscOptionsObject->options, &PetscOptionsObject->printhelp);
 39:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1) {
 40:     if (!PetscOptionsObject->alreadyprinted) (*PetscHelpPrintf)(comm, "----------------------------------------\n%s:\n", title);
 41:   }
 42:   return 0;
 43: }

 45: /*
 46:     Handles setting up the data structure in a call to PetscObjectOptionsBegin()
 47: */
 48: PetscErrorCode PetscObjectOptionsBegin_Private(PetscObject obj, PetscOptionItems *PetscOptionsObject)
 49: {
 50:   char      title[256];
 51:   PetscBool flg;

 55:   PetscOptionsObject->object         = obj;
 56:   PetscOptionsObject->alreadyprinted = obj->optionsprinted;

 58:   PetscStrcmp(obj->description, obj->class_name, &flg);
 59:   if (flg) PetscSNPrintf(title, sizeof(title), "%s options", obj->class_name);
 60:   else PetscSNPrintf(title, sizeof(title), "%s (%s) options", obj->description, obj->class_name);
 61:   PetscOptionsBegin_Private(PetscOptionsObject, obj->comm, obj->prefix, title, obj->mansec);
 62:   return 0;
 63: }

 65: /*
 66:      Handles adding another option to the list of options within this particular PetscOptionsBegin() PetscOptionsEnd()
 67: */
 68: static int PetscOptionItemCreate_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscOptionType t, PetscOptionItem *amsopt)
 69: {
 70:   PetscOptionItem next;
 71:   PetscBool       valid;

 73:   PetscOptionsValidKey(opt, &valid);

 76:   PetscNew(amsopt);
 77:   (*amsopt)->next = NULL;
 78:   (*amsopt)->set  = PETSC_FALSE;
 79:   (*amsopt)->type = t;
 80:   (*amsopt)->data = NULL;

 82:   PetscStrallocpy(text, &(*amsopt)->text);
 83:   PetscStrallocpy(opt, &(*amsopt)->option);
 84:   PetscStrallocpy(man, &(*amsopt)->man);

 86:   if (!PetscOptionsObject->next) PetscOptionsObject->next = *amsopt;
 87:   else {
 88:     next = PetscOptionsObject->next;
 89:     while (next->next) next = next->next;
 90:     next->next = *amsopt;
 91:   }
 92:   return 0;
 93: }

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

 98:     Collective

100:    Input Parameters:
101: +     commm - communicator for the broadcast, must be PETSC_COMM_WORLD
102: .     n - length of the string, must be the same on all processes
103: -     str - location to store input

105:     Bugs:
106: .   Assumes process 0 of the given communicator has access to stdin

108: */
109: static PetscErrorCode PetscScanString(MPI_Comm comm, size_t n, char str[])
110: {
111:   PetscMPIInt rank, nm;

113:   MPI_Comm_rank(comm, &rank);
114:   if (rank == 0) {
115:     char   c = (char)getchar();
116:     size_t i = 0;

118:     while (c != '\n' && i < n - 1) {
119:       str[i++] = c;
120:       c        = (char)getchar();
121:     }
122:     str[i] = 0;
123:   }
124:   PetscMPIIntCast(n, &nm);
125:   MPI_Bcast(str, nm, MPI_CHAR, 0, comm);
126:   return 0;
127: }

129: /*
130:     This is needed because certain strings may be freed by SAWs, hence we cannot use PetscStrallocpy()
131: */
132: static PetscErrorCode PetscStrdup(const char s[], char *t[])
133: {
134:   char *tmp = NULL;

136:   if (s) {
137:     size_t len;

139:     PetscStrlen(s, &len);
140:     tmp = (char *)malloc((len + 1) * sizeof(*tmp));
142:     PetscStrcpy(tmp, s);
143:   }
144:   *t = tmp;
145:   return 0;
146: }

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

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

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

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

162:     Developer Note:
163:     Normally the GUI that presents the options the user and retrieves the values would be running in a different
164:      address space and communicating with the PETSc program

166: */
167: PetscErrorCode PetscOptionsGetFromTextInput(PetscOptionItems *PetscOptionsObject)
168: {
169:   PetscOptionItem next = PetscOptionsObject->next;
170:   char            str[512];
171:   PetscBool       bid;
172:   PetscReal       ir, *valr;
173:   PetscInt       *vald;
174:   size_t          i;

176:   (*PetscPrintf)(PETSC_COMM_WORLD, "%s --------------------\n", PetscOptionsObject->title);
177:   while (next) {
178:     switch (next->type) {
179:     case OPTION_HEAD:
180:       break;
181:     case OPTION_INT_ARRAY:
182:       PetscPrintf(PETSC_COMM_WORLD, "-%s%s <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1);
183:       vald = (PetscInt *)next->data;
184:       for (i = 0; i < next->arraylength; i++) {
185:         PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT, vald[i]);
186:         if (i < next->arraylength - 1) PetscPrintf(PETSC_COMM_WORLD, ",");
187:       }
188:       PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man);
189:       PetscScanString(PETSC_COMM_WORLD, 512, str);
190:       if (str[0]) {
191:         PetscToken token;
192:         PetscInt   n = 0, nmax = next->arraylength, *dvalue = (PetscInt *)next->data, start, end;
193:         size_t     len;
194:         char      *value;
195:         PetscBool  foundrange;

197:         next->set = PETSC_TRUE;
198:         value     = str;
199:         PetscTokenCreate(value, ',', &token);
200:         PetscTokenFind(token, &value);
201:         while (n < nmax) {
202:           if (!value) break;

204:           /* look for form  d-D where d and D are integers */
205:           foundrange = PETSC_FALSE;
206:           PetscStrlen(value, &len);
207:           if (value[0] == '-') i = 2;
208:           else i = 1;
209:           for (; i < len; i++) {
210:             if (value[i] == '-') {
212:               value[i] = 0;
213:               PetscOptionsStringToInt(value, &start);
214:               PetscOptionsStringToInt(value + i + 1, &end);
217:               for (; start < end; start++) {
218:                 *dvalue = start;
219:                 dvalue++;
220:                 n++;
221:               }
222:               foundrange = PETSC_TRUE;
223:               break;
224:             }
225:           }
226:           if (!foundrange) {
227:             PetscOptionsStringToInt(value, dvalue);
228:             dvalue++;
229:             n++;
230:           }
231:           PetscTokenFind(token, &value);
232:         }
233:         PetscTokenDestroy(&token);
234:       }
235:       break;
236:     case OPTION_REAL_ARRAY:
237:       PetscPrintf(PETSC_COMM_WORLD, "-%s%s <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1);
238:       valr = (PetscReal *)next->data;
239:       for (i = 0; i < next->arraylength; i++) {
240:         PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i]);
241:         if (i < next->arraylength - 1) PetscPrintf(PETSC_COMM_WORLD, ",");
242:       }
243:       PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man);
244:       PetscScanString(PETSC_COMM_WORLD, 512, str);
245:       if (str[0]) {
246:         PetscToken token;
247:         PetscInt   n = 0, nmax = next->arraylength;
248:         PetscReal *dvalue = (PetscReal *)next->data;
249:         char      *value;

251:         next->set = PETSC_TRUE;
252:         value     = str;
253:         PetscTokenCreate(value, ',', &token);
254:         PetscTokenFind(token, &value);
255:         while (n < nmax) {
256:           if (!value) break;
257:           PetscOptionsStringToReal(value, dvalue);
258:           dvalue++;
259:           n++;
260:           PetscTokenFind(token, &value);
261:         }
262:         PetscTokenDestroy(&token);
263:       }
264:       break;
265:     case OPTION_INT:
266:       PetscPrintf(PETSC_COMM_WORLD, "-%s%s <%d>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(int *)next->data, next->text, next->man);
267:       PetscScanString(PETSC_COMM_WORLD, 512, str);
268:       if (str[0]) {
269: #if defined(PETSC_SIZEOF_LONG_LONG)
270:         long long lid;
271:         sscanf(str, "%lld", &lid);
273: #else
274:         long lid;
275:         sscanf(str, "%ld", &lid);
277: #endif

279:         next->set                 = PETSC_TRUE;
280:         *((PetscInt *)next->data) = (PetscInt)lid;
281:       }
282:       break;
283:     case OPTION_REAL:
284:       PetscPrintf(PETSC_COMM_WORLD, "-%s%s <%g>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(double *)next->data, next->text, next->man);
285:       PetscScanString(PETSC_COMM_WORLD, 512, str);
286:       if (str[0]) {
287: #if defined(PETSC_USE_REAL_SINGLE)
288:         sscanf(str, "%e", &ir);
289: #elif defined(PETSC_USE_REAL___FP16)
290:         float irtemp;
291:         sscanf(str, "%e", &irtemp);
292:         ir = irtemp;
293: #elif defined(PETSC_USE_REAL_DOUBLE)
294:         sscanf(str, "%le", &ir);
295: #elif defined(PETSC_USE_REAL___FLOAT128)
296:         ir = strtoflt128(str, 0);
297: #else
298:         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type");
299: #endif
300:         next->set                  = PETSC_TRUE;
301:         *((PetscReal *)next->data) = ir;
302:       }
303:       break;
304:     case OPTION_BOOL:
305:       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);
306:       PetscScanString(PETSC_COMM_WORLD, 512, str);
307:       if (str[0]) {
308:         PetscOptionsStringToBool(str, &bid);
309:         next->set                  = PETSC_TRUE;
310:         *((PetscBool *)next->data) = bid;
311:       }
312:       break;
313:     case OPTION_STRING:
314:       PetscPrintf(PETSC_COMM_WORLD, "-%s%s <%s>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, (char *)next->data, next->text, next->man);
315:       PetscScanString(PETSC_COMM_WORLD, 512, str);
316:       if (str[0]) {
317:         next->set = PETSC_TRUE;
318:         /* must use system malloc since SAWs may free this */
319:         PetscStrdup(str, (char **)&next->data);
320:       }
321:       break;
322:     case OPTION_FLIST:
323:       PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data);
324:       PetscScanString(PETSC_COMM_WORLD, 512, str);
325:       if (str[0]) {
326:         PetscOptionsObject->changedmethod = PETSC_TRUE;
327:         next->set                         = PETSC_TRUE;
328:         /* must use system malloc since SAWs may free this */
329:         PetscStrdup(str, (char **)&next->data);
330:       }
331:       break;
332:     default:
333:       break;
334:     }
335:     next = next->next;
336:   }
337:   return 0;
338: }

340: #if defined(PETSC_HAVE_SAWS)
341: #include <petscviewersaws.h>

343: static int count = 0;

345: PetscErrorCode PetscOptionsSAWsDestroy(void)
346: {
347:   return 0;
348: }

350: static const char *OptionsHeader = "<head>\n"
351:                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/jquery-1.9.1.js\"></script>\n"
352:                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/SAWs.js\"></script>\n"
353:                                    "<script type=\"text/javascript\" src=\"js/PETSc.js\"></script>\n"
354:                                    "<script>\n"
355:                                    "jQuery(document).ready(function() {\n"
356:                                    "PETSc.getAndDisplayDirectory(null,\"#variablesInfo\")\n"
357:                                    "})\n"
358:                                    "</script>\n"
359:                                    "</head>\n";

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

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

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

372: */
373: PetscErrorCode PetscOptionsSAWsInput(PetscOptionItems *PetscOptionsObject)
374: {
375:   PetscOptionItem next     = PetscOptionsObject->next;
376:   static int      mancount = 0;
377:   char            options[16];
378:   PetscBool       changedmethod = PETSC_FALSE;
379:   PetscBool       stopasking    = PETSC_FALSE;
380:   char            manname[16], textname[16];
381:   char            dir[1024];

383:   /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */
384:   sprintf(options, "Options_%d", count++);

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

388:   PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "_title");
389:   SAWs_Register, (dir, &PetscOptionsObject->title, 1, SAWs_READ, SAWs_STRING);
390:   PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "prefix");
391:   SAWs_Register, (dir, &PetscOptionsObject->pprefix, 1, SAWs_READ, SAWs_STRING);
392:   SAWs_Register, ("/PETSc/Options/ChangedMethod", &changedmethod, 1, SAWs_WRITE, SAWs_BOOLEAN);
393:   SAWs_Register, ("/PETSc/Options/StopAsking", &stopasking, 1, SAWs_WRITE, SAWs_BOOLEAN);

395:   while (next) {
396:     sprintf(manname, "_man_%d", mancount);
397:     PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", manname);
398:     SAWs_Register, (dir, &next->man, 1, SAWs_READ, SAWs_STRING);
399:     sprintf(textname, "_text_%d", mancount++);
400:     PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", textname);
401:     SAWs_Register, (dir, &next->text, 1, SAWs_READ, SAWs_STRING);

403:     switch (next->type) {
404:     case OPTION_HEAD:
405:       break;
406:     case OPTION_INT_ARRAY:
407:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
408:       SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_INT);
409:       break;
410:     case OPTION_REAL_ARRAY:
411:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
412:       SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_DOUBLE);
413:       break;
414:     case OPTION_INT:
415:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
416:       SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_INT);
417:       break;
418:     case OPTION_REAL:
419:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
420:       SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_DOUBLE);
421:       break;
422:     case OPTION_BOOL:
423:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
424:       SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_BOOLEAN);
425:       break;
426:     case OPTION_BOOL_ARRAY:
427:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
428:       SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_BOOLEAN);
429:       break;
430:     case OPTION_STRING:
431:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
432:       SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING);
433:       break;
434:     case OPTION_STRING_ARRAY:
435:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
436:       SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_STRING);
437:       break;
438:     case OPTION_FLIST: {
439:       PetscInt ntext;
440:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
441:       SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING);
442:       PetscFunctionListGet(next->flist, (const char ***)&next->edata, &ntext);
443:       SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata);
444:     } break;
445:     case OPTION_ELIST: {
446:       PetscInt ntext = next->nlist;
447:       PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
448:       SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING);
449:       PetscMalloc1((ntext + 1), (char ***)&next->edata);
450:       PetscMemcpy(next->edata, next->list, ntext * sizeof(char *));
451:       SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata);
452:     } break;
453:     default:
454:       break;
455:     }
456:     next = next->next;
457:   }

459:   /* wait until accessor has unlocked the memory */
460:   SAWs_Push_Header, ("index.html", OptionsHeader);
461:   SAWs_Push_Body, ("index.html", 2, OptionsBodyBottom);
462:   PetscSAWsBlock();
463:   SAWs_Pop_Header, ("index.html");
464:   SAWs_Pop_Body, ("index.html", 2);

466:   /* determine if any values have been set in GUI */
467:   next = PetscOptionsObject->next;
468:   while (next) {
469:     PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option);
470:     SAWs_Selected, (dir, (int *)&next->set);
471:     next = next->next;
472:   }

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

477:   if (stopasking) {
478:     PetscOptionsPublish       = PETSC_FALSE;
479:     PetscOptionsObject->count = 0; //do not ask for same thing again
480:   }

482:   SAWs_Delete, ("/PETSc/Options");
483:   return 0;
484: }
485: #endif

487: PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems *PetscOptionsObject)
488: {
489:   PetscOptionItem last;
490:   char            option[256], value[1024], tmp[32];
491:   size_t          j;

493:   if (PetscOptionsObject->next) {
494:     if (!PetscOptionsObject->count) {
495: #if defined(PETSC_HAVE_SAWS)
496:       PetscOptionsSAWsInput(PetscOptionsObject);
497: #else
498:       PetscOptionsGetFromTextInput(PetscOptionsObject);
499: #endif
500:     }
501:   }

503:   PetscFree(PetscOptionsObject->title);

505:   /* reset counter to -2; this updates the screen with the new options for the selected method */
506:   if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2;
507:   /* reset alreadyprinted flag */
508:   PetscOptionsObject->alreadyprinted = PETSC_FALSE;
509:   if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE;
510:   PetscOptionsObject->object = NULL;

512:   while (PetscOptionsObject->next) {
513:     if (PetscOptionsObject->next->set) {
514:       if (PetscOptionsObject->prefix) {
515:         PetscStrcpy(option, "-");
516:         PetscStrcat(option, PetscOptionsObject->prefix);
517:         PetscStrcat(option, PetscOptionsObject->next->option + 1);
518:       } else PetscStrcpy(option, PetscOptionsObject->next->option);

520:       switch (PetscOptionsObject->next->type) {
521:       case OPTION_HEAD:
522:         break;
523:       case OPTION_INT_ARRAY:
524:         sprintf(value, "%d", (int)((PetscInt *)PetscOptionsObject->next->data)[0]);
525:         for (j = 1; j < PetscOptionsObject->next->arraylength; j++) {
526:           sprintf(tmp, "%d", (int)((PetscInt *)PetscOptionsObject->next->data)[j]);
527:           PetscStrcat(value, ",");
528:           PetscStrcat(value, tmp);
529:         }
530:         break;
531:       case OPTION_INT:
532:         sprintf(value, "%d", (int)*(PetscInt *)PetscOptionsObject->next->data);
533:         break;
534:       case OPTION_REAL:
535:         sprintf(value, "%g", (double)*(PetscReal *)PetscOptionsObject->next->data);
536:         break;
537:       case OPTION_REAL_ARRAY:
538:         sprintf(value, "%g", (double)((PetscReal *)PetscOptionsObject->next->data)[0]);
539:         for (j = 1; j < PetscOptionsObject->next->arraylength; j++) {
540:           sprintf(tmp, "%g", (double)((PetscReal *)PetscOptionsObject->next->data)[j]);
541:           PetscStrcat(value, ",");
542:           PetscStrcat(value, tmp);
543:         }
544:         break;
545:       case OPTION_SCALAR_ARRAY:
546:         sprintf(value, "%g+%gi", (double)PetscRealPart(((PetscScalar *)PetscOptionsObject->next->data)[0]), (double)PetscImaginaryPart(((PetscScalar *)PetscOptionsObject->next->data)[0]));
547:         for (j = 1; j < PetscOptionsObject->next->arraylength; j++) {
548:           sprintf(tmp, "%g+%gi", (double)PetscRealPart(((PetscScalar *)PetscOptionsObject->next->data)[j]), (double)PetscImaginaryPart(((PetscScalar *)PetscOptionsObject->next->data)[j]));
549:           PetscStrcat(value, ",");
550:           PetscStrcat(value, tmp);
551:         }
552:         break;
553:       case OPTION_BOOL:
554:         sprintf(value, "%d", *(int *)PetscOptionsObject->next->data);
555:         break;
556:       case OPTION_BOOL_ARRAY:
557:         sprintf(value, "%d", (int)((PetscBool *)PetscOptionsObject->next->data)[0]);
558:         for (j = 1; j < PetscOptionsObject->next->arraylength; j++) {
559:           sprintf(tmp, "%d", (int)((PetscBool *)PetscOptionsObject->next->data)[j]);
560:           PetscStrcat(value, ",");
561:           PetscStrcat(value, tmp);
562:         }
563:         break;
564:       case OPTION_FLIST:
565:         PetscStrcpy(value, (char *)PetscOptionsObject->next->data);
566:         break;
567:       case OPTION_ELIST:
568:         PetscStrcpy(value, (char *)PetscOptionsObject->next->data);
569:         break;
570:       case OPTION_STRING:
571:         PetscStrcpy(value, (char *)PetscOptionsObject->next->data);
572:         break;
573:       case OPTION_STRING_ARRAY:
574:         sprintf(value, "%s", ((char **)PetscOptionsObject->next->data)[0]);
575:         for (j = 1; j < PetscOptionsObject->next->arraylength; j++) {
576:           sprintf(tmp, "%s", ((char **)PetscOptionsObject->next->data)[j]);
577:           PetscStrcat(value, ",");
578:           PetscStrcat(value, tmp);
579:         }
580:         break;
581:       }
582:       PetscOptionsSetValue(PetscOptionsObject->options, option, value);
583:     }
584:     if (PetscOptionsObject->next->type == OPTION_ELIST) PetscStrNArrayDestroy(PetscOptionsObject->next->nlist, (char ***)&PetscOptionsObject->next->list);
585:     PetscFree(PetscOptionsObject->next->text);
586:     PetscFree(PetscOptionsObject->next->option);
587:     PetscFree(PetscOptionsObject->next->man);
588:     PetscFree(PetscOptionsObject->next->edata);

590:     if ((PetscOptionsObject->next->type == OPTION_STRING) || (PetscOptionsObject->next->type == OPTION_FLIST) || (PetscOptionsObject->next->type == OPTION_ELIST)) {
591:       free(PetscOptionsObject->next->data);
592:     } else {
593:       PetscFree(PetscOptionsObject->next->data);
594:     }

596:     last                     = PetscOptionsObject->next;
597:     PetscOptionsObject->next = PetscOptionsObject->next->next;
598:     PetscFree(last);
599:   }
600:   PetscFree(PetscOptionsObject->prefix);
601:   PetscOptionsObject->next = NULL;
602:   return 0;
603: }

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

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

610:    Synopsis:
611:    #include "petscsys.h"
612:    PetscErrorCode  PetscOptionsEnum(const char opt[],const char text[],const char man[],const char *const *list,PetscEnum currentvalue,PetscEnum *value,PetscBool  *set)

614:    Input Parameters:
615: +  opt - option name
616: .  text - short string that describes the option
617: .  man - manual page with additional information on option
618: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
619: -  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
620: $                 PetscOptionsEnum(..., obj->value,&object->value,...) or
621: $                 value = defaultvalue
622: $                 PetscOptionsEnum(..., value,&value,&flg);
623: $                 if (flg) {

625:    Output Parameters:
626: +  value - the  value to return
627: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

629:    Level: beginner

631:    Notes:
632:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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

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

639:           The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.

641: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
642:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
643:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
644:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
645:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
646:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
647:           `PetscOptionsFList()`, `PetscOptionsEList()`
648: M*/

650: PetscErrorCode PetscOptionsEnum_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum currentvalue, PetscEnum *value, PetscBool *set)
651: {
652:   PetscInt  ntext = 0;
653:   PetscInt  tval;
654:   PetscBool tflg;

658:   ntext -= 3;
659:   PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[currentvalue], &tval, &tflg);
660:   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
661:   if (tflg) *value = (PetscEnum)tval;
662:   if (set) *set = tflg;
663:   return 0;
664: }

666: /*MC
667:    PetscOptionsEnumArray - Gets an array of enum values for a particular
668:    option in the database.

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

672:    Synopsis:
673:    #include "petscsys.h"
674:    PetscErrorCode  PetscOptionsEnumArray(const char opt[],const char text[],const char man[],const char *const *list,PetscEnum value[],PetscInt *n,PetscBool  *set)

676:    Input Parameters:
677: +  opt - the option one is seeking
678: .  text - short string describing option
679: .  man - manual page for option
680: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
681: -  n - maximum number of values allowed in the value array

683:    Output Parameters:
684: +  value - location to copy values
685: .  n - actual number of values found
686: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

688:    Level: beginner

690:    Notes:
691:    The array must be passed as a comma separated list.

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

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

697: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
698:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
699:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
700:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
701:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
702:           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsRealArray()`
703: M*/

705: PetscErrorCode PetscOptionsEnumArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum value[], PetscInt *n, PetscBool *set)
706: {
707:   PetscInt        i, nlist = 0;
708:   PetscOptionItem amsopt;

712:   nlist -= 3;                            /* drop enum name, prefix, and null termination */
713:   if (0 && !PetscOptionsObject->count) { /* XXX Requires additional support */
714:     PetscEnum *vals;
715:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY /*XXX OPTION_ENUM_ARRAY*/, &amsopt);
716:     PetscStrNArrayallocpy(nlist, list, (char ***)&amsopt->list);
717:     amsopt->nlist = nlist;
718:     PetscMalloc1(*n, (PetscEnum **)&amsopt->data);
719:     amsopt->arraylength = *n;
720:     vals                = (PetscEnum *)amsopt->data;
721:     for (i = 0; i < *n; i++) vals[i] = value[i];
722:   }
723:   PetscOptionsGetEnumArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, list, value, n, set);
724:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
725:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%s", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, list[value[0]]);
726:     for (i = 1; i < *n; i++) (*PetscHelpPrintf)(PetscOptionsObject->comm, ",%s", list[value[i]]);
727:     (*PetscHelpPrintf)(PetscOptionsObject->comm, ">: %s (choose from)", text);
728:     for (i = 0; i < nlist; i++) (*PetscHelpPrintf)(PetscOptionsObject->comm, " %s", list[i]);
729:     (*PetscHelpPrintf)(PetscOptionsObject->comm, " (%s)\n", ManSection(man));
730:   }
731:   return 0;
732: }

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

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

739:    Synopsis:
740:    #include "petscsys.h"
741:    PetscErrorCode  PetscOptionsBoundInt(const char opt[],const char text[],const char man[],PetscInt currentvalue,PetscInt *value,PetscBool *flg,PetscInt bound)

743:    Input Parameters:
744: +  opt - option name
745: .  text - short string that describes the option
746: .  man - manual page with additional information on option
747: .  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
748: $                 PetscOptionsInt(..., obj->value,&obj->value,...) or
749: $                 value = defaultvalue
750: $                 PetscOptionsInt(..., value,&value,&flg);
751: $                 if (flg) {
752: -  bound - the requested value should be greater than or equal this bound or an error is generated

754:    Output Parameters:
755: +  value - the integer value to return
756: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

758:    Notes:
759:     If the user does not supply the option at all value is NOT changed. Thus
760:     you should ALWAYS initialize value if you access it without first checking if the set flag is true.

762:     The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.

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

766:    Level: beginner

768: .seealso: `PetscOptionsInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
769:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`, `PetscOptionsRangeInt()`
770:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
771:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
772:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
773:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
774:           `PetscOptionsFList()`, `PetscOptionsEList()`
775: M*/

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

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

782:    Synopsis:
783:    #include "petscsys.h"
784:    PetscErrorCode  PetscOptionsRangeInt(const char opt[],const char text[],const char man[],PetscInt currentvalue,PetscInt *value,PetscBool *flg,PetscInt lb,PetscInt ub)

786:    Input Parameters:
787: +  opt - option name
788: .  text - short string that describes the option
789: .  man - manual page with additional information on option
790: .  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
791: $                 PetscOptionsInt(..., obj->value,&obj->value,...) or
792: $                 value = defaultvalue
793: $                 PetscOptionsInt(..., value,&value,&flg);
794: $                 if (flg) {
795: .  lb - the lower bound, provided value must be greater than or equal to this value or an error is generated
796: -  ub - the upper bound, provided value must be less than or equal to this value 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:    Notes:
803:     If the user does not supply the option at all value is NOT changed. Thus
804:     you should ALWAYS initialize value if you access it without first checking if the set flag is true.

806:     The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.

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

810:    Level: beginner

812: .seealso: `PetscOptionsInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
813:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`, `PetscOptionsBoundedInt()`
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:    PetscOptionsInt - Gets the integer value for a particular option in the database.

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

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

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: $                 PetscOptionsInt(..., obj->value,&obj->value,...) or
836: $                 value = defaultvalue
837: $                 PetscOptionsInt(..., value,&value,&flg);
838: $                 if (flg) {

840:    Output Parameters:
841: +  value - the integer value to return
842: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

844:    Notes:
845:     If the user does not supply the option at all value is NOT changed. Thus
846:     you should ALWAYS initialize value if you access it without first checking if the set flag is true.

848:     The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.

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

852:    Level: beginner

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

863: PetscErrorCode PetscOptionsInt_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *set, PetscInt lb, PetscInt ub)
864: {
865:   PetscOptionItem amsopt;
866:   PetscBool       wasset;

870:   if (!PetscOptionsObject->count) {
871:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt);
872:     PetscMalloc(sizeof(PetscInt), &amsopt->data);
873:     *(PetscInt *)amsopt->data = currentvalue;

875:     PetscOptionsGetInt(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, &currentvalue, &wasset);
876:     if (wasset) *(PetscInt *)amsopt->data = currentvalue;
877:   }
878:   PetscOptionsGetInt(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, &wasset);
881:   if (set) *set = wasset;
882:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
883:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <now %" PetscInt_FMT " : formerly %" PetscInt_FMT ">: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, wasset && value ? *value : currentvalue, currentvalue, text, ManSection(man));
884:   }
885:   return 0;
886: }

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

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

893:    Synopsis:
894:    #include "petscsys.h"
895:    PetscErrorCode  PetscOptionsString(const char opt[],const char text[],const char man[],const char currentvalue[],char value[],size_t len,PetscBool  *set)

897:    Input Parameters:
898: +  opt - option name
899: .  text - short string that describes the option
900: .  man - manual page with additional information on option
901: .  currentvalue - the current value; caller is responsible for setting this value correctly. This is not used to set value
902: -  len - length of the result string including null terminator

904:    Output Parameters:
905: +  value - the value to return
906: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

908:    Level: beginner

910:    Notes:
911:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

913:    Even if the user provided no string (for example -optionname -someotheroption) the flag is set to PETSC_TRUE (and the string is fulled with nulls).

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

918:           The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.

920: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
921:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
922:           `PetscOptionsInt()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
923:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
924:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
925:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
926:           `PetscOptionsFList()`, `PetscOptionsEList()`
927: M*/

929: PetscErrorCode PetscOptionsString_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char currentvalue[], char value[], size_t len, PetscBool *set)
930: {
931:   PetscOptionItem amsopt;
932:   PetscBool       lset;

934:   if (!PetscOptionsObject->count) {
935:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt);
936:     /* must use system malloc since SAWs may free this */
937:     PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data);
938:   }
939:   PetscOptionsGetString(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, len, &lset);
940:   if (set) *set = lset;
941:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
942:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <now %s : formerly %s>: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, lset && value ? value : currentvalue, currentvalue, text, ManSection(man));
943:   }
944:   return 0;
945: }

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

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

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

956:    Input Parameters:
957: +  opt - option name
958: .  text - short string that describes the option
959: .  man - manual page with additional information on option
960: -  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with either
961: $                 PetscOptionsReal(..., obj->value,&obj->value,...) or
962: $                 value = defaultvalue
963: $                 PetscOptionsReal(..., value,&value,&flg);
964: $                 if (flg) {

966:    Output Parameters:
967: +  value - the value to return
968: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

970:    Notes:
971:     If the user does not supply the option at all value is NOT changed. Thus
972:     you should ALWAYS initialize value if you access it without first checking if the set flag is true.

974:     The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.

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

978:    Level: beginner

980: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
981:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
982:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
983:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
984:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
985:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
986:           `PetscOptionsFList()`, `PetscOptionsEList()`
987: M*/

989: PetscErrorCode PetscOptionsReal_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal currentvalue, PetscReal *value, PetscBool *set)
990: {
991:   PetscOptionItem amsopt;
992:   PetscBool       lset;

994:   if (!PetscOptionsObject->count) {
995:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt);
996:     PetscMalloc(sizeof(PetscReal), &amsopt->data);

998:     *(PetscReal *)amsopt->data = currentvalue;
999:   }
1000:   PetscOptionsGetReal(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, &lset);
1001:   if (set) *set = lset;
1002:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1003:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%g : %g>: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, lset && value ? (double)*value : (double)currentvalue, (double)currentvalue, text, ManSection(man));
1004:   }
1005:   return 0;
1006: }

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

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

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

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

1027:    Output Parameters:
1028: +  value - the value to return
1029: -  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

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 the set flag is true.

1035:     The default/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:    Level: beginner

1041: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1042:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
1043:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
1044:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1045:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1046:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1047:           `PetscOptionsFList()`, `PetscOptionsEList()`
1048: M*/

1050: PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set)
1051: {
1052: #if !defined(PETSC_USE_COMPLEX)
1053:   PetscOptionsReal(opt, text, man, currentvalue, value, set);
1054: #else
1055:   PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set);
1056: #endif
1057:   return 0;
1058: }

1060: /*MC
1061:    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
1062:                       its value is set to false.

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

1066:    Synopsis:
1067:    #include "petscsys.h"
1068:    PetscErrorCode PetscOptionsName(const char opt[],const char text[],const char man[],PetscBool  *flg)

1070:    Input Parameters:
1071: +  opt - option name
1072: .  text - short string that describes the option
1073: -  man - manual page with additional information on option

1075:    Output Parameter:
1076: .  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1078:    Level: beginner

1080:    Note:
1081:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1083: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1084:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
1085:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
1086:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1087:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1088:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1089:           `PetscOptionsFList()`, `PetscOptionsEList()`
1090: M*/

1092: PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1093: {
1094:   PetscOptionItem amsopt;

1096:   if (!PetscOptionsObject->count) {
1097:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt);
1098:     PetscMalloc(sizeof(PetscBool), &amsopt->data);

1100:     *(PetscBool *)amsopt->data = PETSC_FALSE;
1101:   }
1102:   PetscOptionsHasName(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, flg);
1103:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1104:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, text, ManSection(man));
1105:   }
1106:   return 0;
1107: }

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

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

1114:    Synopsis:
1115:    #include "petscsys.h"
1116:    PetscErrorCode  PetscOptionsFList(const char opt[],const char ltext[],const char man[],PetscFunctionList list,const char currentvalue[],char value[],size_t len,PetscBool  *set)

1118:    Input Parameters:
1119: +  opt - option name
1120: .  text - short string that describes the option
1121: .  man - manual page with additional information on option
1122: .  list - the possible choices
1123: .  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with
1124: $                 PetscOptionsFlist(..., obj->value,value,len,&flg);
1125: $                 if (flg) {
1126: -  len - the length of the character array value

1128:    Output Parameters:
1129: +  value - the value to return
1130: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1132:    Level: intermediate

1134:    Notes:
1135:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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

1140:           The default/currentvalue passed into this routine does not get transferred to the output value variable automatically.

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

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

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

1150: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1151:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1152:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1153:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1154:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1155:           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsEnum()`
1156: M*/

1158: 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)
1159: {
1160:   PetscOptionItem amsopt;
1161:   PetscBool       lset;

1163:   if (!PetscOptionsObject->count) {
1164:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt);
1165:     /* must use system malloc since SAWs may free this */
1166:     PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data);
1167:     amsopt->flist = list;
1168:   }
1169:   PetscOptionsGetString(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, len, &lset);
1170:   if (set) *set = lset;
1171:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1172:     PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, PetscOptionsObject->prefix, opt, ltext, man, list, currentvalue, lset && value ? value : currentvalue);
1173:   }
1174:   return 0;
1175: }

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

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

1182:    Synopsis:
1183:    #include "petscsys.h"
1184:    PetscErrorCode  PetscOptionsEList(const char opt[],const char ltext[],const char man[],const char *const *list,PetscInt ntext,const char currentvalue[],PetscInt *value,PetscBool  *set)

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 (one of these must be selected, anything else is invalid)
1191: .  ntext - number of choices
1192: -  currentvalue - the current value; caller is responsible for setting this value correctly. Normally this is done with
1193: $                 PetscOptionsElist(..., obj->value,&value,&flg);
1194: $                 if (flg) {

1196:    Output Parameters:
1197: +  value - the index of the value to return
1198: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1200:    Level: intermediate

1202:    Notes:
1203:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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

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

1210: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1211:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1212:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1213:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1214:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1215:           `PetscOptionsFList()`, `PetscOptionsEnum()`
1216: M*/

1218: 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)
1219: {
1220:   PetscInt        i;
1221:   PetscOptionItem amsopt;
1222:   PetscBool       lset;

1224:   if (!PetscOptionsObject->count) {
1225:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt);
1226:     /* must use system malloc since SAWs may free this */
1227:     PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data);
1228:     PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list);
1229:     amsopt->nlist = ntext;
1230:   }
1231:   PetscOptionsGetEList(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, list, ntext, value, &lset);
1232:   if (set) *set = lset;
1233:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1234:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <now %s : formerly %s> %s (choose one of)", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, lset && value ? list[*value] : currentvalue, currentvalue, ltext);
1235:     for (i = 0; i < ntext; i++) (*PetscHelpPrintf)(PetscOptionsObject->comm, " %s", list[i]);
1236:     (*PetscHelpPrintf)(PetscOptionsObject->comm, " (%s)\n", ManSection(man));
1237:   }
1238:   return 0;
1239: }

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

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

1247:    Synopsis:
1248:    #include "petscsys.h"
1249:    PetscErrorCode PetscOptionsBoolGroupBegin(const char opt[],const char text[],const char man[],PetscBool  *flg)

1251:    Input Parameters:
1252: +  opt - option name
1253: .  text - short string that describes the option
1254: -  man - manual page with additional information on option

1256:    Output Parameter:
1257: .  flg - whether that option was set or not

1259:    Level: intermediate

1261:    Notes:
1262:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1264:    Must be followed by 0 or more P`etscOptionsBoolGroup()`s and `PetscOptionsBoolGroupEnd()`

1266: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1267:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1268:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1269:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1270:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1271:           `PetscOptionsFList()`, `PetscOptionsEList()`
1272: M*/

1274: PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1275: {
1276:   PetscOptionItem amsopt;

1278:   if (!PetscOptionsObject->count) {
1279:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt);
1280:     PetscMalloc(sizeof(PetscBool), &amsopt->data);

1282:     *(PetscBool *)amsopt->data = PETSC_FALSE;
1283:   }
1284:   *flg = PETSC_FALSE;
1285:   PetscOptionsGetBool(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, flg, NULL);
1286:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1287:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  Pick at most one of -------------\n");
1288:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, text, ManSection(man));
1289:   }
1290:   return 0;
1291: }

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

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

1299:    Synopsis:
1300:    #include "petscsys.h"
1301:    PetscErrorCode PetscOptionsBoolGroup(const char opt[],const char text[],const char man[],PetscBool  *flg)

1303:    Input Parameters:
1304: +  opt - option name
1305: .  text - short string that describes the option
1306: -  man - manual page with additional information on option

1308:    Output Parameter:
1309: .  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1311:    Level: intermediate

1313:    Notes:
1314:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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

1318: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1319:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1320:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1321:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1322:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1323:           `PetscOptionsFList()`, `PetscOptionsEList()`
1324: M*/

1326: PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1327: {
1328:   PetscOptionItem amsopt;

1330:   if (!PetscOptionsObject->count) {
1331:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt);
1332:     PetscMalloc(sizeof(PetscBool), &amsopt->data);

1334:     *(PetscBool *)amsopt->data = PETSC_FALSE;
1335:   }
1336:   *flg = PETSC_FALSE;
1337:   PetscOptionsGetBool(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, flg, NULL);
1338:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1339:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, text, ManSection(man));
1340:   }
1341:   return 0;
1342: }

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

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

1350:    Synopsis:
1351:    #include "petscsys.h"
1352:    PetscErrorCode PetscOptionsBoolGroupEnd(const char opt[],const char text[],const char man[],PetscBool  *flg)

1354:    Input Parameters:
1355: +  opt - option name
1356: .  text - short string that describes the option
1357: -  man - manual page with additional information on option

1359:    Output Parameter:
1360: .  flg - `PETSC_TRUE` if found, else `PETSC_FALSE`

1362:    Level: intermediate

1364:    Notes:
1365:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

1367:    Must follow a `PetscOptionsBoolGroupBegin()`

1369: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1370:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1371:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1372:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1373:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1374:           `PetscOptionsFList()`, `PetscOptionsEList()`
1375: M*/

1377: PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
1378: {
1379:   PetscOptionItem amsopt;

1381:   if (!PetscOptionsObject->count) {
1382:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt);
1383:     PetscMalloc(sizeof(PetscBool), &amsopt->data);

1385:     *(PetscBool *)amsopt->data = PETSC_FALSE;
1386:   }
1387:   *flg = PETSC_FALSE;
1388:   PetscOptionsGetBool(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, flg, NULL);
1389:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1390:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, text, ManSection(man));
1391:   }
1392:   return 0;
1393: }

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

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

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

1404:    Input Parameters:
1405: +  opt - option name
1406: .  text - short string that describes the option
1407: .  man - manual page with additional information on option
1408: -  currentvalue - the current value

1410:    Output Parameters:
1411: +  flg -` PETSC_TRUE` or `PETSC_FALSE`
1412: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1414:    Notes:
1415:        TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`
1416:        FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`

1418:       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
1419:      is equivalent to -requested_bool true

1421:        If the user does not supply the option at all flg is NOT changed. Thus
1422:      you should ALWAYS initialize the flg if you access it without first checking if the set flag is true.

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

1426:    Level: beginner

1428: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1429:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetBool()`,
1430:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1431:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1432:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1433:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1434:           `PetscOptionsFList()`, `PetscOptionsEList()`
1435: M*/

1437: PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set)
1438: {
1439:   PetscBool       iset;
1440:   PetscOptionItem amsopt;

1442:   if (!PetscOptionsObject->count) {
1443:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt);
1444:     PetscMalloc(sizeof(PetscBool), &amsopt->data);

1446:     *(PetscBool *)amsopt->data = currentvalue;
1447:   }
1448:   PetscOptionsGetBool(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, flg, &iset);
1449:   if (set) *set = iset;
1450:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1451:     const char *v = PetscBools[currentvalue], *vn = PetscBools[iset && flg ? *flg : currentvalue];
1452:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <%s : %s> %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, v, vn, text, ManSection(man));
1453:   }
1454:   return 0;
1455: }

1457: /*MC
1458:    PetscOptionsRealArray - Gets an array of double values for a particular
1459:    option in the database. The values must be separated with commas with
1460:    no intervening spaces.

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

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

1468:    Input Parameters:
1469: +  opt - the option one is seeking
1470: .  text - short string describing option
1471: .  man - manual page for option
1472: -  n - maximum number of values that value has room for

1474:    Output Parameters:
1475: +  value - location to copy values
1476: .  n - actual number of values found
1477: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1479:    Level: beginner

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

1483: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1484:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1485:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1486:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1487:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1488:           `PetscOptionsFList()`, `PetscOptionsEList()`
1489: M*/

1491: PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set)
1492: {
1493:   PetscInt        i;
1494:   PetscOptionItem amsopt;

1496:   if (!PetscOptionsObject->count) {
1497:     PetscReal *vals;

1499:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt);
1500:     PetscMalloc((*n) * sizeof(PetscReal), &amsopt->data);
1501:     vals = (PetscReal *)amsopt->data;
1502:     for (i = 0; i < *n; i++) vals[i] = value[i];
1503:     amsopt->arraylength = *n;
1504:   }
1505:   PetscOptionsGetRealArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, n, set);
1506:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1507:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%g", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, (double)value[0]);
1508:     for (i = 1; i < *n; i++) (*PetscHelpPrintf)(PetscOptionsObject->comm, ",%g", (double)value[i]);
1509:     (*PetscHelpPrintf)(PetscOptionsObject->comm, ">: %s (%s)\n", text, ManSection(man));
1510:   }
1511:   return 0;
1512: }

1514: /*MC
1515:    PetscOptionsScalarArray - Gets an array of `PetscScalar` values for a particular
1516:    option in the database. The values must be separated with commas with
1517:    no intervening spaces.

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

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

1525:    Input Parameters:
1526: +  opt - the option one is seeking
1527: .  text - short string describing option
1528: .  man - manual page for option
1529: -  n - maximum number of values allowed in the value array

1531:    Output Parameters:
1532: +  value - location to copy values
1533: .  n - actual number of values found
1534: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1536:    Level: beginner

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

1540: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1541:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1542:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1543:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1544:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1545:           `PetscOptionsFList()`, `PetscOptionsEList()`
1546: M*/

1548: PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set)
1549: {
1550:   PetscInt        i;
1551:   PetscOptionItem amsopt;

1553:   if (!PetscOptionsObject->count) {
1554:     PetscScalar *vals;

1556:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt);
1557:     PetscMalloc((*n) * sizeof(PetscScalar), &amsopt->data);
1558:     vals = (PetscScalar *)amsopt->data;
1559:     for (i = 0; i < *n; i++) vals[i] = value[i];
1560:     amsopt->arraylength = *n;
1561:   }
1562:   PetscOptionsGetScalarArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, n, set);
1563:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1564:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%g+%gi", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0]));
1565:     for (i = 1; i < *n; i++) (*PetscHelpPrintf)(PetscOptionsObject->comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i]));
1566:     (*PetscHelpPrintf)(PetscOptionsObject->comm, ">: %s (%s)\n", text, ManSection(man));
1567:   }
1568:   return 0;
1569: }

1571: /*MC
1572:    PetscOptionsIntArray - Gets an array of integers for a particular
1573:    option in the database.

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

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

1581:    Input Parameters:
1582: +  opt - the option one is seeking
1583: .  text - short string describing option
1584: .  man - manual page for option
1585: -  n - maximum number of values

1587:    Output Parameters:
1588: +  value - location to copy values
1589: .  n - actual number of values found
1590: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1592:    Level: beginner

1594:    Notes:
1595:    The array can be passed as
1596: +   a comma separated list -                                  0,1,2,3,4,5,6,7
1597: .   a range (start\-end+1) -                                  0-8
1598: .   a range with given increment (start\-end+1:inc) -         0-7:2
1599: -   a combination of values and ranges separated by commas -  0,1-8,8-15:2

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

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

1605: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1606:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1607:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1608:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1609:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1610:           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsRealArray()`
1611: M*/

1613: PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set)
1614: {
1615:   PetscInt        i;
1616:   PetscOptionItem amsopt;

1618:   if (!PetscOptionsObject->count) {
1619:     PetscInt *vals;

1621:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt);
1622:     PetscMalloc1(*n, (PetscInt **)&amsopt->data);
1623:     vals = (PetscInt *)amsopt->data;
1624:     for (i = 0; i < *n; i++) vals[i] = value[i];
1625:     amsopt->arraylength = *n;
1626:   }
1627:   PetscOptionsGetIntArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, n, set);
1628:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1629:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%" PetscInt_FMT, PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, value[0]);
1630:     for (i = 1; i < *n; i++) (*PetscHelpPrintf)(PetscOptionsObject->comm, ",%" PetscInt_FMT, value[i]);
1631:     (*PetscHelpPrintf)(PetscOptionsObject->comm, ">: %s (%s)\n", text, ManSection(man));
1632:   }
1633:   return 0;
1634: }

1636: /*MC
1637:    PetscOptionsStringArray - Gets an array of string values for a particular
1638:    option in the database. The values must be separated with commas with
1639:    no intervening spaces.

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

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

1647:    Input Parameters:
1648: +  opt - the option one is seeking
1649: .  text - short string describing option
1650: .  man - manual page for option
1651: -  nmax - maximum number of strings

1653:    Output Parameters:
1654: +  value - location to copy strings
1655: .  nmax - actual number of strings found
1656: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1658:    Level: beginner

1660:    Notes:
1661:    The user should pass in an array of pointers to char, to hold all the
1662:    strings returned by this function.

1664:    The user is responsible for deallocating the strings that are
1665:    returned.

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

1669: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1670:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1671:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1672:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1673:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1674:           `PetscOptionsFList()`, `PetscOptionsEList()`
1675: M*/

1677: PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set)
1678: {
1679:   PetscOptionItem amsopt;

1681:   if (!PetscOptionsObject->count) {
1682:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt);
1683:     PetscMalloc1(*nmax, (char **)&amsopt->data);

1685:     amsopt->arraylength = *nmax;
1686:   }
1687:   PetscOptionsGetStringArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, nmax, set);
1688:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1689:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <string1,string2,...>: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, text, ManSection(man));
1690:   }
1691:   return 0;
1692: }

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

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

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

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 allowed in the value array

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 user should pass in an array of doubles

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

1723: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1724:           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1725:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1726:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1727:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1728:           `PetscOptionsFList()`, `PetscOptionsEList()`
1729: M*/

1731: PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set)
1732: {
1733:   PetscInt        i;
1734:   PetscOptionItem amsopt;

1736:   if (!PetscOptionsObject->count) {
1737:     PetscBool *vals;

1739:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt);
1740:     PetscMalloc1(*n, (PetscBool **)&amsopt->data);
1741:     vals = (PetscBool *)amsopt->data;
1742:     for (i = 0; i < *n; i++) vals[i] = value[i];
1743:     amsopt->arraylength = *n;
1744:   }
1745:   PetscOptionsGetBoolArray(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, n, set);
1746:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1747:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%d", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, value[0]);
1748:     for (i = 1; i < *n; i++) (*PetscHelpPrintf)(PetscOptionsObject->comm, ",%d", value[i]);
1749:     (*PetscHelpPrintf)(PetscOptionsObject->comm, ">: %s (%s)\n", text, ManSection(man));
1750:   }
1751:   return 0;
1752: }

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

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

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

1763:    Input Parameters:
1764: +  opt - option name
1765: .  text - short string that describes the option
1766: -  man - manual page with additional information on option

1768:    Output Parameters:
1769: +  viewer - the viewer
1770: .  format - the PetscViewerFormat requested by the user, pass NULL if not needed
1771: -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`

1773:    Level: beginner

1775:    Notes:
1776:     Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`

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

1780: .seealso: `PetscOptionsGetViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1781:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
1782:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
1783:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1784:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1785:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1786:           `PetscOptionsFList()`, `PetscOptionsEList()`
1787: M*/

1789: PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
1790: {
1791:   PetscOptionItem amsopt;

1793:   if (!PetscOptionsObject->count) {
1794:     PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt);
1795:     /* must use system malloc since SAWs may free this */
1796:     PetscStrdup("", (char **)&amsopt->data);
1797:   }
1798:   PetscOptionsGetViewer(PetscOptionsObject->comm, PetscOptionsObject->options, PetscOptionsObject->prefix, opt, viewer, format, set);
1799:   if (PetscOptionsObject->printhelp && PetscOptionsObject->count == 1 && !PetscOptionsObject->alreadyprinted) {
1800:     (*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s <%s>: %s (%s)\n", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", opt + 1, "", text, ManSection(man));
1801:   }
1802:   return 0;
1803: }