xref: /petsc/src/sys/objects/aoptions.c (revision 9314d9b798781688e05556f819200786dc9eceaa)
153acd3b1SBarry Smith /*
23fc1eb6aSBarry Smith    Implements the higher-level options database querying methods. These are self-documenting and can attach at runtime to
33fc1eb6aSBarry Smith    GUI code to display the options and get values from the users.
453acd3b1SBarry Smith 
553acd3b1SBarry Smith */
653acd3b1SBarry Smith 
7af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I  "petscsys.h"   I*/
8665c2dedSJed Brown #include <petscviewer.h>
953acd3b1SBarry Smith 
1010c654e6SJacob Faibussowitsch static const char *ManSection(const char *str)
1110c654e6SJacob Faibussowitsch {
1210c654e6SJacob Faibussowitsch   return str ? str : "None";
1310c654e6SJacob Faibussowitsch }
1410c654e6SJacob Faibussowitsch 
1510c654e6SJacob Faibussowitsch static const char *Prefix(const char *str)
1610c654e6SJacob Faibussowitsch {
1710c654e6SJacob Faibussowitsch   return str ? str : "";
1810c654e6SJacob Faibussowitsch }
1910c654e6SJacob Faibussowitsch 
2010c654e6SJacob Faibussowitsch static int ShouldPrintHelp(const PetscOptionItems *opts)
2110c654e6SJacob Faibussowitsch {
2210c654e6SJacob Faibussowitsch   return opts->printhelp && opts->count == 1 && !opts->alreadyprinted;
2310c654e6SJacob Faibussowitsch }
242aa6d131SJed Brown 
2553acd3b1SBarry Smith /*
2653acd3b1SBarry Smith     Keep a linked list of options that have been posted and we are waiting for
273fc1eb6aSBarry Smith    user selection. See the manual page for PetscOptionsBegin()
2853acd3b1SBarry Smith 
2953acd3b1SBarry Smith     Eventually we'll attach this beast to a MPI_Comm
3053acd3b1SBarry Smith */
31e55864a3SBarry Smith 
3253acd3b1SBarry Smith /*
3353acd3b1SBarry Smith     Handles setting up the data structure in a call to PetscOptionsBegin()
3453acd3b1SBarry Smith */
35d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBegin_Private(PetscOptionItems *PetscOptionsObject, MPI_Comm comm, const char prefix[], const char title[], const char mansec[])
36d71ae5a4SJacob Faibussowitsch {
3753acd3b1SBarry Smith   PetscFunctionBegin;
384f572ea9SToby Isaac   if (prefix) PetscAssertPointer(prefix, 3);
394f572ea9SToby Isaac   PetscAssertPointer(title, 4);
404f572ea9SToby Isaac   if (mansec) PetscAssertPointer(mansec, 5);
410eb63584SBarry Smith   if (!PetscOptionsObject->alreadyprinted) {
429566063dSJacob Faibussowitsch     if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton));
439566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, prefix, title, &PetscOptionsObject->alreadyprinted));
440eb63584SBarry Smith   }
4502c9f0b5SLisandro Dalcin   PetscOptionsObject->next          = NULL;
46e55864a3SBarry Smith   PetscOptionsObject->comm          = comm;
47e55864a3SBarry Smith   PetscOptionsObject->changedmethod = PETSC_FALSE;
48a297a907SKarl Rupp 
499566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(prefix, &PetscOptionsObject->prefix));
509566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(title, &PetscOptionsObject->title));
5153acd3b1SBarry Smith 
529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(PetscOptionsObject->options, &PetscOptionsObject->printhelp));
5310c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\n%s:\n", title));
543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5553acd3b1SBarry Smith }
5653acd3b1SBarry Smith 
573194b578SJed Brown /*
583194b578SJed Brown     Handles setting up the data structure in a call to PetscObjectOptionsBegin()
593194b578SJed Brown */
60d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectOptionsBegin_Private(PetscObject obj, PetscOptionItems *PetscOptionsObject)
61d71ae5a4SJacob Faibussowitsch {
623194b578SJed Brown   char      title[256];
633194b578SJed Brown   PetscBool flg;
643194b578SJed Brown 
653194b578SJed Brown   PetscFunctionBegin;
664f572ea9SToby Isaac   PetscAssertPointer(PetscOptionsObject, 2);
67dbbe0bcdSBarry Smith   PetscValidHeader(obj, 1);
68e55864a3SBarry Smith   PetscOptionsObject->object         = obj;
69e55864a3SBarry Smith   PetscOptionsObject->alreadyprinted = obj->optionsprinted;
70a297a907SKarl Rupp 
719566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(obj->description, obj->class_name, &flg));
729566063dSJacob Faibussowitsch   if (flg) PetscCall(PetscSNPrintf(title, sizeof(title), "%s options", obj->class_name));
739566063dSJacob Faibussowitsch   else PetscCall(PetscSNPrintf(title, sizeof(title), "%s (%s) options", obj->description, obj->class_name));
749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBegin_Private(PetscOptionsObject, obj->comm, obj->prefix, title, obj->mansec));
753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
763194b578SJed Brown }
773194b578SJed Brown 
7853acd3b1SBarry Smith /*
7953acd3b1SBarry Smith      Handles adding another option to the list of options within this particular PetscOptionsBegin() PetscOptionsEnd()
8053acd3b1SBarry Smith */
813ba16761SJacob Faibussowitsch static PetscErrorCode PetscOptionItemCreate_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscOptionType t, PetscOptionItem *amsopt)
82d71ae5a4SJacob Faibussowitsch {
833be6e4c3SJed Brown   PetscBool valid;
8453acd3b1SBarry Smith 
8553acd3b1SBarry Smith   PetscFunctionBegin;
869566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(opt, &valid));
875f80ce2aSJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "The option '%s' is not a valid key", opt);
883be6e4c3SJed Brown 
899566063dSJacob Faibussowitsch   PetscCall(PetscNew(amsopt));
9002c9f0b5SLisandro Dalcin   (*amsopt)->next = NULL;
9153acd3b1SBarry Smith   (*amsopt)->set  = PETSC_FALSE;
926356e834SBarry Smith   (*amsopt)->type = t;
9302c9f0b5SLisandro Dalcin   (*amsopt)->data = NULL;
9461b37b28SSatish Balay 
959566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(text, &(*amsopt)->text));
969566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(opt, &(*amsopt)->option));
979566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(man, &(*amsopt)->man));
9853acd3b1SBarry Smith 
9910c654e6SJacob Faibussowitsch   {
10010c654e6SJacob Faibussowitsch     PetscOptionItem cur = PetscOptionsObject->next;
10110c654e6SJacob Faibussowitsch 
10210c654e6SJacob Faibussowitsch     while (cur->next) cur = cur->next;
10310c654e6SJacob Faibussowitsch     cur->next = *amsopt;
10453acd3b1SBarry Smith   }
1053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10653acd3b1SBarry Smith }
10753acd3b1SBarry Smith 
108aee2cecaSBarry Smith /*
10910450e9eSJacob Faibussowitsch     This is needed because certain strings may be freed by SAWs, hence we cannot use PetscStrallocpy()
11010450e9eSJacob Faibussowitsch */
11110450e9eSJacob Faibussowitsch static PetscErrorCode PetscStrdup(const char s[], char *t[])
11210450e9eSJacob Faibussowitsch {
11310450e9eSJacob Faibussowitsch   char *tmp = NULL;
11410450e9eSJacob Faibussowitsch 
11510450e9eSJacob Faibussowitsch   PetscFunctionBegin;
11610450e9eSJacob Faibussowitsch   if (s) {
11710450e9eSJacob Faibussowitsch     size_t len;
11810450e9eSJacob Faibussowitsch 
11910450e9eSJacob Faibussowitsch     PetscCall(PetscStrlen(s, &len));
12010450e9eSJacob Faibussowitsch     tmp = (char *)malloc((len + 1) * sizeof(*tmp));
12110450e9eSJacob Faibussowitsch     PetscCheck(tmp, PETSC_COMM_SELF, PETSC_ERR_MEM, "No memory to duplicate string");
12210450e9eSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmp, s, len + 1));
12310450e9eSJacob Faibussowitsch   }
12410450e9eSJacob Faibussowitsch   *t = tmp;
12510450e9eSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12610450e9eSJacob Faibussowitsch }
12710450e9eSJacob Faibussowitsch 
12810450e9eSJacob Faibussowitsch #if defined(PETSC_HAVE_SAWS)
12910450e9eSJacob Faibussowitsch   #include <petscviewersaws.h>
13010450e9eSJacob Faibussowitsch 
13110450e9eSJacob Faibussowitsch static int count = 0;
13210450e9eSJacob Faibussowitsch 
13310450e9eSJacob Faibussowitsch PetscErrorCode PetscOptionsSAWsDestroy(void)
13410450e9eSJacob Faibussowitsch {
13510450e9eSJacob Faibussowitsch   PetscFunctionBegin;
13610450e9eSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13710450e9eSJacob Faibussowitsch }
13810450e9eSJacob Faibussowitsch 
13910450e9eSJacob Faibussowitsch static const char *OptionsHeader = "<head>\n"
14010450e9eSJacob Faibussowitsch                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/jquery-1.9.1.js\"></script>\n"
14110450e9eSJacob Faibussowitsch                                    "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/SAWs.js\"></script>\n"
14210450e9eSJacob Faibussowitsch                                    "<script type=\"text/javascript\" src=\"js/PETSc.js\"></script>\n"
14310450e9eSJacob Faibussowitsch                                    "<script>\n"
14410450e9eSJacob Faibussowitsch                                    "jQuery(document).ready(function() {\n"
14510450e9eSJacob Faibussowitsch                                    "PETSc.getAndDisplayDirectory(null,\"#variablesInfo\")\n"
14610450e9eSJacob Faibussowitsch                                    "})\n"
14710450e9eSJacob Faibussowitsch                                    "</script>\n"
14810450e9eSJacob Faibussowitsch                                    "</head>\n";
14910450e9eSJacob Faibussowitsch 
15010450e9eSJacob Faibussowitsch /*  Determines the size and style of the scroll region where PETSc options selectable from users are displayed */
15110450e9eSJacob Faibussowitsch static const char *OptionsBodyBottom = "<div id=\"variablesInfo\" style=\"background-color:lightblue;height:auto;max-height:500px;overflow:scroll;\"></div>\n<br>\n</body>";
15210450e9eSJacob Faibussowitsch 
15310450e9eSJacob Faibussowitsch /*
15410450e9eSJacob Faibussowitsch     PetscOptionsSAWsInput - Presents all the PETSc Options processed by the program so the user may change them at runtime using the SAWs
15510450e9eSJacob Faibussowitsch 
15610450e9eSJacob Faibussowitsch     Bugs:
15710450e9eSJacob Faibussowitsch +    All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
15810450e9eSJacob Faibussowitsch .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
15910450e9eSJacob Faibussowitsch -    Only works for PetscInt == int, PetscReal == double etc
16010450e9eSJacob Faibussowitsch 
16110450e9eSJacob Faibussowitsch */
16266976f2fSJacob Faibussowitsch static PetscErrorCode PetscOptionsSAWsInput(PetscOptionItems *PetscOptionsObject)
16310450e9eSJacob Faibussowitsch {
16410450e9eSJacob Faibussowitsch   PetscOptionItem next     = PetscOptionsObject->next;
16510450e9eSJacob Faibussowitsch   static int      mancount = 0;
16610450e9eSJacob Faibussowitsch   char            options[16];
16710450e9eSJacob Faibussowitsch   PetscBool       changedmethod = PETSC_FALSE;
16810450e9eSJacob Faibussowitsch   PetscBool       stopasking    = PETSC_FALSE;
16910450e9eSJacob Faibussowitsch   char            manname[16], textname[16];
17010450e9eSJacob Faibussowitsch   char            dir[1024];
17110450e9eSJacob Faibussowitsch 
17210450e9eSJacob Faibussowitsch   PetscFunctionBegin;
17310450e9eSJacob Faibussowitsch   /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */
17410450e9eSJacob Faibussowitsch   PetscCall(PetscSNPrintf(options, PETSC_STATIC_ARRAY_LENGTH(options), "Options_%d", count++));
17510450e9eSJacob Faibussowitsch 
17610450e9eSJacob Faibussowitsch   PetscOptionsObject->pprefix = PetscOptionsObject->prefix; /* SAWs will change this, so cannot pass prefix directly */
17710450e9eSJacob Faibussowitsch 
17810450e9eSJacob Faibussowitsch   PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "_title"));
17910450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->title, 1, SAWs_READ, SAWs_STRING));
18010450e9eSJacob Faibussowitsch   PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "prefix"));
18110450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->pprefix, 1, SAWs_READ, SAWs_STRING));
18210450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, ("/PETSc/Options/ChangedMethod", &changedmethod, 1, SAWs_WRITE, SAWs_BOOLEAN));
18310450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Register, ("/PETSc/Options/StopAsking", &stopasking, 1, SAWs_WRITE, SAWs_BOOLEAN));
18410450e9eSJacob Faibussowitsch 
18510450e9eSJacob Faibussowitsch   while (next) {
18610450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(manname, PETSC_STATIC_ARRAY_LENGTH(manname), "_man_%d", mancount));
18710450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", manname));
18810450e9eSJacob Faibussowitsch     PetscCallSAWs(SAWs_Register, (dir, &next->man, 1, SAWs_READ, SAWs_STRING));
18910450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(textname, PETSC_STATIC_ARRAY_LENGTH(textname), "_text_%d", mancount++));
19010450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", textname));
19110450e9eSJacob Faibussowitsch     PetscCallSAWs(SAWs_Register, (dir, &next->text, 1, SAWs_READ, SAWs_STRING));
19210450e9eSJacob Faibussowitsch 
19310450e9eSJacob Faibussowitsch     switch (next->type) {
19410450e9eSJacob Faibussowitsch     case OPTION_HEAD:
19510450e9eSJacob Faibussowitsch       break;
19610450e9eSJacob Faibussowitsch     case OPTION_INT_ARRAY:
19710450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
19810450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_INT));
19910450e9eSJacob Faibussowitsch       break;
20010450e9eSJacob Faibussowitsch     case OPTION_REAL_ARRAY:
20110450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
20210450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_DOUBLE));
20310450e9eSJacob Faibussowitsch       break;
20410450e9eSJacob Faibussowitsch     case OPTION_INT:
20510450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
20610450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_INT));
20710450e9eSJacob Faibussowitsch       break;
20810450e9eSJacob Faibussowitsch     case OPTION_REAL:
20910450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
21010450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_DOUBLE));
21110450e9eSJacob Faibussowitsch       break;
21210450e9eSJacob Faibussowitsch     case OPTION_BOOL:
21310450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
21410450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_BOOLEAN));
21510450e9eSJacob Faibussowitsch       break;
21610450e9eSJacob Faibussowitsch     case OPTION_BOOL_ARRAY:
21710450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
21810450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_BOOLEAN));
21910450e9eSJacob Faibussowitsch       break;
22010450e9eSJacob Faibussowitsch     case OPTION_STRING:
22110450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
22210450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
22310450e9eSJacob Faibussowitsch       break;
22410450e9eSJacob Faibussowitsch     case OPTION_STRING_ARRAY:
22510450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
22610450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_STRING));
22710450e9eSJacob Faibussowitsch       break;
22810450e9eSJacob Faibussowitsch     case OPTION_FLIST: {
22910450e9eSJacob Faibussowitsch       PetscInt ntext;
23010450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
23110450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
23210450e9eSJacob Faibussowitsch       PetscCall(PetscFunctionListGet(next->flist, (const char ***)&next->edata, &ntext));
23310450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
23410450e9eSJacob Faibussowitsch     } break;
23510450e9eSJacob Faibussowitsch     case OPTION_ELIST: {
23610450e9eSJacob Faibussowitsch       PetscInt ntext = next->nlist;
23710450e9eSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
23810450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING));
23910450e9eSJacob Faibussowitsch       PetscCall(PetscMalloc1((ntext + 1), (char ***)&next->edata));
24010450e9eSJacob Faibussowitsch       PetscCall(PetscMemcpy(next->edata, next->list, ntext * sizeof(char *)));
24110450e9eSJacob Faibussowitsch       PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata));
24210450e9eSJacob Faibussowitsch     } break;
24310450e9eSJacob Faibussowitsch     default:
24410450e9eSJacob Faibussowitsch       break;
24510450e9eSJacob Faibussowitsch     }
24610450e9eSJacob Faibussowitsch     next = next->next;
24710450e9eSJacob Faibussowitsch   }
24810450e9eSJacob Faibussowitsch 
24910450e9eSJacob Faibussowitsch   /* wait until accessor has unlocked the memory */
25010450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Push_Header, ("index.html", OptionsHeader));
25110450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Push_Body, ("index.html", 2, OptionsBodyBottom));
25210450e9eSJacob Faibussowitsch   PetscCall(PetscSAWsBlock());
25310450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Pop_Header, ("index.html"));
25410450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Pop_Body, ("index.html", 2));
25510450e9eSJacob Faibussowitsch 
25610450e9eSJacob Faibussowitsch   /* determine if any values have been set in GUI */
25710450e9eSJacob Faibussowitsch   next = PetscOptionsObject->next;
25810450e9eSJacob Faibussowitsch   while (next) {
25910450e9eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option));
26010450e9eSJacob Faibussowitsch     PetscCallSAWs(SAWs_Selected, (dir, (int *)&next->set));
26110450e9eSJacob Faibussowitsch     next = next->next;
26210450e9eSJacob Faibussowitsch   }
26310450e9eSJacob Faibussowitsch 
26410450e9eSJacob Faibussowitsch   /* reset counter to -2; this updates the screen with the new options for the selected method */
26510450e9eSJacob Faibussowitsch   if (changedmethod) PetscOptionsObject->count = -2;
26610450e9eSJacob Faibussowitsch 
26710450e9eSJacob Faibussowitsch   if (stopasking) {
26810450e9eSJacob Faibussowitsch     PetscOptionsPublish       = PETSC_FALSE;
26910450e9eSJacob Faibussowitsch     PetscOptionsObject->count = 0; //do not ask for same thing again
27010450e9eSJacob Faibussowitsch   }
27110450e9eSJacob Faibussowitsch 
27210450e9eSJacob Faibussowitsch   PetscCallSAWs(SAWs_Delete, ("/PETSc/Options"));
27310450e9eSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
27410450e9eSJacob Faibussowitsch }
27510450e9eSJacob Faibussowitsch #else
27610450e9eSJacob Faibussowitsch /*
2773fc1eb6aSBarry Smith     PetscScanString -  Gets user input via stdin from process and broadcasts to all processes
2783fc1eb6aSBarry Smith 
279d083f849SBarry Smith     Collective
2803fc1eb6aSBarry Smith 
2813fc1eb6aSBarry Smith    Input Parameters:
2823fc1eb6aSBarry Smith +     commm - communicator for the broadcast, must be PETSC_COMM_WORLD
2833fc1eb6aSBarry Smith .     n - length of the string, must be the same on all processes
2843fc1eb6aSBarry Smith -     str - location to store input
285aee2cecaSBarry Smith 
286aee2cecaSBarry Smith     Bugs:
287aee2cecaSBarry Smith .   Assumes process 0 of the given communicator has access to stdin
288aee2cecaSBarry Smith 
289aee2cecaSBarry Smith */
290d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscScanString(MPI_Comm comm, size_t n, char str[])
291d71ae5a4SJacob Faibussowitsch {
2923fc1eb6aSBarry Smith   PetscMPIInt rank, nm;
293aee2cecaSBarry Smith 
294aee2cecaSBarry Smith   PetscFunctionBegin;
2959566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
296dd400576SPatrick Sanan   if (rank == 0) {
2975f80ce2aSJacob Faibussowitsch     char   c = (char)getchar();
2985f80ce2aSJacob Faibussowitsch     size_t i = 0;
2995f80ce2aSJacob Faibussowitsch 
300aee2cecaSBarry Smith     while (c != '\n' && i < n - 1) {
301aee2cecaSBarry Smith       str[i++] = c;
302aee2cecaSBarry Smith       c        = (char)getchar();
303aee2cecaSBarry Smith     }
30410c654e6SJacob Faibussowitsch     str[i] = '\0';
305aee2cecaSBarry Smith   }
3069566063dSJacob Faibussowitsch   PetscCall(PetscMPIIntCast(n, &nm));
3079566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(str, nm, MPI_CHAR, 0, comm));
3083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
309aee2cecaSBarry Smith }
310aee2cecaSBarry Smith 
3115b02f95dSBarry Smith /*
3123cc1e11dSBarry Smith   PetscOptionsGetFromTextInput - Presents all the PETSc Options processed by the program so the user may change them at runtime
313aee2cecaSBarry Smith 
31495452b02SPatrick Sanan   Notes:
31595452b02SPatrick Sanan   this isn't really practical, it is just to demonstrate the principle
316aee2cecaSBarry Smith 
3177781c08eSBarry Smith   A carriage return indicates no change from the default; but this like -ksp_monitor <stdout>  the default is actually not stdout the default
3187781c08eSBarry Smith   is to do nothing so to get it to use stdout you need to type stdout. This is kind of bug?
3197781c08eSBarry Smith 
320aee2cecaSBarry Smith   Bugs:
3217781c08eSBarry Smith +    All processes must traverse through the exact same set of option queries due to the call to PetscScanString()
3223cc1e11dSBarry Smith .    Internal strings have arbitrary length and string copies are not checked that they fit into string space
323aee2cecaSBarry Smith -    Only works for PetscInt == int, PetscReal == double etc
324aee2cecaSBarry Smith 
325aec76313SJacob Faibussowitsch   Developer Notes:
32695452b02SPatrick Sanan   Normally the GUI that presents the options the user and retrieves the values would be running in a different
3273cc1e11dSBarry Smith   address space and communicating with the PETSc program
3283cc1e11dSBarry Smith 
329aee2cecaSBarry Smith */
33010450e9eSJacob Faibussowitsch static PetscErrorCode PetscOptionsGetFromTextInput(PetscOptionItems *PetscOptionsObject)
331d71ae5a4SJacob Faibussowitsch {
3324416b707SBarry Smith   PetscOptionItem next = PetscOptionsObject->next;
3336356e834SBarry Smith   char            str[512];
3347781c08eSBarry Smith   PetscBool       bid;
335a4404d99SBarry Smith   PetscReal       ir, *valr;
336330cf3c9SBarry Smith   PetscInt       *vald;
337330cf3c9SBarry Smith   size_t          i;
3386356e834SBarry Smith 
3392a409bb0SBarry Smith   PetscFunctionBegin;
3409566063dSJacob Faibussowitsch   PetscCall((*PetscPrintf)(PETSC_COMM_WORLD, "%s --------------------\n", PetscOptionsObject->title));
3416356e834SBarry Smith   while (next) {
3426356e834SBarry Smith     switch (next->type) {
343d71ae5a4SJacob Faibussowitsch     case OPTION_HEAD:
344d71ae5a4SJacob Faibussowitsch       break;
345e26ddf31SBarry Smith     case OPTION_INT_ARRAY:
3464bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
347e26ddf31SBarry Smith       vald = (PetscInt *)next->data;
348e26ddf31SBarry Smith       for (i = 0; i < next->arraylength; i++) {
3499566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT, vald[i]));
35048a46eb9SPierre Jolivet         if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
351e26ddf31SBarry Smith       }
3529566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
3539566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
354e26ddf31SBarry Smith       if (str[0]) {
355e26ddf31SBarry Smith         PetscToken token;
356e26ddf31SBarry Smith         PetscInt   n = 0, nmax = next->arraylength, *dvalue = (PetscInt *)next->data, start, end;
357e26ddf31SBarry Smith         size_t     len;
358e26ddf31SBarry Smith         char      *value;
359ace3abfcSBarry Smith         PetscBool  foundrange;
360e26ddf31SBarry Smith 
361e26ddf31SBarry Smith         next->set = PETSC_TRUE;
362e26ddf31SBarry Smith         value     = str;
3639566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(value, ',', &token));
3649566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &value));
365e26ddf31SBarry Smith         while (n < nmax) {
366e26ddf31SBarry Smith           if (!value) break;
367e26ddf31SBarry Smith 
368e26ddf31SBarry Smith           /* look for form  d-D where d and D are integers */
369e26ddf31SBarry Smith           foundrange = PETSC_FALSE;
3709566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(value, &len));
371e26ddf31SBarry Smith           if (value[0] == '-') i = 2;
372e26ddf31SBarry Smith           else i = 1;
373330cf3c9SBarry Smith           for (; i < len; i++) {
374e26ddf31SBarry Smith             if (value[i] == '-') {
37508401ef6SPierre Jolivet               PetscCheck(i != len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
376e26ddf31SBarry Smith               value[i] = 0;
3779566063dSJacob Faibussowitsch               PetscCall(PetscOptionsStringToInt(value, &start));
3789566063dSJacob Faibussowitsch               PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
37908401ef6SPierre Jolivet               PetscCheck(end > start, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, %s-%s cannot have decreasing list", n, value, value + i + 1);
380cc73adaaSBarry Smith               PetscCheck(n + end - start - 1 < nmax, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, not enough space in left in array (%" PetscInt_FMT ") to contain entire range from %" PetscInt_FMT " to %" PetscInt_FMT, n, nmax - n, start, end);
381e26ddf31SBarry Smith               for (; start < end; start++) {
3829371c9d4SSatish Balay                 *dvalue = start;
3839371c9d4SSatish Balay                 dvalue++;
3849371c9d4SSatish Balay                 n++;
385e26ddf31SBarry Smith               }
386e26ddf31SBarry Smith               foundrange = PETSC_TRUE;
387e26ddf31SBarry Smith               break;
388e26ddf31SBarry Smith             }
389e26ddf31SBarry Smith           }
390e26ddf31SBarry Smith           if (!foundrange) {
3919566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value, dvalue));
392e26ddf31SBarry Smith             dvalue++;
393e26ddf31SBarry Smith             n++;
394e26ddf31SBarry Smith           }
3959566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &value));
396e26ddf31SBarry Smith         }
3979566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
398e26ddf31SBarry Smith       }
399e26ddf31SBarry Smith       break;
400e26ddf31SBarry Smith     case OPTION_REAL_ARRAY:
4014bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1));
402e26ddf31SBarry Smith       valr = (PetscReal *)next->data;
403e26ddf31SBarry Smith       for (i = 0; i < next->arraylength; i++) {
4049566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i]));
40548a46eb9SPierre Jolivet         if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ","));
406e26ddf31SBarry Smith       }
4079566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man));
4089566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
409e26ddf31SBarry Smith       if (str[0]) {
410e26ddf31SBarry Smith         PetscToken token;
411e26ddf31SBarry Smith         PetscInt   n = 0, nmax = next->arraylength;
412e26ddf31SBarry Smith         PetscReal *dvalue = (PetscReal *)next->data;
413e26ddf31SBarry Smith         char      *value;
414e26ddf31SBarry Smith 
415e26ddf31SBarry Smith         next->set = PETSC_TRUE;
416e26ddf31SBarry Smith         value     = str;
4179566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(value, ',', &token));
4189566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &value));
419e26ddf31SBarry Smith         while (n < nmax) {
420e26ddf31SBarry Smith           if (!value) break;
4219566063dSJacob Faibussowitsch           PetscCall(PetscOptionsStringToReal(value, dvalue));
422e26ddf31SBarry Smith           dvalue++;
423e26ddf31SBarry Smith           n++;
4249566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &value));
425e26ddf31SBarry Smith         }
4269566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
427e26ddf31SBarry Smith       }
428e26ddf31SBarry Smith       break;
4296356e834SBarry Smith     case OPTION_INT:
4304bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%d>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(int *)next->data, next->text, next->man));
4319566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4323fc1eb6aSBarry Smith       if (str[0]) {
433d25d7f95SJed Brown   #if defined(PETSC_SIZEOF_LONG_LONG)
434d25d7f95SJed Brown         long long lid;
435d25d7f95SJed Brown         sscanf(str, "%lld", &lid);
436cc73adaaSBarry Smith         PetscCheck(lid <= PETSC_MAX_INT && lid >= PETSC_MIN_INT, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %lld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid);
437c272547aSJed Brown   #else
438d25d7f95SJed Brown         long lid;
439d25d7f95SJed Brown         sscanf(str, "%ld", &lid);
440cc73adaaSBarry Smith         PetscCheck(lid <= PETSC_MAX_INT && lid >= PETSC_MIN_INT, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %ld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid);
441c272547aSJed Brown   #endif
442a297a907SKarl Rupp 
443d25d7f95SJed Brown         next->set                 = PETSC_TRUE;
444d25d7f95SJed Brown         *((PetscInt *)next->data) = (PetscInt)lid;
445aee2cecaSBarry Smith       }
446aee2cecaSBarry Smith       break;
447aee2cecaSBarry Smith     case OPTION_REAL:
4484bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%g>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(double *)next->data, next->text, next->man));
4499566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4503fc1eb6aSBarry Smith       if (str[0]) {
451ce63c4c1SBarry Smith   #if defined(PETSC_USE_REAL_SINGLE)
452a4404d99SBarry Smith         sscanf(str, "%e", &ir);
453570b7f6dSBarry Smith   #elif defined(PETSC_USE_REAL___FP16)
454570b7f6dSBarry Smith         float irtemp;
455570b7f6dSBarry Smith         sscanf(str, "%e", &irtemp);
456570b7f6dSBarry Smith         ir = irtemp;
457ce63c4c1SBarry Smith   #elif defined(PETSC_USE_REAL_DOUBLE)
458aee2cecaSBarry Smith         sscanf(str, "%le", &ir);
459ce63c4c1SBarry Smith   #elif defined(PETSC_USE_REAL___FLOAT128)
460d9822059SBarry Smith         ir = strtoflt128(str, 0);
461d9822059SBarry Smith   #else
462513dbe71SLisandro Dalcin         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type");
463a4404d99SBarry Smith   #endif
464aee2cecaSBarry Smith         next->set                  = PETSC_TRUE;
465aee2cecaSBarry Smith         *((PetscReal *)next->data) = ir;
466aee2cecaSBarry Smith       }
467aee2cecaSBarry Smith       break;
4687781c08eSBarry Smith     case OPTION_BOOL:
4694bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%s>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(PetscBool *)next->data ? "true" : "false", next->text, next->man));
4709566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4717781c08eSBarry Smith       if (str[0]) {
4729566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToBool(str, &bid));
4737781c08eSBarry Smith         next->set                  = PETSC_TRUE;
4747781c08eSBarry Smith         *((PetscBool *)next->data) = bid;
4757781c08eSBarry Smith       }
4767781c08eSBarry Smith       break;
477aee2cecaSBarry Smith     case OPTION_STRING:
4784bb2516aSBarry Smith       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%s>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, (char *)next->data, next->text, next->man));
4799566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4803fc1eb6aSBarry Smith       if (str[0]) {
481aee2cecaSBarry Smith         next->set = PETSC_TRUE;
48264facd6cSBarry Smith         /* must use system malloc since SAWs may free this */
4839566063dSJacob Faibussowitsch         PetscCall(PetscStrdup(str, (char **)&next->data));
4846356e834SBarry Smith       }
4856356e834SBarry Smith       break;
486a264d7a6SBarry Smith     case OPTION_FLIST:
4879566063dSJacob Faibussowitsch       PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data));
4889566063dSJacob Faibussowitsch       PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str));
4893cc1e11dSBarry Smith       if (str[0]) {
490e55864a3SBarry Smith         PetscOptionsObject->changedmethod = PETSC_TRUE;
4913cc1e11dSBarry Smith         next->set                         = PETSC_TRUE;
49264facd6cSBarry Smith         /* must use system malloc since SAWs may free this */
4939566063dSJacob Faibussowitsch         PetscCall(PetscStrdup(str, (char **)&next->data));
4943cc1e11dSBarry Smith       }
4953cc1e11dSBarry Smith       break;
496d71ae5a4SJacob Faibussowitsch     default:
497d71ae5a4SJacob Faibussowitsch       break;
4986356e834SBarry Smith     }
4996356e834SBarry Smith     next = next->next;
5006356e834SBarry Smith   }
5013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5026356e834SBarry Smith }
503b3506946SBarry Smith #endif
504b3506946SBarry Smith 
505d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems *PetscOptionsObject)
506d71ae5a4SJacob Faibussowitsch {
50710c654e6SJacob Faibussowitsch   PetscOptionItem next, last;
50853acd3b1SBarry Smith 
50953acd3b1SBarry Smith   PetscFunctionBegin;
51083355fc5SBarry Smith   if (PetscOptionsObject->next) {
51183355fc5SBarry Smith     if (!PetscOptionsObject->count) {
512a264d7a6SBarry Smith #if defined(PETSC_HAVE_SAWS)
5139566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSAWsInput(PetscOptionsObject));
514b3506946SBarry Smith #else
5159566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetFromTextInput(PetscOptionsObject));
516b3506946SBarry Smith #endif
517aee2cecaSBarry Smith     }
518aee2cecaSBarry Smith   }
5196356e834SBarry Smith 
5209566063dSJacob Faibussowitsch   PetscCall(PetscFree(PetscOptionsObject->title));
5216356e834SBarry Smith 
522e26ddf31SBarry Smith   /* reset counter to -2; this updates the screen with the new options for the selected method */
523e55864a3SBarry Smith   if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2;
5247a72a596SBarry Smith   /* reset alreadyprinted flag */
525e55864a3SBarry Smith   PetscOptionsObject->alreadyprinted = PETSC_FALSE;
526e55864a3SBarry Smith   if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE;
527e55864a3SBarry Smith   PetscOptionsObject->object = NULL;
52853acd3b1SBarry Smith 
52910c654e6SJacob Faibussowitsch   while ((next = PetscOptionsObject->next)) {
53010c654e6SJacob Faibussowitsch     const PetscOptionType type        = next->type;
53110c654e6SJacob Faibussowitsch     const size_t          arraylength = next->arraylength;
53210c654e6SJacob Faibussowitsch     void                 *data        = next->data;
53310c654e6SJacob Faibussowitsch 
53410c654e6SJacob Faibussowitsch     if (next->set) {
53510c654e6SJacob Faibussowitsch       char option[256], value[1024], tmp[32];
53610c654e6SJacob Faibussowitsch 
537e55864a3SBarry Smith       if (PetscOptionsObject->prefix) {
538c6a7a370SJeremy L Thompson         PetscCall(PetscStrncpy(option, "-", sizeof(option)));
539c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(option, PetscOptionsObject->prefix, sizeof(option)));
54010c654e6SJacob Faibussowitsch         PetscCall(PetscStrlcat(option, next->option + 1, sizeof(option)));
54110c654e6SJacob Faibussowitsch       } else {
54210c654e6SJacob Faibussowitsch         PetscCall(PetscStrncpy(option, next->option, sizeof(option)));
54310c654e6SJacob Faibussowitsch       }
5446356e834SBarry Smith 
54510c654e6SJacob Faibussowitsch       switch (type) {
546d71ae5a4SJacob Faibussowitsch       case OPTION_HEAD:
547d71ae5a4SJacob Faibussowitsch         break;
5486356e834SBarry Smith       case OPTION_INT_ARRAY:
54910c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscInt *)data)[0]));
55010c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
55110c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscInt *)data)[j]));
552c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
553c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5546356e834SBarry Smith         }
5556356e834SBarry Smith         break;
556d71ae5a4SJacob Faibussowitsch       case OPTION_INT:
55710c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)*(PetscInt *)data));
558d71ae5a4SJacob Faibussowitsch         break;
559d71ae5a4SJacob Faibussowitsch       case OPTION_REAL:
56010c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)*(PetscReal *)data));
561d71ae5a4SJacob Faibussowitsch         break;
5626356e834SBarry Smith       case OPTION_REAL_ARRAY:
56310c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)((PetscReal *)data)[0]));
56410c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
56510c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g", (double)((PetscReal *)data)[j]));
566c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
567c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5686356e834SBarry Smith         }
5696356e834SBarry Smith         break;
570050cccc3SHong Zhang       case OPTION_SCALAR_ARRAY:
57110c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[0]), (double)PetscImaginaryPart(((PetscScalar *)data)[0])));
57210c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
57310c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[j]), (double)PetscImaginaryPart(((PetscScalar *)data)[j])));
574c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
575c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
576050cccc3SHong Zhang         }
577050cccc3SHong Zhang         break;
578d71ae5a4SJacob Faibussowitsch       case OPTION_BOOL:
57910c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", *(int *)data));
580d71ae5a4SJacob Faibussowitsch         break;
5817781c08eSBarry Smith       case OPTION_BOOL_ARRAY:
58210c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscBool *)data)[0]));
58310c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; ++j) {
58410c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscBool *)data)[j]));
585c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
586c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
5871ae3d29cSBarry Smith         }
5881ae3d29cSBarry Smith         break;
58910c654e6SJacob Faibussowitsch       case OPTION_FLIST: // fall-through
59010c654e6SJacob Faibussowitsch       case OPTION_ELIST: // fall-through
591d71ae5a4SJacob Faibussowitsch       case OPTION_STRING:
59210c654e6SJacob Faibussowitsch         PetscCall(PetscStrncpy(value, (char *)data, sizeof(value)));
593d71ae5a4SJacob Faibussowitsch         break;
5941ae3d29cSBarry Smith       case OPTION_STRING_ARRAY:
59510c654e6SJacob Faibussowitsch         PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%s", ((char **)data)[0]));
59610c654e6SJacob Faibussowitsch         for (size_t j = 1; j < arraylength; j++) {
59710c654e6SJacob Faibussowitsch           PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%s", ((char **)data)[j]));
598c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, ",", sizeof(value)));
599c6a7a370SJeremy L Thompson           PetscCall(PetscStrlcat(value, tmp, sizeof(value)));
6001ae3d29cSBarry Smith         }
6016356e834SBarry Smith         break;
6026356e834SBarry Smith       }
6039566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(PetscOptionsObject->options, option, value));
6046356e834SBarry Smith     }
60510c654e6SJacob Faibussowitsch     if (type == OPTION_ELIST) PetscCall(PetscStrNArrayDestroy(next->nlist, (char ***)&next->list));
60610c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->text));
60710c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->option));
60810c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->man));
60910c654e6SJacob Faibussowitsch     PetscCall(PetscFree(next->edata));
610c979a496SBarry Smith 
61110c654e6SJacob Faibussowitsch     if (type == OPTION_STRING || type == OPTION_FLIST || type == OPTION_ELIST) {
61210c654e6SJacob Faibussowitsch       free(data);
613c979a496SBarry Smith     } else {
61410c654e6SJacob Faibussowitsch       // use next->data instead of data because PetscFree() sets it to NULL
61510c654e6SJacob Faibussowitsch       PetscCall(PetscFree(next->data));
616c979a496SBarry Smith     }
6177781c08eSBarry Smith 
61810c654e6SJacob Faibussowitsch     last                     = next;
61910c654e6SJacob Faibussowitsch     PetscOptionsObject->next = next->next;
6209566063dSJacob Faibussowitsch     PetscCall(PetscFree(last));
6216356e834SBarry Smith   }
6229566063dSJacob Faibussowitsch   PetscCall(PetscFree(PetscOptionsObject->prefix));
62302c9f0b5SLisandro Dalcin   PetscOptionsObject->next = NULL;
6243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
62553acd3b1SBarry Smith }
62653acd3b1SBarry Smith 
62710c654e6SJacob Faibussowitsch static PetscErrorCode GetListLength(const char *const *list, PetscInt *len)
62810c654e6SJacob Faibussowitsch {
62910c654e6SJacob Faibussowitsch   PetscInt retlen = 0;
63010c654e6SJacob Faibussowitsch 
63110c654e6SJacob Faibussowitsch   PetscFunctionBegin;
6324f572ea9SToby Isaac   PetscAssertPointer(len, 2);
63310c654e6SJacob Faibussowitsch   while (list[retlen]) {
6344f572ea9SToby Isaac     PetscAssertPointer(list[retlen], 1);
63510c654e6SJacob Faibussowitsch     PetscCheck(++retlen < 50, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "List argument appears to be wrong or have more than 50 entries");
63610c654e6SJacob Faibussowitsch   }
63710c654e6SJacob Faibussowitsch   PetscCheck(retlen > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least 2 entries: typename and type prefix");
63810c654e6SJacob Faibussowitsch   /* drop item name and prefix*/
63910c654e6SJacob Faibussowitsch   *len = retlen - 2;
64010c654e6SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
64110c654e6SJacob Faibussowitsch }
64210c654e6SJacob Faibussowitsch 
643d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnum_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum currentvalue, PetscEnum *value, PetscBool *set)
644d71ae5a4SJacob Faibussowitsch {
64553acd3b1SBarry Smith   PetscInt  ntext = 0;
646aa5bb8c0SSatish Balay   PetscInt  tval;
647ace3abfcSBarry Smith   PetscBool tflg;
64853acd3b1SBarry Smith 
64953acd3b1SBarry Smith   PetscFunctionBegin;
6504f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6514f572ea9SToby Isaac   PetscAssertPointer(list, 5);
6524f572ea9SToby Isaac   PetscAssertPointer(value, 7);
6534f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
65410c654e6SJacob Faibussowitsch   PetscCall(GetListLength(list, &ntext));
6559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[currentvalue], &tval, &tflg));
656aa5bb8c0SSatish Balay   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
657aa5bb8c0SSatish Balay   if (tflg) *value = (PetscEnum)tval;
658aa5bb8c0SSatish Balay   if (set) *set = tflg;
6593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
66053acd3b1SBarry Smith }
66153acd3b1SBarry Smith 
662d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnumArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum value[], PetscInt *n, PetscBool *set)
663d71ae5a4SJacob Faibussowitsch {
66410c654e6SJacob Faibussowitsch   PetscInt    nlist  = 0;
66510c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
666d3e47460SLisandro Dalcin 
667d3e47460SLisandro Dalcin   PetscFunctionBegin;
6684f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6694f572ea9SToby Isaac   PetscAssertPointer(list, 5);
6704f572ea9SToby Isaac   PetscAssertPointer(value, 6);
6714f572ea9SToby Isaac   PetscAssertPointer(n, 7);
67210c654e6SJacob Faibussowitsch   PetscCheck(*n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") must be > 0", *n);
6734f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
67410c654e6SJacob Faibussowitsch   PetscCall(GetListLength(list, &nlist));
67510c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetEnumArray(PetscOptionsObject->options, prefix, opt, list, value, n, set));
67610c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
67710c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
67810c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
67910c654e6SJacob Faibussowitsch 
68010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s", Prefix(prefix), opt + 1, list[value[0]]));
68110c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%s", list[value[i]]));
68210c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (choose from)", text));
68310c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nlist; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
68410c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
685d3e47460SLisandro Dalcin   }
6863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
687d3e47460SLisandro Dalcin }
688d3e47460SLisandro Dalcin 
689d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInt_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *set, PetscInt lb, PetscInt ub)
690d71ae5a4SJacob Faibussowitsch {
69110c654e6SJacob Faibussowitsch   const char        *prefix  = PetscOptionsObject->prefix;
69210c654e6SJacob Faibussowitsch   const PetscOptions options = PetscOptionsObject->options;
69312655325SBarry Smith   PetscBool          wasset;
69453acd3b1SBarry Smith 
69553acd3b1SBarry Smith   PetscFunctionBegin;
6964f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
6974f572ea9SToby Isaac   PetscAssertPointer(value, 6);
6984f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
69908401ef6SPierre Jolivet   PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, currentvalue, lb);
70008401ef6SPierre Jolivet   PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, currentvalue, ub);
701e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
70210c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
70310c654e6SJacob Faibussowitsch 
7049566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt));
7059566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data));
70612655325SBarry Smith     *(PetscInt *)amsopt->data = currentvalue;
7073e211508SBarry Smith 
70810c654e6SJacob Faibussowitsch     PetscCall(PetscOptionsGetInt(options, prefix, opt, &currentvalue, &wasset));
709ad540459SPierre Jolivet     if (wasset) *(PetscInt *)amsopt->data = currentvalue;
710af6d86caSBarry Smith   }
71110c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(options, prefix, opt, value, &wasset));
712cc73adaaSBarry Smith   PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, *value, lb);
713cc73adaaSBarry Smith   PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, *value, ub);
71444ef3d73SBarry Smith   if (set) *set = wasset;
71510c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
71610c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <now %" PetscInt_FMT " : formerly %" PetscInt_FMT ">: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? *value : currentvalue, currentvalue, text, ManSection(man)));
71753acd3b1SBarry Smith   }
7183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71953acd3b1SBarry Smith }
72053acd3b1SBarry Smith 
721d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsString_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char currentvalue[], char value[], size_t len, PetscBool *set)
722d71ae5a4SJacob Faibussowitsch {
72310c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
72444ef3d73SBarry Smith   PetscBool   lset;
72553acd3b1SBarry Smith 
72653acd3b1SBarry Smith   PetscFunctionBegin;
7274f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
7284f572ea9SToby Isaac   PetscAssertPointer(value, 6);
7294f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 8);
7301a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
73110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
73210c654e6SJacob Faibussowitsch 
7339566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
73464facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
7359566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
736af6d86caSBarry Smith   }
73710c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
73844ef3d73SBarry Smith   if (set) *set = lset;
73910c654e6SJacob 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)));
7403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
74153acd3b1SBarry Smith }
74253acd3b1SBarry Smith 
743d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsReal_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal currentvalue, PetscReal *value, PetscBool *set)
744d71ae5a4SJacob Faibussowitsch {
74510c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
74644ef3d73SBarry Smith   PetscBool   lset;
74753acd3b1SBarry Smith 
74853acd3b1SBarry Smith   PetscFunctionBegin;
7494f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
7504f572ea9SToby Isaac   PetscAssertPointer(value, 6);
7514f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
752e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
75310c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
75410c654e6SJacob Faibussowitsch 
7559566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt));
7569566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data));
757a297a907SKarl Rupp 
7580fdccdaeSBarry Smith     *(PetscReal *)amsopt->data = currentvalue;
759538aa990SBarry Smith   }
76010c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &lset));
76144ef3d73SBarry Smith   if (set) *set = lset;
76210c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
76310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <now %g : formerly %g>: %s (%s)\n", Prefix(prefix), opt + 1, lset ? (double)*value : (double)currentvalue, (double)currentvalue, text, ManSection(man)));
76453acd3b1SBarry Smith   }
7653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
76653acd3b1SBarry Smith }
76753acd3b1SBarry Smith 
768d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set)
769d71ae5a4SJacob Faibussowitsch {
77053acd3b1SBarry Smith   PetscFunctionBegin;
77153acd3b1SBarry Smith #if !defined(PETSC_USE_COMPLEX)
7729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set));
77353acd3b1SBarry Smith #else
7749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set));
77553acd3b1SBarry Smith #endif
7763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
77753acd3b1SBarry Smith }
77853acd3b1SBarry Smith 
779d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
780d71ae5a4SJacob Faibussowitsch {
78110c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
78253acd3b1SBarry Smith 
78353acd3b1SBarry Smith   PetscFunctionBegin;
7844f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
7854f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
786e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
78710c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
78810c654e6SJacob Faibussowitsch 
7899566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
7909566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
791a297a907SKarl Rupp 
792ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
7931ae3d29cSBarry Smith   }
79410c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg));
79510c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
7963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
79753acd3b1SBarry Smith }
79853acd3b1SBarry Smith 
799d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFList_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char ltext[], const char man[], PetscFunctionList list, const char currentvalue[], char value[], size_t len, PetscBool *set)
800d71ae5a4SJacob Faibussowitsch {
80110c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
80244ef3d73SBarry Smith   PetscBool   lset;
80353acd3b1SBarry Smith 
80453acd3b1SBarry Smith   PetscFunctionBegin;
8054f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8064f572ea9SToby Isaac   PetscAssertPointer(value, 7);
8074f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 9);
8081a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
80910c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
81010c654e6SJacob Faibussowitsch 
8119566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt));
81264facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
8139566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
8143cc1e11dSBarry Smith     amsopt->flist = list;
8153cc1e11dSBarry Smith   }
81610c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
81744ef3d73SBarry Smith   if (set) *set = lset;
81810c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue));
8193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
82053acd3b1SBarry Smith }
82153acd3b1SBarry Smith 
82210c654e6SJacob Faibussowitsch #ifdef __cplusplus
82310c654e6SJacob Faibussowitsch   #include <type_traits>
82410c654e6SJacob Faibussowitsch #endif
82510c654e6SJacob Faibussowitsch 
826d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEList_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char ltext[], const char man[], const char *const *list, PetscInt ntext, const char currentvalue[], PetscInt *value, PetscBool *set)
827d71ae5a4SJacob Faibussowitsch {
82810c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
82944ef3d73SBarry Smith   PetscBool   lset;
83053acd3b1SBarry Smith 
83153acd3b1SBarry Smith   PetscFunctionBegin;
8324f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8334f572ea9SToby Isaac   PetscAssertPointer(value, 8);
8344f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 9);
8351a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
83610c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
83710c654e6SJacob Faibussowitsch 
8389566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt));
83964facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
8409566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
8419566063dSJacob Faibussowitsch     PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list));
84210c654e6SJacob Faibussowitsch     PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX);
84310c654e6SJacob Faibussowitsch #ifdef __cplusplus
84410c654e6SJacob Faibussowitsch     static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, "");
84510c654e6SJacob Faibussowitsch #endif
84610c654e6SJacob Faibussowitsch     amsopt->nlist = (char)ntext;
8471ae3d29cSBarry Smith   }
84810c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset));
84944ef3d73SBarry Smith   if (set) *set = lset;
85010c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
85110c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
85210c654e6SJacob Faibussowitsch 
85310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext));
85410c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
85510c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
85653acd3b1SBarry Smith   }
8573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
85853acd3b1SBarry Smith }
85953acd3b1SBarry Smith 
860d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
861d71ae5a4SJacob Faibussowitsch {
86210c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
86353acd3b1SBarry Smith 
86453acd3b1SBarry Smith   PetscFunctionBegin;
8654f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8664f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
867e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
86810c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
86910c654e6SJacob Faibussowitsch 
8709566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
8719566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
872a297a907SKarl Rupp 
873ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
8741ae3d29cSBarry Smith   }
87568b16fdaSBarry Smith   *flg = PETSC_FALSE;
87610c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
87710c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
87810c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
87910c654e6SJacob Faibussowitsch 
88010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  Pick at most one of -------------\n"));
88110c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
88253acd3b1SBarry Smith   }
8833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
88453acd3b1SBarry Smith }
88553acd3b1SBarry Smith 
886d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
887d71ae5a4SJacob Faibussowitsch {
88810c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
88953acd3b1SBarry Smith 
89053acd3b1SBarry Smith   PetscFunctionBegin;
8914f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8924f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
893e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
89410c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
89510c654e6SJacob Faibussowitsch 
8969566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
8979566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
898a297a907SKarl Rupp 
899ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9001ae3d29cSBarry Smith   }
90117326d04SJed Brown   *flg = PETSC_FALSE;
90210c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
90310c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
9043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
90553acd3b1SBarry Smith }
90653acd3b1SBarry Smith 
907d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
908d71ae5a4SJacob Faibussowitsch {
90910c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
91053acd3b1SBarry Smith 
91153acd3b1SBarry Smith   PetscFunctionBegin;
9124f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9134f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
914e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
91510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
91610c654e6SJacob Faibussowitsch 
9179566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9189566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
919a297a907SKarl Rupp 
920ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9211ae3d29cSBarry Smith   }
92217326d04SJed Brown   *flg = PETSC_FALSE;
92310c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
92410c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
9253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
92653acd3b1SBarry Smith }
92753acd3b1SBarry Smith 
928d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set)
929d71ae5a4SJacob Faibussowitsch {
93010c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
931ace3abfcSBarry Smith   PetscBool   iset;
93253acd3b1SBarry Smith 
93353acd3b1SBarry Smith   PetscFunctionBegin;
9344f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9354f572ea9SToby Isaac   PetscAssertPointer(flg, 6);
9364f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
937e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
93810c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
93910c654e6SJacob Faibussowitsch 
9409566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9419566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
942a297a907SKarl Rupp 
94394ae4db5SBarry Smith     *(PetscBool *)amsopt->data = currentvalue;
944af6d86caSBarry Smith   }
94510c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset));
94653acd3b1SBarry Smith   if (set) *set = iset;
94710c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
94810c654e6SJacob Faibussowitsch     const char *curvalue = PetscBools[currentvalue];
94910c654e6SJacob Faibussowitsch 
95010c654e6SJacob 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)));
95153acd3b1SBarry Smith   }
9523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
95353acd3b1SBarry Smith }
95453acd3b1SBarry Smith 
955d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set)
956d71ae5a4SJacob Faibussowitsch {
95710c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
95853acd3b1SBarry Smith 
95953acd3b1SBarry Smith   PetscFunctionBegin;
9604f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9614f572ea9SToby Isaac   PetscAssertPointer(n, 6);
96210c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
9634f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
9644f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
965e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
96610c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
967e26ddf31SBarry Smith     PetscReal      *vals;
96810c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
969e26ddf31SBarry Smith 
9709566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt));
97110c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
97210c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
97310c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
97410c654e6SJacob Faibussowitsch     amsopt->data        = vals;
975e26ddf31SBarry Smith   }
97610c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set));
97710c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
97810c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
97910c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
98010c654e6SJacob Faibussowitsch 
98110c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0]));
98210c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i]));
98310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
98453acd3b1SBarry Smith   }
9853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
98653acd3b1SBarry Smith }
98753acd3b1SBarry Smith 
988d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set)
989d71ae5a4SJacob Faibussowitsch {
99010c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
991050cccc3SHong Zhang 
992050cccc3SHong Zhang   PetscFunctionBegin;
9934f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9944f572ea9SToby Isaac   PetscAssertPointer(n, 6);
99510c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
9964f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
9974f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
998050cccc3SHong Zhang   if (!PetscOptionsObject->count) {
99910c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
100010c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1001050cccc3SHong Zhang     PetscScalar    *vals;
1002050cccc3SHong Zhang 
10039566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt));
100410c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
100510c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
100610c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
100710c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1008050cccc3SHong Zhang   }
100910c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set));
101010c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
101110c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
101210c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
101310c654e6SJacob Faibussowitsch 
101410c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0])));
101510c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i])));
101610c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1017050cccc3SHong Zhang   }
10183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1019050cccc3SHong Zhang }
102053acd3b1SBarry Smith 
1021d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set)
1022d71ae5a4SJacob Faibussowitsch {
102310c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
102453acd3b1SBarry Smith 
102553acd3b1SBarry Smith   PetscFunctionBegin;
10264f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10274f572ea9SToby Isaac   PetscAssertPointer(n, 6);
102810c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10294f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10304f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1031e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
103210c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1033e26ddf31SBarry Smith     PetscInt       *vals;
103410c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1035e26ddf31SBarry Smith 
10369566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt));
103710c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
103810c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
103910c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
104010c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1041e26ddf31SBarry Smith   }
104210c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set));
104310c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
104410c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
104510c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
104610c654e6SJacob Faibussowitsch 
104710c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0]));
104810c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i]));
104910c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
105053acd3b1SBarry Smith   }
10513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
105253acd3b1SBarry Smith }
105353acd3b1SBarry Smith 
1054d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set)
1055d71ae5a4SJacob Faibussowitsch {
105610c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
105753acd3b1SBarry Smith 
105853acd3b1SBarry Smith   PetscFunctionBegin;
10594f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10604f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
106110c654e6SJacob Faibussowitsch   PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax);
10624f572ea9SToby Isaac   if (*nmax) PetscAssertPointer(value, 5);
10634f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1064e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
106510c654e6SJacob Faibussowitsch     const PetscInt  nmaxv = *nmax;
106610c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1067a297a907SKarl Rupp 
106810c654e6SJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt));
106910c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data));
107010c654e6SJacob Faibussowitsch     amsopt->arraylength = nmaxv;
10711ae3d29cSBarry Smith   }
107210c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set));
107310c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
10743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
107553acd3b1SBarry Smith }
107653acd3b1SBarry Smith 
1077d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set)
1078d71ae5a4SJacob Faibussowitsch {
107910c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
1080e2446a98SMatthew Knepley 
1081e2446a98SMatthew Knepley   PetscFunctionBegin;
10824f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10834f572ea9SToby Isaac   PetscAssertPointer(n, 6);
108410c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10854f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10864f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1087e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
108810c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1089ace3abfcSBarry Smith     PetscBool      *vals;
109010c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
10911ae3d29cSBarry Smith 
10929566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt));
109310c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
109410c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
109510c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
109610c654e6SJacob Faibussowitsch     amsopt->data        = vals;
10971ae3d29cSBarry Smith   }
109810c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set));
109910c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
110010c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
110110c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
110210c654e6SJacob Faibussowitsch 
110310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%d", Prefix(prefix), opt + 1, value[0]));
110410c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i]));
110510c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1106e2446a98SMatthew Knepley   }
11073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1108e2446a98SMatthew Knepley }
1109e2446a98SMatthew Knepley 
111088aa4217SBarry Smith /*MC
1111d1da0b69SBarry Smith   PetscOptionsViewer - Gets a viewer appropriate for the type indicated by the user
11128cc676e6SMatthew G Knepley 
111388aa4217SBarry Smith   Synopsis:
111410450e9eSJacob Faibussowitsch   #include <petscviewer.h>
11153a89f35bSSatish Balay   PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
111688aa4217SBarry Smith 
11177cdbe19fSJose E. Roman   Logically Collective on the communicator passed in `PetscOptionsBegin()`
11187cdbe19fSJose E. Roman 
11198cc676e6SMatthew G Knepley   Input Parameters:
11208cc676e6SMatthew G Knepley + opt  - option name
11218cc676e6SMatthew G Knepley . text - short string that describes the option
11228cc676e6SMatthew G Knepley - man  - manual page with additional information on option
11238cc676e6SMatthew G Knepley 
1124d8d19677SJose E. Roman   Output Parameters:
11258cc676e6SMatthew G Knepley + viewer - the viewer
1126*9314d9b7SBarry Smith . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed
1127811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
11288cc676e6SMatthew G Knepley 
11298cc676e6SMatthew G Knepley   Level: beginner
11308cc676e6SMatthew G Knepley 
113195452b02SPatrick Sanan   Notes:
1132811af0c4SBarry Smith   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`
11338cc676e6SMatthew G Knepley 
1134811af0c4SBarry Smith   See `PetscOptionsGetViewer()` for the format of the supplied viewer and its options
11358cc676e6SMatthew G Knepley 
1136db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1137db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
1138aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1139db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1140c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1141db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1142db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
114388aa4217SBarry Smith M*/
1144d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
1145d71ae5a4SJacob Faibussowitsch {
114610c654e6SJacob Faibussowitsch   const MPI_Comm comm   = PetscOptionsObject->comm;
114710c654e6SJacob Faibussowitsch   const char    *prefix = PetscOptionsObject->prefix;
11488cc676e6SMatthew G Knepley 
11498cc676e6SMatthew G Knepley   PetscFunctionBegin;
11504f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
11514f572ea9SToby Isaac   PetscAssertPointer(viewer, 5);
11524f572ea9SToby Isaac   if (format) PetscAssertPointer(format, 6);
11534f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
11541a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
115510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
115610c654e6SJacob Faibussowitsch 
11579566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
115864facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
11599566063dSJacob Faibussowitsch     PetscCall(PetscStrdup("", (char **)&amsopt->data));
11608cc676e6SMatthew G Knepley   }
116110c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set));
116210c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man)));
11633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11648cc676e6SMatthew G Knepley }
1165