xref: /petsc/src/sys/objects/aoptions.c (revision 9e210917fd2290210f7150e13ff15b3541f55af7)
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 
ManSection(const char * str)1010c654e6SJacob Faibussowitsch static const char *ManSection(const char *str)
1110c654e6SJacob Faibussowitsch {
1210c654e6SJacob Faibussowitsch   return str ? str : "None";
1310c654e6SJacob Faibussowitsch }
1410c654e6SJacob Faibussowitsch 
Prefix(const char * str)1510c654e6SJacob Faibussowitsch static const char *Prefix(const char *str)
1610c654e6SJacob Faibussowitsch {
1710c654e6SJacob Faibussowitsch   return str ? str : "";
1810c654e6SJacob Faibussowitsch }
1910c654e6SJacob Faibussowitsch 
ShouldPrintHelp(const PetscOptionItems opts)20ce78bad3SBarry Smith 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 */
PetscOptionsBegin_Private(PetscOptionItems PetscOptionsObject,MPI_Comm comm,const char prefix[],const char title[],const char mansec[])35ce78bad3SBarry Smith 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 */
PetscObjectOptionsBegin_Private(PetscObject obj,PetscOptionItems PetscOptionsObject)60ce78bad3SBarry Smith 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 */
PetscOptionItemCreate_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscOptionType t,PetscOptionItem * amsopt)81ce78bad3SBarry Smith 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 */
PetscStrdup(const char s[],char * t[])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 static const char *OptionsHeader = "<head>\n"
13410450e9eSJacob Faibussowitsch                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/jquery-1.9.1.js\"></script>\n"
13510450e9eSJacob Faibussowitsch                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/SAWs.js\"></script>\n"
13610450e9eSJacob Faibussowitsch                                    "<script type=\"text/javascript\" src=\"js/PETSc.js\"></script>\n"
13710450e9eSJacob Faibussowitsch                                    "<script>\n"
13810450e9eSJacob Faibussowitsch                                    "jQuery(document).ready(function() {\n"
13910450e9eSJacob Faibussowitsch                                    "PETSc.getAndDisplayDirectory(null,\"#variablesInfo\")\n"
14010450e9eSJacob Faibussowitsch                                    "})\n"
14110450e9eSJacob Faibussowitsch                                    "</script>\n"
14210450e9eSJacob Faibussowitsch                                    "</head>\n";
14310450e9eSJacob Faibussowitsch 
14410450e9eSJacob Faibussowitsch /*  Determines the size and style of the scroll region where PETSc options selectable from users are displayed */
14510450e9eSJacob Faibussowitsch static const char *OptionsBodyBottom = "<div id=\"variablesInfo\" style=\"background-color:lightblue;height:auto;max-height:500px;overflow:scroll;\"></div>\n<br>\n</body>";
14610450e9eSJacob Faibussowitsch 
14710450e9eSJacob Faibussowitsch /*
14810450e9eSJacob Faibussowitsch     PetscOptionsSAWsInput - Presents all the PETSc Options processed by the program so the user may change them at runtime using the SAWs
14910450e9eSJacob Faibussowitsch 
15010450e9eSJacob Faibussowitsch     Bugs:
15110450e9eSJacob Faibussowitsch +    All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
15210450e9eSJacob Faibussowitsch .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
15310450e9eSJacob Faibussowitsch -    Only works for PetscInt == int, PetscReal == double etc
15410450e9eSJacob Faibussowitsch 
15510450e9eSJacob Faibussowitsch */
PetscOptionsSAWsInput(PetscOptionItems PetscOptionsObject)156ce78bad3SBarry Smith static PetscErrorCode PetscOptionsSAWsInput(PetscOptionItems PetscOptionsObject)
15710450e9eSJacob Faibussowitsch {
15810450e9eSJacob Faibussowitsch   PetscOptionItem next     = PetscOptionsObject->next;
15910450e9eSJacob Faibussowitsch   static int      mancount = 0;
16010450e9eSJacob Faibussowitsch   char            options[16];
16110450e9eSJacob Faibussowitsch   PetscBool       changedmethod = PETSC_FALSE;
16210450e9eSJacob Faibussowitsch   PetscBool       stopasking    = PETSC_FALSE;
16310450e9eSJacob Faibussowitsch   char            manname[16], textname[16];
16410450e9eSJacob Faibussowitsch   char            dir[1024];
16510450e9eSJacob Faibussowitsch 
16610450e9eSJacob Faibussowitsch   PetscFunctionBegin;
16710450e9eSJacob Faibussowitsch   /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */
16810450e9eSJacob Faibussowitsch   PetscCall(PetscSNPrintf(options, PETSC_STATIC_ARRAY_LENGTH(options), "Options_%d", count++));
16910450e9eSJacob Faibussowitsch 
17010450e9eSJacob Faibussowitsch   PetscOptionsObject->pprefix = PetscOptionsObject->prefix; /* SAWs will change this, so cannot pass prefix directly */
17110450e9eSJacob Faibussowitsch 
17210450e9eSJacob Faibussowitsch   PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "_title"));
17310450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->title, 1, SAWs_READ, SAWs_STRING));
17410450e9eSJacob Faibussowitsch   PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "prefix"));
17510450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->pprefix, 1, SAWs_READ, SAWs_STRING));
17610450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, ("/PETSc/Options/ChangedMethod", &changedmethod, 1, SAWs_WRITE, SAWs_BOOLEAN));
17710450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, ("/PETSc/Options/StopAsking", &stopasking, 1, SAWs_WRITE, SAWs_BOOLEAN));
17810450e9eSJacob Faibussowitsch 
17910450e9eSJacob Faibussowitsch   while (next) {
18010450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(manname, PETSC_STATIC_ARRAY_LENGTH(manname), "_man_%d", mancount));
18110450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", manname));
18210450e9eSJacob Faibussowitsch     PetscCallSAWs(SAWs_Register, (dir, &next->man, 1, SAWs_READ, SAWs_STRING));
18310450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(textname, PETSC_STATIC_ARRAY_LENGTH(textname), "_text_%d", mancount++));
18410450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", textname));
18510450e9eSJacob Faibussowitsch     PetscCallSAWs(SAWs_Register, (dir, &next->text, 1, SAWs_READ, SAWs_STRING));
18610450e9eSJacob Faibussowitsch 
18710450e9eSJacob Faibussowitsch     switch (next->type) {
18810450e9eSJacob Faibussowitsch     case OPTION_HEAD:
18910450e9eSJacob Faibussowitsch       break;
19010450e9eSJacob Faibussowitsch     case OPTION_INT_ARRAY:
19110450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
19210450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_INT));
19310450e9eSJacob Faibussowitsch       break;
19410450e9eSJacob Faibussowitsch     case OPTION_REAL_ARRAY:
19510450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
19610450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_DOUBLE));
19710450e9eSJacob Faibussowitsch       break;
19810450e9eSJacob Faibussowitsch     case OPTION_INT:
19910450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
20010450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_INT));
20110450e9eSJacob Faibussowitsch       break;
20210450e9eSJacob Faibussowitsch     case OPTION_REAL:
20310450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
20410450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_DOUBLE));
20510450e9eSJacob Faibussowitsch       break;
20610450e9eSJacob Faibussowitsch     case OPTION_BOOL:
20710450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
20810450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_BOOLEAN));
20910450e9eSJacob Faibussowitsch       break;
21010450e9eSJacob Faibussowitsch     case OPTION_BOOL_ARRAY:
21110450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
21210450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_BOOLEAN));
21310450e9eSJacob Faibussowitsch       break;
21410450e9eSJacob Faibussowitsch     case OPTION_STRING:
21510450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
21610450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
21710450e9eSJacob Faibussowitsch       break;
21810450e9eSJacob Faibussowitsch     case OPTION_STRING_ARRAY:
21910450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
22010450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_STRING));
22110450e9eSJacob Faibussowitsch       break;
22210450e9eSJacob Faibussowitsch     case OPTION_FLIST: {
22310450e9eSJacob Faibussowitsch       PetscInt ntext;
22410450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
22510450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
22610450e9eSJacob Faibussowitsch       PetscCall(PetscFunctionListGet(next->flist, (const char ***)&next->edata, &ntext));
22710450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
22810450e9eSJacob Faibussowitsch     } break;
22910450e9eSJacob Faibussowitsch     case OPTION_ELIST: {
23010450e9eSJacob Faibussowitsch       PetscInt ntext = next->nlist;
23110450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
23210450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
23357508eceSPierre Jolivet       PetscCall(PetscMalloc1(ntext + 1, (char ***)&next->edata));
23410450e9eSJacob Faibussowitsch       PetscCall(PetscMemcpy(next->edata, next->list, ntext * sizeof(char *)));
23510450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
23610450e9eSJacob Faibussowitsch     } break;
23710450e9eSJacob Faibussowitsch     default:
23810450e9eSJacob Faibussowitsch       break;
23910450e9eSJacob Faibussowitsch     }
24010450e9eSJacob Faibussowitsch     next = next->next;
24110450e9eSJacob Faibussowitsch   }
24210450e9eSJacob Faibussowitsch 
24310450e9eSJacob Faibussowitsch   /* wait until accessor has unlocked the memory */
24410450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Push_Header, ("index.html", OptionsHeader));
24510450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Push_Body, ("index.html", 2, OptionsBodyBottom));
24610450e9eSJacob Faibussowitsch   PetscCall(PetscSAWsBlock());
24710450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Pop_Header, ("index.html"));
24810450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Pop_Body, ("index.html", 2));
24910450e9eSJacob Faibussowitsch 
25010450e9eSJacob Faibussowitsch   /* determine if any values have been set in GUI */
25110450e9eSJacob Faibussowitsch   next = PetscOptionsObject->next;
25210450e9eSJacob Faibussowitsch   while (next) {
25310450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
25410450e9eSJacob Faibussowitsch     PetscCallSAWs(SAWs_Selected, (dir, (int *)&next->set));
25510450e9eSJacob Faibussowitsch     next = next->next;
25610450e9eSJacob Faibussowitsch   }
25710450e9eSJacob Faibussowitsch 
25810450e9eSJacob Faibussowitsch   /* reset counter to -2; this updates the screen with the new options for the selected method */
25910450e9eSJacob Faibussowitsch   if (changedmethod) PetscOptionsObject->count = -2;
26010450e9eSJacob Faibussowitsch 
26110450e9eSJacob Faibussowitsch   if (stopasking) {
26210450e9eSJacob Faibussowitsch     PetscOptionsPublish       = PETSC_FALSE;
26310450e9eSJacob Faibussowitsch     PetscOptionsObject->count = 0; //do not ask for same thing again
26410450e9eSJacob Faibussowitsch   }
26510450e9eSJacob Faibussowitsch 
26610450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Delete, ("/PETSc/Options"));
26710450e9eSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26810450e9eSJacob Faibussowitsch }
26910450e9eSJacob Faibussowitsch #else
27010450e9eSJacob Faibussowitsch /*
2713fc1eb6aSBarry Smith     PetscScanString -  Gets user input via stdin from process and broadcasts to all processes
2723fc1eb6aSBarry Smith 
273d083f849SBarry Smith     Collective
2743fc1eb6aSBarry Smith 
2753fc1eb6aSBarry Smith    Input Parameters:
2763fc1eb6aSBarry Smith +     commm - communicator for the broadcast, must be PETSC_COMM_WORLD
2773fc1eb6aSBarry Smith .     n - length of the string, must be the same on all processes
2783fc1eb6aSBarry Smith -     str - location to store input
279aee2cecaSBarry Smith 
280aee2cecaSBarry Smith     Bugs:
281aee2cecaSBarry Smith .   Assumes process 0 of the given communicator has access to stdin
282aee2cecaSBarry Smith 
283aee2cecaSBarry Smith */
PetscScanString(MPI_Comm comm,size_t n,char str[])284d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscScanString(MPI_Comm comm, size_t n, char str[])
285d71ae5a4SJacob Faibussowitsch {
2863fc1eb6aSBarry Smith   PetscMPIInt rank, nm;
287aee2cecaSBarry Smith 
288aee2cecaSBarry Smith   PetscFunctionBegin;
2899566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
290dd400576SPatrick Sanan   if (rank == 0) {
2915f80ce2aSJacob Faibussowitsch     char   c = (char)getchar();
2925f80ce2aSJacob Faibussowitsch     size_t i = 0;
2935f80ce2aSJacob Faibussowitsch 
294aee2cecaSBarry Smith     while (c != '\n' && i < n - 1) {
295aee2cecaSBarry Smith       str[i++] = c;
296aee2cecaSBarry Smith       c        = (char)getchar();
297aee2cecaSBarry Smith     }
29810c654e6SJacob Faibussowitsch     str[i] = '\0';
299aee2cecaSBarry Smith   }
3009566063dSJacob Faibussowitsch   PetscCall(PetscMPIIntCast(n, &nm));
3019566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(str, nm, MPI_CHAR, 0, comm));
3023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
303aee2cecaSBarry Smith }
304aee2cecaSBarry Smith 
3055b02f95dSBarry Smith /*
3063cc1e11dSBarry Smith   PetscOptionsGetFromTextInput - Presents all the PETSc Options processed by the program so the user may change them at runtime
307aee2cecaSBarry Smith 
30895452b02SPatrick Sanan   Notes:
30995452b02SPatrick Sanan   this isn't really practical, it is just to demonstrate the principle
310aee2cecaSBarry Smith 
3117781c08eSBarry Smith   A carriage return indicates no change from the default; but this like -ksp_monitor <stdout>  the default is actually not stdout the default
3127781c08eSBarry Smith   is to do nothing so to get it to use stdout you need to type stdout. This is kind of bug?
3137781c08eSBarry Smith 
314aee2cecaSBarry Smith   Bugs:
3157781c08eSBarry Smith +    All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
3163cc1e11dSBarry Smith .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
317aee2cecaSBarry Smith -    Only works for PetscInt == int, PetscReal == double etc
318aee2cecaSBarry Smith 
319aec76313SJacob Faibussowitsch   Developer Notes:
32095452b02SPatrick Sanan   Normally the GUI that presents the options the user and retrieves the values would be running in a different
3213cc1e11dSBarry Smith   address space and communicating with the PETSc program
3223cc1e11dSBarry Smith 
323aee2cecaSBarry Smith */
PetscOptionsGetFromTextInput(PetscOptionItems PetscOptionsObject)324ce78bad3SBarry Smith static PetscErrorCode PetscOptionsGetFromTextInput(PetscOptionItems PetscOptionsObject)
325d71ae5a4SJacob Faibussowitsch {
3264416b707SBarry Smith   PetscOptionItem next = PetscOptionsObject->next;
3276356e834SBarry Smith   char            str[512];
3287781c08eSBarry Smith   PetscBool       bid;
329a4404d99SBarry Smith   PetscReal       ir, *valr;
330330cf3c9SBarry Smith   PetscInt       *vald;
3316356e834SBarry Smith 
3322a409bb0SBarry Smith   PetscFunctionBegin;
3339566063dSJacob Faibussowitsch   PetscCall((*PetscPrintf)(PETSC_COMM_WORLD, "%s --------------------\n", PetscOptionsObject->title));
3346356e834SBarry Smith   while (next) {
3356356e834SBarry Smith     switch (next->type) {
336d71ae5a4SJacob Faibussowitsch     case OPTION_HEAD:
337d71ae5a4SJacob Faibussowitsch       break;
338e26ddf31SBarry Smith     case OPTION_INT_ARRAY:
3394bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
340e26ddf31SBarry Smith       vald = (PetscInt *)next->data;
3416497c311SBarry Smith       for (PetscInt i = 0; i < next->arraylength; i++) {
3429566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT, vald[i]));
34348a46eb9SPierre Jolivet         if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
344e26ddf31SBarry Smith       }
3459566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
3469566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
347e26ddf31SBarry Smith       if (str[0]) {
348e26ddf31SBarry Smith         PetscToken  token;
349e26ddf31SBarry Smith         PetscInt    n = 0, nmax = next->arraylength, *dvalue = (PetscInt *)next->data, start, end;
350ce78bad3SBarry Smith         size_t      len;
351ce78bad3SBarry Smith         const char *value;
352ace3abfcSBarry Smith         PetscBool   foundrange;
353e26ddf31SBarry Smith 
354e26ddf31SBarry Smith         next->set = PETSC_TRUE;
355e26ddf31SBarry Smith         value     = str;
3569566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(value, ',', &token));
3579566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &value));
358e26ddf31SBarry Smith         while (n < nmax) {
359ce78bad3SBarry Smith           char    *ivalue;
360ce78bad3SBarry Smith           PetscInt i;
361ce78bad3SBarry Smith 
362e26ddf31SBarry Smith           if (!value) break;
363ce78bad3SBarry Smith           PetscCall(PetscStrallocpy(value, &ivalue));
364e26ddf31SBarry Smith 
365e26ddf31SBarry Smith           /* look for form  d-D where d and D are integers */
366e26ddf31SBarry Smith           foundrange = PETSC_FALSE;
367ce78bad3SBarry Smith           PetscCall(PetscStrlen(ivalue, &len));
368ce78bad3SBarry Smith           if (ivalue[0] == '-') i = 2;
369e26ddf31SBarry Smith           else i = 1;
370ce78bad3SBarry Smith           for (; i < (PetscInt)len; i++) {
371ce78bad3SBarry Smith             if (ivalue[i] == '-') {
372ce78bad3SBarry Smith               PetscCheck(i != (PetscInt)(len - 1), PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, ivalue);
373ce78bad3SBarry Smith               ivalue[i] = 0;
374ce78bad3SBarry Smith               PetscCall(PetscOptionsStringToInt(ivalue, &start));
375ce78bad3SBarry Smith               PetscCall(PetscOptionsStringToInt(ivalue + i + 1, &end));
376ce78bad3SBarry Smith               PetscCheck(end > start, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, %s-%s cannot have decreasing list", n, ivalue, ivalue + i + 1);
377cc73adaaSBarry 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);
378e26ddf31SBarry Smith               for (; start < end; start++) {
3799371c9d4SSatish Balay                 *dvalue = start;
3809371c9d4SSatish Balay                 dvalue++;
3819371c9d4SSatish Balay                 n++;
382e26ddf31SBarry Smith               }
383e26ddf31SBarry Smith               foundrange = PETSC_TRUE;
384e26ddf31SBarry Smith               break;
385e26ddf31SBarry Smith             }
386e26ddf31SBarry Smith           }
387e26ddf31SBarry Smith           if (!foundrange) {
388ce78bad3SBarry Smith             PetscCall(PetscOptionsStringToInt(ivalue, dvalue));
389e26ddf31SBarry Smith             dvalue++;
390e26ddf31SBarry Smith             n++;
391e26ddf31SBarry Smith           }
392ce78bad3SBarry Smith           PetscCall(PetscFree(ivalue));
3939566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &value));
394e26ddf31SBarry Smith         }
3959566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
396e26ddf31SBarry Smith       }
397e26ddf31SBarry Smith       break;
398e26ddf31SBarry Smith     case OPTION_REAL_ARRAY:
3994bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
400e26ddf31SBarry Smith       valr = (PetscReal *)next->data;
4016497c311SBarry Smith       for (PetscInt i = 0; i < next->arraylength; i++) {
4029566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i]));
40348a46eb9SPierre Jolivet         if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
404e26ddf31SBarry Smith       }
4059566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
4069566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
407e26ddf31SBarry Smith       if (str[0]) {
408e26ddf31SBarry Smith         PetscToken  token;
409e26ddf31SBarry Smith         PetscInt    n = 0, nmax = next->arraylength;
410e26ddf31SBarry Smith         PetscReal  *dvalue = (PetscReal *)next->data;
411ce78bad3SBarry Smith         const char *value;
412e26ddf31SBarry Smith 
413e26ddf31SBarry Smith         next->set = PETSC_TRUE;
414e26ddf31SBarry Smith         value     = str;
4159566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(value, ',', &token));
4169566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &value));
417e26ddf31SBarry Smith         while (n < nmax) {
418e26ddf31SBarry Smith           if (!value) break;
4199566063dSJacob Faibussowitsch           PetscCall(PetscOptionsStringToReal(value, dvalue));
420e26ddf31SBarry Smith           dvalue++;
421e26ddf31SBarry Smith           n++;
4229566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &value));
423e26ddf31SBarry Smith         }
4249566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
425e26ddf31SBarry Smith       }
426e26ddf31SBarry Smith       break;
4276356e834SBarry Smith     case OPTION_INT:
4284bb2516aSBarry 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));
4299566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4303fc1eb6aSBarry Smith       if (str[0]) {
431d25d7f95SJed Brown   #if defined(PETSC_SIZEOF_LONG_LONG)
432d25d7f95SJed Brown         long long lid;
433d25d7f95SJed Brown         sscanf(str, "%lld", &lid);
4341690c2aeSBarry 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);
435c272547aSJed Brown   #else
436d25d7f95SJed Brown         long lid;
437d25d7f95SJed Brown         sscanf(str, "%ld", &lid);
4381690c2aeSBarry 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);
439c272547aSJed Brown   #endif
440a297a907SKarl Rupp 
441d25d7f95SJed Brown         next->set                 = PETSC_TRUE;
442d25d7f95SJed Brown         *((PetscInt *)next->data) = (PetscInt)lid;
443aee2cecaSBarry Smith       }
444aee2cecaSBarry Smith       break;
445aee2cecaSBarry Smith     case OPTION_REAL:
4464bb2516aSBarry 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));
4479566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4483fc1eb6aSBarry Smith       if (str[0]) {
449ce63c4c1SBarry Smith   #if defined(PETSC_USE_REAL_SINGLE)
450a4404d99SBarry Smith         sscanf(str, "%e", &ir);
451570b7f6dSBarry Smith   #elif defined(PETSC_USE_REAL___FP16)
452570b7f6dSBarry Smith         float irtemp;
453570b7f6dSBarry Smith         sscanf(str, "%e", &irtemp);
454570b7f6dSBarry Smith         ir = irtemp;
455ce63c4c1SBarry Smith   #elif defined(PETSC_USE_REAL_DOUBLE)
456aee2cecaSBarry Smith         sscanf(str, "%le", &ir);
457ce63c4c1SBarry Smith   #elif defined(PETSC_USE_REAL___FLOAT128)
458d9822059SBarry Smith         ir = strtoflt128(str, 0);
459d9822059SBarry Smith   #else
460513dbe71SLisandro Dalcin         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type");
461a4404d99SBarry Smith   #endif
462aee2cecaSBarry Smith         next->set                  = PETSC_TRUE;
463aee2cecaSBarry Smith         *((PetscReal *)next->data) = ir;
464aee2cecaSBarry Smith       }
465aee2cecaSBarry Smith       break;
4667781c08eSBarry Smith     case OPTION_BOOL:
4674bb2516aSBarry 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));
4689566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4697781c08eSBarry Smith       if (str[0]) {
4709566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToBool(str, &bid));
4717781c08eSBarry Smith         next->set                  = PETSC_TRUE;
4727781c08eSBarry Smith         *((PetscBool *)next->data) = bid;
4737781c08eSBarry Smith       }
4747781c08eSBarry Smith       break;
475aee2cecaSBarry Smith     case OPTION_STRING:
4764bb2516aSBarry 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));
4779566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4783fc1eb6aSBarry Smith       if (str[0]) {
479aee2cecaSBarry Smith         next->set = PETSC_TRUE;
48064facd6cSBarry Smith         /* must use system malloc since SAWs may free this */
4819566063dSJacob Faibussowitsch         PetscCall(PetscStrdup(str, (char **)&next->data));
4826356e834SBarry Smith       }
4836356e834SBarry Smith       break;
484a264d7a6SBarry Smith     case OPTION_FLIST:
4859566063dSJacob Faibussowitsch       PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data));
4869566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4873cc1e11dSBarry Smith       if (str[0]) {
488e55864a3SBarry Smith         PetscOptionsObject->changedmethod = PETSC_TRUE;
4893cc1e11dSBarry Smith         next->set                         = PETSC_TRUE;
49064facd6cSBarry Smith         /* must use system malloc since SAWs may free this */
4919566063dSJacob Faibussowitsch         PetscCall(PetscStrdup(str, (char **)&next->data));
4923cc1e11dSBarry Smith       }
4933cc1e11dSBarry Smith       break;
494d71ae5a4SJacob Faibussowitsch     default:
495d71ae5a4SJacob Faibussowitsch       break;
4966356e834SBarry Smith     }
4976356e834SBarry Smith     next = next->next;
4986356e834SBarry Smith   }
4993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5006356e834SBarry Smith }
501b3506946SBarry Smith #endif
502b3506946SBarry Smith 
PetscOptionsEnd_Private(PetscOptionItems PetscOptionsObject)503ce78bad3SBarry Smith PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems PetscOptionsObject)
504d71ae5a4SJacob Faibussowitsch {
50510c654e6SJacob Faibussowitsch   PetscOptionItem next, last;
50653acd3b1SBarry Smith 
50753acd3b1SBarry Smith   PetscFunctionBegin;
50883355fc5SBarry Smith   if (PetscOptionsObject->next) {
50983355fc5SBarry Smith     if (!PetscOptionsObject->count) {
510a264d7a6SBarry Smith #if defined(PETSC_HAVE_SAWS)
5119566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSAWsInput(PetscOptionsObject));
512b3506946SBarry Smith #else
5139566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetFromTextInput(PetscOptionsObject));
514b3506946SBarry Smith #endif
515aee2cecaSBarry Smith     }
516aee2cecaSBarry Smith   }
5176356e834SBarry Smith 
5189566063dSJacob Faibussowitsch   PetscCall(PetscFree(PetscOptionsObject->title));
5196356e834SBarry Smith 
520e26ddf31SBarry Smith   /* reset counter to -2; this updates the screen with the new options for the selected method */
521e55864a3SBarry Smith   if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2;
5227a72a596SBarry Smith   /* reset alreadyprinted flag */
523e55864a3SBarry Smith   PetscOptionsObject->alreadyprinted = PETSC_FALSE;
524e55864a3SBarry Smith   if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE;
525e55864a3SBarry Smith   PetscOptionsObject->object = NULL;
52653acd3b1SBarry Smith 
52710c654e6SJacob Faibussowitsch   while ((next = PetscOptionsObject->next)) {
52810c654e6SJacob Faibussowitsch     const PetscOptionType type        = next->type;
52910c654e6SJacob Faibussowitsch     const size_t          arraylength = next->arraylength;
53010c654e6SJacob Faibussowitsch     void                 *data        = next->data;
53110c654e6SJacob Faibussowitsch 
53210c654e6SJacob Faibussowitsch     if (next->set) {
53310c654e6SJacob Faibussowitsch       char option[256], value[1024], tmp[32];
53410c654e6SJacob Faibussowitsch 
535e55864a3SBarry Smith       if (PetscOptionsObject->prefix) {
536c6a7a370SJeremy L Thompson         PetscCall(PetscStrncpy(option, "-", sizeof(option)));
537c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(option, PetscOptionsObject->prefix, sizeof(option)));
53810c654e6SJacob Faibussowitsch         PetscCall(PetscStrlcat(option, next->option + 1, sizeof(option)));
53910c654e6SJacob Faibussowitsch       } else {
54010c654e6SJacob Faibussowitsch         PetscCall(PetscStrncpy(option, next->option, sizeof(option)));
54110c654e6SJacob Faibussowitsch       }
5426356e834SBarry Smith 
54310c654e6SJacob Faibussowitsch       switch (type) {
544d71ae5a4SJacob Faibussowitsch       case OPTION_HEAD:
545d71ae5a4SJacob Faibussowitsch         break;
5466356e834SBarry Smith       case OPTION_INT_ARRAY:
547835f2295SStefano Zampini         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%" PetscInt_FMT, ((PetscInt *)data)[0]));
54810c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
549835f2295SStefano Zampini           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%" PetscInt_FMT, ((PetscInt *)data)[j]));
550c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
551c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5526356e834SBarry Smith         }
5536356e834SBarry Smith         break;
554d71ae5a4SJacob Faibussowitsch       case OPTION_INT:
555835f2295SStefano Zampini         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%" PetscInt_FMT, *(PetscInt *)data));
556d71ae5a4SJacob Faibussowitsch         break;
557d71ae5a4SJacob Faibussowitsch       case OPTION_REAL:
55810c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)*(PetscReal *)data));
559d71ae5a4SJacob Faibussowitsch         break;
5606356e834SBarry Smith       case OPTION_REAL_ARRAY:
56110c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)((PetscReal *)data)[0]));
56210c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
56310c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g", (double)((PetscReal *)data)[j]));
564c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
565c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5666356e834SBarry Smith         }
5676356e834SBarry Smith         break;
568050cccc3SHong Zhang       case OPTION_SCALAR_ARRAY:
56910c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[0]), (double)PetscImaginaryPart(((PetscScalar *)data)[0])));
57010c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
57110c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[j]), (double)PetscImaginaryPart(((PetscScalar *)data)[j])));
572c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
573c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
574050cccc3SHong Zhang         }
575050cccc3SHong Zhang         break;
576d71ae5a4SJacob Faibussowitsch       case OPTION_BOOL:
57710c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", *(int *)data));
578d71ae5a4SJacob Faibussowitsch         break;
5797781c08eSBarry Smith       case OPTION_BOOL_ARRAY:
58010c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscBool *)data)[0]));
58110c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
58210c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscBool *)data)[j]));
583c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
584c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5851ae3d29cSBarry Smith         }
5861ae3d29cSBarry Smith         break;
58710c654e6SJacob Faibussowitsch       case OPTION_FLIST: // fall-through
58810c654e6SJacob Faibussowitsch       case OPTION_ELIST: // fall-through
589d71ae5a4SJacob Faibussowitsch       case OPTION_STRING:
59010c654e6SJacob Faibussowitsch         PetscCall(PetscStrncpy(value, (char *)data, sizeof(value)));
591d71ae5a4SJacob Faibussowitsch         break;
5921ae3d29cSBarry Smith       case OPTION_STRING_ARRAY:
59310c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%s", ((char **)data)[0]));
59410c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; j++) {
59510c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%s", ((char **)data)[j]));
596c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
597c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5981ae3d29cSBarry Smith         }
5996356e834SBarry Smith         break;
6006356e834SBarry Smith       }
6019566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(PetscOptionsObject->options, option, value));
6026356e834SBarry Smith     }
60310c654e6SJacob Faibussowitsch     if (type == OPTION_ELIST) PetscCall(PetscStrNArrayDestroy(next->nlist, (char ***)&next->list));
60410c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->text));
60510c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->option));
60610c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->man));
60710c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->edata));
608c979a496SBarry Smith 
60910c654e6SJacob Faibussowitsch     if (type == OPTION_STRING || type == OPTION_FLIST || type == OPTION_ELIST) {
61010c654e6SJacob Faibussowitsch       free(data);
611c979a496SBarry Smith     } else {
61210c654e6SJacob Faibussowitsch       // use next->data instead of data because PetscFree() sets it to NULL
61310c654e6SJacob Faibussowitsch       PetscCall(PetscFree(next->data));
614c979a496SBarry Smith     }
6157781c08eSBarry Smith 
61610c654e6SJacob Faibussowitsch     last                     = next;
61710c654e6SJacob Faibussowitsch     PetscOptionsObject->next = next->next;
6189566063dSJacob Faibussowitsch     PetscCall(PetscFree(last));
6196356e834SBarry Smith   }
6209566063dSJacob Faibussowitsch   PetscCall(PetscFree(PetscOptionsObject->prefix));
62102c9f0b5SLisandro Dalcin   PetscOptionsObject->next = NULL;
6223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
62353acd3b1SBarry Smith }
62453acd3b1SBarry Smith 
GetListLength(const char * const * list,PetscInt * len)62510c654e6SJacob Faibussowitsch static PetscErrorCode GetListLength(const char *const *list, PetscInt *len)
62610c654e6SJacob Faibussowitsch {
62710c654e6SJacob Faibussowitsch   PetscInt retlen = 0;
62810c654e6SJacob Faibussowitsch 
62910c654e6SJacob Faibussowitsch   PetscFunctionBegin;
6304f572ea9SToby Isaac   PetscAssertPointer(len, 2);
63110c654e6SJacob Faibussowitsch   while (list[retlen]) {
6324f572ea9SToby Isaac     PetscAssertPointer(list[retlen], 1);
63310c654e6SJacob Faibussowitsch     PetscCheck(++retlen < 50, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "List argument appears to be wrong or have more than 50 entries");
63410c654e6SJacob Faibussowitsch   }
63510c654e6SJacob Faibussowitsch   PetscCheck(retlen > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least 2 entries: typename and type prefix");
63610c654e6SJacob Faibussowitsch   /* drop item name and prefix*/
63710c654e6SJacob Faibussowitsch   *len = retlen - 2;
63810c654e6SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
63910c654e6SJacob Faibussowitsch }
64010c654e6SJacob Faibussowitsch 
PetscOptionsEnum_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],const char * const * list,PetscEnum currentvalue,PetscEnum * value,PetscBool * set)641ce78bad3SBarry Smith PetscErrorCode PetscOptionsEnum_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum currentvalue, PetscEnum *value, PetscBool *set)
642d71ae5a4SJacob Faibussowitsch {
64353acd3b1SBarry Smith   PetscInt  ntext = 0;
644aa5bb8c0SSatish Balay   PetscInt  tval;
645ace3abfcSBarry Smith   PetscBool tflg;
64653acd3b1SBarry Smith 
64753acd3b1SBarry Smith   PetscFunctionBegin;
6484f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6494f572ea9SToby Isaac   PetscAssertPointer(list, 5);
6504f572ea9SToby Isaac   PetscAssertPointer(value, 7);
6514f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
65210c654e6SJacob Faibussowitsch   PetscCall(GetListLength(list, &ntext));
6531163e504SMatthew G. Knepley   PetscCall(PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[(int)currentvalue], &tval, &tflg));
654aa5bb8c0SSatish Balay   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
655aa5bb8c0SSatish Balay   if (tflg) *value = (PetscEnum)tval;
656aa5bb8c0SSatish Balay   if (set) *set = tflg;
6573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
65853acd3b1SBarry Smith }
65953acd3b1SBarry Smith 
PetscOptionsEnumArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],const char * const * list,PetscEnum value[],PetscInt * n,PetscBool * set)660ce78bad3SBarry Smith PetscErrorCode PetscOptionsEnumArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum value[], PetscInt *n, PetscBool *set)
661d71ae5a4SJacob Faibussowitsch {
66210c654e6SJacob Faibussowitsch   PetscInt    nlist  = 0;
66310c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
664d3e47460SLisandro Dalcin 
665d3e47460SLisandro Dalcin   PetscFunctionBegin;
6664f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6674f572ea9SToby Isaac   PetscAssertPointer(list, 5);
6684f572ea9SToby Isaac   PetscAssertPointer(value, 6);
6694f572ea9SToby Isaac   PetscAssertPointer(n, 7);
67010c654e6SJacob Faibussowitsch   PetscCheck(*n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") must be > 0", *n);
6714f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
67210c654e6SJacob Faibussowitsch   PetscCall(GetListLength(list, &nlist));
673*159a2f88SStefano Zampini   const PetscInt nin = *n;
67410c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetEnumArray(PetscOptionsObject->options, prefix, opt, list, value, n, set));
675*159a2f88SStefano Zampini   if (ShouldPrintHelp(PetscOptionsObject) && nin) {
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 
PetscOptionsInt_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt currentvalue,PetscInt * value,PetscBool * set,PetscInt lb,PetscInt ub)688ce78bad3SBarry Smith 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 
PetscOptionsMPIInt_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscMPIInt currentvalue,PetscMPIInt * value,PetscBool * set,PetscMPIInt lb,PetscMPIInt ub)720ce78bad3SBarry 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;
7463a7d0413SPierre Jolivet   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 
PetscOptionsString_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],const char currentvalue[],char value[],size_t len,PetscBool * set)750ce78bad3SBarry Smith 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 
PetscOptionsReal_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscReal currentvalue,PetscReal * value,PetscBool * set,PetscReal lb,PetscReal ub)772ce78bad3SBarry Smith 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 
PetscOptionsScalar_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscScalar currentvalue,PetscScalar * value,PetscBool * set)804ce78bad3SBarry Smith 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 
PetscOptionsName_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool * flg)815ce78bad3SBarry Smith 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 
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)835ce78bad3SBarry Smith 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 
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)862ce78bad3SBarry Smith 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 
PetscOptionsBoolGroupBegin_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool * flg)896ce78bad3SBarry Smith 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 
PetscOptionsBoolGroup_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool * flg)922ce78bad3SBarry Smith 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 
PetscOptionsBoolGroupEnd_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool * flg)943ce78bad3SBarry Smith 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 
PetscOptionsBool_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool currentvalue,PetscBool * flg,PetscBool * set)964ce78bad3SBarry Smith 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 
PetscOptionsBool3_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool3 currentvalue,PetscBool3 * flg,PetscBool * set)9914d81f786SBarry Smith PetscErrorCode PetscOptionsBool3_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool3 currentvalue, PetscBool3 *flg, PetscBool *set)
9924d81f786SBarry Smith {
9934d81f786SBarry Smith   const char *prefix = PetscOptionsObject->prefix;
9944d81f786SBarry Smith   PetscBool   iset;
9954d81f786SBarry Smith 
9964d81f786SBarry Smith   PetscFunctionBegin;
9974d81f786SBarry Smith   PetscAssertPointer(opt, 2);
9984d81f786SBarry Smith   PetscAssertPointer(flg, 6);
9994d81f786SBarry Smith   if (set) PetscAssertPointer(set, 7);
10004d81f786SBarry Smith   PetscCall(PetscOptionsGetBool3(PetscOptionsObject->options, prefix, opt, flg, &iset));
10014d81f786SBarry Smith   if (set) *set = iset;
10024d81f786SBarry Smith   if (ShouldPrintHelp(PetscOptionsObject)) {
10034d81f786SBarry Smith     const char *curvalue = PetscBool3s[currentvalue];
10044d81f786SBarry Smith 
10054d81f786SBarry Smith     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)));
10064d81f786SBarry Smith   }
10074d81f786SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
10084d81f786SBarry Smith }
10094d81f786SBarry Smith 
PetscOptionsRealArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscReal value[],PetscInt * n,PetscBool * set)1010ce78bad3SBarry Smith PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set)
1011d71ae5a4SJacob Faibussowitsch {
101210c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
101353acd3b1SBarry Smith 
101453acd3b1SBarry Smith   PetscFunctionBegin;
10154f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10164f572ea9SToby Isaac   PetscAssertPointer(n, 6);
101710c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10184f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10194f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1020e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
102110c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1022e26ddf31SBarry Smith     PetscReal      *vals;
102310c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1024e26ddf31SBarry Smith 
10259566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt));
102610c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
102710c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
102810c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
102910c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1030e26ddf31SBarry Smith   }
1031*159a2f88SStefano Zampini   const PetscInt nin = *n;
103210c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1033*159a2f88SStefano Zampini   if (ShouldPrintHelp(PetscOptionsObject) && nin) {
103410c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
103510c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
103610c654e6SJacob Faibussowitsch 
103710c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0]));
103810c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i]));
103910c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
104053acd3b1SBarry Smith   }
10413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
104253acd3b1SBarry Smith }
104353acd3b1SBarry Smith 
PetscOptionsScalarArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscScalar value[],PetscInt * n,PetscBool * set)1044ce78bad3SBarry Smith PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set)
1045d71ae5a4SJacob Faibussowitsch {
104610c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
1047050cccc3SHong Zhang 
1048050cccc3SHong Zhang   PetscFunctionBegin;
10494f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10504f572ea9SToby Isaac   PetscAssertPointer(n, 6);
105110c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10524f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10534f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1054050cccc3SHong Zhang   if (!PetscOptionsObject->count) {
105510c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
105610c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1057050cccc3SHong Zhang     PetscScalar    *vals;
1058050cccc3SHong Zhang 
10599566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt));
106010c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
106110c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
106210c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
106310c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1064050cccc3SHong Zhang   }
1065*159a2f88SStefano Zampini   const PetscInt nin = *n;
106610c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1067*159a2f88SStefano Zampini   if (ShouldPrintHelp(PetscOptionsObject) && nin) {
106810c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
106910c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
107010c654e6SJacob Faibussowitsch 
107110c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0])));
107210c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i])));
107310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1074050cccc3SHong Zhang   }
10753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1076050cccc3SHong Zhang }
107753acd3b1SBarry Smith 
PetscOptionsIntArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscInt value[],PetscInt * n,PetscBool * set)1078ce78bad3SBarry Smith PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set)
1079d71ae5a4SJacob Faibussowitsch {
108010c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
108153acd3b1SBarry Smith 
108253acd3b1SBarry Smith   PetscFunctionBegin;
10834f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10844f572ea9SToby Isaac   PetscAssertPointer(n, 6);
108510c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10864f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10874f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1088e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
108910c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1090e26ddf31SBarry Smith     PetscInt       *vals;
109110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1092e26ddf31SBarry Smith 
10939566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt));
109410c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
109510c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
109610c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
109710c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1098e26ddf31SBarry Smith   }
1099*159a2f88SStefano Zampini   const PetscInt nin = *n;
110010c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1101*159a2f88SStefano Zampini   if (ShouldPrintHelp(PetscOptionsObject) && nin) {
110210c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
110310c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
110410c654e6SJacob Faibussowitsch 
110510c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0]));
110610c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i]));
110710c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
110853acd3b1SBarry Smith   }
11093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
111053acd3b1SBarry Smith }
111153acd3b1SBarry Smith 
PetscOptionsStringArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],char * value[],PetscInt * nmax,PetscBool * set)1112ce78bad3SBarry Smith PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set)
1113d71ae5a4SJacob Faibussowitsch {
111410c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
111553acd3b1SBarry Smith 
111653acd3b1SBarry Smith   PetscFunctionBegin;
11174f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
11184f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
111910c654e6SJacob Faibussowitsch   PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax);
11204f572ea9SToby Isaac   if (*nmax) PetscAssertPointer(value, 5);
11214f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1122e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
112310c654e6SJacob Faibussowitsch     const PetscInt  nmaxv = *nmax;
112410c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1125a297a907SKarl Rupp 
112610c654e6SJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt));
112710c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data));
112810c654e6SJacob Faibussowitsch     amsopt->arraylength = nmaxv;
11291ae3d29cSBarry Smith   }
1130*159a2f88SStefano Zampini   const PetscInt nin = *nmax;
113110c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set));
1132*159a2f88SStefano Zampini   if (ShouldPrintHelp(PetscOptionsObject) && nin) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
11333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
113453acd3b1SBarry Smith }
113553acd3b1SBarry Smith 
PetscOptionsBoolArray_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscBool value[],PetscInt * n,PetscBool * set)1136ce78bad3SBarry Smith PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set)
1137d71ae5a4SJacob Faibussowitsch {
113810c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
1139e2446a98SMatthew Knepley 
1140e2446a98SMatthew Knepley   PetscFunctionBegin;
11414f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
11424f572ea9SToby Isaac   PetscAssertPointer(n, 6);
114310c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
11444f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
11454f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1146e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
114710c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1148ace3abfcSBarry Smith     PetscBool      *vals;
114910c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
11501ae3d29cSBarry Smith 
11519566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt));
115210c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
115310c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
115410c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
115510c654e6SJacob Faibussowitsch     amsopt->data        = vals;
11561ae3d29cSBarry Smith   }
1157*159a2f88SStefano Zampini   const PetscInt nin = *n;
115810c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set));
1159*159a2f88SStefano Zampini   if (ShouldPrintHelp(PetscOptionsObject) && nin) {
116010c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
116110c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
116210c654e6SJacob Faibussowitsch 
116310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%d", Prefix(prefix), opt + 1, value[0]));
116410c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i]));
116510c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1166e2446a98SMatthew Knepley   }
11673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1168e2446a98SMatthew Knepley }
1169e2446a98SMatthew Knepley 
117088aa4217SBarry Smith /*MC
1171648c30bcSBarry Smith   PetscOptionsViewer - Creates a viewer appropriate for the type indicated by the user
11728cc676e6SMatthew G Knepley 
117388aa4217SBarry Smith   Synopsis:
117410450e9eSJacob Faibussowitsch   #include <petscviewer.h>
11753a89f35bSSatish Balay   PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
117688aa4217SBarry Smith 
11777cdbe19fSJose E. Roman   Logically Collective on the communicator passed in `PetscOptionsBegin()`
11787cdbe19fSJose E. Roman 
11798cc676e6SMatthew G Knepley   Input Parameters:
11808cc676e6SMatthew G Knepley + opt  - option name
11818cc676e6SMatthew G Knepley . text - short string that describes the option
11828cc676e6SMatthew G Knepley - man  - manual page with additional information on option
11838cc676e6SMatthew G Knepley 
1184d8d19677SJose E. Roman   Output Parameters:
11858cc676e6SMatthew G Knepley + viewer - the viewer
11869314d9b7SBarry Smith . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed
1187811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
11888cc676e6SMatthew G Knepley 
11898cc676e6SMatthew G Knepley   Level: beginner
11908cc676e6SMatthew G Knepley 
119195452b02SPatrick Sanan   Notes:
1192811af0c4SBarry Smith   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`
11938cc676e6SMatthew G Knepley 
1194648c30bcSBarry Smith   See `PetscOptionsCreateViewer()` for the format of the supplied viewer and its options
11958cc676e6SMatthew G Knepley 
1196648c30bcSBarry Smith .seealso: `PetscOptionsCreateViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1197db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
1198aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1199db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1200c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1201db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1202db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
120388aa4217SBarry Smith M*/
PetscOptionsViewer_Private(PetscOptionItems PetscOptionsObject,const char opt[],const char text[],const char man[],PetscViewer * viewer,PetscViewerFormat * format,PetscBool * set)1204ce78bad3SBarry Smith PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
1205d71ae5a4SJacob Faibussowitsch {
120610c654e6SJacob Faibussowitsch   const MPI_Comm comm   = PetscOptionsObject->comm;
120710c654e6SJacob Faibussowitsch   const char    *prefix = PetscOptionsObject->prefix;
12088cc676e6SMatthew G Knepley 
12098cc676e6SMatthew G Knepley   PetscFunctionBegin;
12104f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
12114f572ea9SToby Isaac   PetscAssertPointer(viewer, 5);
12124f572ea9SToby Isaac   if (format) PetscAssertPointer(format, 6);
12134f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
12141a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
121510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
121610c654e6SJacob Faibussowitsch 
12179566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
121864facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
12199566063dSJacob Faibussowitsch     PetscCall(PetscStrdup("", (char **)&amsopt->data));
12208cc676e6SMatthew G Knepley   }
1221648c30bcSBarry Smith   PetscCall(PetscOptionsCreateViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set));
122210c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man)));
12233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12248cc676e6SMatthew G Knepley }
1225