xref: /petsc/src/sys/objects/aoptions.c (revision 57508ece14a6b1339c0bbf016ecd72f673a062b0)
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));
239*57508eceSPierre Jolivet       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;
356dd460d27SBarry Smith         size_t     i, len;
357e26ddf31SBarry Smith         char      *value;
358ace3abfcSBarry Smith         PetscBool  foundrange;
359e26ddf31SBarry Smith 
360e26ddf31SBarry Smith         next->set = PETSC_TRUE;
361e26ddf31SBarry Smith         value     = str;
3629566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(value, ',', &token));
3639566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &value));
364e26ddf31SBarry Smith         while (n < nmax) {
365e26ddf31SBarry Smith           if (!value) break;
366e26ddf31SBarry Smith 
367e26ddf31SBarry Smith           /* look for form  d-D where d and D are integers */
368e26ddf31SBarry Smith           foundrange = PETSC_FALSE;
3699566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(value, &len));
370e26ddf31SBarry Smith           if (value[0] == '-') i = 2;
371e26ddf31SBarry Smith           else i = 1;
372dd460d27SBarry Smith           for (; i < len; i++) {
373e26ddf31SBarry Smith             if (value[i] == '-') {
374dd460d27SBarry Smith               PetscCheck(i != len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
375e26ddf31SBarry Smith               value[i] = 0;
3769566063dSJacob Faibussowitsch               PetscCall(PetscOptionsStringToInt(value, &start));
3779566063dSJacob Faibussowitsch               PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
37808401ef6SPierre 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);
379cc73adaaSBarry 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);
380e26ddf31SBarry Smith               for (; start < end; start++) {
3819371c9d4SSatish Balay                 *dvalue = start;
3829371c9d4SSatish Balay                 dvalue++;
3839371c9d4SSatish Balay                 n++;
384e26ddf31SBarry Smith               }
385e26ddf31SBarry Smith               foundrange = PETSC_TRUE;
386e26ddf31SBarry Smith               break;
387e26ddf31SBarry Smith             }
388e26ddf31SBarry Smith           }
389e26ddf31SBarry Smith           if (!foundrange) {
3909566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value, dvalue));
391e26ddf31SBarry Smith             dvalue++;
392e26ddf31SBarry Smith             n++;
393e26ddf31SBarry Smith           }
3949566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &value));
395e26ddf31SBarry Smith         }
3969566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
397e26ddf31SBarry Smith       }
398e26ddf31SBarry Smith       break;
399e26ddf31SBarry Smith     case OPTION_REAL_ARRAY:
4004bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
401e26ddf31SBarry Smith       valr = (PetscReal *)next->data;
4026497c311SBarry Smith       for (PetscInt i = 0; i < next->arraylength; i++) {
4039566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i]));
40448a46eb9SPierre Jolivet         if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
405e26ddf31SBarry Smith       }
4069566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
4079566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
408e26ddf31SBarry Smith       if (str[0]) {
409e26ddf31SBarry Smith         PetscToken token;
410e26ddf31SBarry Smith         PetscInt   n = 0, nmax = next->arraylength;
411e26ddf31SBarry Smith         PetscReal *dvalue = (PetscReal *)next->data;
412e26ddf31SBarry Smith         char      *value;
413e26ddf31SBarry Smith 
414e26ddf31SBarry Smith         next->set = PETSC_TRUE;
415e26ddf31SBarry Smith         value     = str;
4169566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(value, ',', &token));
4179566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &value));
418e26ddf31SBarry Smith         while (n < nmax) {
419e26ddf31SBarry Smith           if (!value) break;
4209566063dSJacob Faibussowitsch           PetscCall(PetscOptionsStringToReal(value, dvalue));
421e26ddf31SBarry Smith           dvalue++;
422e26ddf31SBarry Smith           n++;
4239566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &value));
424e26ddf31SBarry Smith         }
4259566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
426e26ddf31SBarry Smith       }
427e26ddf31SBarry Smith       break;
4286356e834SBarry Smith     case OPTION_INT:
4294bb2516aSBarry 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));
4309566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4313fc1eb6aSBarry Smith       if (str[0]) {
432d25d7f95SJed Brown   #if defined(PETSC_SIZEOF_LONG_LONG)
433d25d7f95SJed Brown         long long lid;
434d25d7f95SJed Brown         sscanf(str, "%lld", &lid);
4351690c2aeSBarry 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);
436c272547aSJed Brown   #else
437d25d7f95SJed Brown         long lid;
438d25d7f95SJed Brown         sscanf(str, "%ld", &lid);
4391690c2aeSBarry 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);
440c272547aSJed Brown   #endif
441a297a907SKarl Rupp 
442d25d7f95SJed Brown         next->set                 = PETSC_TRUE;
443d25d7f95SJed Brown         *((PetscInt *)next->data) = (PetscInt)lid;
444aee2cecaSBarry Smith       }
445aee2cecaSBarry Smith       break;
446aee2cecaSBarry Smith     case OPTION_REAL:
4474bb2516aSBarry 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));
4489566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4493fc1eb6aSBarry Smith       if (str[0]) {
450ce63c4c1SBarry Smith   #if defined(PETSC_USE_REAL_SINGLE)
451a4404d99SBarry Smith         sscanf(str, "%e", &ir);
452570b7f6dSBarry Smith   #elif defined(PETSC_USE_REAL___FP16)
453570b7f6dSBarry Smith         float irtemp;
454570b7f6dSBarry Smith         sscanf(str, "%e", &irtemp);
455570b7f6dSBarry Smith         ir = irtemp;
456ce63c4c1SBarry Smith   #elif defined(PETSC_USE_REAL_DOUBLE)
457aee2cecaSBarry Smith         sscanf(str, "%le", &ir);
458ce63c4c1SBarry Smith   #elif defined(PETSC_USE_REAL___FLOAT128)
459d9822059SBarry Smith         ir = strtoflt128(str, 0);
460d9822059SBarry Smith   #else
461513dbe71SLisandro Dalcin         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type");
462a4404d99SBarry Smith   #endif
463aee2cecaSBarry Smith         next->set                  = PETSC_TRUE;
464aee2cecaSBarry Smith         *((PetscReal *)next->data) = ir;
465aee2cecaSBarry Smith       }
466aee2cecaSBarry Smith       break;
4677781c08eSBarry Smith     case OPTION_BOOL:
4684bb2516aSBarry 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));
4699566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4707781c08eSBarry Smith       if (str[0]) {
4719566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToBool(str, &bid));
4727781c08eSBarry Smith         next->set                  = PETSC_TRUE;
4737781c08eSBarry Smith         *((PetscBool *)next->data) = bid;
4747781c08eSBarry Smith       }
4757781c08eSBarry Smith       break;
476aee2cecaSBarry Smith     case OPTION_STRING:
4774bb2516aSBarry 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));
4789566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4793fc1eb6aSBarry Smith       if (str[0]) {
480aee2cecaSBarry Smith         next->set = PETSC_TRUE;
48164facd6cSBarry Smith         /* must use system malloc since SAWs may free this */
4829566063dSJacob Faibussowitsch         PetscCall(PetscStrdup(str, (char **)&next->data));
4836356e834SBarry Smith       }
4846356e834SBarry Smith       break;
485a264d7a6SBarry Smith     case OPTION_FLIST:
4869566063dSJacob Faibussowitsch       PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data));
4879566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4883cc1e11dSBarry Smith       if (str[0]) {
489e55864a3SBarry Smith         PetscOptionsObject->changedmethod = PETSC_TRUE;
4903cc1e11dSBarry Smith         next->set                         = PETSC_TRUE;
49164facd6cSBarry Smith         /* must use system malloc since SAWs may free this */
4929566063dSJacob Faibussowitsch         PetscCall(PetscStrdup(str, (char **)&next->data));
4933cc1e11dSBarry Smith       }
4943cc1e11dSBarry Smith       break;
495d71ae5a4SJacob Faibussowitsch     default:
496d71ae5a4SJacob Faibussowitsch       break;
4976356e834SBarry Smith     }
4986356e834SBarry Smith     next = next->next;
4996356e834SBarry Smith   }
5003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5016356e834SBarry Smith }
502b3506946SBarry Smith #endif
503b3506946SBarry Smith 
504d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems *PetscOptionsObject)
505d71ae5a4SJacob Faibussowitsch {
50610c654e6SJacob Faibussowitsch   PetscOptionItem next, last;
50753acd3b1SBarry Smith 
50853acd3b1SBarry Smith   PetscFunctionBegin;
50983355fc5SBarry Smith   if (PetscOptionsObject->next) {
51083355fc5SBarry Smith     if (!PetscOptionsObject->count) {
511a264d7a6SBarry Smith #if defined(PETSC_HAVE_SAWS)
5129566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSAWsInput(PetscOptionsObject));
513b3506946SBarry Smith #else
5149566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetFromTextInput(PetscOptionsObject));
515b3506946SBarry Smith #endif
516aee2cecaSBarry Smith     }
517aee2cecaSBarry Smith   }
5186356e834SBarry Smith 
5199566063dSJacob Faibussowitsch   PetscCall(PetscFree(PetscOptionsObject->title));
5206356e834SBarry Smith 
521e26ddf31SBarry Smith   /* reset counter to -2; this updates the screen with the new options for the selected method */
522e55864a3SBarry Smith   if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2;
5237a72a596SBarry Smith   /* reset alreadyprinted flag */
524e55864a3SBarry Smith   PetscOptionsObject->alreadyprinted = PETSC_FALSE;
525e55864a3SBarry Smith   if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE;
526e55864a3SBarry Smith   PetscOptionsObject->object = NULL;
52753acd3b1SBarry Smith 
52810c654e6SJacob Faibussowitsch   while ((next = PetscOptionsObject->next)) {
52910c654e6SJacob Faibussowitsch     const PetscOptionType type        = next->type;
53010c654e6SJacob Faibussowitsch     const size_t          arraylength = next->arraylength;
53110c654e6SJacob Faibussowitsch     void                 *data        = next->data;
53210c654e6SJacob Faibussowitsch 
53310c654e6SJacob Faibussowitsch     if (next->set) {
53410c654e6SJacob Faibussowitsch       char option[256], value[1024], tmp[32];
53510c654e6SJacob Faibussowitsch 
536e55864a3SBarry Smith       if (PetscOptionsObject->prefix) {
537c6a7a370SJeremy L Thompson         PetscCall(PetscStrncpy(option, "-", sizeof(option)));
538c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(option, PetscOptionsObject->prefix, sizeof(option)));
53910c654e6SJacob Faibussowitsch         PetscCall(PetscStrlcat(option, next->option + 1, sizeof(option)));
54010c654e6SJacob Faibussowitsch       } else {
54110c654e6SJacob Faibussowitsch         PetscCall(PetscStrncpy(option, next->option, sizeof(option)));
54210c654e6SJacob Faibussowitsch       }
5436356e834SBarry Smith 
54410c654e6SJacob Faibussowitsch       switch (type) {
545d71ae5a4SJacob Faibussowitsch       case OPTION_HEAD:
546d71ae5a4SJacob Faibussowitsch         break;
5476356e834SBarry Smith       case OPTION_INT_ARRAY:
54810c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscInt *)data)[0]));
54910c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
55010c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscInt *)data)[j]));
551c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
552c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5536356e834SBarry Smith         }
5546356e834SBarry Smith         break;
555d71ae5a4SJacob Faibussowitsch       case OPTION_INT:
55610c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)*(PetscInt *)data));
557d71ae5a4SJacob Faibussowitsch         break;
558d71ae5a4SJacob Faibussowitsch       case OPTION_REAL:
55910c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)*(PetscReal *)data));
560d71ae5a4SJacob Faibussowitsch         break;
5616356e834SBarry Smith       case OPTION_REAL_ARRAY:
56210c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)((PetscReal *)data)[0]));
56310c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
56410c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g", (double)((PetscReal *)data)[j]));
565c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
566c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5676356e834SBarry Smith         }
5686356e834SBarry Smith         break;
569050cccc3SHong Zhang       case OPTION_SCALAR_ARRAY:
57010c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[0]), (double)PetscImaginaryPart(((PetscScalar *)data)[0])));
57110c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
57210c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[j]), (double)PetscImaginaryPart(((PetscScalar *)data)[j])));
573c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
574c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
575050cccc3SHong Zhang         }
576050cccc3SHong Zhang         break;
577d71ae5a4SJacob Faibussowitsch       case OPTION_BOOL:
57810c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", *(int *)data));
579d71ae5a4SJacob Faibussowitsch         break;
5807781c08eSBarry Smith       case OPTION_BOOL_ARRAY:
58110c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscBool *)data)[0]));
58210c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
58310c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscBool *)data)[j]));
584c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
585c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5861ae3d29cSBarry Smith         }
5871ae3d29cSBarry Smith         break;
58810c654e6SJacob Faibussowitsch       case OPTION_FLIST: // fall-through
58910c654e6SJacob Faibussowitsch       case OPTION_ELIST: // fall-through
590d71ae5a4SJacob Faibussowitsch       case OPTION_STRING:
59110c654e6SJacob Faibussowitsch         PetscCall(PetscStrncpy(value, (char *)data, sizeof(value)));
592d71ae5a4SJacob Faibussowitsch         break;
5931ae3d29cSBarry Smith       case OPTION_STRING_ARRAY:
59410c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%s", ((char **)data)[0]));
59510c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; j++) {
59610c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%s", ((char **)data)[j]));
597c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
598c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5991ae3d29cSBarry Smith         }
6006356e834SBarry Smith         break;
6016356e834SBarry Smith       }
6029566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(PetscOptionsObject->options, option, value));
6036356e834SBarry Smith     }
60410c654e6SJacob Faibussowitsch     if (type == OPTION_ELIST) PetscCall(PetscStrNArrayDestroy(next->nlist, (char ***)&next->list));
60510c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->text));
60610c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->option));
60710c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->man));
60810c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->edata));
609c979a496SBarry Smith 
61010c654e6SJacob Faibussowitsch     if (type == OPTION_STRING || type == OPTION_FLIST || type == OPTION_ELIST) {
61110c654e6SJacob Faibussowitsch       free(data);
612c979a496SBarry Smith     } else {
61310c654e6SJacob Faibussowitsch       // use next->data instead of data because PetscFree() sets it to NULL
61410c654e6SJacob Faibussowitsch       PetscCall(PetscFree(next->data));
615c979a496SBarry Smith     }
6167781c08eSBarry Smith 
61710c654e6SJacob Faibussowitsch     last                     = next;
61810c654e6SJacob Faibussowitsch     PetscOptionsObject->next = next->next;
6199566063dSJacob Faibussowitsch     PetscCall(PetscFree(last));
6206356e834SBarry Smith   }
6219566063dSJacob Faibussowitsch   PetscCall(PetscFree(PetscOptionsObject->prefix));
62202c9f0b5SLisandro Dalcin   PetscOptionsObject->next = NULL;
6233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
62453acd3b1SBarry Smith }
62553acd3b1SBarry Smith 
62610c654e6SJacob Faibussowitsch static PetscErrorCode GetListLength(const char *const *list, PetscInt *len)
62710c654e6SJacob Faibussowitsch {
62810c654e6SJacob Faibussowitsch   PetscInt retlen = 0;
62910c654e6SJacob Faibussowitsch 
63010c654e6SJacob Faibussowitsch   PetscFunctionBegin;
6314f572ea9SToby Isaac   PetscAssertPointer(len, 2);
63210c654e6SJacob Faibussowitsch   while (list[retlen]) {
6334f572ea9SToby Isaac     PetscAssertPointer(list[retlen], 1);
63410c654e6SJacob Faibussowitsch     PetscCheck(++retlen < 50, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "List argument appears to be wrong or have more than 50 entries");
63510c654e6SJacob Faibussowitsch   }
63610c654e6SJacob Faibussowitsch   PetscCheck(retlen > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least 2 entries: typename and type prefix");
63710c654e6SJacob Faibussowitsch   /* drop item name and prefix*/
63810c654e6SJacob Faibussowitsch   *len = retlen - 2;
63910c654e6SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
64010c654e6SJacob Faibussowitsch }
64110c654e6SJacob Faibussowitsch 
642d71ae5a4SJacob 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)
643d71ae5a4SJacob Faibussowitsch {
64453acd3b1SBarry Smith   PetscInt  ntext = 0;
645aa5bb8c0SSatish Balay   PetscInt  tval;
646ace3abfcSBarry Smith   PetscBool tflg;
64753acd3b1SBarry Smith 
64853acd3b1SBarry Smith   PetscFunctionBegin;
6494f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6504f572ea9SToby Isaac   PetscAssertPointer(list, 5);
6514f572ea9SToby Isaac   PetscAssertPointer(value, 7);
6524f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
65310c654e6SJacob Faibussowitsch   PetscCall(GetListLength(list, &ntext));
6549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[currentvalue], &tval, &tflg));
655aa5bb8c0SSatish Balay   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
656aa5bb8c0SSatish Balay   if (tflg) *value = (PetscEnum)tval;
657aa5bb8c0SSatish Balay   if (set) *set = tflg;
6583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
65953acd3b1SBarry Smith }
66053acd3b1SBarry Smith 
661d71ae5a4SJacob 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)
662d71ae5a4SJacob Faibussowitsch {
66310c654e6SJacob Faibussowitsch   PetscInt    nlist  = 0;
66410c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
665d3e47460SLisandro Dalcin 
666d3e47460SLisandro Dalcin   PetscFunctionBegin;
6674f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6684f572ea9SToby Isaac   PetscAssertPointer(list, 5);
6694f572ea9SToby Isaac   PetscAssertPointer(value, 6);
6704f572ea9SToby Isaac   PetscAssertPointer(n, 7);
67110c654e6SJacob Faibussowitsch   PetscCheck(*n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") must be > 0", *n);
6724f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
67310c654e6SJacob Faibussowitsch   PetscCall(GetListLength(list, &nlist));
67410c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetEnumArray(PetscOptionsObject->options, prefix, opt, list, value, n, set));
67510c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
67610c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
67710c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
67810c654e6SJacob Faibussowitsch 
67910c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s", Prefix(prefix), opt + 1, list[value[0]]));
68010c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%s", list[value[i]]));
68110c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (choose from)", text));
68210c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nlist; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
68310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
684d3e47460SLisandro Dalcin   }
6853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
686d3e47460SLisandro Dalcin }
687d3e47460SLisandro Dalcin 
688d71ae5a4SJacob 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)
689d71ae5a4SJacob Faibussowitsch {
69010c654e6SJacob Faibussowitsch   const char        *prefix  = PetscOptionsObject->prefix;
69110c654e6SJacob Faibussowitsch   const PetscOptions options = PetscOptionsObject->options;
69212655325SBarry Smith   PetscBool          wasset;
69353acd3b1SBarry Smith 
69453acd3b1SBarry Smith   PetscFunctionBegin;
6954f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6964f572ea9SToby Isaac   PetscAssertPointer(value, 6);
6974f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
69808401ef6SPierre Jolivet   PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, currentvalue, lb);
69908401ef6SPierre Jolivet   PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, currentvalue, ub);
700e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
70110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
70210c654e6SJacob Faibussowitsch 
7039566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt));
7049566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data));
70512655325SBarry Smith     *(PetscInt *)amsopt->data = currentvalue;
7063e211508SBarry Smith 
70710c654e6SJacob Faibussowitsch     PetscCall(PetscOptionsGetInt(options, prefix, opt, &currentvalue, &wasset));
708ad540459SPierre Jolivet     if (wasset) *(PetscInt *)amsopt->data = currentvalue;
709af6d86caSBarry Smith   }
71010c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(options, prefix, opt, value, &wasset));
711cc73adaaSBarry 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);
712cc73adaaSBarry 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);
71344ef3d73SBarry Smith   if (set) *set = wasset;
71410c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
71510c654e6SJacob 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)));
71653acd3b1SBarry Smith   }
7173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71853acd3b1SBarry Smith }
71953acd3b1SBarry Smith 
7206497c311SBarry 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)
7216497c311SBarry Smith {
7226497c311SBarry Smith   const char        *prefix  = PetscOptionsObject->prefix;
7236497c311SBarry Smith   const PetscOptions options = PetscOptionsObject->options;
7246497c311SBarry Smith   PetscBool          wasset;
7256497c311SBarry Smith 
7266497c311SBarry Smith   PetscFunctionBegin;
7276497c311SBarry Smith   PetscAssertPointer(opt, 2);
7286497c311SBarry Smith   PetscAssertPointer(value, 6);
7296497c311SBarry Smith   if (set) PetscAssertPointer(set, 7);
7306497c311SBarry Smith   PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d less than allowed bound %d", currentvalue, lb);
7316497c311SBarry Smith   PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d greater than allowed bound %d", currentvalue, ub);
7326497c311SBarry Smith   if (!PetscOptionsObject->count) {
7336497c311SBarry Smith     PetscOptionItem amsopt;
7346497c311SBarry Smith 
7356497c311SBarry Smith     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt));
7366497c311SBarry Smith     PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data));
7376497c311SBarry Smith     *(PetscMPIInt *)amsopt->data = currentvalue;
7386497c311SBarry Smith 
7396497c311SBarry Smith     PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, &currentvalue, &wasset));
7406497c311SBarry Smith     if (wasset) *(PetscMPIInt *)amsopt->data = currentvalue;
7416497c311SBarry Smith   }
7426497c311SBarry Smith   PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, value, &wasset));
7436497c311SBarry Smith   PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d less than allowed bound %d", *value, lb);
7446497c311SBarry Smith   PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d greater than allowed bound %d", *value, ub);
7456497c311SBarry Smith   if (set) *set = wasset;
7466497c311SBarry 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))); }
7476497c311SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
7486497c311SBarry Smith }
7496497c311SBarry Smith 
750d71ae5a4SJacob 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)
751d71ae5a4SJacob Faibussowitsch {
75210c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
75344ef3d73SBarry Smith   PetscBool   lset;
75453acd3b1SBarry Smith 
75553acd3b1SBarry Smith   PetscFunctionBegin;
7564f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
7574f572ea9SToby Isaac   PetscAssertPointer(value, 6);
7584f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
7591a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
76010c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
76110c654e6SJacob Faibussowitsch 
7629566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
76364facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
7649566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
765af6d86caSBarry Smith   }
76610c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
76744ef3d73SBarry Smith   if (set) *set = lset;
76810c654e6SJacob 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)));
7693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
77053acd3b1SBarry Smith }
77153acd3b1SBarry Smith 
77252ce0ab5SPierre 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)
773d71ae5a4SJacob Faibussowitsch {
77410c654e6SJacob Faibussowitsch   const char        *prefix  = PetscOptionsObject->prefix;
77552ce0ab5SPierre Jolivet   const PetscOptions options = PetscOptionsObject->options;
77652ce0ab5SPierre Jolivet   PetscBool          wasset;
77753acd3b1SBarry Smith 
77853acd3b1SBarry Smith   PetscFunctionBegin;
7794f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
7804f572ea9SToby Isaac   PetscAssertPointer(value, 6);
7814f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
78252ce0ab5SPierre Jolivet   PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g less than allowed bound %g", (double)currentvalue, (double)lb);
78352ce0ab5SPierre Jolivet   PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g greater than allowed bound %g", (double)currentvalue, (double)ub);
784e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
78510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
78610c654e6SJacob Faibussowitsch 
7879566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt));
7889566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data));
7890fdccdaeSBarry Smith     *(PetscReal *)amsopt->data = currentvalue;
79052ce0ab5SPierre Jolivet 
79152ce0ab5SPierre Jolivet     PetscCall(PetscOptionsGetReal(options, prefix, opt, &currentvalue, &wasset));
79252ce0ab5SPierre Jolivet     if (wasset) *(PetscReal *)amsopt->data = currentvalue;
793538aa990SBarry Smith   }
79452ce0ab5SPierre Jolivet   PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &wasset));
79552ce0ab5SPierre 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);
79652ce0ab5SPierre 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);
79752ce0ab5SPierre Jolivet   if (set) *set = wasset;
79810c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
79952ce0ab5SPierre 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)));
80053acd3b1SBarry Smith   }
8013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
80253acd3b1SBarry Smith }
80353acd3b1SBarry Smith 
804d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set)
805d71ae5a4SJacob Faibussowitsch {
80653acd3b1SBarry Smith   PetscFunctionBegin;
80753acd3b1SBarry Smith #if !defined(PETSC_USE_COMPLEX)
8089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set));
80953acd3b1SBarry Smith #else
8109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set));
81153acd3b1SBarry Smith #endif
8123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
81353acd3b1SBarry Smith }
81453acd3b1SBarry Smith 
815d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
816d71ae5a4SJacob Faibussowitsch {
81710c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
81853acd3b1SBarry Smith 
81953acd3b1SBarry Smith   PetscFunctionBegin;
8204f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8214f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
822e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
82310c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
82410c654e6SJacob Faibussowitsch 
8259566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
8269566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
827a297a907SKarl Rupp 
828ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
8291ae3d29cSBarry Smith   }
83010c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg));
83110c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
8323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
83353acd3b1SBarry Smith }
83453acd3b1SBarry Smith 
835d71ae5a4SJacob 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)
836d71ae5a4SJacob Faibussowitsch {
83710c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
83844ef3d73SBarry Smith   PetscBool   lset;
83953acd3b1SBarry Smith 
84053acd3b1SBarry Smith   PetscFunctionBegin;
8414f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8424f572ea9SToby Isaac   PetscAssertPointer(value, 7);
8434f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 9);
8441a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
84510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
84610c654e6SJacob Faibussowitsch 
8479566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt));
84864facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
8499566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
8503cc1e11dSBarry Smith     amsopt->flist = list;
8513cc1e11dSBarry Smith   }
85210c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
85344ef3d73SBarry Smith   if (set) *set = lset;
85410c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue));
8553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
85653acd3b1SBarry Smith }
85753acd3b1SBarry Smith 
85810c654e6SJacob Faibussowitsch #ifdef __cplusplus
85910c654e6SJacob Faibussowitsch   #include <type_traits>
86010c654e6SJacob Faibussowitsch #endif
86110c654e6SJacob Faibussowitsch 
862d71ae5a4SJacob 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)
863d71ae5a4SJacob Faibussowitsch {
86410c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
86544ef3d73SBarry Smith   PetscBool   lset;
86653acd3b1SBarry Smith 
86753acd3b1SBarry Smith   PetscFunctionBegin;
8684f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8694f572ea9SToby Isaac   PetscAssertPointer(value, 8);
8704f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 9);
8711a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
87210c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
87310c654e6SJacob Faibussowitsch 
8749566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt));
87564facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
8769566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
8779566063dSJacob Faibussowitsch     PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list));
87810c654e6SJacob Faibussowitsch     PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX);
87910c654e6SJacob Faibussowitsch #ifdef __cplusplus
88010c654e6SJacob Faibussowitsch     static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, "");
88110c654e6SJacob Faibussowitsch #endif
88210c654e6SJacob Faibussowitsch     amsopt->nlist = (char)ntext;
8831ae3d29cSBarry Smith   }
88410c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset));
88544ef3d73SBarry Smith   if (set) *set = lset;
88610c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
88710c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
88810c654e6SJacob Faibussowitsch 
88910c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext));
89010c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
89110c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
89253acd3b1SBarry Smith   }
8933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
89453acd3b1SBarry Smith }
89553acd3b1SBarry Smith 
896d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
897d71ae5a4SJacob Faibussowitsch {
89810c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
89953acd3b1SBarry Smith 
90053acd3b1SBarry Smith   PetscFunctionBegin;
9014f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9024f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
903e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
90410c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
90510c654e6SJacob Faibussowitsch 
9069566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9079566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
908a297a907SKarl Rupp 
909ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9101ae3d29cSBarry Smith   }
91168b16fdaSBarry Smith   *flg = PETSC_FALSE;
91210c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
91310c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
91410c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
91510c654e6SJacob Faibussowitsch 
91610c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  Pick at most one of -------------\n"));
91710c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
91853acd3b1SBarry Smith   }
9193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
92053acd3b1SBarry Smith }
92153acd3b1SBarry Smith 
922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
923d71ae5a4SJacob Faibussowitsch {
92410c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
92553acd3b1SBarry Smith 
92653acd3b1SBarry Smith   PetscFunctionBegin;
9274f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9284f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
929e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
93010c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
93110c654e6SJacob Faibussowitsch 
9329566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9339566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
934a297a907SKarl Rupp 
935ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9361ae3d29cSBarry Smith   }
93717326d04SJed Brown   *flg = PETSC_FALSE;
93810c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
93910c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
9403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
94153acd3b1SBarry Smith }
94253acd3b1SBarry Smith 
943d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
944d71ae5a4SJacob Faibussowitsch {
94510c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
94653acd3b1SBarry Smith 
94753acd3b1SBarry Smith   PetscFunctionBegin;
9484f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9494f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
950e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
95110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
95210c654e6SJacob Faibussowitsch 
9539566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9549566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
955a297a907SKarl Rupp 
956ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9571ae3d29cSBarry Smith   }
95817326d04SJed Brown   *flg = PETSC_FALSE;
95910c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
96010c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
9613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
96253acd3b1SBarry Smith }
96353acd3b1SBarry Smith 
964d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set)
965d71ae5a4SJacob Faibussowitsch {
96610c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
967ace3abfcSBarry Smith   PetscBool   iset;
96853acd3b1SBarry Smith 
96953acd3b1SBarry Smith   PetscFunctionBegin;
9704f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9714f572ea9SToby Isaac   PetscAssertPointer(flg, 6);
9724f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
973e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
97410c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
97510c654e6SJacob Faibussowitsch 
9769566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9779566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
978a297a907SKarl Rupp 
97994ae4db5SBarry Smith     *(PetscBool *)amsopt->data = currentvalue;
980af6d86caSBarry Smith   }
98110c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset));
98253acd3b1SBarry Smith   if (set) *set = iset;
98310c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
98410c654e6SJacob Faibussowitsch     const char *curvalue = PetscBools[currentvalue];
98510c654e6SJacob Faibussowitsch 
98610c654e6SJacob 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)));
98753acd3b1SBarry Smith   }
9883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
98953acd3b1SBarry Smith }
99053acd3b1SBarry Smith 
991d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set)
992d71ae5a4SJacob Faibussowitsch {
99310c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
99453acd3b1SBarry Smith 
99553acd3b1SBarry Smith   PetscFunctionBegin;
9964f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9974f572ea9SToby Isaac   PetscAssertPointer(n, 6);
99810c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
9994f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10004f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1001e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
100210c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1003e26ddf31SBarry Smith     PetscReal      *vals;
100410c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1005e26ddf31SBarry Smith 
10069566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt));
100710c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
100810c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
100910c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
101010c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1011e26ddf31SBarry Smith   }
101210c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set));
101310c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
101410c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
101510c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
101610c654e6SJacob Faibussowitsch 
101710c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0]));
101810c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i]));
101910c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
102053acd3b1SBarry Smith   }
10213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
102253acd3b1SBarry Smith }
102353acd3b1SBarry Smith 
1024d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set)
1025d71ae5a4SJacob Faibussowitsch {
102610c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
1027050cccc3SHong Zhang 
1028050cccc3SHong Zhang   PetscFunctionBegin;
10294f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10304f572ea9SToby Isaac   PetscAssertPointer(n, 6);
103110c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10324f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10334f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1034050cccc3SHong Zhang   if (!PetscOptionsObject->count) {
103510c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
103610c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1037050cccc3SHong Zhang     PetscScalar    *vals;
1038050cccc3SHong Zhang 
10399566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt));
104010c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
104110c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
104210c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
104310c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1044050cccc3SHong Zhang   }
104510c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set));
104610c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
104710c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
104810c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
104910c654e6SJacob Faibussowitsch 
105010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0])));
105110c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i])));
105210c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1053050cccc3SHong Zhang   }
10543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1055050cccc3SHong Zhang }
105653acd3b1SBarry Smith 
1057d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set)
1058d71ae5a4SJacob Faibussowitsch {
105910c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
106053acd3b1SBarry Smith 
106153acd3b1SBarry Smith   PetscFunctionBegin;
10624f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10634f572ea9SToby Isaac   PetscAssertPointer(n, 6);
106410c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10654f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10664f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1067e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
106810c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1069e26ddf31SBarry Smith     PetscInt       *vals;
107010c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1071e26ddf31SBarry Smith 
10729566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt));
107310c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
107410c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
107510c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
107610c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1077e26ddf31SBarry Smith   }
107810c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set));
107910c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
108010c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
108110c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
108210c654e6SJacob Faibussowitsch 
108310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0]));
108410c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i]));
108510c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
108653acd3b1SBarry Smith   }
10873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108853acd3b1SBarry Smith }
108953acd3b1SBarry Smith 
1090d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set)
1091d71ae5a4SJacob Faibussowitsch {
109210c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
109353acd3b1SBarry Smith 
109453acd3b1SBarry Smith   PetscFunctionBegin;
10954f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10964f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
109710c654e6SJacob Faibussowitsch   PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax);
10984f572ea9SToby Isaac   if (*nmax) PetscAssertPointer(value, 5);
10994f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1100e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
110110c654e6SJacob Faibussowitsch     const PetscInt  nmaxv = *nmax;
110210c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1103a297a907SKarl Rupp 
110410c654e6SJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt));
110510c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data));
110610c654e6SJacob Faibussowitsch     amsopt->arraylength = nmaxv;
11071ae3d29cSBarry Smith   }
110810c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set));
110910c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
11103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
111153acd3b1SBarry Smith }
111253acd3b1SBarry Smith 
1113d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set)
1114d71ae5a4SJacob Faibussowitsch {
111510c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
1116e2446a98SMatthew Knepley 
1117e2446a98SMatthew Knepley   PetscFunctionBegin;
11184f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
11194f572ea9SToby Isaac   PetscAssertPointer(n, 6);
112010c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
11214f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
11224f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1123e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
112410c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1125ace3abfcSBarry Smith     PetscBool      *vals;
112610c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
11271ae3d29cSBarry Smith 
11289566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt));
112910c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
113010c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
113110c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
113210c654e6SJacob Faibussowitsch     amsopt->data        = vals;
11331ae3d29cSBarry Smith   }
113410c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set));
113510c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
113610c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
113710c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
113810c654e6SJacob Faibussowitsch 
113910c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%d", Prefix(prefix), opt + 1, value[0]));
114010c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i]));
114110c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1142e2446a98SMatthew Knepley   }
11433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1144e2446a98SMatthew Knepley }
1145e2446a98SMatthew Knepley 
114688aa4217SBarry Smith /*MC
1147648c30bcSBarry Smith   PetscOptionsViewer - Creates a viewer appropriate for the type indicated by the user
11488cc676e6SMatthew G Knepley 
114988aa4217SBarry Smith   Synopsis:
115010450e9eSJacob Faibussowitsch   #include <petscviewer.h>
11513a89f35bSSatish Balay   PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
115288aa4217SBarry Smith 
11537cdbe19fSJose E. Roman   Logically Collective on the communicator passed in `PetscOptionsBegin()`
11547cdbe19fSJose E. Roman 
11558cc676e6SMatthew G Knepley   Input Parameters:
11568cc676e6SMatthew G Knepley + opt  - option name
11578cc676e6SMatthew G Knepley . text - short string that describes the option
11588cc676e6SMatthew G Knepley - man  - manual page with additional information on option
11598cc676e6SMatthew G Knepley 
1160d8d19677SJose E. Roman   Output Parameters:
11618cc676e6SMatthew G Knepley + viewer - the viewer
11629314d9b7SBarry Smith . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed
1163811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
11648cc676e6SMatthew G Knepley 
11658cc676e6SMatthew G Knepley   Level: beginner
11668cc676e6SMatthew G Knepley 
116795452b02SPatrick Sanan   Notes:
1168811af0c4SBarry Smith   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`
11698cc676e6SMatthew G Knepley 
1170648c30bcSBarry Smith   See `PetscOptionsCreateViewer()` for the format of the supplied viewer and its options
11718cc676e6SMatthew G Knepley 
1172648c30bcSBarry Smith .seealso: `PetscOptionsCreateViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1173db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
1174aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1175db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1176c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1177db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1178db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
117988aa4217SBarry Smith M*/
1180d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
1181d71ae5a4SJacob Faibussowitsch {
118210c654e6SJacob Faibussowitsch   const MPI_Comm comm   = PetscOptionsObject->comm;
118310c654e6SJacob Faibussowitsch   const char    *prefix = PetscOptionsObject->prefix;
11848cc676e6SMatthew G Knepley 
11858cc676e6SMatthew G Knepley   PetscFunctionBegin;
11864f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
11874f572ea9SToby Isaac   PetscAssertPointer(viewer, 5);
11884f572ea9SToby Isaac   if (format) PetscAssertPointer(format, 6);
11894f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
11901a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
119110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
119210c654e6SJacob Faibussowitsch 
11939566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
119464facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
11959566063dSJacob Faibussowitsch     PetscCall(PetscStrdup("", (char **)&amsopt->data));
11968cc676e6SMatthew G Knepley   }
1197648c30bcSBarry Smith   PetscCall(PetscOptionsCreateViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set));
119810c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man)));
11993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12008cc676e6SMatthew G Knepley }
1201