xref: /petsc/src/sys/objects/aoptions.c (revision 648c30bcb65f74c3cbd15d7a91a7ed7c1890e25b)
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 
74352ce0ab5SPierre Jolivet PetscErrorCode PetscOptionsReal_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal currentvalue, PetscReal *value, PetscBool *set, PetscReal lb, PetscReal ub)
744d71ae5a4SJacob Faibussowitsch {
74510c654e6SJacob Faibussowitsch   const char        *prefix  = PetscOptionsObject->prefix;
74652ce0ab5SPierre Jolivet   const PetscOptions options = PetscOptionsObject->options;
74752ce0ab5SPierre Jolivet   PetscBool          wasset;
74853acd3b1SBarry Smith 
74953acd3b1SBarry Smith   PetscFunctionBegin;
7504f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
7514f572ea9SToby Isaac   PetscAssertPointer(value, 6);
7524f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
75352ce0ab5SPierre Jolivet   PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g less than allowed bound %g", (double)currentvalue, (double)lb);
75452ce0ab5SPierre Jolivet   PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g greater than allowed bound %g", (double)currentvalue, (double)ub);
755e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
75610c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
75710c654e6SJacob Faibussowitsch 
7589566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt));
7599566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data));
7600fdccdaeSBarry Smith     *(PetscReal *)amsopt->data = currentvalue;
76152ce0ab5SPierre Jolivet 
76252ce0ab5SPierre Jolivet     PetscCall(PetscOptionsGetReal(options, prefix, opt, &currentvalue, &wasset));
76352ce0ab5SPierre Jolivet     if (wasset) *(PetscReal *)amsopt->data = currentvalue;
764538aa990SBarry Smith   }
76552ce0ab5SPierre Jolivet   PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &wasset));
76652ce0ab5SPierre 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);
76752ce0ab5SPierre 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);
76852ce0ab5SPierre Jolivet   if (set) *set = wasset;
76910c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
77052ce0ab5SPierre 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)));
77153acd3b1SBarry Smith   }
7723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
77353acd3b1SBarry Smith }
77453acd3b1SBarry Smith 
775d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set)
776d71ae5a4SJacob Faibussowitsch {
77753acd3b1SBarry Smith   PetscFunctionBegin;
77853acd3b1SBarry Smith #if !defined(PETSC_USE_COMPLEX)
7799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set));
78053acd3b1SBarry Smith #else
7819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set));
78253acd3b1SBarry Smith #endif
7833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
78453acd3b1SBarry Smith }
78553acd3b1SBarry Smith 
786d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
787d71ae5a4SJacob Faibussowitsch {
78810c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
78953acd3b1SBarry Smith 
79053acd3b1SBarry Smith   PetscFunctionBegin;
7914f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
7924f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
793e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
79410c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
79510c654e6SJacob Faibussowitsch 
7969566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
7979566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
798a297a907SKarl Rupp 
799ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
8001ae3d29cSBarry Smith   }
80110c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg));
80210c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
8033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
80453acd3b1SBarry Smith }
80553acd3b1SBarry Smith 
806d71ae5a4SJacob 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)
807d71ae5a4SJacob Faibussowitsch {
80810c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
80944ef3d73SBarry Smith   PetscBool   lset;
81053acd3b1SBarry Smith 
81153acd3b1SBarry Smith   PetscFunctionBegin;
8124f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8134f572ea9SToby Isaac   PetscAssertPointer(value, 7);
8144f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 9);
8151a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
81610c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
81710c654e6SJacob Faibussowitsch 
8189566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt));
81964facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
8209566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
8213cc1e11dSBarry Smith     amsopt->flist = list;
8223cc1e11dSBarry Smith   }
82310c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset));
82444ef3d73SBarry Smith   if (set) *set = lset;
82510c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue));
8263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
82753acd3b1SBarry Smith }
82853acd3b1SBarry Smith 
82910c654e6SJacob Faibussowitsch #ifdef __cplusplus
83010c654e6SJacob Faibussowitsch   #include <type_traits>
83110c654e6SJacob Faibussowitsch #endif
83210c654e6SJacob Faibussowitsch 
833d71ae5a4SJacob 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)
834d71ae5a4SJacob Faibussowitsch {
83510c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
83644ef3d73SBarry Smith   PetscBool   lset;
83753acd3b1SBarry Smith 
83853acd3b1SBarry Smith   PetscFunctionBegin;
8394f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8404f572ea9SToby Isaac   PetscAssertPointer(value, 8);
8414f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 9);
8421a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
84310c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
84410c654e6SJacob Faibussowitsch 
8459566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt));
84664facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
8479566063dSJacob Faibussowitsch     PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data));
8489566063dSJacob Faibussowitsch     PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list));
84910c654e6SJacob Faibussowitsch     PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX);
85010c654e6SJacob Faibussowitsch #ifdef __cplusplus
85110c654e6SJacob Faibussowitsch     static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, "");
85210c654e6SJacob Faibussowitsch #endif
85310c654e6SJacob Faibussowitsch     amsopt->nlist = (char)ntext;
8541ae3d29cSBarry Smith   }
85510c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset));
85644ef3d73SBarry Smith   if (set) *set = lset;
85710c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
85810c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
85910c654e6SJacob Faibussowitsch 
86010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext));
86110c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i]));
86210c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man)));
86353acd3b1SBarry Smith   }
8643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
86553acd3b1SBarry Smith }
86653acd3b1SBarry Smith 
867d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
868d71ae5a4SJacob Faibussowitsch {
86910c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
87053acd3b1SBarry Smith 
87153acd3b1SBarry Smith   PetscFunctionBegin;
8724f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8734f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
874e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
87510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
87610c654e6SJacob Faibussowitsch 
8779566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
8789566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
879a297a907SKarl Rupp 
880ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
8811ae3d29cSBarry Smith   }
88268b16fdaSBarry Smith   *flg = PETSC_FALSE;
88310c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
88410c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
88510c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
88610c654e6SJacob Faibussowitsch 
88710c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  Pick at most one of -------------\n"));
88810c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
88953acd3b1SBarry Smith   }
8903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
89153acd3b1SBarry Smith }
89253acd3b1SBarry Smith 
893d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
894d71ae5a4SJacob Faibussowitsch {
89510c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
89653acd3b1SBarry Smith 
89753acd3b1SBarry Smith   PetscFunctionBegin;
8984f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
8994f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
900e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
90110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
90210c654e6SJacob Faibussowitsch 
9039566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9049566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
905a297a907SKarl Rupp 
906ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9071ae3d29cSBarry Smith   }
90817326d04SJed Brown   *flg = PETSC_FALSE;
90910c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
91010c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
9113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
91253acd3b1SBarry Smith }
91353acd3b1SBarry Smith 
914d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg)
915d71ae5a4SJacob Faibussowitsch {
91610c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
91753acd3b1SBarry Smith 
91853acd3b1SBarry Smith   PetscFunctionBegin;
9194f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9204f572ea9SToby Isaac   PetscAssertPointer(flg, 5);
921e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
92210c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
92310c654e6SJacob Faibussowitsch 
9249566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9259566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
926a297a907SKarl Rupp 
927ace3abfcSBarry Smith     *(PetscBool *)amsopt->data = PETSC_FALSE;
9281ae3d29cSBarry Smith   }
92917326d04SJed Brown   *flg = PETSC_FALSE;
93010c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL));
93110c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "    -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
9323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
93353acd3b1SBarry Smith }
93453acd3b1SBarry Smith 
935d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set)
936d71ae5a4SJacob Faibussowitsch {
93710c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
938ace3abfcSBarry Smith   PetscBool   iset;
93953acd3b1SBarry Smith 
94053acd3b1SBarry Smith   PetscFunctionBegin;
9414f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9424f572ea9SToby Isaac   PetscAssertPointer(flg, 6);
9434f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
944e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
94510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
94610c654e6SJacob Faibussowitsch 
9479566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt));
9489566063dSJacob Faibussowitsch     PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data));
949a297a907SKarl Rupp 
95094ae4db5SBarry Smith     *(PetscBool *)amsopt->data = currentvalue;
951af6d86caSBarry Smith   }
95210c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset));
95353acd3b1SBarry Smith   if (set) *set = iset;
95410c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
95510c654e6SJacob Faibussowitsch     const char *curvalue = PetscBools[currentvalue];
95610c654e6SJacob Faibussowitsch 
95710c654e6SJacob 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)));
95853acd3b1SBarry Smith   }
9593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
96053acd3b1SBarry Smith }
96153acd3b1SBarry Smith 
962d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set)
963d71ae5a4SJacob Faibussowitsch {
96410c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
96553acd3b1SBarry Smith 
96653acd3b1SBarry Smith   PetscFunctionBegin;
9674f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
9684f572ea9SToby Isaac   PetscAssertPointer(n, 6);
96910c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
9704f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
9714f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
972e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
97310c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
974e26ddf31SBarry Smith     PetscReal      *vals;
97510c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
976e26ddf31SBarry Smith 
9779566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt));
97810c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
97910c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
98010c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
98110c654e6SJacob Faibussowitsch     amsopt->data        = vals;
982e26ddf31SBarry Smith   }
98310c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set));
98410c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
98510c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
98610c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
98710c654e6SJacob Faibussowitsch 
98810c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0]));
98910c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i]));
99010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
99153acd3b1SBarry Smith   }
9923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
99353acd3b1SBarry Smith }
99453acd3b1SBarry Smith 
995d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set)
996d71ae5a4SJacob Faibussowitsch {
99710c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
998050cccc3SHong Zhang 
999050cccc3SHong Zhang   PetscFunctionBegin;
10004f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10014f572ea9SToby Isaac   PetscAssertPointer(n, 6);
100210c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10034f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10044f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1005050cccc3SHong Zhang   if (!PetscOptionsObject->count) {
100610c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
100710c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1008050cccc3SHong Zhang     PetscScalar    *vals;
1009050cccc3SHong Zhang 
10109566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt));
101110c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc(nv * sizeof(*vals), &vals));
101210c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
101310c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
101410c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1015050cccc3SHong Zhang   }
101610c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set));
101710c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
101810c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
101910c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
102010c654e6SJacob Faibussowitsch 
102110c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0])));
102210c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i])));
102310c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1024050cccc3SHong Zhang   }
10253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1026050cccc3SHong Zhang }
102753acd3b1SBarry Smith 
1028d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set)
1029d71ae5a4SJacob Faibussowitsch {
103010c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
103153acd3b1SBarry Smith 
103253acd3b1SBarry Smith   PetscFunctionBegin;
10334f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10344f572ea9SToby Isaac   PetscAssertPointer(n, 6);
103510c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10364f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10374f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1038e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
103910c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1040e26ddf31SBarry Smith     PetscInt       *vals;
104110c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1042e26ddf31SBarry Smith 
10439566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt));
104410c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
104510c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
104610c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
104710c654e6SJacob Faibussowitsch     amsopt->data        = vals;
1048e26ddf31SBarry Smith   }
104910c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set));
105010c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
105110c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
105210c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
105310c654e6SJacob Faibussowitsch 
105410c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0]));
105510c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i]));
105610c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
105753acd3b1SBarry Smith   }
10583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
105953acd3b1SBarry Smith }
106053acd3b1SBarry Smith 
1061d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set)
1062d71ae5a4SJacob Faibussowitsch {
106310c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
106453acd3b1SBarry Smith 
106553acd3b1SBarry Smith   PetscFunctionBegin;
10664f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10674f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
106810c654e6SJacob Faibussowitsch   PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax);
10694f572ea9SToby Isaac   if (*nmax) PetscAssertPointer(value, 5);
10704f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1071e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
107210c654e6SJacob Faibussowitsch     const PetscInt  nmaxv = *nmax;
107310c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
1074a297a907SKarl Rupp 
107510c654e6SJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt));
107610c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data));
107710c654e6SJacob Faibussowitsch     amsopt->arraylength = nmaxv;
10781ae3d29cSBarry Smith   }
107910c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set));
108010c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, "  -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man)));
10813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108253acd3b1SBarry Smith }
108353acd3b1SBarry Smith 
1084d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set)
1085d71ae5a4SJacob Faibussowitsch {
108610c654e6SJacob Faibussowitsch   const char *prefix = PetscOptionsObject->prefix;
1087e2446a98SMatthew Knepley 
1088e2446a98SMatthew Knepley   PetscFunctionBegin;
10894f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
10904f572ea9SToby Isaac   PetscAssertPointer(n, 6);
109110c654e6SJacob Faibussowitsch   PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n);
10924f572ea9SToby Isaac   if (*n) PetscAssertPointer(value, 5);
10934f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
1094e55864a3SBarry Smith   if (!PetscOptionsObject->count) {
109510c654e6SJacob Faibussowitsch     const PetscInt  nv = *n;
1096ace3abfcSBarry Smith     PetscBool      *vals;
109710c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
10981ae3d29cSBarry Smith 
10999566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt));
110010c654e6SJacob Faibussowitsch     PetscCall(PetscMalloc1(nv, &vals));
110110c654e6SJacob Faibussowitsch     for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i];
110210c654e6SJacob Faibussowitsch     amsopt->arraylength = nv;
110310c654e6SJacob Faibussowitsch     amsopt->data        = vals;
11041ae3d29cSBarry Smith   }
110510c654e6SJacob Faibussowitsch   PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set));
110610c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) {
110710c654e6SJacob Faibussowitsch     const PetscInt nv   = *n;
110810c654e6SJacob Faibussowitsch     const MPI_Comm comm = PetscOptionsObject->comm;
110910c654e6SJacob Faibussowitsch 
111010c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%d", Prefix(prefix), opt + 1, value[0]));
111110c654e6SJacob Faibussowitsch     for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i]));
111210c654e6SJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man)));
1113e2446a98SMatthew Knepley   }
11143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1115e2446a98SMatthew Knepley }
1116e2446a98SMatthew Knepley 
111788aa4217SBarry Smith /*MC
1118*648c30bcSBarry Smith   PetscOptionsViewer - Creates a viewer appropriate for the type indicated by the user
11198cc676e6SMatthew G Knepley 
112088aa4217SBarry Smith   Synopsis:
112110450e9eSJacob Faibussowitsch   #include <petscviewer.h>
11223a89f35bSSatish Balay   PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
112388aa4217SBarry Smith 
11247cdbe19fSJose E. Roman   Logically Collective on the communicator passed in `PetscOptionsBegin()`
11257cdbe19fSJose E. Roman 
11268cc676e6SMatthew G Knepley   Input Parameters:
11278cc676e6SMatthew G Knepley + opt  - option name
11288cc676e6SMatthew G Knepley . text - short string that describes the option
11298cc676e6SMatthew G Knepley - man  - manual page with additional information on option
11308cc676e6SMatthew G Knepley 
1131d8d19677SJose E. Roman   Output Parameters:
11328cc676e6SMatthew G Knepley + viewer - the viewer
11339314d9b7SBarry Smith . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed
1134811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
11358cc676e6SMatthew G Knepley 
11368cc676e6SMatthew G Knepley   Level: beginner
11378cc676e6SMatthew G Knepley 
113895452b02SPatrick Sanan   Notes:
1139811af0c4SBarry Smith   Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()`
11408cc676e6SMatthew G Knepley 
1141*648c30bcSBarry Smith   See `PetscOptionsCreateViewer()` for the format of the supplied viewer and its options
11428cc676e6SMatthew G Knepley 
1143*648c30bcSBarry Smith .seealso: `PetscOptionsCreateViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
1144db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
1145aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
1146db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1147c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1148db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1149db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
115088aa4217SBarry Smith M*/
1151d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set)
1152d71ae5a4SJacob Faibussowitsch {
115310c654e6SJacob Faibussowitsch   const MPI_Comm comm   = PetscOptionsObject->comm;
115410c654e6SJacob Faibussowitsch   const char    *prefix = PetscOptionsObject->prefix;
11558cc676e6SMatthew G Knepley 
11568cc676e6SMatthew G Knepley   PetscFunctionBegin;
11574f572ea9SToby Isaac   PetscAssertPointer(opt, 2);
11584f572ea9SToby Isaac   PetscAssertPointer(viewer, 5);
11594f572ea9SToby Isaac   if (format) PetscAssertPointer(format, 6);
11604f572ea9SToby Isaac   if (set) PetscAssertPointer(set, 7);
11611a1499c8SBarry Smith   if (!PetscOptionsObject->count) {
116210c654e6SJacob Faibussowitsch     PetscOptionItem amsopt;
116310c654e6SJacob Faibussowitsch 
11649566063dSJacob Faibussowitsch     PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt));
116564facd6cSBarry Smith     /* must use system malloc since SAWs may free this */
11669566063dSJacob Faibussowitsch     PetscCall(PetscStrdup("", (char **)&amsopt->data));
11678cc676e6SMatthew G Knepley   }
1168*648c30bcSBarry Smith   PetscCall(PetscOptionsCreateViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set));
116910c654e6SJacob Faibussowitsch   if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "  -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man)));
11703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11718cc676e6SMatthew G Knepley }
1172