xref: /petsc/src/sys/objects/aoptions.c (revision 1690c2ae071c7584458d4e437df7b47bc4686b3c)
153acd3b1SBarry Smith /*
23fc1eb6aSBarry Smith    Implements the higher-level options database querying methods. These are self-documenting and can attach at runtime to
33fc1eb6aSBarry Smith    GUI code to display the options and get values from the users.
453acd3b1SBarry Smith 
553acd3b1SBarry Smith */
653acd3b1SBarry Smith 
7af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I  "petscsys.h"   I*/
8665c2dedSJed Brown #include <petscviewer.h>
953acd3b1SBarry Smith 
1010c654e6SJacob Faibussowitsch static const char *ManSection(const char *str)
1110c654e6SJacob Faibussowitsch {
1210c654e6SJacob Faibussowitsch   return str ? str : "None";
1310c654e6SJacob Faibussowitsch }
1410c654e6SJacob Faibussowitsch 
1510c654e6SJacob Faibussowitsch static const char *Prefix(const char *str)
1610c654e6SJacob Faibussowitsch {
1710c654e6SJacob Faibussowitsch   return str ? str : "";
1810c654e6SJacob Faibussowitsch }
1910c654e6SJacob Faibussowitsch 
2010c654e6SJacob Faibussowitsch static int ShouldPrintHelp(const PetscOptionItems *opts)
2110c654e6SJacob Faibussowitsch {
2210c654e6SJacob Faibussowitsch   return opts->printhelp && opts->count == 1 && !opts->alreadyprinted;
2310c654e6SJacob Faibussowitsch }
242aa6d131SJed Brown 
2553acd3b1SBarry Smith /*
2653acd3b1SBarry Smith     Keep a linked list of options that have been posted and we are waiting for
273fc1eb6aSBarry Smith    user selection. See the manual page for PetscOptionsBegin()
2853acd3b1SBarry Smith 
2953acd3b1SBarry Smith     Eventually we'll attach this beast to a MPI_Comm
3053acd3b1SBarry Smith */
31e55864a3SBarry Smith 
3253acd3b1SBarry Smith /*
3353acd3b1SBarry Smith     Handles setting up the data structure in a call to PetscOptionsBegin()
3453acd3b1SBarry Smith */
35d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBegin_Private(PetscOptionItems *PetscOptionsObject, MPI_Comm comm, const char prefix[], const char title[], const char mansec[])
36d71ae5a4SJacob Faibussowitsch {
3753acd3b1SBarry Smith   PetscFunctionBegin;
384f572ea9SToby Isaac   if (prefix) PetscAssertPointer(prefix, 3);
394f572ea9SToby Isaac   PetscAssertPointer(title, 4);
404f572ea9SToby Isaac   if (mansec) PetscAssertPointer(mansec, 5);
410eb63584SBarry Smith   if (!PetscOptionsObject->alreadyprinted) {
429566063dSJacob Faibussowitsch     if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
439566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, prefix, title, &PetscOptionsObject->alreadyprinted));
440eb63584SBarry Smith   }
4502c9f0b5SLisandro Dalcin   PetscOptionsObject->next          = NULL;
46e55864a3SBarry Smith   PetscOptionsObject->comm          = comm;
47e55864a3SBarry Smith   PetscOptionsObject->changedmethod = PETSC_FALSE;
48a297a907SKarl Rupp 
499566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(prefix, &PetscOptionsObject->prefix));
509566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(title, &PetscOptionsObject->title));
5153acd3b1SBarry Smith 
529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(PetscOptionsObject->options, &PetscOptionsObject->printhelp));
5310c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\n%s:\n", title));
543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5553acd3b1SBarry Smith }
5653acd3b1SBarry Smith 
573194b578SJed Brown /*
583194b578SJed Brown     Handles setting up the data structure in a call to PetscObjectOptionsBegin()
593194b578SJed Brown */
60d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectOptionsBegin_Private(PetscObject obj, PetscOptionItems *PetscOptionsObject)
61d71ae5a4SJacob Faibussowitsch {
623194b578SJed Brown   char      title[256];
633194b578SJed Brown   PetscBool flg;
643194b578SJed Brown 
653194b578SJed Brown   PetscFunctionBegin;
664f572ea9SToby Isaac   PetscAssertPointer(PetscOptionsObject, 2);
67dbbe0bcdSBarry Smith   PetscValidHeader(obj, 1);
68e55864a3SBarry Smith   PetscOptionsObject->object         = obj;
69e55864a3SBarry Smith   PetscOptionsObject->alreadyprinted = obj->optionsprinted;
70a297a907SKarl Rupp 
719566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(obj->description, obj->class_name, &flg));
729566063dSJacob Faibussowitsch   if (flg) PetscCall(PetscSNPrintf(title, sizeof(title), "%s options", obj->class_name));
739566063dSJacob Faibussowitsch   else PetscCall(PetscSNPrintf(title, sizeof(title), "%s (%s) options", obj->description, obj->class_name));
749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBegin_Private(PetscOptionsObject, obj->comm, obj->prefix, title, obj->mansec));
753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
763194b578SJed Brown }
773194b578SJed Brown 
7853acd3b1SBarry Smith /*
7953acd3b1SBarry Smith      Handles adding another option to the list of options within this particular PetscOptionsBegin() PetscOptionsEnd()
8053acd3b1SBarry Smith */
813ba16761SJacob Faibussowitsch static PetscErrorCode PetscOptionItemCreate_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscOptionType t, PetscOptionItem *amsopt)
82d71ae5a4SJacob Faibussowitsch {
833be6e4c3SJed Brown   PetscBool valid;
8453acd3b1SBarry Smith 
8553acd3b1SBarry Smith   PetscFunctionBegin;
869566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(opt, &valid));
875f80ce2aSJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "The option '%s' is not a valid key", opt);
883be6e4c3SJed Brown 
899566063dSJacob Faibussowitsch   PetscCall(PetscNew(amsopt));
9002c9f0b5SLisandro Dalcin   (*amsopt)->next = NULL;
9153acd3b1SBarry Smith   (*amsopt)->set  = PETSC_FALSE;
926356e834SBarry Smith   (*amsopt)->type = t;
9302c9f0b5SLisandro Dalcin   (*amsopt)->data = NULL;
9461b37b28SSatish Balay 
959566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(text, &(*amsopt)->text));
969566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(opt, &(*amsopt)->option));
979566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(man, &(*amsopt)->man));
9853acd3b1SBarry Smith 
9910c654e6SJacob Faibussowitsch   {
10010c654e6SJacob Faibussowitsch     PetscOptionItem cur = PetscOptionsObject->next;
10110c654e6SJacob Faibussowitsch 
10210c654e6SJacob Faibussowitsch     while (cur->next) cur = cur->next;
10310c654e6SJacob Faibussowitsch     cur->next = *amsopt;
10453acd3b1SBarry Smith   }
1053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10653acd3b1SBarry Smith }
10753acd3b1SBarry Smith 
108aee2cecaSBarry Smith /*
10910450e9eSJacob Faibussowitsch     This is needed because certain strings may be freed by SAWs, hence we cannot use PetscStrallocpy()
11010450e9eSJacob Faibussowitsch */
11110450e9eSJacob Faibussowitsch static PetscErrorCode PetscStrdup(const char s[], char *t[])
11210450e9eSJacob Faibussowitsch {
11310450e9eSJacob Faibussowitsch   char *tmp = NULL;
11410450e9eSJacob Faibussowitsch 
11510450e9eSJacob Faibussowitsch   PetscFunctionBegin;
11610450e9eSJacob Faibussowitsch   if (s) {
11710450e9eSJacob Faibussowitsch     size_t len;
11810450e9eSJacob Faibussowitsch 
11910450e9eSJacob Faibussowitsch     PetscCall(PetscStrlen(s, &len));
12010450e9eSJacob Faibussowitsch     tmp = (char *)malloc((len + 1) * sizeof(*tmp));
12110450e9eSJacob Faibussowitsch     PetscCheck(tmp, PETSC_COMM_SELF, PETSC_ERR_MEM, "No memory to duplicate string");
12210450e9eSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmp, s, len + 1));
12310450e9eSJacob Faibussowitsch   }
12410450e9eSJacob Faibussowitsch   *t = tmp;
12510450e9eSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12610450e9eSJacob Faibussowitsch }
12710450e9eSJacob Faibussowitsch 
12810450e9eSJacob Faibussowitsch #if defined(PETSC_HAVE_SAWS)
12910450e9eSJacob Faibussowitsch   #include <petscviewersaws.h>
13010450e9eSJacob Faibussowitsch 
13110450e9eSJacob Faibussowitsch static int count = 0;
13210450e9eSJacob Faibussowitsch 
13310450e9eSJacob Faibussowitsch PetscErrorCode PetscOptionsSAWsDestroy(void)
13410450e9eSJacob Faibussowitsch {
13510450e9eSJacob Faibussowitsch   PetscFunctionBegin;
13610450e9eSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13710450e9eSJacob Faibussowitsch }
13810450e9eSJacob Faibussowitsch 
13910450e9eSJacob Faibussowitsch static const char *OptionsHeader = "<head>\n"
14010450e9eSJacob Faibussowitsch                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/jquery-1.9.1.js\"></script>\n"
14110450e9eSJacob Faibussowitsch                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/SAWs.js\"></script>\n"
14210450e9eSJacob Faibussowitsch                                    "<script type=\"text/javascript\" src=\"js/PETSc.js\"></script>\n"
14310450e9eSJacob Faibussowitsch                                    "<script>\n"
14410450e9eSJacob Faibussowitsch                                    "jQuery(document).ready(function() {\n"
14510450e9eSJacob Faibussowitsch                                    "PETSc.getAndDisplayDirectory(null,\"#variablesInfo\")\n"
14610450e9eSJacob Faibussowitsch                                    "})\n"
14710450e9eSJacob Faibussowitsch                                    "</script>\n"
14810450e9eSJacob Faibussowitsch                                    "</head>\n";
14910450e9eSJacob Faibussowitsch 
15010450e9eSJacob Faibussowitsch /*  Determines the size and style of the scroll region where PETSc options selectable from users are displayed */
15110450e9eSJacob Faibussowitsch static const char *OptionsBodyBottom = "<div id=\"variablesInfo\" style=\"background-color:lightblue;height:auto;max-height:500px;overflow:scroll;\"></div>\n<br>\n</body>";
15210450e9eSJacob Faibussowitsch 
15310450e9eSJacob Faibussowitsch /*
15410450e9eSJacob Faibussowitsch     PetscOptionsSAWsInput - Presents all the PETSc Options processed by the program so the user may change them at runtime using the SAWs
15510450e9eSJacob Faibussowitsch 
15610450e9eSJacob Faibussowitsch     Bugs:
15710450e9eSJacob Faibussowitsch +    All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
15810450e9eSJacob Faibussowitsch .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
15910450e9eSJacob Faibussowitsch -    Only works for PetscInt == int, PetscReal == double etc
16010450e9eSJacob Faibussowitsch 
16110450e9eSJacob Faibussowitsch */
16266976f2fSJacob Faibussowitsch static PetscErrorCode PetscOptionsSAWsInput(PetscOptionItems *PetscOptionsObject)
16310450e9eSJacob Faibussowitsch {
16410450e9eSJacob Faibussowitsch   PetscOptionItem next     = PetscOptionsObject->next;
16510450e9eSJacob Faibussowitsch   static int      mancount = 0;
16610450e9eSJacob Faibussowitsch   char            options[16];
16710450e9eSJacob Faibussowitsch   PetscBool       changedmethod = PETSC_FALSE;
16810450e9eSJacob Faibussowitsch   PetscBool       stopasking    = PETSC_FALSE;
16910450e9eSJacob Faibussowitsch   char            manname[16], textname[16];
17010450e9eSJacob Faibussowitsch   char            dir[1024];
17110450e9eSJacob Faibussowitsch 
17210450e9eSJacob Faibussowitsch   PetscFunctionBegin;
17310450e9eSJacob Faibussowitsch   /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */
17410450e9eSJacob Faibussowitsch   PetscCall(PetscSNPrintf(options, PETSC_STATIC_ARRAY_LENGTH(options), "Options_%d", count++));
17510450e9eSJacob Faibussowitsch 
17610450e9eSJacob Faibussowitsch   PetscOptionsObject->pprefix = PetscOptionsObject->prefix; /* SAWs will change this, so cannot pass prefix directly */
17710450e9eSJacob Faibussowitsch 
17810450e9eSJacob Faibussowitsch   PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "_title"));
17910450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->title, 1, SAWs_READ, SAWs_STRING));
18010450e9eSJacob Faibussowitsch   PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "prefix"));
18110450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->pprefix, 1, SAWs_READ, SAWs_STRING));
18210450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, ("/PETSc/Options/ChangedMethod", &changedmethod, 1, SAWs_WRITE, SAWs_BOOLEAN));
18310450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, ("/PETSc/Options/StopAsking", &stopasking, 1, SAWs_WRITE, SAWs_BOOLEAN));
18410450e9eSJacob Faibussowitsch 
18510450e9eSJacob Faibussowitsch   while (next) {
18610450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(manname, PETSC_STATIC_ARRAY_LENGTH(manname), "_man_%d", mancount));
18710450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", manname));
18810450e9eSJacob Faibussowitsch     PetscCallSAWs(SAWs_Register, (dir, &next->man, 1, SAWs_READ, SAWs_STRING));
18910450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(textname, PETSC_STATIC_ARRAY_LENGTH(textname), "_text_%d", mancount++));
19010450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", textname));
19110450e9eSJacob Faibussowitsch     PetscCallSAWs(SAWs_Register, (dir, &next->text, 1, SAWs_READ, SAWs_STRING));
19210450e9eSJacob Faibussowitsch 
19310450e9eSJacob Faibussowitsch     switch (next->type) {
19410450e9eSJacob Faibussowitsch     case OPTION_HEAD:
19510450e9eSJacob Faibussowitsch       break;
19610450e9eSJacob Faibussowitsch     case OPTION_INT_ARRAY:
19710450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
19810450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_INT));
19910450e9eSJacob Faibussowitsch       break;
20010450e9eSJacob Faibussowitsch     case OPTION_REAL_ARRAY:
20110450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
20210450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_DOUBLE));
20310450e9eSJacob Faibussowitsch       break;
20410450e9eSJacob Faibussowitsch     case OPTION_INT:
20510450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
20610450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_INT));
20710450e9eSJacob Faibussowitsch       break;
20810450e9eSJacob Faibussowitsch     case OPTION_REAL:
20910450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
21010450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_DOUBLE));
21110450e9eSJacob Faibussowitsch       break;
21210450e9eSJacob Faibussowitsch     case OPTION_BOOL:
21310450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
21410450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_BOOLEAN));
21510450e9eSJacob Faibussowitsch       break;
21610450e9eSJacob Faibussowitsch     case OPTION_BOOL_ARRAY:
21710450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
21810450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_BOOLEAN));
21910450e9eSJacob Faibussowitsch       break;
22010450e9eSJacob Faibussowitsch     case OPTION_STRING:
22110450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
22210450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
22310450e9eSJacob Faibussowitsch       break;
22410450e9eSJacob Faibussowitsch     case OPTION_STRING_ARRAY:
22510450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
22610450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_STRING));
22710450e9eSJacob Faibussowitsch       break;
22810450e9eSJacob Faibussowitsch     case OPTION_FLIST: {
22910450e9eSJacob Faibussowitsch       PetscInt ntext;
23010450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
23110450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
23210450e9eSJacob Faibussowitsch       PetscCall(PetscFunctionListGet(next->flist, (const char ***)&next->edata, &ntext));
23310450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
23410450e9eSJacob Faibussowitsch     } break;
23510450e9eSJacob Faibussowitsch     case OPTION_ELIST: {
23610450e9eSJacob Faibussowitsch       PetscInt ntext = next->nlist;
23710450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
23810450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
23910450e9eSJacob Faibussowitsch       PetscCall(PetscMalloc1((ntext + 1), (char ***)&next->edata));
24010450e9eSJacob Faibussowitsch       PetscCall(PetscMemcpy(next->edata, next->list, ntext * sizeof(char *)));
24110450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
24210450e9eSJacob Faibussowitsch     } break;
24310450e9eSJacob Faibussowitsch     default:
24410450e9eSJacob Faibussowitsch       break;
24510450e9eSJacob Faibussowitsch     }
24610450e9eSJacob Faibussowitsch     next = next->next;
24710450e9eSJacob Faibussowitsch   }
24810450e9eSJacob Faibussowitsch 
24910450e9eSJacob Faibussowitsch   /* wait until accessor has unlocked the memory */
25010450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Push_Header, ("index.html", OptionsHeader));
25110450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Push_Body, ("index.html", 2, OptionsBodyBottom));
25210450e9eSJacob Faibussowitsch   PetscCall(PetscSAWsBlock());
25310450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Pop_Header, ("index.html"));
25410450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Pop_Body, ("index.html", 2));
25510450e9eSJacob Faibussowitsch 
25610450e9eSJacob Faibussowitsch   /* determine if any values have been set in GUI */
25710450e9eSJacob Faibussowitsch   next = PetscOptionsObject->next;
25810450e9eSJacob Faibussowitsch   while (next) {
25910450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
26010450e9eSJacob Faibussowitsch     PetscCallSAWs(SAWs_Selected, (dir, (int *)&next->set));
26110450e9eSJacob Faibussowitsch     next = next->next;
26210450e9eSJacob Faibussowitsch   }
26310450e9eSJacob Faibussowitsch 
26410450e9eSJacob Faibussowitsch   /* reset counter to -2; this updates the screen with the new options for the selected method */
26510450e9eSJacob Faibussowitsch   if (changedmethod) PetscOptionsObject->count = -2;
26610450e9eSJacob Faibussowitsch 
26710450e9eSJacob Faibussowitsch   if (stopasking) {
26810450e9eSJacob Faibussowitsch     PetscOptionsPublish       = PETSC_FALSE;
26910450e9eSJacob Faibussowitsch     PetscOptionsObject->count = 0; //do not ask for same thing again
27010450e9eSJacob Faibussowitsch   }
27110450e9eSJacob Faibussowitsch 
27210450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Delete, ("/PETSc/Options"));
27310450e9eSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
27410450e9eSJacob Faibussowitsch }
27510450e9eSJacob Faibussowitsch #else
27610450e9eSJacob Faibussowitsch /*
2773fc1eb6aSBarry Smith     PetscScanString -  Gets user input via stdin from process and broadcasts to all processes
2783fc1eb6aSBarry Smith 
279d083f849SBarry Smith     Collective
2803fc1eb6aSBarry Smith 
2813fc1eb6aSBarry Smith    Input Parameters:
2823fc1eb6aSBarry Smith +     commm - communicator for the broadcast, must be PETSC_COMM_WORLD
2833fc1eb6aSBarry Smith .     n - length of the string, must be the same on all processes
2843fc1eb6aSBarry Smith -     str - location to store input
285aee2cecaSBarry Smith 
286aee2cecaSBarry Smith     Bugs:
287aee2cecaSBarry Smith .   Assumes process 0 of the given communicator has access to stdin
288aee2cecaSBarry Smith 
289aee2cecaSBarry Smith */
290d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscScanString(MPI_Comm comm, size_t n, char str[])
291d71ae5a4SJacob Faibussowitsch {
2923fc1eb6aSBarry Smith   PetscMPIInt rank, nm;
293aee2cecaSBarry Smith 
294aee2cecaSBarry Smith   PetscFunctionBegin;
2959566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
296dd400576SPatrick Sanan   if (rank == 0) {
2975f80ce2aSJacob Faibussowitsch     char   c = (char)getchar();
2985f80ce2aSJacob Faibussowitsch     size_t i = 0;
2995f80ce2aSJacob Faibussowitsch 
300aee2cecaSBarry Smith     while (c != '\n' && i < n - 1) {
301aee2cecaSBarry Smith       str[i++] = c;
302aee2cecaSBarry Smith       c        = (char)getchar();
303aee2cecaSBarry Smith     }
30410c654e6SJacob Faibussowitsch     str[i] = '\0';
305aee2cecaSBarry Smith   }
3069566063dSJacob Faibussowitsch   PetscCall(PetscMPIIntCast(n, &nm));
3079566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(str, nm, MPI_CHAR, 0, comm));
3083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
309aee2cecaSBarry Smith }
310aee2cecaSBarry Smith 
3115b02f95dSBarry Smith /*
3123cc1e11dSBarry Smith   PetscOptionsGetFromTextInput - Presents all the PETSc Options processed by the program so the user may change them at runtime
313aee2cecaSBarry Smith 
31495452b02SPatrick Sanan   Notes:
31595452b02SPatrick Sanan   this isn't really practical, it is just to demonstrate the principle
316aee2cecaSBarry Smith 
3177781c08eSBarry Smith   A carriage return indicates no change from the default; but this like -ksp_monitor <stdout>  the default is actually not stdout the default
3187781c08eSBarry Smith   is to do nothing so to get it to use stdout you need to type stdout. This is kind of bug?
3197781c08eSBarry Smith 
320aee2cecaSBarry Smith   Bugs:
3217781c08eSBarry Smith +    All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
3223cc1e11dSBarry Smith .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
323aee2cecaSBarry Smith -    Only works for PetscInt == int, PetscReal == double etc
324aee2cecaSBarry Smith 
325aec76313SJacob Faibussowitsch   Developer Notes:
32695452b02SPatrick Sanan   Normally the GUI that presents the options the user and retrieves the values would be running in a different
3273cc1e11dSBarry Smith   address space and communicating with the PETSc program
3283cc1e11dSBarry Smith 
329aee2cecaSBarry Smith */
33010450e9eSJacob Faibussowitsch static PetscErrorCode PetscOptionsGetFromTextInput(PetscOptionItems *PetscOptionsObject)
331d71ae5a4SJacob Faibussowitsch {
3324416b707SBarry Smith   PetscOptionItem next = PetscOptionsObject->next;
3336356e834SBarry Smith   char            str[512];
3347781c08eSBarry Smith   PetscBool       bid;
335a4404d99SBarry Smith   PetscReal       ir, *valr;
336330cf3c9SBarry Smith   PetscInt       *vald;
3376356e834SBarry Smith 
3382a409bb0SBarry Smith   PetscFunctionBegin;
3399566063dSJacob Faibussowitsch   PetscCall((*PetscPrintf)(PETSC_COMM_WORLD, "%s --------------------\n", PetscOptionsObject->title));
3406356e834SBarry Smith   while (next) {
3416356e834SBarry Smith     switch (next->type) {
342d71ae5a4SJacob Faibussowitsch     case OPTION_HEAD:
343d71ae5a4SJacob Faibussowitsch       break;
344e26ddf31SBarry Smith     case OPTION_INT_ARRAY:
3454bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
346e26ddf31SBarry Smith       vald = (PetscInt *)next->data;
3476497c311SBarry Smith       for (PetscInt i = 0; i < next->arraylength; i++) {
3489566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT, vald[i]));
34948a46eb9SPierre Jolivet         if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
350e26ddf31SBarry Smith       }
3519566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
3529566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
353e26ddf31SBarry Smith       if (str[0]) {
354e26ddf31SBarry Smith         PetscToken token;
355e26ddf31SBarry Smith         PetscInt   n = 0, nmax = next->arraylength, *dvalue = (PetscInt *)next->data, start, end;
356e26ddf31SBarry Smith         size_t     len;
357e26ddf31SBarry Smith         char      *value;
358ace3abfcSBarry Smith         PetscBool  foundrange;
3596497c311SBarry Smith         PetscInt   i;
360e26ddf31SBarry Smith 
361e26ddf31SBarry Smith         next->set = PETSC_TRUE;
362e26ddf31SBarry Smith         value     = str;
3639566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(value, ',', &token));
3649566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &value));
365e26ddf31SBarry Smith         while (n < nmax) {
366e26ddf31SBarry Smith           if (!value) break;
367e26ddf31SBarry Smith 
368e26ddf31SBarry Smith           /* look for form  d-D where d and D are integers */
369e26ddf31SBarry Smith           foundrange = PETSC_FALSE;
3709566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(value, &len));
371e26ddf31SBarry Smith           if (value[0] == '-') i = 2;
372e26ddf31SBarry Smith           else i = 1;
3736497c311SBarry Smith           for (; i < (PetscInt)len; i++) {
374e26ddf31SBarry Smith             if (value[i] == '-') {
3756497c311SBarry Smith               PetscCheck(i != (PetscInt)(len - 1), PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
376e26ddf31SBarry Smith               value[i] = 0;
3779566063dSJacob Faibussowitsch               PetscCall(PetscOptionsStringToInt(value, &start));
3789566063dSJacob Faibussowitsch               PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
37908401ef6SPierre Jolivet               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);
380cc73adaaSBarry Smith               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);
381e26ddf31SBarry Smith               for (; start < end; start++) {
3829371c9d4SSatish Balay                 *dvalue = start;
3839371c9d4SSatish Balay                 dvalue++;
3849371c9d4SSatish Balay                 n++;
385e26ddf31SBarry Smith               }
386e26ddf31SBarry Smith               foundrange = PETSC_TRUE;
387e26ddf31SBarry Smith               break;
388e26ddf31SBarry Smith             }
389e26ddf31SBarry Smith           }
390e26ddf31SBarry Smith           if (!foundrange) {
3919566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value, dvalue));
392e26ddf31SBarry Smith             dvalue++;
393e26ddf31SBarry Smith             n++;
394e26ddf31SBarry Smith           }
3959566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &value));
396e26ddf31SBarry Smith         }
3979566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
398e26ddf31SBarry Smith       }
399e26ddf31SBarry Smith       break;
400e26ddf31SBarry Smith     case OPTION_REAL_ARRAY:
4014bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
402e26ddf31SBarry Smith       valr = (PetscReal *)next->data;
4036497c311SBarry Smith       for (PetscInt i = 0; i < next->arraylength; i++) {
4049566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i]));
40548a46eb9SPierre Jolivet         if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
406e26ddf31SBarry Smith       }
4079566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
4089566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
409e26ddf31SBarry Smith       if (str[0]) {
410e26ddf31SBarry Smith         PetscToken token;
411e26ddf31SBarry Smith         PetscInt   n = 0, nmax = next->arraylength;
412e26ddf31SBarry Smith         PetscReal *dvalue = (PetscReal *)next->data;
413e26ddf31SBarry Smith         char      *value;
414e26ddf31SBarry Smith 
415e26ddf31SBarry Smith         next->set = PETSC_TRUE;
416e26ddf31SBarry Smith         value     = str;
4179566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(value, ',', &token));
4189566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &value));
419e26ddf31SBarry Smith         while (n < nmax) {
420e26ddf31SBarry Smith           if (!value) break;
4219566063dSJacob Faibussowitsch           PetscCall(PetscOptionsStringToReal(value, dvalue));
422e26ddf31SBarry Smith           dvalue++;
423e26ddf31SBarry Smith           n++;
4249566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &value));
425e26ddf31SBarry Smith         }
4269566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
427e26ddf31SBarry Smith       }
428e26ddf31SBarry Smith       break;
4296356e834SBarry Smith     case OPTION_INT:
4304bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%d>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(int *)next->data, next->text, next->man));
4319566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4323fc1eb6aSBarry Smith       if (str[0]) {
433d25d7f95SJed Brown   #if defined(PETSC_SIZEOF_LONG_LONG)
434d25d7f95SJed Brown         long long lid;
435d25d7f95SJed Brown         sscanf(str, "%lld", &lid);
436*1690c2aeSBarry Smith         PetscCheck(lid <= PETSC_INT_MAX && lid >= PETSC_INT_MIN, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %lld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid);
437c272547aSJed Brown   #else
438d25d7f95SJed Brown         long lid;
439d25d7f95SJed Brown         sscanf(str, "%ld", &lid);
440*1690c2aeSBarry Smith         PetscCheck(lid <= PETSC_INT_MAX && lid >= PETSC_INT_MIN, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %ld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid);
441c272547aSJed Brown   #endif
442a297a907SKarl Rupp 
443d25d7f95SJed Brown         next->set                 = PETSC_TRUE;
444d25d7f95SJed Brown         *((PetscInt *)next->data) = (PetscInt)lid;
445aee2cecaSBarry Smith       }
446aee2cecaSBarry Smith       break;
447aee2cecaSBarry Smith     case OPTION_REAL:
4484bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%g>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(double *)next->data, next->text, next->man));
4499566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4503fc1eb6aSBarry Smith       if (str[0]) {
451ce63c4c1SBarry Smith   #if defined(PETSC_USE_REAL_SINGLE)
452a4404d99SBarry Smith         sscanf(str, "%e", &ir);
453570b7f6dSBarry Smith   #elif defined(PETSC_USE_REAL___FP16)
454570b7f6dSBarry Smith         float irtemp;
455570b7f6dSBarry Smith         sscanf(str, "%e", &irtemp);
456570b7f6dSBarry Smith         ir = irtemp;
457ce63c4c1SBarry Smith   #elif defined(PETSC_USE_REAL_DOUBLE)
458aee2cecaSBarry Smith         sscanf(str, "%le", &ir);
459ce63c4c1SBarry Smith   #elif defined(PETSC_USE_REAL___FLOAT128)
460d9822059SBarry Smith         ir = strtoflt128(str, 0);
461d9822059SBarry Smith   #else
462513dbe71SLisandro Dalcin         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type");
463a4404d99SBarry Smith   #endif
464aee2cecaSBarry Smith         next->set                  = PETSC_TRUE;
465aee2cecaSBarry Smith         *((PetscReal *)next->data) = ir;
466aee2cecaSBarry Smith       }
467aee2cecaSBarry Smith       break;
4687781c08eSBarry Smith     case OPTION_BOOL:
4694bb2516aSBarry Smith       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));
4709566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4717781c08eSBarry Smith       if (str[0]) {
4729566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToBool(str, &bid));
4737781c08eSBarry Smith         next->set                  = PETSC_TRUE;
4747781c08eSBarry Smith         *((PetscBool *)next->data) = bid;
4757781c08eSBarry Smith       }
4767781c08eSBarry Smith       break;
477aee2cecaSBarry Smith     case OPTION_STRING:
4784bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%s>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, (char *)next->data, next->text, next->man));
4799566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4803fc1eb6aSBarry Smith       if (str[0]) {
481aee2cecaSBarry Smith         next->set = PETSC_TRUE;
48264facd6cSBarry Smith         /* must use system malloc since SAWs may free this */
4839566063dSJacob Faibussowitsch         PetscCall(PetscStrdup(str, (char **)&next->data));
4846356e834SBarry Smith       }
4856356e834SBarry Smith       break;
486a264d7a6SBarry Smith     case OPTION_FLIST:
4879566063dSJacob Faibussowitsch       PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data));
4889566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4893cc1e11dSBarry Smith       if (str[0]) {
490e55864a3SBarry Smith         PetscOptionsObject->changedmethod = PETSC_TRUE;
4913cc1e11dSBarry Smith         next->set                         = PETSC_TRUE;
49264facd6cSBarry Smith         /* must use system malloc since SAWs may free this */
4939566063dSJacob Faibussowitsch         PetscCall(PetscStrdup(str, (char **)&next->data));
4943cc1e11dSBarry Smith       }
4953cc1e11dSBarry Smith       break;
496d71ae5a4SJacob Faibussowitsch     default:
497d71ae5a4SJacob Faibussowitsch       break;
4986356e834SBarry Smith     }
4996356e834SBarry Smith     next = next->next;
5006356e834SBarry Smith   }
5013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5026356e834SBarry Smith }
503b3506946SBarry Smith #endif
504b3506946SBarry Smith 
505d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems *PetscOptionsObject)
506d71ae5a4SJacob Faibussowitsch {
50710c654e6SJacob Faibussowitsch   PetscOptionItem next, last;
50853acd3b1SBarry Smith 
50953acd3b1SBarry Smith   PetscFunctionBegin;
51083355fc5SBarry Smith   if (PetscOptionsObject->next) {
51183355fc5SBarry Smith     if (!PetscOptionsObject->count) {
512a264d7a6SBarry Smith #if defined(PETSC_HAVE_SAWS)
5139566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSAWsInput(PetscOptionsObject));
514b3506946SBarry Smith #else
5159566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetFromTextInput(PetscOptionsObject));
516b3506946SBarry Smith #endif
517aee2cecaSBarry Smith     }
518aee2cecaSBarry Smith   }
5196356e834SBarry Smith 
5209566063dSJacob Faibussowitsch   PetscCall(PetscFree(PetscOptionsObject->title));
5216356e834SBarry Smith 
522e26ddf31SBarry Smith   /* reset counter to -2; this updates the screen with the new options for the selected method */
523e55864a3SBarry Smith   if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2;
5247a72a596SBarry Smith   /* reset alreadyprinted flag */
525e55864a3SBarry Smith   PetscOptionsObject->alreadyprinted = PETSC_FALSE;
526e55864a3SBarry Smith   if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE;
527e55864a3SBarry Smith   PetscOptionsObject->object = NULL;
52853acd3b1SBarry Smith 
52910c654e6SJacob Faibussowitsch   while ((next = PetscOptionsObject->next)) {
53010c654e6SJacob Faibussowitsch     const PetscOptionType type        = next->type;
53110c654e6SJacob Faibussowitsch     const size_t          arraylength = next->arraylength;
53210c654e6SJacob Faibussowitsch     void                 *data        = next->data;
53310c654e6SJacob Faibussowitsch 
53410c654e6SJacob Faibussowitsch     if (next->set) {
53510c654e6SJacob Faibussowitsch       char option[256], value[1024], tmp[32];
53610c654e6SJacob Faibussowitsch 
537e55864a3SBarry Smith       if (PetscOptionsObject->prefix) {
538c6a7a370SJeremy L Thompson         PetscCall(PetscStrncpy(option, "-", sizeof(option)));
539c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(option, PetscOptionsObject->prefix, sizeof(option)));
54010c654e6SJacob Faibussowitsch         PetscCall(PetscStrlcat(option, next->option + 1, sizeof(option)));
54110c654e6SJacob Faibussowitsch       } else {
54210c654e6SJacob Faibussowitsch         PetscCall(PetscStrncpy(option, next->option, sizeof(option)));
54310c654e6SJacob Faibussowitsch       }
5446356e834SBarry Smith 
54510c654e6SJacob Faibussowitsch       switch (type) {
546d71ae5a4SJacob Faibussowitsch       case OPTION_HEAD:
547d71ae5a4SJacob Faibussowitsch         break;
5486356e834SBarry Smith       case OPTION_INT_ARRAY:
54910c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscInt *)data)[0]));
55010c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
55110c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscInt *)data)[j]));
552c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
553c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5546356e834SBarry Smith         }
5556356e834SBarry Smith         break;
556d71ae5a4SJacob Faibussowitsch       case OPTION_INT:
55710c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)*(PetscInt *)data));
558d71ae5a4SJacob Faibussowitsch         break;
559d71ae5a4SJacob Faibussowitsch       case OPTION_REAL:
56010c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)*(PetscReal *)data));
561d71ae5a4SJacob Faibussowitsch         break;
5626356e834SBarry Smith       case OPTION_REAL_ARRAY:
56310c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)((PetscReal *)data)[0]));
56410c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
56510c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g", (double)((PetscReal *)data)[j]));
566c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
567c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5686356e834SBarry Smith         }
5696356e834SBarry Smith         break;
570050cccc3SHong Zhang       case OPTION_SCALAR_ARRAY:
57110c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[0]), (double)PetscImaginaryPart(((PetscScalar *)data)[0])));
57210c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
57310c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[j]), (double)PetscImaginaryPart(((PetscScalar *)data)[j])));
574c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
575c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
576050cccc3SHong Zhang         }
577050cccc3SHong Zhang         break;
578d71ae5a4SJacob Faibussowitsch       case OPTION_BOOL:
57910c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", *(int *)data));
580d71ae5a4SJacob Faibussowitsch         break;
5817781c08eSBarry Smith       case OPTION_BOOL_ARRAY:
58210c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscBool *)data)[0]));
58310c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
58410c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscBool *)data)[j]));
585c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
586c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5871ae3d29cSBarry Smith         }
5881ae3d29cSBarry Smith         break;
58910c654e6SJacob Faibussowitsch       case OPTION_FLIST: // fall-through
59010c654e6SJacob Faibussowitsch       case OPTION_ELIST: // fall-through
591d71ae5a4SJacob Faibussowitsch       case OPTION_STRING:
59210c654e6SJacob Faibussowitsch         PetscCall(PetscStrncpy(value, (char *)data, sizeof(value)));
593d71ae5a4SJacob Faibussowitsch         break;
5941ae3d29cSBarry Smith       case OPTION_STRING_ARRAY:
59510c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%s", ((char **)data)[0]));
59610c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; j++) {
59710c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%s", ((char **)data)[j]));
598c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
599c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
6001ae3d29cSBarry Smith         }
6016356e834SBarry Smith         break;
6026356e834SBarry Smith       }
6039566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(PetscOptionsObject->options, option, value));
6046356e834SBarry Smith     }
60510c654e6SJacob Faibussowitsch     if (type == OPTION_ELIST) PetscCall(PetscStrNArrayDestroy(next->nlist, (char ***)&next->list));
60610c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->text));
60710c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->option));
60810c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->man));
60910c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->edata));
610c979a496SBarry Smith 
61110c654e6SJacob Faibussowitsch     if (type == OPTION_STRING || type == OPTION_FLIST || type == OPTION_ELIST) {
61210c654e6SJacob Faibussowitsch       free(data);
613c979a496SBarry Smith     } else {
61410c654e6SJacob Faibussowitsch       // use next->data instead of data because PetscFree() sets it to NULL
61510c654e6SJacob Faibussowitsch       PetscCall(PetscFree(next->data));
616c979a496SBarry Smith     }
6177781c08eSBarry Smith 
61810c654e6SJacob Faibussowitsch     last                     = next;
61910c654e6SJacob Faibussowitsch     PetscOptionsObject->next = next->next;
6209566063dSJacob Faibussowitsch     PetscCall(PetscFree(last));
6216356e834SBarry Smith   }
6229566063dSJacob Faibussowitsch   PetscCall(PetscFree(PetscOptionsObject->prefix));
62302c9f0b5SLisandro Dalcin   PetscOptionsObject->next = NULL;
6243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
62553acd3b1SBarry Smith }
62653acd3b1SBarry Smith 
62710c654e6SJacob Faibussowitsch static PetscErrorCode GetListLength(const char *const *list, PetscInt *len)
62810c654e6SJacob Faibussowitsch {
62910c654e6SJacob Faibussowitsch   PetscInt retlen = 0;
63010c654e6SJacob Faibussowitsch 
63110c654e6SJacob Faibussowitsch   PetscFunctionBegin;
6324f572ea9SToby Isaac   PetscAssertPointer(len, 2);
63310c654e6SJacob Faibussowitsch   while (list[retlen]) {
6344f572ea9SToby Isaac     PetscAssertPointer(list[retlen], 1);
63510c654e6SJacob Faibussowitsch     PetscCheck(++retlen < 50, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "List argument appears to be wrong or have more than 50 entries");
63610c654e6SJacob Faibussowitsch   }
63710c654e6SJacob Faibussowitsch   PetscCheck(retlen > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least 2 entries: typename and type prefix");
63810c654e6SJacob Faibussowitsch   /* drop item name and prefix*/
63910c654e6SJacob Faibussowitsch   *len = retlen - 2;
64010c654e6SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
64110c654e6SJacob Faibussowitsch }
64210c654e6SJacob Faibussowitsch 
643d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnum_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum currentvalue, PetscEnum *value, PetscBool *set)
644d71ae5a4SJacob Faibussowitsch {
64553acd3b1SBarry Smith   PetscInt  ntext = 0;
646aa5bb8c0SSatish Balay   PetscInt  tval;
647ace3abfcSBarry Smith   PetscBool tflg;
64853acd3b1SBarry Smith 
64953acd3b1SBarry Smith   PetscFunctionBegin;
6504f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6514f572ea9SToby Isaac   PetscAssertPointer(list, 5);
6524f572ea9SToby Isaac   PetscAssertPointer(value, 7);
6534f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
65410c654e6SJacob Faibussowitsch   PetscCall(GetListLength(list, &ntext));
6559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[currentvalue], &tval, &tflg));
656aa5bb8c0SSatish Balay   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
657aa5bb8c0SSatish Balay   if (tflg) *value = (PetscEnum)tval;
658aa5bb8c0SSatish Balay   if (set) *set = tflg;
6593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
66053acd3b1SBarry Smith }
66153acd3b1SBarry Smith 
662d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnumArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum value[], PetscInt *n, PetscBool *set)
663d71ae5a4SJacob Faibussowitsch {
66410c654e6SJacob Faibussowitsch   PetscInt    nlist  = 0;
66510c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
666d3e47460SLisandro Dalcin 
667d3e47460SLisandro Dalcin   PetscFunctionBegin;
6684f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6694f572ea9SToby Isaac   PetscAssertPointer(list, 5);
6704f572ea9SToby Isaac   PetscAssertPointer(value, 6);
6714f572ea9SToby Isaac   PetscAssertPointer(n, 7);
67210c654e6SJacob Faibussowitsch   PetscCheck(*n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") must be > 0", *n);
6734f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
67410c654e6SJacob Faibussowitsch   PetscCall(GetListLength(list, &nlist));
67510c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetEnumArray(PetscOptionsObject->options, prefix, opt, list, value, n, set));
67610c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
67710c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
67810c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
67910c654e6SJacob Faibussowitsch 
68010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s", Prefix(prefix), opt + 1, list[value[0]]));
68110c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%s", list[value[i]]));
68210c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (choose from)", text));
68310c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nlist; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
68410c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
685d3e47460SLisandro Dalcin   }
6863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
687d3e47460SLisandro Dalcin }
688d3e47460SLisandro Dalcin 
689d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInt_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *set, PetscInt lb, PetscInt ub)
690d71ae5a4SJacob Faibussowitsch {
69110c654e6SJacob Faibussowitsch   const char        *prefix  = PetscOptionsObject->prefix;
69210c654e6SJacob Faibussowitsch   const PetscOptions options = PetscOptionsObject->options;
69312655325SBarry Smith   PetscBool          wasset;
69453acd3b1SBarry Smith 
69553acd3b1SBarry Smith   PetscFunctionBegin;
6964f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6974f572ea9SToby Isaac   PetscAssertPointer(value, 6);
6984f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
69908401ef6SPierre Jolivet   PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, currentvalue, lb);
70008401ef6SPierre Jolivet   PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, currentvalue, ub);
701e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
70210c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
70310c654e6SJacob Faibussowitsch 
7049566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt));
7059566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data));
70612655325SBarry Smith     *(PetscInt *)amsopt->data = currentvalue;
7073e211508SBarry Smith 
70810c654e6SJacob Faibussowitsch     PetscCall(PetscOptionsGetInt(options, prefix, opt, &currentvalue, &wasset));
709ad540459SPierre Jolivet     if (wasset) *(PetscInt *)amsopt->data = currentvalue;
710af6d86caSBarry Smith   }
71110c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(options, prefix, opt, value, &wasset));
712cc73adaaSBarry Smith   PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, *value, lb);
713cc73adaaSBarry Smith   PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, *value, ub);
71444ef3d73SBarry Smith   if (set) *set = wasset;
71510c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
71610c654e6SJacob Faibussowitsch     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)));
71753acd3b1SBarry Smith   }
7183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71953acd3b1SBarry Smith }
72053acd3b1SBarry Smith 
7216497c311SBarry Smith PetscErrorCode PetscOptionsMPIInt_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscMPIInt currentvalue, PetscMPIInt *value, PetscBool *set, PetscMPIInt lb, PetscMPIInt ub)
7226497c311SBarry Smith {
7236497c311SBarry Smith   const char        *prefix  = PetscOptionsObject->prefix;
7246497c311SBarry Smith   const PetscOptions options = PetscOptionsObject->options;
7256497c311SBarry Smith   PetscBool          wasset;
7266497c311SBarry Smith 
7276497c311SBarry Smith   PetscFunctionBegin;
7286497c311SBarry Smith   PetscAssertPointer(opt, 2);
7296497c311SBarry Smith   PetscAssertPointer(value, 6);
7306497c311SBarry Smith   if (set) PetscAssertPointer(set, 7);
7316497c311SBarry Smith   PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d less than allowed bound %d", currentvalue, lb);
7326497c311SBarry Smith   PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d greater than allowed bound %d", currentvalue, ub);
7336497c311SBarry Smith   if (!PetscOptionsObject->count) {
7346497c311SBarry Smith     PetscOptionItem amsopt;
7356497c311SBarry Smith 
7366497c311SBarry Smith     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt));
7376497c311SBarry Smith     PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data));
7386497c311SBarry Smith     *(PetscMPIInt *)amsopt->data = currentvalue;
7396497c311SBarry Smith 
7406497c311SBarry Smith     PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, &currentvalue, &wasset));
7416497c311SBarry Smith     if (wasset) *(PetscMPIInt *)amsopt->data = currentvalue;
7426497c311SBarry Smith   }
7436497c311SBarry Smith   PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, value, &wasset));
7446497c311SBarry Smith   PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d less than allowed bound %d", *value, lb);
7456497c311SBarry Smith   PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d greater than allowed bound %d", *value, ub);
7466497c311SBarry Smith   if (set) *set = wasset;
7476497c311SBarry Smith   if (ShouldPrintHelp(PetscOptionsObject)) { PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <now %d : formerly %d>: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? *value : currentvalue, currentvalue, text, ManSection(man))); }
7486497c311SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
7496497c311SBarry Smith }
7506497c311SBarry Smith 
751d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsString_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char currentvalue[], char value[], size_t len, PetscBool *set)
752d71ae5a4SJacob Faibussowitsch {
75310c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
75444ef3d73SBarry Smith   PetscBool   lset;
75553acd3b1SBarry Smith 
75653acd3b1SBarry Smith   PetscFunctionBegin;
7574f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
7584f572ea9SToby Isaac   PetscAssertPointer(value, 6);
7594f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
7601a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
76110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
76210c654e6SJacob Faibussowitsch 
7639566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
76464facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
7659566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
766af6d86caSBarry Smith   }
76710c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
76844ef3d73SBarry Smith   if (set) *set = lset;
76910c654e6SJacob Faibussowitsch   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)));
7703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
77153acd3b1SBarry Smith }
77253acd3b1SBarry Smith 
77352ce0ab5SPierre Jolivet PetscErrorCode PetscOptionsReal_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal currentvalue, PetscReal *value, PetscBool *set, PetscReal lb, PetscReal ub)
774d71ae5a4SJacob Faibussowitsch {
77510c654e6SJacob Faibussowitsch   const char        *prefix  = PetscOptionsObject->prefix;
77652ce0ab5SPierre Jolivet   const PetscOptions options = PetscOptionsObject->options;
77752ce0ab5SPierre Jolivet   PetscBool          wasset;
77853acd3b1SBarry Smith 
77953acd3b1SBarry Smith   PetscFunctionBegin;
7804f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
7814f572ea9SToby Isaac   PetscAssertPointer(value, 6);
7824f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
78352ce0ab5SPierre Jolivet   PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g less than allowed bound %g", (double)currentvalue, (double)lb);
78452ce0ab5SPierre Jolivet   PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g greater than allowed bound %g", (double)currentvalue, (double)ub);
785e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
78610c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
78710c654e6SJacob Faibussowitsch 
7889566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt));
7899566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data));
7900fdccdaeSBarry Smith     *(PetscReal *)amsopt->data = currentvalue;
79152ce0ab5SPierre Jolivet 
79252ce0ab5SPierre Jolivet     PetscCall(PetscOptionsGetReal(options, prefix, opt, &currentvalue, &wasset));
79352ce0ab5SPierre Jolivet     if (wasset) *(PetscReal *)amsopt->data = currentvalue;
794538aa990SBarry Smith   }
79552ce0ab5SPierre Jolivet   PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &wasset));
79652ce0ab5SPierre Jolivet   PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %g less than allowed bound %g", (double)*value, (double)lb);
79752ce0ab5SPierre Jolivet   PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %g greater than allowed bound %g", (double)*value, (double)ub);
79852ce0ab5SPierre Jolivet   if (set) *set = wasset;
79910c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
80052ce0ab5SPierre Jolivet     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <now %g : formerly %g>: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? (double)*value : (double)currentvalue, (double)currentvalue, text, ManSection(man)));
80153acd3b1SBarry Smith   }
8023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
80353acd3b1SBarry Smith }
80453acd3b1SBarry Smith 
805d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set)
806d71ae5a4SJacob Faibussowitsch {
80753acd3b1SBarry Smith   PetscFunctionBegin;
80853acd3b1SBarry Smith #if !defined(PETSC_USE_COMPLEX)
8099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set));
81053acd3b1SBarry Smith #else
8119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set));
81253acd3b1SBarry Smith #endif
8133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
81453acd3b1SBarry Smith }
81553acd3b1SBarry Smith 
816d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
817d71ae5a4SJacob Faibussowitsch {
81810c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
81953acd3b1SBarry Smith 
82053acd3b1SBarry Smith   PetscFunctionBegin;
8214f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8224f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
823e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
82410c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
82510c654e6SJacob Faibussowitsch 
8269566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
8279566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
828a297a907SKarl Rupp 
829ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
8301ae3d29cSBarry Smith   }
83110c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg));
83210c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
8333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
83453acd3b1SBarry Smith }
83553acd3b1SBarry Smith 
836d71ae5a4SJacob Faibussowitsch 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)
837d71ae5a4SJacob Faibussowitsch {
83810c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
83944ef3d73SBarry Smith   PetscBool   lset;
84053acd3b1SBarry Smith 
84153acd3b1SBarry Smith   PetscFunctionBegin;
8424f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8434f572ea9SToby Isaac   PetscAssertPointer(value, 7);
8444f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 9);
8451a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
84610c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
84710c654e6SJacob Faibussowitsch 
8489566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt));
84964facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
8509566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
8513cc1e11dSBarry Smith     amsopt->flist = list;
8523cc1e11dSBarry Smith   }
85310c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
85444ef3d73SBarry Smith   if (set) *set = lset;
85510c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue));
8563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
85753acd3b1SBarry Smith }
85853acd3b1SBarry Smith 
85910c654e6SJacob Faibussowitsch #ifdef __cplusplus
86010c654e6SJacob Faibussowitsch   #include <type_traits>
86110c654e6SJacob Faibussowitsch #endif
86210c654e6SJacob Faibussowitsch 
863d71ae5a4SJacob Faibussowitsch 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)
864d71ae5a4SJacob Faibussowitsch {
86510c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
86644ef3d73SBarry Smith   PetscBool   lset;
86753acd3b1SBarry Smith 
86853acd3b1SBarry Smith   PetscFunctionBegin;
8694f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8704f572ea9SToby Isaac   PetscAssertPointer(value, 8);
8714f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 9);
8721a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
87310c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
87410c654e6SJacob Faibussowitsch 
8759566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt));
87664facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
8779566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
8789566063dSJacob Faibussowitsch     PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list));
87910c654e6SJacob Faibussowitsch     PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX);
88010c654e6SJacob Faibussowitsch #ifdef __cplusplus
88110c654e6SJacob Faibussowitsch     static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, "");
88210c654e6SJacob Faibussowitsch #endif
88310c654e6SJacob Faibussowitsch     amsopt->nlist = (char)ntext;
8841ae3d29cSBarry Smith   }
88510c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset));
88644ef3d73SBarry Smith   if (set) *set = lset;
88710c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
88810c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
88910c654e6SJacob Faibussowitsch 
89010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext));
89110c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
89210c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
89353acd3b1SBarry Smith   }
8943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
89553acd3b1SBarry Smith }
89653acd3b1SBarry Smith 
897d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
898d71ae5a4SJacob Faibussowitsch {
89910c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
90053acd3b1SBarry Smith 
90153acd3b1SBarry Smith   PetscFunctionBegin;
9024f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9034f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
904e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
90510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
90610c654e6SJacob Faibussowitsch 
9079566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9089566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
909a297a907SKarl Rupp 
910ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9111ae3d29cSBarry Smith   }
91268b16fdaSBarry Smith   *flg = PETSC_FALSE;
91310c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
91410c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
91510c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
91610c654e6SJacob Faibussowitsch 
91710c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  Pick at most one of -------------\n"));
91810c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
91953acd3b1SBarry Smith   }
9203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
92153acd3b1SBarry Smith }
92253acd3b1SBarry Smith 
923d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
924d71ae5a4SJacob Faibussowitsch {
92510c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
92653acd3b1SBarry Smith 
92753acd3b1SBarry Smith   PetscFunctionBegin;
9284f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9294f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
930e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
93110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
93210c654e6SJacob Faibussowitsch 
9339566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9349566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
935a297a907SKarl Rupp 
936ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9371ae3d29cSBarry Smith   }
93817326d04SJed Brown   *flg = PETSC_FALSE;
93910c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
94010c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
9413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
94253acd3b1SBarry Smith }
94353acd3b1SBarry Smith 
944d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
945d71ae5a4SJacob Faibussowitsch {
94610c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
94753acd3b1SBarry Smith 
94853acd3b1SBarry Smith   PetscFunctionBegin;
9494f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9504f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
951e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
95210c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
95310c654e6SJacob Faibussowitsch 
9549566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9559566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
956a297a907SKarl Rupp 
957ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9581ae3d29cSBarry Smith   }
95917326d04SJed Brown   *flg = PETSC_FALSE;
96010c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
96110c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
9623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
96353acd3b1SBarry Smith }
96453acd3b1SBarry Smith 
965d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set)
966d71ae5a4SJacob Faibussowitsch {
96710c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
968ace3abfcSBarry Smith   PetscBool   iset;
96953acd3b1SBarry Smith 
97053acd3b1SBarry Smith   PetscFunctionBegin;
9714f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9724f572ea9SToby Isaac   PetscAssertPointer(flg, 6);
9734f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
974e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
97510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
97610c654e6SJacob Faibussowitsch 
9779566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9789566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
979a297a907SKarl Rupp 
98094ae4db5SBarry Smith     *(PetscBool *)amsopt->data = currentvalue;
981af6d86caSBarry Smith   }
98210c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset));
98353acd3b1SBarry Smith   if (set) *set = iset;
98410c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
98510c654e6SJacob Faibussowitsch     const char *curvalue = PetscBools[currentvalue];
98610c654e6SJacob Faibussowitsch 
98710c654e6SJacob Faibussowitsch     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)));
98853acd3b1SBarry Smith   }
9893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
99053acd3b1SBarry Smith }
99153acd3b1SBarry Smith 
992d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set)
993d71ae5a4SJacob Faibussowitsch {
99410c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
99553acd3b1SBarry Smith 
99653acd3b1SBarry Smith   PetscFunctionBegin;
9974f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9984f572ea9SToby Isaac   PetscAssertPointer(n, 6);
99910c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10004f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10014f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1002e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
100310c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1004e26ddf31SBarry Smith     PetscReal      *vals;
100510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1006e26ddf31SBarry Smith 
10079566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt));
100810c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
100910c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
101010c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
101110c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1012e26ddf31SBarry Smith   }
101310c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set));
101410c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
101510c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
101610c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
101710c654e6SJacob Faibussowitsch 
101810c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0]));
101910c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i]));
102010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
102153acd3b1SBarry Smith   }
10223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
102353acd3b1SBarry Smith }
102453acd3b1SBarry Smith 
1025d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set)
1026d71ae5a4SJacob Faibussowitsch {
102710c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
1028050cccc3SHong Zhang 
1029050cccc3SHong Zhang   PetscFunctionBegin;
10304f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10314f572ea9SToby Isaac   PetscAssertPointer(n, 6);
103210c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10334f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10344f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1035050cccc3SHong Zhang   if (!PetscOptionsObject->count) {
103610c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
103710c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1038050cccc3SHong Zhang     PetscScalar    *vals;
1039050cccc3SHong Zhang 
10409566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt));
104110c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
104210c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
104310c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
104410c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1045050cccc3SHong Zhang   }
104610c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set));
104710c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
104810c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
104910c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
105010c654e6SJacob Faibussowitsch 
105110c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0])));
105210c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i])));
105310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1054050cccc3SHong Zhang   }
10553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1056050cccc3SHong Zhang }
105753acd3b1SBarry Smith 
1058d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set)
1059d71ae5a4SJacob Faibussowitsch {
106010c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
106153acd3b1SBarry Smith 
106253acd3b1SBarry Smith   PetscFunctionBegin;
10634f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10644f572ea9SToby Isaac   PetscAssertPointer(n, 6);
106510c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10664f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10674f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1068e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
106910c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1070e26ddf31SBarry Smith     PetscInt       *vals;
107110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1072e26ddf31SBarry Smith 
10739566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt));
107410c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
107510c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
107610c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
107710c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1078e26ddf31SBarry Smith   }
107910c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set));
108010c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
108110c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
108210c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
108310c654e6SJacob Faibussowitsch 
108410c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0]));
108510c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i]));
108610c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
108753acd3b1SBarry Smith   }
10883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108953acd3b1SBarry Smith }
109053acd3b1SBarry Smith 
1091d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set)
1092d71ae5a4SJacob Faibussowitsch {
109310c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
109453acd3b1SBarry Smith 
109553acd3b1SBarry Smith   PetscFunctionBegin;
10964f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10974f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
109810c654e6SJacob Faibussowitsch   PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax);
10994f572ea9SToby Isaac   if (*nmax) PetscAssertPointer(value, 5);
11004f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1101e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
110210c654e6SJacob Faibussowitsch     const PetscInt  nmaxv = *nmax;
110310c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1104a297a907SKarl Rupp 
110510c654e6SJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt));
110610c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data));
110710c654e6SJacob Faibussowitsch     amsopt->arraylength = nmaxv;
11081ae3d29cSBarry Smith   }
110910c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set));
111010c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
11113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
111253acd3b1SBarry Smith }
111353acd3b1SBarry Smith 
1114d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set)
1115d71ae5a4SJacob Faibussowitsch {
111610c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
1117e2446a98SMatthew Knepley 
1118e2446a98SMatthew Knepley   PetscFunctionBegin;
11194f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
11204f572ea9SToby Isaac   PetscAssertPointer(n, 6);
112110c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
11224f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
11234f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1124e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
112510c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1126ace3abfcSBarry Smith     PetscBool      *vals;
112710c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
11281ae3d29cSBarry Smith 
11299566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt));
113010c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
113110c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
113210c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
113310c654e6SJacob Faibussowitsch     amsopt->data        = vals;
11341ae3d29cSBarry Smith   }
113510c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set));
113610c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
113710c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
113810c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
113910c654e6SJacob Faibussowitsch 
114010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%d", Prefix(prefix), opt + 1, value[0]));
114110c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i]));
114210c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1143e2446a98SMatthew Knepley   }
11443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1145e2446a98SMatthew Knepley }
1146e2446a98SMatthew Knepley 
114788aa4217SBarry Smith /*MC
1148648c30bcSBarry Smith   PetscOptionsViewer - Creates a viewer appropriate for the type indicated by the user
11498cc676e6SMatthew G Knepley 
115088aa4217SBarry Smith   Synopsis:
115110450e9eSJacob Faibussowitsch   #include <petscviewer.h>
11523a89f35bSSatish Balay   PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
115388aa4217SBarry Smith 
11547cdbe19fSJose E. Roman   Logically Collective on the communicator passed in `PetscOptionsBegin()`
11557cdbe19fSJose E. Roman 
11568cc676e6SMatthew G Knepley   Input Parameters:
11578cc676e6SMatthew G Knepley + opt  - option name
11588cc676e6SMatthew G Knepley . text - short string that describes the option
11598cc676e6SMatthew G Knepley - man  - manual page with additional information on option
11608cc676e6SMatthew G Knepley 
1161d8d19677SJose E. Roman   Output Parameters:
11628cc676e6SMatthew G Knepley + viewer - the viewer
11639314d9b7SBarry Smith . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed
1164811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
11658cc676e6SMatthew G Knepley 
11668cc676e6SMatthew G Knepley   Level: beginner
11678cc676e6SMatthew G Knepley 
116895452b02SPatrick Sanan   Notes:
1169811af0c4SBarry Smith   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`
11708cc676e6SMatthew G Knepley 
1171648c30bcSBarry Smith   See `PetscOptionsCreateViewer()` for the format of the supplied viewer and its options
11728cc676e6SMatthew G Knepley 
1173648c30bcSBarry Smith .seealso: `PetscOptionsCreateViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1174db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
1175aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1176db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1177c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1178db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1179db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
118088aa4217SBarry Smith M*/
1181d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
1182d71ae5a4SJacob Faibussowitsch {
118310c654e6SJacob Faibussowitsch   const MPI_Comm comm   = PetscOptionsObject->comm;
118410c654e6SJacob Faibussowitsch   const char    *prefix = PetscOptionsObject->prefix;
11858cc676e6SMatthew G Knepley 
11868cc676e6SMatthew G Knepley   PetscFunctionBegin;
11874f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
11884f572ea9SToby Isaac   PetscAssertPointer(viewer, 5);
11894f572ea9SToby Isaac   if (format) PetscAssertPointer(format, 6);
11904f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
11911a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
119210c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
119310c654e6SJacob Faibussowitsch 
11949566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
119564facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
11969566063dSJacob Faibussowitsch     PetscCall(PetscStrdup("", (char **)&amsopt->data));
11978cc676e6SMatthew G Knepley   }
1198648c30bcSBarry Smith   PetscCall(PetscOptionsCreateViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set));
119910c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man)));
12003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12018cc676e6SMatthew G Knepley }
1202