xref: /petsc/src/sys/objects/options.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
173fca5a0SBarry Smith /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
20039db0dSBarry Smith #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for atoll() */
3e5ea902fSJed Brown 
4e5c89e4eSSatish Balay /*
53fc1eb6aSBarry Smith    These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
63fc1eb6aSBarry Smith    This provides the low-level interface, the high level interface is in aoptions.c
7e5c89e4eSSatish Balay 
83fc1eb6aSBarry Smith    Some routines use regular malloc and free because it cannot know  what malloc is requested with the
93fc1eb6aSBarry Smith    options database until it has already processed the input.
10e5c89e4eSSatish Balay */
11e5c89e4eSSatish Balay 
12af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I  "petscsys.h"   I*/
13665c2dedSJed Brown #include <petscviewer.h>
14ad1ac5ecSJed Brown #include <ctype.h>
15e5c89e4eSSatish Balay #if defined(PETSC_HAVE_MALLOC_H)
16e5c89e4eSSatish Balay #include <malloc.h>
17e5c89e4eSSatish Balay #endif
18ef279fd6SBarry Smith #if defined(PETSC_HAVE_STRINGS_H)
19ef279fd6SBarry Smith #include <strings.h> /* strcasecmp */
20ef279fd6SBarry Smith #endif
21e5c89e4eSSatish Balay 
222d747510SLisandro Dalcin #if defined(PETSC_HAVE_STRCASECMP)
232d747510SLisandro Dalcin #define PetscOptNameCmp(a, b) strcasecmp(a, b)
242d747510SLisandro Dalcin #elif defined(PETSC_HAVE_STRICMP)
252d747510SLisandro Dalcin #define PetscOptNameCmp(a, b) stricmp(a, b)
262d747510SLisandro Dalcin #else
272d747510SLisandro Dalcin #define PetscOptNameCmp(a, b) Error_strcasecmp_not_found
282d747510SLisandro Dalcin #endif
292d747510SLisandro Dalcin 
302d747510SLisandro Dalcin #include <petsc/private/hashtable.h>
312d747510SLisandro Dalcin 
322d747510SLisandro Dalcin /* This assumes ASCII encoding and ignores locale settings */
332d747510SLisandro Dalcin /* Using tolower() is about 2X slower in microbenchmarks   */
349371c9d4SSatish Balay static inline int PetscToLower(int c) {
352d747510SLisandro Dalcin   return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
362d747510SLisandro Dalcin }
372d747510SLisandro Dalcin 
382d747510SLisandro Dalcin /* Bob Jenkins's one at a time hash function (case-insensitive) */
399371c9d4SSatish Balay static inline unsigned int PetscOptHash(const char key[]) {
402d747510SLisandro Dalcin   unsigned int hash = 0;
412d747510SLisandro Dalcin   while (*key) {
422d747510SLisandro Dalcin     hash += PetscToLower(*key++);
432d747510SLisandro Dalcin     hash += hash << 10;
442d747510SLisandro Dalcin     hash ^= hash >> 6;
452d747510SLisandro Dalcin   }
462d747510SLisandro Dalcin   hash += hash << 3;
472d747510SLisandro Dalcin   hash ^= hash >> 11;
482d747510SLisandro Dalcin   hash += hash << 15;
492d747510SLisandro Dalcin   return hash;
502d747510SLisandro Dalcin }
512d747510SLisandro Dalcin 
529371c9d4SSatish Balay static inline int PetscOptEqual(const char a[], const char b[]) {
532d747510SLisandro Dalcin   return !PetscOptNameCmp(a, b);
542d747510SLisandro Dalcin }
552d747510SLisandro Dalcin 
562d747510SLisandro Dalcin KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
572d747510SLisandro Dalcin 
58e5c89e4eSSatish Balay /*
593fc1eb6aSBarry Smith     This table holds all the options set by the user. For simplicity, we use a static size database
60e5c89e4eSSatish Balay */
61c5c1f447SLisandro Dalcin #define MAXOPTNAME         PETSC_MAX_OPTION_NAME
62e5c89e4eSSatish Balay #define MAXOPTIONS         512
63e5c89e4eSSatish Balay #define MAXALIASES         25
6474e0666dSJed Brown #define MAXPREFIXES        25
652d747510SLisandro Dalcin #define MAXOPTIONSMONITORS 5
66e5c89e4eSSatish Balay 
674416b707SBarry Smith struct _n_PetscOptions {
683de2bfdfSBarry Smith   PetscOptions previous;
692d747510SLisandro Dalcin   int          N;                  /* number of options */
702d747510SLisandro Dalcin   char        *names[MAXOPTIONS];  /* option names */
712d747510SLisandro Dalcin   char        *values[MAXOPTIONS]; /* option values */
722d747510SLisandro Dalcin   PetscBool    used[MAXOPTIONS];   /* flag option use */
73c5b5d8d5SVaclav Hapla   PetscBool    precedentProcessed;
74081c24baSBoyana Norris 
752d747510SLisandro Dalcin   /* Hash table */
762d747510SLisandro Dalcin   khash_t(HO) * ht;
772d747510SLisandro Dalcin 
782d747510SLisandro Dalcin   /* Prefixes */
792d747510SLisandro Dalcin   int  prefixind;
802d747510SLisandro Dalcin   int  prefixstack[MAXPREFIXES];
812d747510SLisandro Dalcin   char prefix[MAXOPTNAME];
822d747510SLisandro Dalcin 
832d747510SLisandro Dalcin   /* Aliases */
842d747510SLisandro Dalcin   int   Naliases;             /* number or aliases */
852d747510SLisandro Dalcin   char *aliases1[MAXALIASES]; /* aliased */
862d747510SLisandro Dalcin   char *aliases2[MAXALIASES]; /* aliasee */
872d747510SLisandro Dalcin 
882d747510SLisandro Dalcin   /* Help */
892d747510SLisandro Dalcin   PetscBool help;       /* flag whether "-help" is in the database */
90d314f959SVaclav Hapla   PetscBool help_intro; /* flag whether "-help intro" is in the database */
912d747510SLisandro Dalcin 
922d747510SLisandro Dalcin   /* Monitors */
93c5b5d8d5SVaclav Hapla   PetscBool monitorFromOptions, monitorCancel;
94081c24baSBoyana Norris   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], void *); /* returns control to user after */
95c2efdce3SBarry Smith   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void **);                     /* */
96081c24baSBoyana Norris   void    *monitorcontext[MAXOPTIONSMONITORS];                                       /* to pass arbitrary user data into monitor */
97081c24baSBoyana Norris   PetscInt numbermonitors;                                                           /* to, for instance, detect options being set */
984416b707SBarry Smith };
99e5c89e4eSSatish Balay 
100b4205f0bSBarry Smith static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
1012d747510SLisandro Dalcin 
102c5b5d8d5SVaclav Hapla /* list of options which preceed others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
103660278c0SBarry Smith /* these options can only take boolean values, the code will crash if given a non-boolean value */
104660278c0SBarry Smith static const char *precedentOptions[] = {"-petsc_ci", "-options_monitor", "-options_monitor_cancel", "-help", "-skip_petscrc"};
1059371c9d4SSatish Balay enum PetscPrecedentOption {
1069371c9d4SSatish Balay   PO_CI_ENABLE,
1079371c9d4SSatish Balay   PO_OPTIONS_MONITOR,
1089371c9d4SSatish Balay   PO_OPTIONS_MONITOR_CANCEL,
1099371c9d4SSatish Balay   PO_HELP,
1109371c9d4SSatish Balay   PO_SKIP_PETSCRC,
1119371c9d4SSatish Balay   PO_NUM
1129371c9d4SSatish Balay };
113c5b5d8d5SVaclav Hapla 
114c5b5d8d5SVaclav Hapla static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions, const char[], const char[], int *);
115c5b5d8d5SVaclav Hapla 
116081c24baSBoyana Norris /*
117081c24baSBoyana Norris     Options events monitor
118081c24baSBoyana Norris */
1199371c9d4SSatish Balay static PetscErrorCode PetscOptionsMonitor(PetscOptions options, const char name[], const char value[]) {
120e5c89e4eSSatish Balay   PetscFunctionBegin;
121c5b5d8d5SVaclav Hapla   if (!value) value = "";
1229566063dSJacob Faibussowitsch   if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name, value, NULL));
1239566063dSJacob Faibussowitsch   for (PetscInt i = 0; i < options->numbermonitors; i++) PetscCall((*options->monitor[i])(name, value, options->monitorcontext[i]));
124e5c89e4eSSatish Balay   PetscFunctionReturn(0);
125e5c89e4eSSatish Balay }
126e5c89e4eSSatish Balay 
1272d747510SLisandro Dalcin /*@
1282d747510SLisandro Dalcin    PetscOptionsCreate - Creates an empty options database.
129e5c89e4eSSatish Balay 
1301c9f3c13SBarry Smith    Logically collective
1311c9f3c13SBarry Smith 
132e5c89e4eSSatish Balay    Output Parameter:
1332d747510SLisandro Dalcin .  options - Options database object
134e5c89e4eSSatish Balay 
135e5c89e4eSSatish Balay    Level: advanced
136e5c89e4eSSatish Balay 
1371c9f3c13SBarry Smith    Developer Note: We may want eventually to pass a MPI_Comm to determine the ownership of the object
1381c9f3c13SBarry Smith 
139db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
140e5c89e4eSSatish Balay @*/
1419371c9d4SSatish Balay PetscErrorCode PetscOptionsCreate(PetscOptions *options) {
14239a651e2SJacob Faibussowitsch   PetscFunctionBegin;
14339a651e2SJacob Faibussowitsch   PetscValidPointer(options, 1);
1442d747510SLisandro Dalcin   *options = (PetscOptions)calloc(1, sizeof(**options));
14539a651e2SJacob Faibussowitsch   PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
14639a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1472d747510SLisandro Dalcin }
1482d747510SLisandro Dalcin 
1492d747510SLisandro Dalcin /*@
1502d747510SLisandro Dalcin     PetscOptionsDestroy - Destroys an option database.
1512d747510SLisandro Dalcin 
1521c9f3c13SBarry Smith     Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
1531c9f3c13SBarry Smith 
1542d747510SLisandro Dalcin   Input Parameter:
1552d747510SLisandro Dalcin .  options - the PetscOptions object
1562d747510SLisandro Dalcin 
1573de2bfdfSBarry Smith    Level: advanced
1582d747510SLisandro Dalcin 
159db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
1602d747510SLisandro Dalcin @*/
1619371c9d4SSatish Balay PetscErrorCode PetscOptionsDestroy(PetscOptions *options) {
162362febeeSStefano Zampini   PetscFunctionBegin;
16339a651e2SJacob Faibussowitsch   if (!*options) PetscFunctionReturn(0);
1645f80ce2aSJacob Faibussowitsch   PetscCheck(!(*options)->previous, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "You are destroying an option that has been used with PetscOptionsPush() but does not have a corresponding PetscOptionsPop()");
1659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsClear(*options));
1662d747510SLisandro Dalcin   /* XXX what about monitors ? */
1672800570dSLisandro Dalcin   free(*options);
1682d747510SLisandro Dalcin   *options = NULL;
169e5c89e4eSSatish Balay   PetscFunctionReturn(0);
170e5c89e4eSSatish Balay }
171e5c89e4eSSatish Balay 
1722d747510SLisandro Dalcin /*
1732d747510SLisandro Dalcin     PetscOptionsCreateDefault - Creates the default global options database
1742d747510SLisandro Dalcin */
1759371c9d4SSatish Balay PetscErrorCode PetscOptionsCreateDefault(void) {
17639a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1779566063dSJacob Faibussowitsch   if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
17839a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1792d747510SLisandro Dalcin }
1802d747510SLisandro Dalcin 
181b4205f0bSBarry Smith /*@
182b4205f0bSBarry Smith       PetscOptionsPush - Push a new PetscOptions object as the default provider of options
1831c9f3c13SBarry Smith                          Allows using different parts of a code to use different options databases
184b4205f0bSBarry Smith 
185b4205f0bSBarry Smith   Logically Collective
186b4205f0bSBarry Smith 
187b4205f0bSBarry Smith   Input Parameter:
188b4205f0bSBarry Smith .   opt - the options obtained with PetscOptionsCreate()
189b4205f0bSBarry Smith 
190b4205f0bSBarry Smith   Notes:
191b4205f0bSBarry Smith   Use PetscOptionsPop() to return to the previous default options database
1921c9f3c13SBarry Smith 
1939666a313SBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
1941c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
1951c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1961c9f3c13SBarry Smith   on different ranks.
197b4205f0bSBarry Smith 
1983de2bfdfSBarry Smith    Level: advanced
1993de2bfdfSBarry Smith 
200db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
201b4205f0bSBarry Smith 
202b4205f0bSBarry Smith @*/
2039371c9d4SSatish Balay PetscErrorCode PetscOptionsPush(PetscOptions opt) {
204b4205f0bSBarry Smith   PetscFunctionBegin;
2059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsCreateDefault());
206b4205f0bSBarry Smith   opt->previous  = defaultoptions;
207b4205f0bSBarry Smith   defaultoptions = opt;
208b4205f0bSBarry Smith   PetscFunctionReturn(0);
209b4205f0bSBarry Smith }
210b4205f0bSBarry Smith 
211b4205f0bSBarry Smith /*@
212b4205f0bSBarry Smith       PetscOptionsPop - Pop the most recent PetscOptionsPush() to return to the previous default options
213b4205f0bSBarry Smith 
2141c9f3c13SBarry Smith       Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
215b4205f0bSBarry Smith 
216b4205f0bSBarry Smith   Notes:
217b4205f0bSBarry Smith   Use PetscOptionsPop() to return to the previous default options database
218b4205f0bSBarry Smith   Allows using different parts of a code to use different options databases
219b4205f0bSBarry Smith 
2203de2bfdfSBarry Smith    Level: advanced
2213de2bfdfSBarry Smith 
222db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
223b4205f0bSBarry Smith 
224b4205f0bSBarry Smith @*/
2259371c9d4SSatish Balay PetscErrorCode PetscOptionsPop(void) {
2263de2bfdfSBarry Smith   PetscOptions current = defaultoptions;
2273de2bfdfSBarry Smith 
228b4205f0bSBarry Smith   PetscFunctionBegin;
22928b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing default options");
23028b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions->previous, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscOptionsPop() called too many times");
231b4205f0bSBarry Smith   defaultoptions    = defaultoptions->previous;
2323de2bfdfSBarry Smith   current->previous = NULL;
233b4205f0bSBarry Smith   PetscFunctionReturn(0);
234b4205f0bSBarry Smith }
235b4205f0bSBarry Smith 
2362d747510SLisandro Dalcin /*
2372d747510SLisandro Dalcin     PetscOptionsDestroyDefault - Destroys the default global options database
2382d747510SLisandro Dalcin */
2399371c9d4SSatish Balay PetscErrorCode PetscOptionsDestroyDefault(void) {
24039a651e2SJacob Faibussowitsch   PetscFunctionBegin;
24139a651e2SJacob Faibussowitsch   if (!defaultoptions) PetscFunctionReturn(0);
2423de2bfdfSBarry Smith   /* Destroy any options that the user forgot to pop */
2433de2bfdfSBarry Smith   while (defaultoptions->previous) {
24439a651e2SJacob Faibussowitsch     PetscOptions tmp = defaultoptions;
24539a651e2SJacob Faibussowitsch 
2469566063dSJacob Faibussowitsch     PetscCall(PetscOptionsPop());
2479566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDestroy(&tmp));
2483de2bfdfSBarry Smith   }
2499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDestroy(&defaultoptions));
25039a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
251e5c89e4eSSatish Balay }
252e5c89e4eSSatish Balay 
25394ef8ddeSSatish Balay /*@C
2547cd08cecSJed Brown    PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
2553fc1eb6aSBarry Smith 
256447722d5SBarry Smith    Not collective
2571c9f3c13SBarry Smith 
2583fc1eb6aSBarry Smith    Input Parameter:
2592d747510SLisandro Dalcin .  key - string to check if valid
2603fc1eb6aSBarry Smith 
2613fc1eb6aSBarry Smith    Output Parameter:
2622d747510SLisandro Dalcin .  valid - PETSC_TRUE if a valid key
2633fc1eb6aSBarry Smith 
264f6680f47SSatish Balay    Level: intermediate
2653fc1eb6aSBarry Smith @*/
2669371c9d4SSatish Balay PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid) {
267f603b5e9SToby Isaac   char *ptr;
2687c5db45bSBarry Smith 
26996fc60bcSBarry Smith   PetscFunctionBegin;
2702d747510SLisandro Dalcin   if (key) PetscValidCharPointer(key, 1);
271dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(valid, 2);
2722d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2732d747510SLisandro Dalcin   if (!key) PetscFunctionReturn(0);
2742d747510SLisandro Dalcin   if (key[0] != '-') PetscFunctionReturn(0);
2752d747510SLisandro Dalcin   if (key[1] == '-') key++;
276c850d057SPierre Jolivet   if (!isalpha((int)key[1])) PetscFunctionReturn(0);
2772d747510SLisandro Dalcin   (void)strtod(key, &ptr);
278c850d057SPierre Jolivet   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(0);
2792d747510SLisandro Dalcin   *valid = PETSC_TRUE;
28096fc60bcSBarry Smith   PetscFunctionReturn(0);
28196fc60bcSBarry Smith }
28296fc60bcSBarry Smith 
283e5c89e4eSSatish Balay /*@C
284e5c89e4eSSatish Balay    PetscOptionsInsertString - Inserts options into the database from a string
285e5c89e4eSSatish Balay 
2861c9f3c13SBarry Smith    Logically Collective
287e5c89e4eSSatish Balay 
288d8d19677SJose E. Roman    Input Parameters:
289080f0011SToby Isaac +  options - options object
290080f0011SToby Isaac -  in_str - string that contains options separated by blanks
291e5c89e4eSSatish Balay 
292e5c89e4eSSatish Balay    Level: intermediate
293e5c89e4eSSatish Balay 
2949666a313SBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
2951c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
2961c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
2971c9f3c13SBarry Smith   on different ranks.
2981c9f3c13SBarry Smith 
299e5c89e4eSSatish Balay    Contributed by Boyana Norris
300e5c89e4eSSatish Balay 
301db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
302db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
303db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
304c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
305db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
306db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
307e5c89e4eSSatish Balay @*/
3089371c9d4SSatish Balay PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[]) {
309d06005cbSLisandro Dalcin   MPI_Comm   comm = PETSC_COMM_SELF;
310d06005cbSLisandro Dalcin   char      *first, *second;
3119c9d3cfdSBarry Smith   PetscToken token;
312e5c89e4eSSatish Balay 
313e5c89e4eSSatish Balay   PetscFunctionBegin;
3149566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(in_str, ' ', &token));
3159566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &first));
31696fc60bcSBarry Smith   while (first) {
317d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
3189566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
3199566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
3209566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
3219566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
3229566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
3239566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(first, &key));
324d06005cbSLisandro Dalcin     if (!key) {
3259566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
326d06005cbSLisandro Dalcin     } else if (isfile) {
3279566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3289566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, second, PETSC_TRUE));
3299566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
330d06005cbSLisandro Dalcin     } else if (isfileyaml) {
3319566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3329566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, second, PETSC_TRUE));
3339566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
334d06005cbSLisandro Dalcin     } else if (isstringyaml) {
3359566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3369566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options, second));
3379566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
338d06005cbSLisandro Dalcin     } else if (ispush) {
3399566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3409566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, second));
3419566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
3429db968c8SJed Brown     } else if (ispop) {
3439566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
3449566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
345d06005cbSLisandro Dalcin     } else {
3469566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3479566063dSJacob Faibussowitsch       PetscCall(PetscOptionsValidKey(second, &key));
34896fc60bcSBarry Smith       if (!key) {
3499566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, first, second));
3509566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &first));
35196fc60bcSBarry Smith       } else {
3529566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, first, NULL));
35396fc60bcSBarry Smith         first = second;
35496fc60bcSBarry Smith       }
355e5c89e4eSSatish Balay     }
356e5c89e4eSSatish Balay   }
3579566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
358e5c89e4eSSatish Balay   PetscFunctionReturn(0);
359e5c89e4eSSatish Balay }
360e5c89e4eSSatish Balay 
3613fc1eb6aSBarry Smith /*
3623fc1eb6aSBarry Smith     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
3633fc1eb6aSBarry Smith */
3649371c9d4SSatish Balay static char *Petscgetline(FILE *f) {
3655fa91da5SBarry Smith   size_t size = 0;
3665fa91da5SBarry Smith   size_t len  = 0;
3675fa91da5SBarry Smith   size_t last = 0;
3680298fd71SBarry Smith   char  *buf  = NULL;
3695fa91da5SBarry Smith 
37002c9f0b5SLisandro Dalcin   if (feof(f)) return NULL;
3715fa91da5SBarry Smith   do {
3725fa91da5SBarry Smith     size += 1024;                             /* BUFSIZ is defined as "the optimal read size for this platform" */
3736e0c8459SSatish Balay     buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
3745fa91da5SBarry Smith     /* Actually do the read. Note that fgets puts a terminal '\0' on the
3755fa91da5SBarry Smith     end of the string, so we make sure we overwrite this */
376e86f3e45SDave May     if (!fgets(buf + len, 1024, f)) buf[len] = 0;
3775fa91da5SBarry Smith     PetscStrlen(buf, &len);
3785fa91da5SBarry Smith     last = len - 1;
3795fa91da5SBarry Smith   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
38008ac41f7SSatish Balay   if (len) return buf;
3815fa91da5SBarry Smith   free(buf);
38202c9f0b5SLisandro Dalcin   return NULL;
3835fa91da5SBarry Smith }
3845fa91da5SBarry Smith 
3859371c9d4SSatish Balay static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml) {
386be10d61cSLisandro Dalcin   char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
387e5c89e4eSSatish Balay 
388be10d61cSLisandro Dalcin   PetscFunctionBegin;
389362febeeSStefano Zampini   *yaml = PETSC_FALSE;
3909566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
3919566063dSJacob Faibussowitsch   PetscCall(PetscFixFilename(fname, path));
3929566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(path, ":yaml", yaml));
393be10d61cSLisandro Dalcin   if (*yaml) {
3949566063dSJacob Faibussowitsch     PetscCall(PetscStrrchr(path, ':', &tail));
395be10d61cSLisandro Dalcin     tail[-1] = 0; /* remove ":yaml" suffix from path */
396be10d61cSLisandro Dalcin   }
3979566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
398a1d2f846SLisandro Dalcin   /* check for standard YAML and JSON filename extensions */
3999566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
4009566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
4019566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
402a1d2f846SLisandro Dalcin   if (!*yaml) { /* check file contents */
403a1d2f846SLisandro Dalcin     PetscMPIInt rank;
4049566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
405dd400576SPatrick Sanan     if (rank == 0) {
406a1d2f846SLisandro Dalcin       FILE *fh = fopen(filename, "r");
407a1d2f846SLisandro Dalcin       if (fh) {
408a1d2f846SLisandro Dalcin         char buf[6] = "";
409a1d2f846SLisandro Dalcin         if (fread(buf, 1, 6, fh) > 0) {
4109566063dSJacob Faibussowitsch           PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml));          /* check for '%YAML' tag */
4119566063dSJacob Faibussowitsch           if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
412a1d2f846SLisandro Dalcin         }
413a1d2f846SLisandro Dalcin         (void)fclose(fh);
414a1d2f846SLisandro Dalcin       }
415a1d2f846SLisandro Dalcin     }
4169566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(yaml, 1, MPIU_BOOL, 0, comm));
417a1d2f846SLisandro Dalcin   }
418be10d61cSLisandro Dalcin   PetscFunctionReturn(0);
419be10d61cSLisandro Dalcin }
420e5c89e4eSSatish Balay 
4219371c9d4SSatish Balay static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require) {
4228c0b561eSLisandro Dalcin   char       *string, *vstring = NULL, *astring = NULL, *packed = NULL;
4237fb43599SVaclav Hapla   char       *tokens[4];
42413e3f751SJed Brown   size_t      i, len, bytes;
425e5c89e4eSSatish Balay   FILE       *fd;
4267fb43599SVaclav Hapla   PetscToken  token = NULL;
427ed9cf6e9SBarry Smith   int         err;
428581bbe83SVaclav Hapla   char       *cmatch;
429581bbe83SVaclav Hapla   const char  cmt  = '#';
4309210b8eaSVaclav Hapla   PetscInt    line = 1;
4313a018368SJed Brown   PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
4329210b8eaSVaclav Hapla   PetscBool   isdir, alias = PETSC_FALSE, valid;
433e5c89e4eSSatish Balay 
434e5c89e4eSSatish Balay   PetscFunctionBegin;
4359566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tokens, sizeof(tokens)));
4369566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
437dd400576SPatrick Sanan   if (rank == 0) {
4388c0b561eSLisandro Dalcin     char fpath[PETSC_MAX_PATH_LEN];
4398c0b561eSLisandro Dalcin     char fname[PETSC_MAX_PATH_LEN];
44005c7dedfSBarry Smith 
4419566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
4429566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
4438c0b561eSLisandro Dalcin 
444e5c89e4eSSatish Balay     fd = fopen(fname, "r");
4459566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname, 'r', &isdir));
44608401ef6SPierre Jolivet     PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
447ad38b122SPatrick Sanan     if (fd && !isdir) {
4483a018368SJed Brown       PetscSegBuffer vseg, aseg;
4499566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4509566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4513a018368SJed Brown 
4529b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4539566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
454e24ecc5dSJed Brown 
4555fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4564704e885SBarry Smith         /* eliminate comments from each line */
4579566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
45890f79514SSatish Balay         if (cmatch) *cmatch = 0;
4599566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4605981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
461e5c89e4eSSatish Balay         for (i = 0; i < len; i++) {
4629371c9d4SSatish Balay           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') { string[i] = ' '; }
463e5c89e4eSSatish Balay         }
4649566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4659566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4667fb43599SVaclav Hapla         if (!tokens[0]) {
46702b0d46eSSatish Balay           goto destroy;
4687fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
4699566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
47090f79514SSatish Balay         }
471*48a46eb9SPierre Jolivet         for (i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
4727fb43599SVaclav Hapla         if (!tokens[0]) {
4732662f744SSatish Balay           goto destroy;
4747fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
4759566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
47628b400f6SJacob Faibussowitsch           PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": invalid option %s", fname, line, tokens[0]);
4779566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
4789566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
4799566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
480e24ecc5dSJed Brown           vstring[len] = ' ';
4817fb43599SVaclav Hapla           if (tokens[1]) {
4829566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
48328b400f6SJacob Faibussowitsch             PetscCheck(!valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": cannot specify two options per line (%s %s)", fname, line, tokens[0], tokens[1]);
4849566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
4859566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
486e24ecc5dSJed Brown             vstring[0] = '"';
4879566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
488e24ecc5dSJed Brown             vstring[len + 1] = '"';
489e24ecc5dSJed Brown             vstring[len + 2] = ' ';
49009192fe3SBarry Smith           }
49190f79514SSatish Balay         } else {
4929566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
4939210b8eaSVaclav Hapla           if (alias) {
4949566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
49528b400f6SJacob Faibussowitsch             PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": invalid aliased option %s", fname, line, tokens[1]);
49608401ef6SPierre Jolivet             PetscCheck(tokens[2], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": alias missing for %s", fname, line, tokens[1]);
4979566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
49828b400f6SJacob Faibussowitsch             PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": invalid aliasee option %s", fname, line, tokens[2]);
4999566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5009566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5019566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
502e24ecc5dSJed Brown             astring[len] = ' ';
503e24ecc5dSJed Brown 
5049566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5059566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5069566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
507e24ecc5dSJed Brown             astring[len] = ' ';
50898921bdaSJacob Faibussowitsch           } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown first token in options file %s line %" PetscInt_FMT ": %s", fname, line, tokens[0]);
5099210b8eaSVaclav Hapla         }
5109210b8eaSVaclav Hapla         {
5119210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
51228b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
513e5c89e4eSSatish Balay         }
51402b0d46eSSatish Balay       destroy:
5154b40f50bSBarry Smith         free(string);
5169566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5179210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5189210b8eaSVaclav Hapla         line++;
519e5c89e4eSSatish Balay       }
520ed9cf6e9SBarry Smith       err = fclose(fd);
52128b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5229566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5239566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5249566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
525e24ecc5dSJed Brown       astring[0] = 0;
5269566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5279566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5289566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
529e24ecc5dSJed Brown       vstring[0] = 0;
5309566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5319566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5329566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5339566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5349566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
53528b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5369b754dc9SBarry Smith   }
53705c7dedfSBarry Smith 
5383a018368SJed Brown   counts[0] = acnt;
5393a018368SJed Brown   counts[1] = cnt;
5404201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
54128b400f6SJacob Faibussowitsch   PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in first MPI collective call, could be caused by using an incorrect mpiexec or a network problem, it can be caused by having VPN running: see https://petsc.org/release/faq/");
5423a018368SJed Brown   acnt = counts[0];
5433a018368SJed Brown   cnt  = counts[1];
544*48a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5453a018368SJed Brown   if (acnt || cnt) {
5469566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5473a018368SJed Brown     astring = packed;
5483a018368SJed Brown     vstring = packed + acnt + 1;
5493a018368SJed Brown   }
5503a018368SJed Brown 
5519b754dc9SBarry Smith   if (acnt) {
5529566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5539566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5547fb43599SVaclav Hapla     while (tokens[0]) {
5559566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5569566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5579566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5589b754dc9SBarry Smith     }
5599566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5609b754dc9SBarry Smith   }
5619b754dc9SBarry Smith 
5621baa6e33SBarry Smith   if (cnt) PetscCall(PetscOptionsInsertString(options, vstring));
5639566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
564e5c89e4eSSatish Balay   PetscFunctionReturn(0);
565e5c89e4eSSatish Balay }
566e5c89e4eSSatish Balay 
567d06005cbSLisandro Dalcin /*@C
568be10d61cSLisandro Dalcin      PetscOptionsInsertFile - Inserts options into the database from a file.
569be10d61cSLisandro Dalcin 
570be10d61cSLisandro Dalcin      Collective
571be10d61cSLisandro Dalcin 
572d8d19677SJose E. Roman   Input Parameters:
573be10d61cSLisandro Dalcin +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
574be10d61cSLisandro Dalcin .   options - options database, use NULL for default global database
575be10d61cSLisandro Dalcin .   file - name of file,
576be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
577be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
578be10d61cSLisandro Dalcin -   require - if PETSC_TRUE will generate an error if the file does not exist
579be10d61cSLisandro Dalcin 
580be10d61cSLisandro Dalcin   Notes:
581be10d61cSLisandro Dalcin    Use  # for lines that are comments and which should be ignored.
582be10d61cSLisandro Dalcin    Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
583be10d61cSLisandro Dalcin    such as -log_view or -malloc_debug are processed properly. This routine only sets options into the options database that will be processed by later
584be10d61cSLisandro Dalcin    calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().
585be10d61cSLisandro Dalcin    The collectivity of this routine is complex; only the MPI processes in comm will
586be10d61cSLisandro Dalcin    have the affect of these options. If some processes that create objects call this routine and others do
587be10d61cSLisandro Dalcin    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
588be10d61cSLisandro Dalcin    on different ranks.
589be10d61cSLisandro Dalcin 
590be10d61cSLisandro Dalcin   Level: developer
591be10d61cSLisandro Dalcin 
592db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
593db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
594db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
595c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
596db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
597db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
598be10d61cSLisandro Dalcin 
599be10d61cSLisandro Dalcin @*/
6009371c9d4SSatish Balay PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require) {
601be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
602be10d61cSLisandro Dalcin   PetscBool yaml;
603be10d61cSLisandro Dalcin 
604be10d61cSLisandro Dalcin   PetscFunctionBegin;
6059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
606be10d61cSLisandro Dalcin   if (yaml) {
6079566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
608be10d61cSLisandro Dalcin   } else {
6099566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
610be10d61cSLisandro Dalcin   }
611be10d61cSLisandro Dalcin   PetscFunctionReturn(0);
612be10d61cSLisandro Dalcin }
613be10d61cSLisandro Dalcin 
614be10d61cSLisandro Dalcin /*@C
615d06005cbSLisandro Dalcin    PetscOptionsInsertArgs - Inserts options into the database from a array of strings
616d06005cbSLisandro Dalcin 
617d06005cbSLisandro Dalcin    Logically Collective
618d06005cbSLisandro Dalcin 
619d8d19677SJose E. Roman    Input Parameters:
620d06005cbSLisandro Dalcin +  options - options object
6216aad120cSJose E. Roman .  argc - the array length
622d06005cbSLisandro Dalcin -  args - the string array
623d06005cbSLisandro Dalcin 
624d06005cbSLisandro Dalcin    Level: intermediate
625d06005cbSLisandro Dalcin 
626db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
627d06005cbSLisandro Dalcin @*/
6289371c9d4SSatish Balay PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, char *args[]) {
629d06005cbSLisandro Dalcin   MPI_Comm     comm  = PETSC_COMM_WORLD;
630d06005cbSLisandro Dalcin   int          left  = PetscMax(argc, 0);
631d06005cbSLisandro Dalcin   char *const *eargs = args;
63285079163SJed Brown 
63385079163SJed Brown   PetscFunctionBegin;
63485079163SJed Brown   while (left) {
635d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6369566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6379566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6389566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6399566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6409566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6419566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
642093de6efSBarry Smith     if (!key) {
6439371c9d4SSatish Balay       eargs++;
6449371c9d4SSatish Balay       left--;
645d06005cbSLisandro Dalcin     } else if (isfile) {
646cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6479566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6489371c9d4SSatish Balay       eargs += 2;
6499371c9d4SSatish Balay       left -= 2;
650d06005cbSLisandro Dalcin     } else if (isfileyaml) {
651cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6529566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6539371c9d4SSatish Balay       eargs += 2;
6549371c9d4SSatish Balay       left -= 2;
655d06005cbSLisandro Dalcin     } else if (isstringyaml) {
656cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6579566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options, eargs[1]));
6589371c9d4SSatish Balay       eargs += 2;
6599371c9d4SSatish Balay       left -= 2;
660d06005cbSLisandro Dalcin     } else if (ispush) {
66108401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
662cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6639566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6649371c9d4SSatish Balay       eargs += 2;
6659371c9d4SSatish Balay       left -= 2;
666d06005cbSLisandro Dalcin     } else if (ispop) {
6679566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
6689371c9d4SSatish Balay       eargs++;
6699371c9d4SSatish Balay       left--;
6707935c3d8SJed Brown     } else {
6717935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
6729566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
67398b6bf53SJed Brown       if (left < 2 || nextiskey) {
6749566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, eargs[0], NULL));
6759371c9d4SSatish Balay         eargs++;
6769371c9d4SSatish Balay         left--;
67785079163SJed Brown       } else {
6789566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, eargs[0], eargs[1]));
6799371c9d4SSatish Balay         eargs += 2;
6809371c9d4SSatish Balay         left -= 2;
68185079163SJed Brown       }
68285079163SJed Brown     }
6837935c3d8SJed Brown   }
68485079163SJed Brown   PetscFunctionReturn(0);
68585079163SJed Brown }
68685079163SJed Brown 
6879371c9d4SSatish Balay static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], PetscBool set[], PetscBool *flg) {
688c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
689c5b5d8d5SVaclav Hapla   if (set[opt]) {
6909566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
691c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
692c5b5d8d5SVaclav Hapla   PetscFunctionReturn(0);
693c5b5d8d5SVaclav Hapla }
694c5b5d8d5SVaclav Hapla 
695660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
6969371c9d4SSatish Balay static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set) {
697c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
698c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
699c5b5d8d5SVaclav Hapla   size_t             o;
700c5b5d8d5SVaclav Hapla   int                a;
701c5b5d8d5SVaclav Hapla   const char       **val;
7020c99d500SBarry Smith   char             **cval;
703660278c0SBarry Smith   PetscBool         *set, unneeded;
704c5b5d8d5SVaclav Hapla 
705c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7060c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7070c99d500SBarry Smith   val = (const char **)cval;
708c5b5d8d5SVaclav Hapla 
709c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
710*48a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
711c5b5d8d5SVaclav Hapla 
712a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
713c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
714c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
715c5b5d8d5SVaclav Hapla 
7169566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
717c5b5d8d5SVaclav Hapla     if (!valid) continue;
718c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7199566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
720c5b5d8d5SVaclav Hapla       if (eq) {
721c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
722c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
723c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
724c5b5d8d5SVaclav Hapla         break;
725c5b5d8d5SVaclav Hapla       }
726c5b5d8d5SVaclav Hapla     }
727c5b5d8d5SVaclav Hapla   }
728c5b5d8d5SVaclav Hapla 
729c5b5d8d5SVaclav Hapla   /* Process flags */
7309566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
731d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7329566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
733660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
734660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
735660278c0SBarry Smith   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a));
7369566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7379566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
739c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
740c5b5d8d5SVaclav Hapla 
741c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
742660278c0SBarry Smith   for (o = 1; o < n; o++) {
743c5b5d8d5SVaclav Hapla     if (set[o]) {
7449566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a));
745d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
746c5b5d8d5SVaclav Hapla     }
747c5b5d8d5SVaclav Hapla   }
7480c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
749c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
750c5b5d8d5SVaclav Hapla   PetscFunctionReturn(0);
751c5b5d8d5SVaclav Hapla }
752c5b5d8d5SVaclav Hapla 
7539371c9d4SSatish Balay static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg) {
75439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
75539a651e2SJacob Faibussowitsch   PetscValidBoolPointer(flg, 3);
756c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
757c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
75839a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
759c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
760c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7619566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
762c5b5d8d5SVaclav Hapla         if (*flg) break;
763c5b5d8d5SVaclav Hapla       }
764c5b5d8d5SVaclav Hapla     }
765c5b5d8d5SVaclav Hapla   }
76639a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
767c5b5d8d5SVaclav Hapla }
76885079163SJed Brown 
769e5c89e4eSSatish Balay /*@C
770e5c89e4eSSatish Balay    PetscOptionsInsert - Inserts into the options database from the command line,
771e5c89e4eSSatish Balay                         the environmental variable and a file.
772e5c89e4eSSatish Balay 
7731c9f3c13SBarry Smith    Collective on PETSC_COMM_WORLD
7741c9f3c13SBarry Smith 
775e5c89e4eSSatish Balay    Input Parameters:
776c5929fdfSBarry Smith +  options - options database or NULL for the default global database
777c5929fdfSBarry Smith .  argc - count of number of command line arguments
778e5c89e4eSSatish Balay .  args - the command line arguments
779be10d61cSLisandro Dalcin -  file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
780be10d61cSLisandro Dalcin           Use NULL or empty string to not check for code specific file.
781be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
782c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
783e5c89e4eSSatish Balay 
784e5c89e4eSSatish Balay    Note:
785e5c89e4eSSatish Balay    Since PetscOptionsInsert() is automatically called by PetscInitialize(),
786e5c89e4eSSatish Balay    the user does not typically need to call this routine. PetscOptionsInsert()
787e5c89e4eSSatish Balay    can be called several times, adding additional entries into the database.
788e5c89e4eSSatish Balay 
789081c24baSBoyana Norris    Options Database Keys:
790d06005cbSLisandro Dalcin +   -options_file <filename> - read options from a file
791d06005cbSLisandro Dalcin -   -options_file_yaml <filename> - read options from a YAML file
792c5b5d8d5SVaclav Hapla 
793c5b5d8d5SVaclav Hapla    See PetscInitialize() for options related to option database monitoring.
794081c24baSBoyana Norris 
795e5c89e4eSSatish Balay    Level: advanced
796e5c89e4eSSatish Balay 
797db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
798db781477SPatrick Sanan           `PetscInitialize()`
799e5c89e4eSSatish Balay @*/
8009371c9d4SSatish Balay PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[]) {
801d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
802e5c89e4eSSatish Balay   PetscMPIInt rank;
803c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
804c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
805e5c89e4eSSatish Balay 
806e5c89e4eSSatish Balay   PetscFunctionBegin;
80708401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8089566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
809e5c89e4eSSatish Balay 
810c5b5d8d5SVaclav Hapla   if (!options) {
8119566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
812c5b5d8d5SVaclav Hapla     options = defaultoptions;
813c5b5d8d5SVaclav Hapla   }
814c5b5d8d5SVaclav Hapla   if (hasArgs) {
815c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8169566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
817660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
818c5b5d8d5SVaclav Hapla   }
8194b09e917SBarry Smith   if (file && file[0]) {
8209566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
821c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8229566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
823321366bcSBarry Smith   }
824c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
825be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8269566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8279566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
8289566063dSJacob Faibussowitsch     if (filename[0]) PetscCall(PetscStrcat(filename, "/.petscrc"));
8299566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8309566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8319566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
832e5c89e4eSSatish Balay   }
833e5c89e4eSSatish Balay 
8342d747510SLisandro Dalcin   /* insert environment options */
835e5c89e4eSSatish Balay   {
8362d747510SLisandro Dalcin     char  *eoptions = NULL;
837e5c89e4eSSatish Balay     size_t len      = 0;
838dd400576SPatrick Sanan     if (rank == 0) {
839e5c89e4eSSatish Balay       eoptions = (char *)getenv("PETSC_OPTIONS");
8409566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
841e5c89e4eSSatish Balay     }
8429566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
843e5c89e4eSSatish Balay     if (len) {
8449566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8459566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
84696fc60bcSBarry Smith       if (rank) eoptions[len] = 0;
8479566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertString(options, eoptions));
8489566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
849e5c89e4eSSatish Balay     }
850e5c89e4eSSatish Balay   }
851e5c89e4eSSatish Balay 
852d06005cbSLisandro Dalcin   /* insert YAML environment options */
85356a31166SBarry Smith   {
8549fc438c3SToby Isaac     char  *eoptions = NULL;
8559fc438c3SToby Isaac     size_t len      = 0;
856dd400576SPatrick Sanan     if (rank == 0) {
8579fc438c3SToby Isaac       eoptions = (char *)getenv("PETSC_OPTIONS_YAML");
8589566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
8599fc438c3SToby Isaac     }
8609566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8619fc438c3SToby Isaac     if (len) {
8629566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8639566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
8649fc438c3SToby Isaac       if (rank) eoptions[len] = 0;
8659566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options, eoptions));
8669566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
8679fc438c3SToby Isaac     }
8689fc438c3SToby Isaac   }
8693bcbd388SSean Farley 
870c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
8719566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, *args + 1));
872660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
873e5c89e4eSSatish Balay   PetscFunctionReturn(0);
874e5c89e4eSSatish Balay }
875e5c89e4eSSatish Balay 
876660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
877660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
8789371c9d4SSatish Balay static const char *PetscCIOptions[] = {
8799371c9d4SSatish Balay   "malloc_debug",
880660278c0SBarry Smith   "malloc_dump",
881660278c0SBarry Smith   "malloc_test",
882660278c0SBarry Smith   "nox",
883660278c0SBarry Smith   "nox_warning",
884660278c0SBarry Smith   "display",
885660278c0SBarry Smith   "saws_port_auto_select",
886660278c0SBarry Smith   "saws_port_auto_select_silent",
887660278c0SBarry Smith   "vecscatter_mpi1",
888660278c0SBarry Smith   "check_pointer_intensity",
889660278c0SBarry Smith   "cuda_initialize",
890660278c0SBarry Smith   "error_output_stdout",
891660278c0SBarry Smith   "use_gpu_aware_mpi",
892660278c0SBarry Smith   "checkfunctionlist",
893660278c0SBarry Smith   "petsc_ci",
894660278c0SBarry Smith   "petsc_ci_portable_error_output",
895660278c0SBarry Smith };
896660278c0SBarry Smith 
8979371c9d4SSatish Balay static PetscBool PetscCIOption(const char *name) {
898660278c0SBarry Smith   PetscInt  idx;
899660278c0SBarry Smith   PetscBool found;
900660278c0SBarry Smith 
901660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
902660278c0SBarry Smith   PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found);
903660278c0SBarry Smith   return found;
904660278c0SBarry Smith }
905660278c0SBarry Smith 
906e5c89e4eSSatish Balay /*@C
90788c29154SBarry Smith    PetscOptionsView - Prints the options that have been loaded. This is
908e5c89e4eSSatish Balay    useful for debugging purposes.
909e5c89e4eSSatish Balay 
910c139c21fSBarry Smith    Logically Collective on PetscViewer
911e5c89e4eSSatish Balay 
912d8d19677SJose E. Roman    Input Parameters:
913a2b725a8SWilliam Gropp +  options - options database, use NULL for default global database
914a2b725a8SWilliam Gropp -  viewer - must be an PETSCVIEWERASCII viewer
915e5c89e4eSSatish Balay 
916e5c89e4eSSatish Balay    Options Database Key:
91726a7e8d4SBarry Smith .  -options_view - Activates PetscOptionsView() within PetscFinalize()
918e5c89e4eSSatish Balay 
9199666a313SBarry Smith    Notes:
9209666a313SBarry Smith    Only the rank zero process of MPI_Comm used to create view prints the option values. Other processes
9211c9f3c13SBarry Smith    may have different values but they are not printed.
9221c9f3c13SBarry Smith 
923e5c89e4eSSatish Balay    Level: advanced
924e5c89e4eSSatish Balay 
925db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
926e5c89e4eSSatish Balay @*/
9279371c9d4SSatish Balay PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer) {
928660278c0SBarry Smith   PetscInt  i, N = 0;
92988c29154SBarry Smith   PetscBool isascii;
930e5c89e4eSSatish Balay 
931e5c89e4eSSatish Balay   PetscFunctionBegin;
9322d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
933c5929fdfSBarry Smith   options = options ? options : defaultoptions;
93488c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9359566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
93628b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
93788c29154SBarry Smith 
938660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
939660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
940660278c0SBarry Smith     N++;
941660278c0SBarry Smith   }
942660278c0SBarry Smith 
943660278c0SBarry Smith   if (!N) {
9449566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9452d747510SLisandro Dalcin     PetscFunctionReturn(0);
94630694fe9SBarry Smith   }
9472d747510SLisandro Dalcin 
9489566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
949e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
950660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
951e5c89e4eSSatish Balay     if (options->values[i]) {
9529566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s\n", options->names[i], options->values[i]));
953e5c89e4eSSatish Balay     } else {
9549566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s\n", options->names[i]));
955e5c89e4eSSatish Balay     }
956e5c89e4eSSatish Balay   }
9579566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
958e5c89e4eSSatish Balay   PetscFunctionReturn(0);
959e5c89e4eSSatish Balay }
960e5c89e4eSSatish Balay 
961e11779c2SBarry Smith /*
962e11779c2SBarry Smith    Called by error handlers to print options used in run
963e11779c2SBarry Smith */
9649371c9d4SSatish Balay PetscErrorCode PetscOptionsLeftError(void) {
965f4bc716fSBarry Smith   PetscInt i, nopt = 0;
966f4bc716fSBarry Smith 
967f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
968f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
969f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
970f4bc716fSBarry Smith       nopt++;
971f4bc716fSBarry Smith     }
972f4bc716fSBarry Smith   }
973f4bc716fSBarry Smith   if (nopt) {
974f4bc716fSBarry Smith     (*PetscErrorPrintf)("WARNING! There are option(s) set that were not used! Could be the program crashed before they were used or a spelling mistake, etc!\n");
975f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
976f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
977f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
978f4bc716fSBarry Smith         if (defaultoptions->values[i]) (*PetscErrorPrintf)("Option left: name:-%s value: %s\n", defaultoptions->names[i], defaultoptions->values[i]);
979f4bc716fSBarry Smith         else (*PetscErrorPrintf)("Option left: name:-%s (no value)\n", defaultoptions->names[i]);
980f4bc716fSBarry Smith       }
981f4bc716fSBarry Smith     }
982f4bc716fSBarry Smith   }
983f4bc716fSBarry Smith   return 0;
984f4bc716fSBarry Smith }
985f4bc716fSBarry Smith 
9869371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void) {
987660278c0SBarry Smith   PetscInt     i, N = 0;
9884416b707SBarry Smith   PetscOptions options = defaultoptions;
989e11779c2SBarry Smith 
990660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
991660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
992660278c0SBarry Smith     N++;
993660278c0SBarry Smith   }
994660278c0SBarry Smith 
995660278c0SBarry Smith   if (N) {
996e11779c2SBarry Smith     (*PetscErrorPrintf)("PETSc Option Table entries:\n");
997e11779c2SBarry Smith   } else {
998e11779c2SBarry Smith     (*PetscErrorPrintf)("No PETSc Option Table entries\n");
999e11779c2SBarry Smith   }
1000e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1001660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1002e11779c2SBarry Smith     if (options->values[i]) {
1003e11779c2SBarry Smith       (*PetscErrorPrintf)("-%s %s\n", options->names[i], options->values[i]);
1004e11779c2SBarry Smith     } else {
1005e11779c2SBarry Smith       (*PetscErrorPrintf)("-%s\n", options->names[i]);
1006e11779c2SBarry Smith     }
1007e11779c2SBarry Smith   }
1008f4bc716fSBarry Smith   return 0;
1009e11779c2SBarry Smith }
1010e11779c2SBarry Smith 
1011e5c89e4eSSatish Balay /*@C
101274e0666dSJed Brown    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
101374e0666dSJed Brown 
10141c9f3c13SBarry Smith    Logically Collective
101574e0666dSJed Brown 
1016d8d19677SJose E. Roman    Input Parameters:
1017c5929fdfSBarry Smith +  options - options database, or NULL for the default global database
1018c5929fdfSBarry Smith -  prefix - The string to append to the existing prefix
10199db968c8SJed Brown 
10209db968c8SJed Brown    Options Database Keys:
10219db968c8SJed Brown +   -prefix_push <some_prefix_> - push the given prefix
10229db968c8SJed Brown -   -prefix_pop - pop the last prefix
10239db968c8SJed Brown 
10249db968c8SJed Brown    Notes:
10259db968c8SJed Brown    It is common to use this in conjunction with -options_file as in
10269db968c8SJed Brown 
10279db968c8SJed Brown $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10289db968c8SJed Brown 
10299db968c8SJed Brown    where the files no longer require all options to be prefixed with -system2_.
103074e0666dSJed Brown 
10319666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
10321c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
10331c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10341c9f3c13SBarry Smith    on different ranks.
10351c9f3c13SBarry Smith 
103674e0666dSJed Brown Level: advanced
103774e0666dSJed Brown 
1038db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
103974e0666dSJed Brown @*/
10409371c9d4SSatish Balay PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[]) {
104174e0666dSJed Brown   size_t    n;
104274e0666dSJed Brown   PetscInt  start;
10432d747510SLisandro Dalcin   char      key[MAXOPTNAME + 1];
10442d747510SLisandro Dalcin   PetscBool valid;
104574e0666dSJed Brown 
104674e0666dSJed Brown   PetscFunctionBegin;
1047064a246eSJacob Faibussowitsch   PetscValidCharPointer(prefix, 2);
1048c5929fdfSBarry Smith   options = options ? options : defaultoptions;
104908401ef6SPierre Jolivet   PetscCheck(options->prefixind < MAXPREFIXES, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum depth of prefix stack %d exceeded, recompile \n src/sys/objects/options.c with larger value for MAXPREFIXES", MAXPREFIXES);
10502d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10519566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10538bf569ecSLisandro Dalcin   if (!valid && options->prefixind > 0 && isdigit((int)prefix[0])) valid = PETSC_TRUE; /* If the prefix stack is not empty, make numbers a valid prefix */
105428b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_USER, "Given prefix \"%s\" not valid (the first character must be a letter%s, do not include leading '-')", prefix, options->prefixind ? " or digit" : "");
105574e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10569566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
105708401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10589566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
105974e0666dSJed Brown   options->prefixstack[options->prefixind++] = start + n;
106074e0666dSJed Brown   PetscFunctionReturn(0);
106174e0666dSJed Brown }
106274e0666dSJed Brown 
1063c5929fdfSBarry Smith /*@C
106474e0666dSJed Brown    PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details
106574e0666dSJed Brown 
10661c9f3c13SBarry Smith    Logically Collective on the MPI_Comm that called PetscOptionsPrefixPush()
106774e0666dSJed Brown 
1068c5929fdfSBarry Smith   Input Parameters:
1069c5929fdfSBarry Smith .  options - options database, or NULL for the default global database
1070c5929fdfSBarry Smith 
107174e0666dSJed Brown    Level: advanced
107274e0666dSJed Brown 
1073db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
107474e0666dSJed Brown @*/
10759371c9d4SSatish Balay PetscErrorCode PetscOptionsPrefixPop(PetscOptions options) {
107674e0666dSJed Brown   PetscInt offset;
107774e0666dSJed Brown 
107874e0666dSJed Brown   PetscFunctionBegin;
1079c5929fdfSBarry Smith   options = options ? options : defaultoptions;
108008401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
108174e0666dSJed Brown   options->prefixind--;
108274e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
108374e0666dSJed Brown   options->prefix[offset] = 0;
108474e0666dSJed Brown   PetscFunctionReturn(0);
108574e0666dSJed Brown }
108674e0666dSJed Brown 
1087a542b6e8SBarry Smith /*@C
1088a542b6e8SBarry Smith     PetscOptionsClear - Removes all options form the database leaving it empty.
1089a542b6e8SBarry Smith 
10901c9f3c13SBarry Smith     Logically Collective
10911c9f3c13SBarry Smith 
1092c5929fdfSBarry Smith   Input Parameters:
1093c5929fdfSBarry Smith .  options - options database, use NULL for the default global database
1094c5929fdfSBarry Smith 
10959666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
10961c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
10971c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10981c9f3c13SBarry Smith    on different ranks.
10991c9f3c13SBarry Smith 
1100a542b6e8SBarry Smith    Level: developer
1101a542b6e8SBarry Smith 
1102db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1103a542b6e8SBarry Smith @*/
11049371c9d4SSatish Balay PetscErrorCode PetscOptionsClear(PetscOptions options) {
1105a542b6e8SBarry Smith   PetscInt i;
1106a542b6e8SBarry Smith 
110739a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1108c5929fdfSBarry Smith   options = options ? options : defaultoptions;
110939a651e2SJacob Faibussowitsch   if (!options) PetscFunctionReturn(0);
11102d747510SLisandro Dalcin 
1111a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1112a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1113a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1114a542b6e8SBarry Smith   }
11152d747510SLisandro Dalcin   options->N = 0;
11162d747510SLisandro Dalcin 
1117a542b6e8SBarry Smith   for (i = 0; i < options->Naliases; i++) {
1118a542b6e8SBarry Smith     free(options->aliases1[i]);
1119a542b6e8SBarry Smith     free(options->aliases2[i]);
1120a542b6e8SBarry Smith   }
1121a542b6e8SBarry Smith   options->Naliases = 0;
1122a542b6e8SBarry Smith 
11232d747510SLisandro Dalcin   /* destroy hash table */
11242d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11252d747510SLisandro Dalcin   options->ht = NULL;
11260eb63584SBarry Smith 
11272d747510SLisandro Dalcin   options->prefixind = 0;
11282d747510SLisandro Dalcin   options->prefix[0] = 0;
11292d747510SLisandro Dalcin   options->help      = PETSC_FALSE;
113039a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
11314416b707SBarry Smith }
11324416b707SBarry Smith 
11332d747510SLisandro Dalcin /*@C
11342d747510SLisandro Dalcin    PetscOptionsSetAlias - Makes a key and alias for another key
11352d747510SLisandro Dalcin 
11361c9f3c13SBarry Smith    Logically Collective
11372d747510SLisandro Dalcin 
11382d747510SLisandro Dalcin    Input Parameters:
11392d747510SLisandro Dalcin +  options - options database, or NULL for default global database
11402d747510SLisandro Dalcin .  newname - the alias
11412d747510SLisandro Dalcin -  oldname - the name that alias will refer to
11422d747510SLisandro Dalcin 
11432d747510SLisandro Dalcin    Level: advanced
11442d747510SLisandro Dalcin 
11459666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
11461c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
11471c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11481c9f3c13SBarry Smith    on different ranks.
11491c9f3c13SBarry Smith 
1150c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1151c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1152db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1153c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1154db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1155db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
11562d747510SLisandro Dalcin @*/
11579371c9d4SSatish Balay PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[]) {
11582d747510SLisandro Dalcin   PetscInt  n;
11592d747510SLisandro Dalcin   size_t    len;
11609210b8eaSVaclav Hapla   PetscBool valid;
11612d747510SLisandro Dalcin 
11622d747510SLisandro Dalcin   PetscFunctionBegin;
11632d747510SLisandro Dalcin   PetscValidCharPointer(newname, 2);
11642d747510SLisandro Dalcin   PetscValidCharPointer(oldname, 3);
11652d747510SLisandro Dalcin   options = options ? options : defaultoptions;
11669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
116728b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
11689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
116928b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
11702d747510SLisandro Dalcin 
11712d747510SLisandro Dalcin   n = options->Naliases;
117208401ef6SPierre Jolivet   PetscCheck(n < MAXALIASES, PETSC_COMM_SELF, PETSC_ERR_MEM, "You have defined to many PETSc options aliases, limit %d recompile \n  src/sys/objects/options.c with larger value for MAXALIASES", MAXALIASES);
11732d747510SLisandro Dalcin 
11749371c9d4SSatish Balay   newname++;
11759371c9d4SSatish Balay   oldname++;
11769566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
11772d747510SLisandro Dalcin   options->aliases1[n] = (char *)malloc((len + 1) * sizeof(char));
11789566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(options->aliases1[n], newname));
11799566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
11802d747510SLisandro Dalcin   options->aliases2[n] = (char *)malloc((len + 1) * sizeof(char));
11819566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(options->aliases2[n], oldname));
11822d747510SLisandro Dalcin   options->Naliases++;
11832d747510SLisandro Dalcin   PetscFunctionReturn(0);
11842d747510SLisandro Dalcin }
11854416b707SBarry Smith 
1186e5c89e4eSSatish Balay /*@C
1187e5c89e4eSSatish Balay    PetscOptionsSetValue - Sets an option name-value pair in the options
1188e5c89e4eSSatish Balay    database, overriding whatever is already present.
1189e5c89e4eSSatish Balay 
11901c9f3c13SBarry Smith    Logically Collective
1191e5c89e4eSSatish Balay 
1192e5c89e4eSSatish Balay    Input Parameters:
1193c5929fdfSBarry Smith +  options - options database, use NULL for the default global database
1194c5929fdfSBarry Smith .  name - name of option, this SHOULD have the - prepended
11952d747510SLisandro Dalcin -  value - the option value (not used for all options, so can be NULL)
1196e5c89e4eSSatish Balay 
1197e5c89e4eSSatish Balay    Level: intermediate
1198e5c89e4eSSatish Balay 
1199e5c89e4eSSatish Balay    Note:
1200d49172ceSBarry Smith    This function can be called BEFORE PetscInitialize()
1201d49172ceSBarry Smith 
12029666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
12031c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
12041c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12051c9f3c13SBarry Smith    on different ranks.
12061c9f3c13SBarry Smith 
12072d747510SLisandro Dalcin    Developers Note: Uses malloc() directly because PETSc may not be initialized yet.
1208b0250c70SBarry Smith 
1209db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1210e5c89e4eSSatish Balay @*/
12119371c9d4SSatish Balay PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[]) {
121239a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL));
121439a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1215c5b5d8d5SVaclav Hapla }
1216c5b5d8d5SVaclav Hapla 
12179371c9d4SSatish Balay static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos) {
1218e5c89e4eSSatish Balay   size_t    len;
12192d747510SLisandro Dalcin   int       N, n, i;
1220e5c89e4eSSatish Balay   char    **names;
12212d747510SLisandro Dalcin   char      fullname[MAXOPTNAME] = "";
1222c5b5d8d5SVaclav Hapla   PetscBool flg;
1223e5c89e4eSSatish Balay 
122439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12257272c0d2SVaclav Hapla   if (!options) {
12269566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12277272c0d2SVaclav Hapla     options = defaultoptions;
1228c5929fdfSBarry Smith   }
122939a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
12302d747510SLisandro Dalcin 
12319566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
123239a651e2SJacob Faibussowitsch   if (flg) PetscFunctionReturn(0);
1233e5c89e4eSSatish Balay 
12342d747510SLisandro Dalcin   name++; /* skip starting dash */
12352d747510SLisandro Dalcin 
123674e0666dSJed Brown   if (options->prefixind > 0) {
1237d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
12382d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
123989ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
12402d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
124174e0666dSJed Brown     name                           = fullname;
124274e0666dSJed Brown   }
124374e0666dSJed Brown 
124474e0666dSJed Brown   /* check against aliases */
1245e5c89e4eSSatish Balay   N = options->Naliases;
1246e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
12472d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
12489371c9d4SSatish Balay     if (!result) {
12499371c9d4SSatish Balay       name = options->aliases2[i];
12509371c9d4SSatish Balay       break;
12519371c9d4SSatish Balay     }
1252e5c89e4eSSatish Balay   }
1253e5c89e4eSSatish Balay 
12542d747510SLisandro Dalcin   /* slow search */
12552d747510SLisandro Dalcin   N = n = options->N;
1256e5c89e4eSSatish Balay   names = options->names;
1257e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
12582d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
12592d747510SLisandro Dalcin     if (!result) {
12609371c9d4SSatish Balay       n = i;
12619371c9d4SSatish Balay       goto setvalue;
12622d747510SLisandro Dalcin     } else if (result > 0) {
12639371c9d4SSatish Balay       n = i;
12649371c9d4SSatish Balay       break;
1265e5c89e4eSSatish Balay     }
1266e5c89e4eSSatish Balay   }
126739a651e2SJacob Faibussowitsch   PetscCheck(N < MAXOPTIONS, PETSC_COMM_SELF, PETSC_ERR_MEM, "Number of options %d < max number of options %d, can not allocate enough space", N, MAXOPTIONS);
126839a651e2SJacob Faibussowitsch 
12692d747510SLisandro Dalcin   /* shift remaining values up 1 */
1270e5c89e4eSSatish Balay   for (i = N; i > n; i--) {
12715e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1272e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1273e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
1274e5c89e4eSSatish Balay   }
12752d747510SLisandro Dalcin   options->names[n]  = NULL;
12762d747510SLisandro Dalcin   options->values[n] = NULL;
12772d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
12782d747510SLisandro Dalcin   options->N++;
12792d747510SLisandro Dalcin 
12802d747510SLisandro Dalcin   /* destroy hash table */
12812d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
12822d747510SLisandro Dalcin   options->ht = NULL;
12832d747510SLisandro Dalcin 
12842d747510SLisandro Dalcin   /* set new name */
128570d8d27cSBarry Smith   len               = strlen(name);
12865e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
128739a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1288d49172ceSBarry Smith   strcpy(options->names[n], name);
12892d747510SLisandro Dalcin 
12902d747510SLisandro Dalcin setvalue:
12912d747510SLisandro Dalcin   /* set new value */
12922d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1293d49172ceSBarry Smith   len = value ? strlen(value) : 0;
12945e8c5e88SLisandro Dalcin   if (len) {
1295e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1296d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1297d49172ceSBarry Smith     strcpy(options->values[n], value);
12982d747510SLisandro Dalcin   } else {
12992d747510SLisandro Dalcin     options->values[n] = NULL;
13002d747510SLisandro Dalcin   }
13012d747510SLisandro Dalcin 
130291ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
130391ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
130491ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1305d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
130691ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
130791ad3481SVaclav Hapla   }
130891ad3481SVaclav Hapla 
13099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsMonitor(options, name, value));
1310c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
131139a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1312e5c89e4eSSatish Balay }
1313e5c89e4eSSatish Balay 
1314e5c89e4eSSatish Balay /*@C
1315e5c89e4eSSatish Balay    PetscOptionsClearValue - Clears an option name-value pair in the options
1316e5c89e4eSSatish Balay    database, overriding whatever is already present.
1317e5c89e4eSSatish Balay 
13181c9f3c13SBarry Smith    Logically Collective
1319e5c89e4eSSatish Balay 
1320d8d19677SJose E. Roman    Input Parameters:
1321c5929fdfSBarry Smith +  options - options database, use NULL for the default global database
1322a2b725a8SWilliam Gropp -  name - name of option, this SHOULD have the - prepended
1323e5c89e4eSSatish Balay 
1324e5c89e4eSSatish Balay    Level: intermediate
1325e5c89e4eSSatish Balay 
13269666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
13271c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
13281c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
13291c9f3c13SBarry Smith    on different ranks.
13301c9f3c13SBarry Smith 
1331db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1332e5c89e4eSSatish Balay @*/
13339371c9d4SSatish Balay PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[]) {
13342d747510SLisandro Dalcin   int    N, n, i;
13352d747510SLisandro Dalcin   char **names;
1336e5c89e4eSSatish Balay 
1337e5c89e4eSSatish Balay   PetscFunctionBegin;
1338c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1339cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1340c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
13412d747510SLisandro Dalcin 
13422d747510SLisandro Dalcin   name++; /* skip starting dash */
13432d747510SLisandro Dalcin 
13442d747510SLisandro Dalcin   /* slow search */
13452d747510SLisandro Dalcin   N = n = options->N;
1346e5c89e4eSSatish Balay   names = options->names;
1347e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
13482d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13492d747510SLisandro Dalcin     if (!result) {
13509371c9d4SSatish Balay       n = i;
13519371c9d4SSatish Balay       break;
13522d747510SLisandro Dalcin     } else if (result > 0) {
13539371c9d4SSatish Balay       n = N;
13549371c9d4SSatish Balay       break;
1355e5c89e4eSSatish Balay     }
13562d747510SLisandro Dalcin   }
13572d747510SLisandro Dalcin   if (n == N) PetscFunctionReturn(0); /* it was not present */
1358e5c89e4eSSatish Balay 
13592d747510SLisandro Dalcin   /* remove name and value */
13602d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
13612d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1362e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1363e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
13645e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1365e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1366e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
1367e5c89e4eSSatish Balay   }
1368e5c89e4eSSatish Balay   options->N--;
13692d747510SLisandro Dalcin 
13702d747510SLisandro Dalcin   /* destroy hash table */
13712d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13722d747510SLisandro Dalcin   options->ht = NULL;
13732d747510SLisandro Dalcin 
13749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsMonitor(options, name, NULL));
1375e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1376e5c89e4eSSatish Balay }
1377e5c89e4eSSatish Balay 
1378e5c89e4eSSatish Balay /*@C
13792d747510SLisandro Dalcin    PetscOptionsFindPair - Gets an option name-value pair from the options database.
1380e5c89e4eSSatish Balay 
13812d747510SLisandro Dalcin    Not Collective
1382e5c89e4eSSatish Balay 
1383e5c89e4eSSatish Balay    Input Parameters:
13842d747510SLisandro Dalcin +  options - options database, use NULL for the default global database
13852d747510SLisandro Dalcin .  pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
13862d747510SLisandro Dalcin -  name - name of option, this SHOULD have the "-" prepended
1387e5c89e4eSSatish Balay 
13882d747510SLisandro Dalcin    Output Parameters:
13892d747510SLisandro Dalcin +  value - the option value (optional, not used for all options)
13902d747510SLisandro Dalcin -  set - whether the option is set (optional)
1391e5c89e4eSSatish Balay 
13929666a313SBarry Smith    Notes:
13939666a313SBarry Smith    Each process may find different values or no value depending on how options were inserted into the database
13941c9f3c13SBarry Smith 
13952d747510SLisandro Dalcin    Level: developer
13962d747510SLisandro Dalcin 
1397db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1398e5c89e4eSSatish Balay @*/
13999371c9d4SSatish Balay PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set) {
14002d747510SLisandro Dalcin   char      buf[MAXOPTNAME];
1401daabea38SBarry Smith   PetscBool usehashtable = PETSC_TRUE;
14022d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1403e5c89e4eSSatish Balay 
1404e5c89e4eSSatish Balay   PetscFunctionBegin;
1405c5929fdfSBarry Smith   options = options ? options : defaultoptions;
140608401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1407cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1408e5c89e4eSSatish Balay 
14092d747510SLisandro Dalcin   name++; /* skip starting dash */
1410e5c89e4eSSatish Balay 
14117cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
14122d747510SLisandro Dalcin   if (pre && pre[0]) {
14132d747510SLisandro Dalcin     char *ptr = buf;
14149371c9d4SSatish Balay     if (name[0] == '-') {
14159371c9d4SSatish Balay       *ptr++ = '-';
14169371c9d4SSatish Balay       name++;
14179371c9d4SSatish Balay     }
14189566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
14199566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
14202d747510SLisandro Dalcin     name = buf;
14217cd08cecSJed Brown   }
14222d747510SLisandro Dalcin 
142376bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
14242f828895SJed Brown     PetscBool valid;
14252d747510SLisandro Dalcin     char      key[MAXOPTNAME + 1] = "-";
14269566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
14279566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
142828b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
14292f828895SJed Brown   }
1430e5c89e4eSSatish Balay 
14312d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
14322d747510SLisandro Dalcin     int      i, ret;
14332d747510SLisandro Dalcin     khiter_t it;
14342d747510SLisandro Dalcin     khash_t(HO) * ht;
14352d747510SLisandro Dalcin     ht = kh_init(HO);
143628b400f6SJacob Faibussowitsch     PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
14372d747510SLisandro Dalcin     ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
143828b400f6SJacob Faibussowitsch     PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
14392d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
14402d747510SLisandro Dalcin       it = kh_put(HO, ht, options->names[i], &ret);
144108401ef6SPierre Jolivet       PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
14422d747510SLisandro Dalcin       kh_val(ht, it) = i;
14432d747510SLisandro Dalcin     }
14442d747510SLisandro Dalcin     options->ht = ht;
14452d747510SLisandro Dalcin   }
14462d747510SLisandro Dalcin 
14479371c9d4SSatish Balay   if (usehashtable) { /* fast search */
14482d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
14492d747510SLisandro Dalcin     khiter_t it     = kh_get(HO, ht, name);
14502d747510SLisandro Dalcin     if (it != kh_end(ht)) {
14512d747510SLisandro Dalcin       int i            = kh_val(ht, it);
1452e5c89e4eSSatish Balay       options->used[i] = PETSC_TRUE;
14532d747510SLisandro Dalcin       if (value) *value = options->values[i];
14542d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
14552d747510SLisandro Dalcin       PetscFunctionReturn(0);
14562d747510SLisandro Dalcin     }
14579371c9d4SSatish Balay   } else { /* slow search */
14582d747510SLisandro Dalcin     int i, N = options->N;
14592d747510SLisandro Dalcin     for (i = 0; i < N; i++) {
1460daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i], name);
14612d747510SLisandro Dalcin       if (!result) {
14622d747510SLisandro Dalcin         options->used[i] = PETSC_TRUE;
14632d747510SLisandro Dalcin         if (value) *value = options->values[i];
14642d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
14652d747510SLisandro Dalcin         PetscFunctionReturn(0);
14662d747510SLisandro Dalcin       } else if (result > 0) {
1467e5c89e4eSSatish Balay         break;
1468e5c89e4eSSatish Balay       }
1469e5c89e4eSSatish Balay     }
14702d747510SLisandro Dalcin   }
14712d747510SLisandro Dalcin 
14722d747510SLisandro Dalcin   /*
14732d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
14742d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
14752d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
14762d747510SLisandro Dalcin    */
14772d747510SLisandro Dalcin   if (matchnumbers) {
14782d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1479e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
14802d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
14812d747510SLisandro Dalcin       if (name[i] == '_') {
14822d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
14832d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
14842d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1485e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1486e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1487e5c89e4eSSatish Balay           }
14882d747510SLisandro Dalcin           i = j - 1;
1489e5c89e4eSSatish Balay           break;
1490e5c89e4eSSatish Balay         }
1491e5c89e4eSSatish Balay       }
1492e5c89e4eSSatish Balay     }
1493e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
14942d747510SLisandro Dalcin       PetscBool found;
14952d747510SLisandro Dalcin       char      opt[MAXOPTNAME + 1] = "-", tmp[MAXOPTNAME];
14969566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
14979566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
14989566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
14999566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
15009371c9d4SSatish Balay       if (found) {
15019371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
15029371c9d4SSatish Balay         PetscFunctionReturn(0);
15039371c9d4SSatish Balay       }
1504e5c89e4eSSatish Balay     }
1505e5c89e4eSSatish Balay   }
15062d747510SLisandro Dalcin 
15072d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
1508e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1509e5c89e4eSSatish Balay }
1510e5c89e4eSSatish Balay 
1511d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
15129371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set) {
15132d747510SLisandro Dalcin   char buf[MAXOPTNAME];
1514d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1515514bf10dSMatthew G Knepley 
1516514bf10dSMatthew G Knepley   PetscFunctionBegin;
1517c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1518cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1519cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1520514bf10dSMatthew G Knepley 
15212d747510SLisandro Dalcin   name++; /* skip starting dash */
1522514bf10dSMatthew G Knepley 
1523514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
15242d747510SLisandro Dalcin   if (pre && pre[0]) {
15252d747510SLisandro Dalcin     char *ptr = buf;
15269371c9d4SSatish Balay     if (name[0] == '-') {
15279371c9d4SSatish Balay       *ptr++ = '-';
15289371c9d4SSatish Balay       name++;
15299371c9d4SSatish Balay     }
15309566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) + (size_t)(ptr - buf)));
15319566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
15322d747510SLisandro Dalcin     name = buf;
1533514bf10dSMatthew G Knepley   }
15342d747510SLisandro Dalcin 
153576bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1536514bf10dSMatthew G Knepley     PetscBool valid;
15372d747510SLisandro Dalcin     char      key[MAXOPTNAME + 1] = "-";
15389566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
15399566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
154028b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1541514bf10dSMatthew G Knepley   }
1542514bf10dSMatthew G Knepley 
1543d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1544d6ced9c0SMatthew G. Knepley   {
1545d6ced9c0SMatthew G. Knepley     int i, j;
1546d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1547d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1548d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1549d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1550d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1551d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1552d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1553d6ced9c0SMatthew G. Knepley           }
1554d6ced9c0SMatthew G. Knepley           i = j - 1;
1555d6ced9c0SMatthew G. Knepley           break;
1556d6ced9c0SMatthew G. Knepley         }
1557d6ced9c0SMatthew G. Knepley       }
1558d6ced9c0SMatthew G. Knepley     }
1559d6ced9c0SMatthew G. Knepley   }
1560d6ced9c0SMatthew G. Knepley 
15612d747510SLisandro Dalcin   { /* slow search */
1562d6ced9c0SMatthew G. Knepley     int       c, i;
15632d747510SLisandro Dalcin     size_t    len;
15642d747510SLisandro Dalcin     PetscBool match;
1565d6ced9c0SMatthew G. Knepley 
1566d6ced9c0SMatthew G. Knepley     for (c = -1; c < numCnt; ++c) {
1567d6ced9c0SMatthew G. Knepley       char opt[MAXOPTNAME + 1] = "", tmp[MAXOPTNAME];
1568d6ced9c0SMatthew G. Knepley 
1569d6ced9c0SMatthew G. Knepley       if (c < 0) {
15709566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(opt, name));
1571d6ced9c0SMatthew G. Knepley       } else {
15729566063dSJacob Faibussowitsch         PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[c] + 1), sizeof(tmp))));
15739566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15749566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt)));
1575d6ced9c0SMatthew G. Knepley       }
15769566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(opt, &len));
15772d747510SLisandro Dalcin       for (i = 0; i < options->N; i++) {
15789566063dSJacob Faibussowitsch         PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1579514bf10dSMatthew G Knepley         if (match) {
1580514bf10dSMatthew G Knepley           options->used[i] = PETSC_TRUE;
15812d747510SLisandro Dalcin           if (value) *value = options->values[i];
15822d747510SLisandro Dalcin           if (set) *set = PETSC_TRUE;
15832d747510SLisandro Dalcin           PetscFunctionReturn(0);
1584514bf10dSMatthew G Knepley         }
1585514bf10dSMatthew G Knepley       }
15862d747510SLisandro Dalcin     }
1587d6ced9c0SMatthew G. Knepley   }
15882d747510SLisandro Dalcin 
15892d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
1590514bf10dSMatthew G Knepley   PetscFunctionReturn(0);
1591514bf10dSMatthew G Knepley }
1592514bf10dSMatthew G Knepley 
1593e5c89e4eSSatish Balay /*@C
1594e5c89e4eSSatish Balay    PetscOptionsReject - Generates an error if a certain option is given.
1595e5c89e4eSSatish Balay 
15961c9f3c13SBarry Smith    Not Collective
1597e5c89e4eSSatish Balay 
1598e5c89e4eSSatish Balay    Input Parameters:
15995c9cc608SHong Zhang +  options - options database, use NULL for default global database
16002d747510SLisandro Dalcin .  pre - the option prefix (may be NULL)
16012d747510SLisandro Dalcin .  name - the option name one is seeking
16020298fd71SBarry Smith -  mess - error message (may be NULL)
1603e5c89e4eSSatish Balay 
1604e5c89e4eSSatish Balay    Level: advanced
1605e5c89e4eSSatish Balay 
1606c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1607db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1608db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1609c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1610db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1611db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1612e5c89e4eSSatish Balay @*/
16139371c9d4SSatish Balay PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[]) {
1614ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1615e5c89e4eSSatish Balay 
1616e5c89e4eSSatish Balay   PetscFunctionBegin;
16179566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1618e5c89e4eSSatish Balay   if (flag) {
161908401ef6SPierre Jolivet     PetscCheck(!mess || !mess[0], PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s with %s", pre ? pre : "", name + 1, mess);
1620f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1621e5c89e4eSSatish Balay   }
1622e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1623e5c89e4eSSatish Balay }
1624e5c89e4eSSatish Balay 
1625e5c89e4eSSatish Balay /*@C
16262d747510SLisandro Dalcin    PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
16272d747510SLisandro Dalcin 
16282d747510SLisandro Dalcin    Not Collective
16292d747510SLisandro Dalcin 
16302d747510SLisandro Dalcin    Input Parameters:
16312d747510SLisandro Dalcin .  options - options database, use NULL for default global database
16322d747510SLisandro Dalcin 
16332d747510SLisandro Dalcin    Output Parameters:
16342d747510SLisandro Dalcin .  set - PETSC_TRUE if found else PETSC_FALSE.
16352d747510SLisandro Dalcin 
16362d747510SLisandro Dalcin    Level: advanced
16372d747510SLisandro Dalcin 
1638db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
16392d747510SLisandro Dalcin @*/
16409371c9d4SSatish Balay PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set) {
16412d747510SLisandro Dalcin   PetscFunctionBegin;
1642dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
16432d747510SLisandro Dalcin   options = options ? options : defaultoptions;
16442d747510SLisandro Dalcin   *set    = options->help;
16452d747510SLisandro Dalcin   PetscFunctionReturn(0);
16462d747510SLisandro Dalcin }
16472d747510SLisandro Dalcin 
16489371c9d4SSatish Balay PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set) {
1649d314f959SVaclav Hapla   PetscFunctionBegin;
1650dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
1651d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1652d314f959SVaclav Hapla   *set    = options->help_intro;
1653d314f959SVaclav Hapla   PetscFunctionReturn(0);
1654d314f959SVaclav Hapla }
1655d314f959SVaclav Hapla 
16562d747510SLisandro Dalcin /*@C
1657e24fcbf7SPierre Jolivet    PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or Boolean, even
1658e24fcbf7SPierre Jolivet                       if its value is set to false.
1659e5c89e4eSSatish Balay 
1660e5c89e4eSSatish Balay    Not Collective
1661e5c89e4eSSatish Balay 
1662e5c89e4eSSatish Balay    Input Parameters:
16635c9cc608SHong Zhang +  options - options database, use NULL for default global database
16643de71b31SHong Zhang .  pre - string to prepend to the name or NULL
16653de71b31SHong Zhang -  name - the option one is seeking
1666e5c89e4eSSatish Balay 
1667e5c89e4eSSatish Balay    Output Parameters:
166896ef3cdfSSatish Balay .  set - PETSC_TRUE if found else PETSC_FALSE.
1669e5c89e4eSSatish Balay 
1670e5c89e4eSSatish Balay    Level: beginner
1671e5c89e4eSSatish Balay 
167295452b02SPatrick Sanan    Notes:
1673acfcf0e5SJed Brown    In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.
167490d69ab7SBarry Smith 
1675db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1676db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1677db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1678c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1679db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1680db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1681e5c89e4eSSatish Balay @*/
16829371c9d4SSatish Balay PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set) {
16832d747510SLisandro Dalcin   const char *value;
1684ace3abfcSBarry Smith   PetscBool   flag;
1685e5c89e4eSSatish Balay 
1686e5c89e4eSSatish Balay   PetscFunctionBegin;
16879566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
168896ef3cdfSSatish Balay   if (set) *set = flag;
1689e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1690e5c89e4eSSatish Balay }
1691e5c89e4eSSatish Balay 
1692e5c89e4eSSatish Balay /*@C
16932d747510SLisandro Dalcin    PetscOptionsGetAll - Lists all the options the program was run with in a single string.
16942d747510SLisandro Dalcin 
16952d747510SLisandro Dalcin    Not Collective
16962d747510SLisandro Dalcin 
1697fd292e60Sprj-    Input Parameter:
16982d747510SLisandro Dalcin .  options - the options database, use NULL for the default global database
16992d747510SLisandro Dalcin 
17002d747510SLisandro Dalcin    Output Parameter:
17012d747510SLisandro Dalcin .  copts - pointer where string pointer is stored
17022d747510SLisandro Dalcin 
17032d747510SLisandro Dalcin    Notes:
17041c9f3c13SBarry Smith     The array and each entry in the array should be freed with PetscFree()
17051c9f3c13SBarry Smith     Each process may have different values depending on how the options were inserted into the database
17062d747510SLisandro Dalcin 
17072d747510SLisandro Dalcin    Level: advanced
17082d747510SLisandro Dalcin 
1709db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
17102d747510SLisandro Dalcin @*/
17119371c9d4SSatish Balay PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[]) {
17122d747510SLisandro Dalcin   PetscInt i;
17132d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
17142d747510SLisandro Dalcin   char    *coptions = NULL;
17152d747510SLisandro Dalcin 
17162d747510SLisandro Dalcin   PetscFunctionBegin;
17172d747510SLisandro Dalcin   PetscValidPointer(copts, 2);
17182d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17192d747510SLisandro Dalcin   /* count the length of the required string */
17202d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
17219566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
17222d747510SLisandro Dalcin     len += 2 + lent;
17232d747510SLisandro Dalcin     if (options->values[i]) {
17249566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
17252d747510SLisandro Dalcin       len += 1 + lent;
17262d747510SLisandro Dalcin     }
17272d747510SLisandro Dalcin   }
17289566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
17292d747510SLisandro Dalcin   coptions[0] = 0;
17302d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
17319566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions, "-"));
17329566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions, options->names[i]));
17339566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions, " "));
17342d747510SLisandro Dalcin     if (options->values[i]) {
17359566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(coptions, options->values[i]));
17369566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(coptions, " "));
17372d747510SLisandro Dalcin     }
17382d747510SLisandro Dalcin   }
17392d747510SLisandro Dalcin   *copts = coptions;
17402d747510SLisandro Dalcin   PetscFunctionReturn(0);
17412d747510SLisandro Dalcin }
17422d747510SLisandro Dalcin 
17432d747510SLisandro Dalcin /*@C
17442d747510SLisandro Dalcin    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
17452d747510SLisandro Dalcin 
17462d747510SLisandro Dalcin    Not Collective
17472d747510SLisandro Dalcin 
1748d8d19677SJose E. Roman    Input Parameters:
17492d747510SLisandro Dalcin +  options - options database, use NULL for default global database
17502d747510SLisandro Dalcin -  name - string name of option
17512d747510SLisandro Dalcin 
17522d747510SLisandro Dalcin    Output Parameter:
17532d747510SLisandro Dalcin .  used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database
17542d747510SLisandro Dalcin 
17552d747510SLisandro Dalcin    Level: advanced
17562d747510SLisandro Dalcin 
17579666a313SBarry Smith    Notes:
17589666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
17591c9f3c13SBarry Smith    on the given process
17601c9f3c13SBarry Smith 
1761db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
17622d747510SLisandro Dalcin @*/
17639371c9d4SSatish Balay PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used) {
17642d747510SLisandro Dalcin   PetscInt i;
17652d747510SLisandro Dalcin 
17662d747510SLisandro Dalcin   PetscFunctionBegin;
17672d747510SLisandro Dalcin   PetscValidCharPointer(name, 2);
1768dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(used, 3);
17692d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17702d747510SLisandro Dalcin   *used   = PETSC_FALSE;
17712d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
17729566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
17732d747510SLisandro Dalcin     if (*used) {
17742d747510SLisandro Dalcin       *used = options->used[i];
17752d747510SLisandro Dalcin       break;
17762d747510SLisandro Dalcin     }
17772d747510SLisandro Dalcin   }
17782d747510SLisandro Dalcin   PetscFunctionReturn(0);
17792d747510SLisandro Dalcin }
17802d747510SLisandro Dalcin 
1781487a658cSBarry Smith /*@
17822d747510SLisandro Dalcin    PetscOptionsAllUsed - Returns a count of the number of options in the
17832d747510SLisandro Dalcin    database that have never been selected.
17842d747510SLisandro Dalcin 
17852d747510SLisandro Dalcin    Not Collective
17862d747510SLisandro Dalcin 
17872d747510SLisandro Dalcin    Input Parameter:
17882d747510SLisandro Dalcin .  options - options database, use NULL for default global database
17892d747510SLisandro Dalcin 
17902d747510SLisandro Dalcin    Output Parameter:
17912d747510SLisandro Dalcin .  N - count of options not used
17922d747510SLisandro Dalcin 
17932d747510SLisandro Dalcin    Level: advanced
17942d747510SLisandro Dalcin 
17959666a313SBarry Smith    Notes:
17969666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
17971c9f3c13SBarry Smith    on the given process
17981c9f3c13SBarry Smith 
1799db781477SPatrick Sanan .seealso: `PetscOptionsView()`
18002d747510SLisandro Dalcin @*/
18019371c9d4SSatish Balay PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N) {
18022d747510SLisandro Dalcin   PetscInt i, n = 0;
18032d747510SLisandro Dalcin 
18042d747510SLisandro Dalcin   PetscFunctionBegin;
18052d747510SLisandro Dalcin   PetscValidIntPointer(N, 2);
18062d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18072d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18082d747510SLisandro Dalcin     if (!options->used[i]) n++;
18092d747510SLisandro Dalcin   }
18102d747510SLisandro Dalcin   *N = n;
18112d747510SLisandro Dalcin   PetscFunctionReturn(0);
18122d747510SLisandro Dalcin }
18132d747510SLisandro Dalcin 
1814487a658cSBarry Smith /*@
18152d747510SLisandro Dalcin    PetscOptionsLeft - Prints to screen any options that were set and never used.
18162d747510SLisandro Dalcin 
18172d747510SLisandro Dalcin    Not Collective
18182d747510SLisandro Dalcin 
18192d747510SLisandro Dalcin    Input Parameter:
18202d747510SLisandro Dalcin .  options - options database; use NULL for default global database
18212d747510SLisandro Dalcin 
18222d747510SLisandro Dalcin    Options Database Key:
18233c6db4c4SPierre Jolivet .  -options_left - activates PetscOptionsAllUsed() within PetscFinalize()
18242d747510SLisandro Dalcin 
18253de2bfdfSBarry Smith    Notes:
18263de2bfdfSBarry Smith       This is rarely used directly, it is called by PetscFinalize() in debug more or if -options_left
18271c9f3c13SBarry Smith       is passed otherwise to help users determine possible mistakes in their usage of options. This
18281c9f3c13SBarry Smith       only prints values on process zero of PETSC_COMM_WORLD. Other processes depending the objects
18291c9f3c13SBarry Smith       used may have different options that are left unused.
18303de2bfdfSBarry Smith 
18312d747510SLisandro Dalcin    Level: advanced
18322d747510SLisandro Dalcin 
1833db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
18342d747510SLisandro Dalcin @*/
18359371c9d4SSatish Balay PetscErrorCode PetscOptionsLeft(PetscOptions options) {
18362d747510SLisandro Dalcin   PetscInt     i;
18373de2bfdfSBarry Smith   PetscInt     cnt = 0;
18383de2bfdfSBarry Smith   PetscOptions toptions;
18392d747510SLisandro Dalcin 
18402d747510SLisandro Dalcin   PetscFunctionBegin;
18413de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
18423de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
18433de2bfdfSBarry Smith     if (!toptions->used[i]) {
1844660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
18453de2bfdfSBarry Smith       if (toptions->values[i]) {
18469566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s value: %s\n", toptions->names[i], toptions->values[i]));
18472d747510SLisandro Dalcin       } else {
18489566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value)\n", toptions->names[i]));
18492d747510SLisandro Dalcin       }
18502d747510SLisandro Dalcin     }
18512d747510SLisandro Dalcin   }
18523de2bfdfSBarry Smith   if (!options) {
18533de2bfdfSBarry Smith     toptions = defaultoptions;
18543de2bfdfSBarry Smith     while (toptions->previous) {
18553de2bfdfSBarry Smith       cnt++;
18563de2bfdfSBarry Smith       toptions = toptions->previous;
18573de2bfdfSBarry Smith     }
1858*48a46eb9SPierre Jolivet     if (cnt) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: You may have forgotten some calls to PetscOptionsPop(),\n             PetscOptionsPop() has been called %" PetscInt_FMT " less times than PetscOptionsPush()\n", cnt));
18593de2bfdfSBarry Smith   }
18602d747510SLisandro Dalcin   PetscFunctionReturn(0);
18612d747510SLisandro Dalcin }
18622d747510SLisandro Dalcin 
18632d747510SLisandro Dalcin /*@C
18642d747510SLisandro Dalcin    PetscOptionsLeftGet - Returns all options that were set and never used.
18652d747510SLisandro Dalcin 
18662d747510SLisandro Dalcin    Not Collective
18672d747510SLisandro Dalcin 
18682d747510SLisandro Dalcin    Input Parameter:
18692d747510SLisandro Dalcin .  options - options database, use NULL for default global database
18702d747510SLisandro Dalcin 
1871d8d19677SJose E. Roman    Output Parameters:
1872a2b725a8SWilliam Gropp +  N - count of options not used
18732d747510SLisandro Dalcin .  names - names of options not used
1874a2b725a8SWilliam Gropp -  values - values of options not used
18752d747510SLisandro Dalcin 
18762d747510SLisandro Dalcin    Level: advanced
18772d747510SLisandro Dalcin 
18782d747510SLisandro Dalcin    Notes:
18792d747510SLisandro Dalcin    Users should call PetscOptionsLeftRestore() to free the memory allocated in this routine
18801c9f3c13SBarry Smith    Notes: The value returned may be different on each process and depends on which options have been processed
18811c9f3c13SBarry Smith    on the given process
18822d747510SLisandro Dalcin 
1883db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
18842d747510SLisandro Dalcin @*/
18859371c9d4SSatish Balay PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[]) {
18862d747510SLisandro Dalcin   PetscInt i, n;
18872d747510SLisandro Dalcin 
18882d747510SLisandro Dalcin   PetscFunctionBegin;
18892d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
18902d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
18912d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
18922d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18932d747510SLisandro Dalcin 
18942d747510SLisandro Dalcin   /* The number of unused PETSc options */
18952d747510SLisandro Dalcin   n = 0;
18962d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1897660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
18982d747510SLisandro Dalcin     if (!options->used[i]) n++;
18992d747510SLisandro Dalcin   }
19002d747510SLisandro Dalcin   if (N) { *N = n; }
19019566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
19029566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
19032d747510SLisandro Dalcin 
19042d747510SLisandro Dalcin   n = 0;
19052d747510SLisandro Dalcin   if (names || values) {
19062d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
19072d747510SLisandro Dalcin       if (!options->used[i]) {
1908660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
19092d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
19102d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
19112d747510SLisandro Dalcin         n++;
19122d747510SLisandro Dalcin       }
19132d747510SLisandro Dalcin     }
19142d747510SLisandro Dalcin   }
19152d747510SLisandro Dalcin   PetscFunctionReturn(0);
19162d747510SLisandro Dalcin }
19172d747510SLisandro Dalcin 
19182d747510SLisandro Dalcin /*@C
19192d747510SLisandro Dalcin    PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using PetscOptionsLeftGet.
19202d747510SLisandro Dalcin 
19212d747510SLisandro Dalcin    Not Collective
19222d747510SLisandro Dalcin 
1923d8d19677SJose E. Roman    Input Parameters:
1924a2b725a8SWilliam Gropp +  options - options database, use NULL for default global database
19252d747510SLisandro Dalcin .  names - names of options not used
1926a2b725a8SWilliam Gropp -  values - values of options not used
19272d747510SLisandro Dalcin 
19282d747510SLisandro Dalcin    Level: advanced
19292d747510SLisandro Dalcin 
1930db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
19312d747510SLisandro Dalcin @*/
19329371c9d4SSatish Balay PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[]) {
19332d747510SLisandro Dalcin   PetscFunctionBegin;
19342d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
19352d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
19362d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
19372d747510SLisandro Dalcin   if (N) { *N = 0; }
19389566063dSJacob Faibussowitsch   if (names) PetscCall(PetscFree(*names));
19399566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
19402d747510SLisandro Dalcin   PetscFunctionReturn(0);
19412d747510SLisandro Dalcin }
19422d747510SLisandro Dalcin 
19432d747510SLisandro Dalcin /*@C
19449060e2f9SVaclav Hapla    PetscOptionsMonitorDefault - Print all options set value events using the supplied PetscViewer.
19452d747510SLisandro Dalcin 
19461c9f3c13SBarry Smith    Logically Collective on ctx
19472d747510SLisandro Dalcin 
19482d747510SLisandro Dalcin    Input Parameters:
19492d747510SLisandro Dalcin +  name  - option name string
19502d747510SLisandro Dalcin .  value - option value string
19519060e2f9SVaclav Hapla -  ctx - an ASCII viewer or NULL
19522d747510SLisandro Dalcin 
19532d747510SLisandro Dalcin    Level: intermediate
19542d747510SLisandro Dalcin 
19559666a313SBarry Smith    Notes:
19569060e2f9SVaclav Hapla      If ctx=NULL, PetscPrintf() is used.
19579666a313SBarry Smith      The first MPI rank in the PetscViewer viewer actually prints the values, other
19581c9f3c13SBarry Smith      processes may have different values set
19591c9f3c13SBarry Smith 
1960660278c0SBarry Smith      If PetscCIEnabled then do not print the test harness options
1961660278c0SBarry Smith 
1962db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
19632d747510SLisandro Dalcin @*/
19649371c9d4SSatish Balay PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], void *ctx) {
19652d747510SLisandro Dalcin   PetscFunctionBegin;
1966660278c0SBarry Smith   if (PetscCIOption(name)) PetscFunctionReturn(0);
1967660278c0SBarry Smith 
19689060e2f9SVaclav Hapla   if (ctx) {
19699060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
19702d747510SLisandro Dalcin     if (!value) {
19719566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
19722d747510SLisandro Dalcin     } else if (!value[0]) {
19739566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value)\n", name));
19742d747510SLisandro Dalcin     } else {
19759566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s\n", name, value));
19762d747510SLisandro Dalcin     }
19779060e2f9SVaclav Hapla   } else {
19789060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
19799060e2f9SVaclav Hapla     if (!value) {
19809566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
19819060e2f9SVaclav Hapla     } else if (!value[0]) {
19829566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Setting option: %s (no value)\n", name));
19839060e2f9SVaclav Hapla     } else {
19849566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Setting option: %s = %s\n", name, value));
19859060e2f9SVaclav Hapla     }
19869060e2f9SVaclav Hapla   }
19872d747510SLisandro Dalcin   PetscFunctionReturn(0);
19882d747510SLisandro Dalcin }
19892d747510SLisandro Dalcin 
19902d747510SLisandro Dalcin /*@C
19912d747510SLisandro Dalcin    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
19922d747510SLisandro Dalcin    modified the PETSc options database.
19932d747510SLisandro Dalcin 
19942d747510SLisandro Dalcin    Not Collective
19952d747510SLisandro Dalcin 
19962d747510SLisandro Dalcin    Input Parameters:
19972d747510SLisandro Dalcin +  monitor - pointer to function (if this is NULL, it turns off monitoring
19982d747510SLisandro Dalcin .  mctx    - [optional] context for private data for the
19992d747510SLisandro Dalcin              monitor routine (use NULL if no context is desired)
20002d747510SLisandro Dalcin -  monitordestroy - [optional] routine that frees monitor context
20012d747510SLisandro Dalcin           (may be NULL)
20022d747510SLisandro Dalcin 
20032d747510SLisandro Dalcin    Calling Sequence of monitor:
20042d747510SLisandro Dalcin $     monitor (const char name[], const char value[], void *mctx)
20052d747510SLisandro Dalcin 
20062d747510SLisandro Dalcin +  name - option name string
20072d747510SLisandro Dalcin .  value - option value string
20082d747510SLisandro Dalcin -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()
20092d747510SLisandro Dalcin 
20102d747510SLisandro Dalcin    Options Database Keys:
2011c5b5d8d5SVaclav Hapla    See PetscInitialize() for options related to option database monitoring.
20122d747510SLisandro Dalcin 
20132d747510SLisandro Dalcin    Notes:
20142d747510SLisandro Dalcin    The default is to do nothing.  To print the name and value of options
20152d747510SLisandro Dalcin    being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
20162d747510SLisandro Dalcin    with a null monitoring context.
20172d747510SLisandro Dalcin 
20182d747510SLisandro Dalcin    Several different monitoring routines may be set by calling
20192d747510SLisandro Dalcin    PetscOptionsMonitorSet() multiple times; all will be called in the
20202d747510SLisandro Dalcin    order in which they were set.
20212d747510SLisandro Dalcin 
20229060e2f9SVaclav Hapla    Level: intermediate
20232d747510SLisandro Dalcin 
2024db781477SPatrick Sanan .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
20252d747510SLisandro Dalcin @*/
20269371c9d4SSatish Balay PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) {
20272d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
20282d747510SLisandro Dalcin 
20292d747510SLisandro Dalcin   PetscFunctionBegin;
2030c5b5d8d5SVaclav Hapla   if (options->monitorCancel) PetscFunctionReturn(0);
203108401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
20322d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
20332d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
20342d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void *)mctx;
20352d747510SLisandro Dalcin   PetscFunctionReturn(0);
20362d747510SLisandro Dalcin }
20372d747510SLisandro Dalcin 
20382d747510SLisandro Dalcin /*
20392d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
204063fe8743SVaclav Hapla      Empty string is considered as true.
20412d747510SLisandro Dalcin */
20429371c9d4SSatish Balay PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a) {
20432d747510SLisandro Dalcin   PetscBool istrue, isfalse;
20442d747510SLisandro Dalcin   size_t    len;
20452d747510SLisandro Dalcin 
20462d747510SLisandro Dalcin   PetscFunctionBegin;
204763fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
20489566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
20499371c9d4SSatish Balay   if (!len) {
20509371c9d4SSatish Balay     *a = PETSC_TRUE;
20519371c9d4SSatish Balay     PetscFunctionReturn(0);
20529371c9d4SSatish Balay   }
20539566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
20549371c9d4SSatish Balay   if (istrue) {
20559371c9d4SSatish Balay     *a = PETSC_TRUE;
20569371c9d4SSatish Balay     PetscFunctionReturn(0);
20579371c9d4SSatish Balay   }
20589566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
20599371c9d4SSatish Balay   if (istrue) {
20609371c9d4SSatish Balay     *a = PETSC_TRUE;
20619371c9d4SSatish Balay     PetscFunctionReturn(0);
20629371c9d4SSatish Balay   }
20639566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
20649371c9d4SSatish Balay   if (istrue) {
20659371c9d4SSatish Balay     *a = PETSC_TRUE;
20669371c9d4SSatish Balay     PetscFunctionReturn(0);
20679371c9d4SSatish Balay   }
20689566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
20699371c9d4SSatish Balay   if (istrue) {
20709371c9d4SSatish Balay     *a = PETSC_TRUE;
20719371c9d4SSatish Balay     PetscFunctionReturn(0);
20729371c9d4SSatish Balay   }
20739566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
20749371c9d4SSatish Balay   if (isfalse) {
20759371c9d4SSatish Balay     *a = PETSC_FALSE;
20769371c9d4SSatish Balay     PetscFunctionReturn(0);
20779371c9d4SSatish Balay   }
20789566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
20799371c9d4SSatish Balay   if (isfalse) {
20809371c9d4SSatish Balay     *a = PETSC_FALSE;
20819371c9d4SSatish Balay     PetscFunctionReturn(0);
20829371c9d4SSatish Balay   }
20839566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
20849371c9d4SSatish Balay   if (isfalse) {
20859371c9d4SSatish Balay     *a = PETSC_FALSE;
20869371c9d4SSatish Balay     PetscFunctionReturn(0);
20879371c9d4SSatish Balay   }
20889566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
20899371c9d4SSatish Balay   if (isfalse) {
20909371c9d4SSatish Balay     *a = PETSC_FALSE;
20919371c9d4SSatish Balay     PetscFunctionReturn(0);
20929371c9d4SSatish Balay   }
209398921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
20942d747510SLisandro Dalcin }
20952d747510SLisandro Dalcin 
20962d747510SLisandro Dalcin /*
20972d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
20982d747510SLisandro Dalcin */
20999371c9d4SSatish Balay PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a) {
21002d747510SLisandro Dalcin   size_t    len;
21012d747510SLisandro Dalcin   PetscBool decide, tdefault, mouse;
21022d747510SLisandro Dalcin 
21032d747510SLisandro Dalcin   PetscFunctionBegin;
21049566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
21055f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
21062d747510SLisandro Dalcin 
21079566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
2108*48a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
21099566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
2110*48a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
21119566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
21122d747510SLisandro Dalcin 
21132d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
21142d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
21152d747510SLisandro Dalcin   else if (mouse) *a = -1;
21162d747510SLisandro Dalcin   else {
21172d747510SLisandro Dalcin     char *endptr;
21182d747510SLisandro Dalcin     long  strtolval;
21192d747510SLisandro Dalcin 
21202d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2121cc73adaaSBarry Smith     PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no integer value (do not include . in it)", name);
21222d747510SLisandro Dalcin 
21232d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
21242d747510SLisandro Dalcin     (void)strtolval;
21252d747510SLisandro Dalcin     *a = atoll(name);
21262d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
21272d747510SLisandro Dalcin     (void)strtolval;
21282d747510SLisandro Dalcin     *a = _atoi64(name);
21292d747510SLisandro Dalcin #else
21302d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
21312d747510SLisandro Dalcin #endif
21322d747510SLisandro Dalcin   }
21332d747510SLisandro Dalcin   PetscFunctionReturn(0);
21342d747510SLisandro Dalcin }
21352d747510SLisandro Dalcin 
21362d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
21372d747510SLisandro Dalcin #include <quadmath.h>
21382d747510SLisandro Dalcin #endif
21392d747510SLisandro Dalcin 
21409371c9d4SSatish Balay static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr) {
21412d747510SLisandro Dalcin   PetscFunctionBegin;
21422d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
21432d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
21442d747510SLisandro Dalcin #else
21452d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
21462d747510SLisandro Dalcin #endif
21472d747510SLisandro Dalcin   PetscFunctionReturn(0);
21482d747510SLisandro Dalcin }
21492d747510SLisandro Dalcin 
21509371c9d4SSatish Balay static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary) {
21512d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
21522d747510SLisandro Dalcin   char     *ptr;
21532d747510SLisandro Dalcin   PetscReal strtoval;
21542d747510SLisandro Dalcin 
21552d747510SLisandro Dalcin   PetscFunctionBegin;
21569566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
21572d747510SLisandro Dalcin   if (ptr == name) {
21582d747510SLisandro Dalcin     strtoval = 1.;
21592d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
21602d747510SLisandro Dalcin     if (name[0] == 'i') {
21612d747510SLisandro Dalcin       ptr++;
21622d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
21632d747510SLisandro Dalcin       ptr += 2;
21642d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
21652d747510SLisandro Dalcin       strtoval = -1.;
21662d747510SLisandro Dalcin       ptr += 2;
21672d747510SLisandro Dalcin     }
21682d747510SLisandro Dalcin   } else if (*ptr == 'i') {
21692d747510SLisandro Dalcin     hasi = PETSC_TRUE;
21702d747510SLisandro Dalcin     ptr++;
21712d747510SLisandro Dalcin   }
21722d747510SLisandro Dalcin   *endptr      = ptr;
21732d747510SLisandro Dalcin   *isImaginary = hasi;
21742d747510SLisandro Dalcin   if (hasi) {
21752d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
217698921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
21772d747510SLisandro Dalcin #else
21782d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
21792d747510SLisandro Dalcin #endif
21802d747510SLisandro Dalcin   } else {
21812d747510SLisandro Dalcin     *a = strtoval;
21822d747510SLisandro Dalcin   }
21832d747510SLisandro Dalcin   PetscFunctionReturn(0);
21842d747510SLisandro Dalcin }
21852d747510SLisandro Dalcin 
21862d747510SLisandro Dalcin /*
21872d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
21882d747510SLisandro Dalcin */
21899371c9d4SSatish Balay PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a) {
21902d747510SLisandro Dalcin   size_t    len;
21912d747510SLisandro Dalcin   PetscBool match;
21922d747510SLisandro Dalcin   char     *endptr;
21932d747510SLisandro Dalcin 
21942d747510SLisandro Dalcin   PetscFunctionBegin;
21959566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
219628b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
21972d747510SLisandro Dalcin 
21989566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
21999566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
22009371c9d4SSatish Balay   if (match) {
22019371c9d4SSatish Balay     *a = PETSC_DEFAULT;
22029371c9d4SSatish Balay     PetscFunctionReturn(0);
22039371c9d4SSatish Balay   }
22042d747510SLisandro Dalcin 
22059566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
22069566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
22079371c9d4SSatish Balay   if (match) {
22089371c9d4SSatish Balay     *a = PETSC_DECIDE;
22099371c9d4SSatish Balay     PetscFunctionReturn(0);
22109371c9d4SSatish Balay   }
22112d747510SLisandro Dalcin 
22129566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
221339a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
22142d747510SLisandro Dalcin   PetscFunctionReturn(0);
22152d747510SLisandro Dalcin }
22162d747510SLisandro Dalcin 
22179371c9d4SSatish Balay PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a) {
22182d747510SLisandro Dalcin   PetscBool   imag1;
22192d747510SLisandro Dalcin   size_t      len;
22202d747510SLisandro Dalcin   PetscScalar val = 0.;
22212d747510SLisandro Dalcin   char       *ptr = NULL;
22222d747510SLisandro Dalcin 
22232d747510SLisandro Dalcin   PetscFunctionBegin;
22249566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
222528b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22269566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
22272d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
22282d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
22292d747510SLisandro Dalcin     PetscBool   imag2;
22302d747510SLisandro Dalcin     PetscScalar val2;
22312d747510SLisandro Dalcin 
22329566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
223339a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
22342d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
22352d747510SLisandro Dalcin   }
22362d747510SLisandro Dalcin #endif
223739a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
22382d747510SLisandro Dalcin   *a = val;
22392d747510SLisandro Dalcin   PetscFunctionReturn(0);
22402d747510SLisandro Dalcin }
22412d747510SLisandro Dalcin 
22422d747510SLisandro Dalcin /*@C
22432d747510SLisandro Dalcin    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
22442d747510SLisandro Dalcin             option in the database.
2245e5c89e4eSSatish Balay 
2246e5c89e4eSSatish Balay    Not Collective
2247e5c89e4eSSatish Balay 
2248e5c89e4eSSatish Balay    Input Parameters:
22495c9cc608SHong Zhang +  options - options database, use NULL for default global database
2250c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2251e5c89e4eSSatish Balay -  name - the option one is seeking
2252e5c89e4eSSatish Balay 
2253d8d19677SJose E. Roman    Output Parameters:
22542d747510SLisandro Dalcin +  ivalue - the logical value to return
225596ef3cdfSSatish Balay -  set - PETSC_TRUE  if found, else PETSC_FALSE
2256e5c89e4eSSatish Balay 
2257e5c89e4eSSatish Balay    Level: beginner
2258e5c89e4eSSatish Balay 
225995452b02SPatrick Sanan    Notes:
22602d747510SLisandro Dalcin        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
22612d747510SLisandro Dalcin        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
22622d747510SLisandro Dalcin 
22632d747510SLisandro Dalcin       If the option is given, but no value is provided, then ivalue and set are both given the value PETSC_TRUE. That is -requested_bool
22642d747510SLisandro Dalcin      is equivalent to -requested_bool true
22652d747510SLisandro Dalcin 
22662d747510SLisandro Dalcin        If the user does not supply the option at all ivalue is NOT changed. Thus
22672efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
22682efd9cb1SBarry Smith 
2269db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2270db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2271db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2272c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2273db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2274db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2275e5c89e4eSSatish Balay @*/
22769371c9d4SSatish Balay PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set) {
22772d747510SLisandro Dalcin   const char *value;
2278ace3abfcSBarry Smith   PetscBool   flag;
2279e5c89e4eSSatish Balay 
2280e5c89e4eSSatish Balay   PetscFunctionBegin;
22812d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2282064a246eSJacob Faibussowitsch   if (ivalue) PetscValidBoolPointer(ivalue, 4);
22839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2284e5c89e4eSSatish Balay   if (flag) {
228596ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
22869566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
22872d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2288e5c89e4eSSatish Balay   } else {
228996ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2290e5c89e4eSSatish Balay   }
2291e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2292e5c89e4eSSatish Balay }
2293e5c89e4eSSatish Balay 
2294e5c89e4eSSatish Balay /*@C
2295e5c89e4eSSatish Balay    PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2296e5c89e4eSSatish Balay 
2297e5c89e4eSSatish Balay    Not Collective
2298e5c89e4eSSatish Balay 
2299e5c89e4eSSatish Balay    Input Parameters:
23005c9cc608SHong Zhang +  options - options database, use NULL for default global database
2301c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2302e5c89e4eSSatish Balay .  opt - option name
2303a264d7a6SBarry Smith .  list - the possible choices (one of these must be selected, anything else is invalid)
2304a2b725a8SWilliam Gropp -  ntext - number of choices
2305e5c89e4eSSatish Balay 
2306d8d19677SJose E. Roman    Output Parameters:
23072efd9cb1SBarry Smith +  value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2308e5c89e4eSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2309e5c89e4eSSatish Balay 
2310e5c89e4eSSatish Balay    Level: intermediate
2311e5c89e4eSSatish Balay 
231295452b02SPatrick Sanan    Notes:
231395452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
23142efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
23152efd9cb1SBarry Smith 
2316a264d7a6SBarry Smith    See PetscOptionsFList() for when the choices are given in a PetscFunctionList()
2317e5c89e4eSSatish Balay 
2318db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2319db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2320db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2321c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2322db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2323db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2324e5c89e4eSSatish Balay @*/
23259371c9d4SSatish Balay PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscInt ntext, PetscInt *value, PetscBool *set) {
232658b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2327e5c89e4eSSatish Balay   char     *svalue;
2328ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2329e5c89e4eSSatish Balay   PetscInt  i;
2330e5c89e4eSSatish Balay 
2331e5c89e4eSSatish Balay   PetscFunctionBegin;
23322d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
2333e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
23349566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2335e5c89e4eSSatish Balay     if (alen > len) len = alen;
233658b0ac4eSStefano Zampini     tlen += len + 1;
2337e5c89e4eSSatish Balay   }
2338e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
23399566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
23409566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2341e5c89e4eSSatish Balay   if (aset) {
23429566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
234358b0ac4eSStefano Zampini     if (!flg) {
234458b0ac4eSStefano Zampini       char *avail, *pavl;
234558b0ac4eSStefano Zampini 
23469566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
234758b0ac4eSStefano Zampini       pavl = avail;
234858b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
23499566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(list[i], &alen));
23509566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(pavl, list[i]));
235158b0ac4eSStefano Zampini         pavl += alen;
23529566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(pavl, " "));
235358b0ac4eSStefano Zampini         pavl += 1;
235458b0ac4eSStefano Zampini       }
23559566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
235698921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
235758b0ac4eSStefano Zampini     }
2358fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2359a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
23609566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
2361e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2362e5c89e4eSSatish Balay }
2363e5c89e4eSSatish Balay 
2364e5c89e4eSSatish Balay /*@C
2365e5c89e4eSSatish Balay    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2366e5c89e4eSSatish Balay 
2367e5c89e4eSSatish Balay    Not Collective
2368e5c89e4eSSatish Balay 
2369e5c89e4eSSatish Balay    Input Parameters:
23705c9cc608SHong Zhang +  options - options database, use NULL for default global database
2371c5929fdfSBarry Smith .  pre - option prefix or NULL
2372e5c89e4eSSatish Balay .  opt - option name
23736b867d5aSJose E. Roman -  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2374e5c89e4eSSatish Balay 
2375d8d19677SJose E. Roman    Output Parameters:
2376e5c89e4eSSatish Balay +  value - the  value to return
237796ef3cdfSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2378e5c89e4eSSatish Balay 
2379e5c89e4eSSatish Balay    Level: beginner
2380e5c89e4eSSatish Balay 
238195452b02SPatrick Sanan    Notes:
238295452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
23832efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2384e5c89e4eSSatish Balay 
23852efd9cb1SBarry Smith           List is usually something like PCASMTypes or some other predefined list of enum names
2386e5c89e4eSSatish Balay 
2387db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2388db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2389db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2390db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2391c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2392db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2393db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2394e5c89e4eSSatish Balay @*/
23959371c9d4SSatish Balay PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscEnum *value, PetscBool *set) {
239669a24498SJed Brown   PetscInt  ntext = 0, tval;
2397ace3abfcSBarry Smith   PetscBool fset;
2398e5c89e4eSSatish Balay 
2399e5c89e4eSSatish Balay   PetscFunctionBegin;
24002d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
24019371c9d4SSatish Balay   while (list[ntext++]) { PetscCheck(ntext <= 50, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument appears to be wrong or have more than 50 entries"); }
240208401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2403e5c89e4eSSatish Balay   ntext -= 3;
24049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
240569a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2406809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2407809ceb46SBarry Smith   if (set) *set = fset;
2408e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2409e5c89e4eSSatish Balay }
2410e5c89e4eSSatish Balay 
2411e5c89e4eSSatish Balay /*@C
24122d747510SLisandro Dalcin    PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2413e5c89e4eSSatish Balay 
2414e5c89e4eSSatish Balay    Not Collective
2415e5c89e4eSSatish Balay 
2416e5c89e4eSSatish Balay    Input Parameters:
24175c9cc608SHong Zhang +  options - options database, use NULL for default global database
2418c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2419e5c89e4eSSatish Balay -  name - the option one is seeking
2420e5c89e4eSSatish Balay 
2421d8d19677SJose E. Roman    Output Parameters:
24222d747510SLisandro Dalcin +  ivalue - the integer value to return
242396ef3cdfSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2424e5c89e4eSSatish Balay 
2425e5c89e4eSSatish Balay    Level: beginner
2426e5c89e4eSSatish Balay 
2427e5c89e4eSSatish Balay    Notes:
24282d747510SLisandro Dalcin    If the user does not supply the option ivalue is NOT changed. Thus
24292efd9cb1SBarry Smith    you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
24305c07ccb8SBarry Smith 
2431db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2432db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2433db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2434db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2435c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2436db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2437db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2438e5c89e4eSSatish Balay @*/
24399371c9d4SSatish Balay PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set) {
24402d747510SLisandro Dalcin   const char *value;
24412d747510SLisandro Dalcin   PetscBool   flag;
2442e5c89e4eSSatish Balay 
2443e5c89e4eSSatish Balay   PetscFunctionBegin;
24442d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
24452d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
24469566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2447e5c89e4eSSatish Balay   if (flag) {
244834a9cc2cSBarry Smith     if (!value) {
24492d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
245034a9cc2cSBarry Smith     } else {
24512d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
24529566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2453e5c89e4eSSatish Balay     }
2454e5c89e4eSSatish Balay   } else {
245596ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2456e5c89e4eSSatish Balay   }
2457e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2458e5c89e4eSSatish Balay }
2459e5c89e4eSSatish Balay 
2460e2446a98SMatthew Knepley /*@C
2461e5c89e4eSSatish Balay    PetscOptionsGetReal - Gets the double precision value for a particular
2462e5c89e4eSSatish Balay    option in the database.
2463e5c89e4eSSatish Balay 
2464e5c89e4eSSatish Balay    Not Collective
2465e5c89e4eSSatish Balay 
2466e5c89e4eSSatish Balay    Input Parameters:
24675c9cc608SHong Zhang +  options - options database, use NULL for default global database
2468c5929fdfSBarry Smith .  pre - string to prepend to each name or NULL
2469e5c89e4eSSatish Balay -  name - the option one is seeking
2470e5c89e4eSSatish Balay 
2471d8d19677SJose E. Roman    Output Parameters:
2472e5c89e4eSSatish Balay +  dvalue - the double value to return
247396ef3cdfSSatish Balay -  set - PETSC_TRUE if found, PETSC_FALSE if not found
2474e5c89e4eSSatish Balay 
247595452b02SPatrick Sanan    Notes:
247695452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
24772efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2478e4974155SBarry Smith 
2479e5c89e4eSSatish Balay    Level: beginner
2480e5c89e4eSSatish Balay 
2481db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2482c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2483db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2484c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2485db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2486db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2487e5c89e4eSSatish Balay @*/
24889371c9d4SSatish Balay PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set) {
24892d747510SLisandro Dalcin   const char *value;
2490ace3abfcSBarry Smith   PetscBool   flag;
2491e5c89e4eSSatish Balay 
2492e5c89e4eSSatish Balay   PetscFunctionBegin;
24932d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
24942d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
24959566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2496e5c89e4eSSatish Balay   if (flag) {
2497a297a907SKarl Rupp     if (!value) {
2498a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2499a297a907SKarl Rupp     } else {
2500a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
25019566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2502a297a907SKarl Rupp     }
2503e5c89e4eSSatish Balay   } else {
250496ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2505e5c89e4eSSatish Balay   }
2506e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2507e5c89e4eSSatish Balay }
2508e5c89e4eSSatish Balay 
2509e5c89e4eSSatish Balay /*@C
2510e5c89e4eSSatish Balay    PetscOptionsGetScalar - Gets the scalar value for a particular
2511e5c89e4eSSatish Balay    option in the database.
2512e5c89e4eSSatish Balay 
2513e5c89e4eSSatish Balay    Not Collective
2514e5c89e4eSSatish Balay 
2515e5c89e4eSSatish Balay    Input Parameters:
25165c9cc608SHong Zhang +  options - options database, use NULL for default global database
2517c5929fdfSBarry Smith .  pre - string to prepend to each name or NULL
2518e5c89e4eSSatish Balay -  name - the option one is seeking
2519e5c89e4eSSatish Balay 
2520d8d19677SJose E. Roman    Output Parameters:
2521e5c89e4eSSatish Balay +  dvalue - the double value to return
252296ef3cdfSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2523e5c89e4eSSatish Balay 
2524e5c89e4eSSatish Balay    Level: beginner
2525e5c89e4eSSatish Balay 
2526e5c89e4eSSatish Balay    Usage:
2527eb4ae41dSBarry Smith    A complex number 2+3i must be specified with NO spaces
2528e5c89e4eSSatish Balay 
252995452b02SPatrick Sanan    Notes:
253095452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
25312efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2532e4974155SBarry Smith 
2533db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2534db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2535db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2536c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2537db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2538db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2539e5c89e4eSSatish Balay @*/
25409371c9d4SSatish Balay PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set) {
25412d747510SLisandro Dalcin   const char *value;
2542ace3abfcSBarry Smith   PetscBool   flag;
2543e5c89e4eSSatish Balay 
2544e5c89e4eSSatish Balay   PetscFunctionBegin;
25452d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
25462d747510SLisandro Dalcin   PetscValidScalarPointer(dvalue, 4);
25479566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2548e5c89e4eSSatish Balay   if (flag) {
2549e5c89e4eSSatish Balay     if (!value) {
255096ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2551e5c89e4eSSatish Balay     } else {
2552e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
25539566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2554e5c89e4eSSatish Balay #else
25559566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2556e5c89e4eSSatish Balay #endif
255796ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2558e5c89e4eSSatish Balay     }
2559e5c89e4eSSatish Balay   } else { /* flag */
256096ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2561e5c89e4eSSatish Balay   }
2562e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2563e5c89e4eSSatish Balay }
2564e5c89e4eSSatish Balay 
2565e5c89e4eSSatish Balay /*@C
2566e5c89e4eSSatish Balay    PetscOptionsGetString - Gets the string value for a particular option in
2567e5c89e4eSSatish Balay    the database.
2568e5c89e4eSSatish Balay 
2569e5c89e4eSSatish Balay    Not Collective
2570e5c89e4eSSatish Balay 
2571e5c89e4eSSatish Balay    Input Parameters:
25725c9cc608SHong Zhang +  options - options database, use NULL for default global database
2573c5929fdfSBarry Smith .  pre - string to prepend to name or NULL
2574e5c89e4eSSatish Balay .  name - the option one is seeking
2575bcbf2dc5SJed Brown -  len - maximum length of the string including null termination
2576e5c89e4eSSatish Balay 
2577e5c89e4eSSatish Balay    Output Parameters:
2578e5c89e4eSSatish Balay +  string - location to copy string
257996ef3cdfSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2580e5c89e4eSSatish Balay 
2581e5c89e4eSSatish Balay    Level: beginner
2582e5c89e4eSSatish Balay 
2583e5c89e4eSSatish Balay    Fortran Note:
2584e5c89e4eSSatish Balay    The Fortran interface is slightly different from the C/C++
2585e5c89e4eSSatish Balay    interface (len is not used).  Sample usage in Fortran follows
2586e5c89e4eSSatish Balay .vb
2587e5c89e4eSSatish Balay       character *20    string
258893e6ba5cSBarry Smith       PetscErrorCode   ierr
258993e6ba5cSBarry Smith       PetscBool        set
25901b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2591e5c89e4eSSatish Balay .ve
2592e5c89e4eSSatish Balay 
259395452b02SPatrick Sanan    Notes:
259495452b02SPatrick Sanan     if the option is given but no string is provided then an empty string is returned and set is given the value of PETSC_TRUE
2595e4974155SBarry Smith 
25962efd9cb1SBarry Smith            If the user does not use the option then the string is not changed. Thus
25972efd9cb1SBarry Smith            you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
25982efd9cb1SBarry Smith 
2599f3dea69dSBarry Smith     Note:
2600f3dea69dSBarry Smith       Even if the user provided no string (for example -optionname -someotheroption) the flag is set to PETSC_TRUE (and the string is fulled with nulls).
2601f3dea69dSBarry Smith 
2602db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2603db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2604db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2605c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2606db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2607db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2608e5c89e4eSSatish Balay @*/
26099371c9d4SSatish Balay PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set) {
26102d747510SLisandro Dalcin   const char *value;
2611ace3abfcSBarry Smith   PetscBool   flag;
2612e5c89e4eSSatish Balay 
2613e5c89e4eSSatish Balay   PetscFunctionBegin;
26142d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
26152d747510SLisandro Dalcin   PetscValidCharPointer(string, 4);
26169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2617e5c89e4eSSatish Balay   if (!flag) {
261896ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2619e5c89e4eSSatish Balay   } else {
262096ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
26219566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
26229566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2623e5c89e4eSSatish Balay   }
2624e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2625e5c89e4eSSatish Balay }
2626e5c89e4eSSatish Balay 
26279371c9d4SSatish Balay char *PetscOptionsGetStringMatlab(PetscOptions options, const char pre[], const char name[]) {
26282d747510SLisandro Dalcin   const char *value;
262914ce751eSBarry Smith   PetscBool   flag;
263014ce751eSBarry Smith 
263114ce751eSBarry Smith   PetscFunctionBegin;
263239a651e2SJacob Faibussowitsch   if (PetscOptionsFindPair(options, pre, name, &value, &flag)) PetscFunctionReturn(NULL);
26332d747510SLisandro Dalcin   if (flag) PetscFunctionReturn((char *)value);
263439a651e2SJacob Faibussowitsch   PetscFunctionReturn(NULL);
263514ce751eSBarry Smith }
263614ce751eSBarry Smith 
26372d747510SLisandro Dalcin /*@C
26382d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2639f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
26402d747510SLisandro Dalcin 
26412d747510SLisandro Dalcin   Not Collective
26422d747510SLisandro Dalcin 
26432d747510SLisandro Dalcin   Input Parameters:
26442d747510SLisandro Dalcin + options - options database, use NULL for default global database
26452d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
26466b867d5aSJose E. Roman - name - the option one is seeking
26476b867d5aSJose E. Roman 
2648d8d19677SJose E. Roman   Output Parameters:
26492d747510SLisandro Dalcin + dvalue - the integer values to return
2650f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
26512d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
26522d747510SLisandro Dalcin 
26532d747510SLisandro Dalcin   Level: beginner
26542d747510SLisandro Dalcin 
26552d747510SLisandro Dalcin   Notes:
2656f1a722f8SMatthew G. Knepley   TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE. FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
26572d747510SLisandro Dalcin 
2658db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2659db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2660db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2661c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2662db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2663db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
26642d747510SLisandro Dalcin @*/
26659371c9d4SSatish Balay PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set) {
26662d747510SLisandro Dalcin   const char *svalue;
26672d747510SLisandro Dalcin   char       *value;
26682d747510SLisandro Dalcin   PetscInt    n = 0;
26692d747510SLisandro Dalcin   PetscBool   flag;
26702d747510SLisandro Dalcin   PetscToken  token;
26712d747510SLisandro Dalcin 
26722d747510SLisandro Dalcin   PetscFunctionBegin;
26732d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2674064a246eSJacob Faibussowitsch   PetscValidBoolPointer(dvalue, 4);
26752d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
26762d747510SLisandro Dalcin 
26779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
26789371c9d4SSatish Balay   if (!flag || !svalue) {
26799371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
26809371c9d4SSatish Balay     *nmax = 0;
26819371c9d4SSatish Balay     PetscFunctionReturn(0);
26829371c9d4SSatish Balay   }
26832d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
26849566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
26859566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
26862d747510SLisandro Dalcin   while (value && n < *nmax) {
26879566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
26889566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
26892d747510SLisandro Dalcin     dvalue++;
26902d747510SLisandro Dalcin     n++;
26912d747510SLisandro Dalcin   }
26929566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
26932d747510SLisandro Dalcin   *nmax = n;
26942d747510SLisandro Dalcin   PetscFunctionReturn(0);
26952d747510SLisandro Dalcin }
26962d747510SLisandro Dalcin 
26972d747510SLisandro Dalcin /*@C
26982d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
26992d747510SLisandro Dalcin 
27002d747510SLisandro Dalcin   Not Collective
27012d747510SLisandro Dalcin 
27022d747510SLisandro Dalcin   Input Parameters:
27032d747510SLisandro Dalcin + options - options database, use NULL for default global database
27042d747510SLisandro Dalcin . pre - option prefix or NULL
27052d747510SLisandro Dalcin . name - option name
27066b867d5aSJose E. Roman - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
27076b867d5aSJose E. Roman 
27082d747510SLisandro Dalcin   Output Parameters:
27092d747510SLisandro Dalcin + ivalue - the  enum values to return
2710f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
27112d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
27122d747510SLisandro Dalcin 
27132d747510SLisandro Dalcin   Level: beginner
27142d747510SLisandro Dalcin 
27152d747510SLisandro Dalcin   Notes:
27162d747510SLisandro Dalcin   The array must be passed as a comma separated list.
27172d747510SLisandro Dalcin 
27182d747510SLisandro Dalcin   There must be no intervening spaces between the values.
27192d747510SLisandro Dalcin 
27202d747510SLisandro Dalcin   list is usually something like PCASMTypes or some other predefined list of enum names.
27212d747510SLisandro Dalcin 
2722db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2723db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2724db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, `PetscOptionsName()`,
2725c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2726db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2727db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
27282d747510SLisandro Dalcin @*/
27299371c9d4SSatish Balay PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const *list, PetscEnum ivalue[], PetscInt *nmax, PetscBool *set) {
27302d747510SLisandro Dalcin   const char *svalue;
27312d747510SLisandro Dalcin   char       *value;
27322d747510SLisandro Dalcin   PetscInt    n = 0;
27332d747510SLisandro Dalcin   PetscEnum   evalue;
27342d747510SLisandro Dalcin   PetscBool   flag;
27352d747510SLisandro Dalcin   PetscToken  token;
27362d747510SLisandro Dalcin 
27372d747510SLisandro Dalcin   PetscFunctionBegin;
27382d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
27392d747510SLisandro Dalcin   PetscValidPointer(list, 4);
27402d747510SLisandro Dalcin   PetscValidPointer(ivalue, 5);
27412d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 6);
27422d747510SLisandro Dalcin 
27439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
27449371c9d4SSatish Balay   if (!flag || !svalue) {
27459371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
27469371c9d4SSatish Balay     *nmax = 0;
27479371c9d4SSatish Balay     PetscFunctionReturn(0);
27489371c9d4SSatish Balay   }
27492d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
27509566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
27519566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
27522d747510SLisandro Dalcin   while (value && n < *nmax) {
27539566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
275428b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
27552d747510SLisandro Dalcin     ivalue[n++] = evalue;
27569566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
27572d747510SLisandro Dalcin   }
27589566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
27592d747510SLisandro Dalcin   *nmax = n;
27602d747510SLisandro Dalcin   PetscFunctionReturn(0);
27612d747510SLisandro Dalcin }
27622d747510SLisandro Dalcin 
27632d747510SLisandro Dalcin /*@C
2764f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
27652d747510SLisandro Dalcin 
27662d747510SLisandro Dalcin   Not Collective
27672d747510SLisandro Dalcin 
27682d747510SLisandro Dalcin   Input Parameters:
27692d747510SLisandro Dalcin + options - options database, use NULL for default global database
27702d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
27716b867d5aSJose E. Roman - name - the option one is seeking
27726b867d5aSJose E. Roman 
2773d8d19677SJose E. Roman   Output Parameters:
27742d747510SLisandro Dalcin + ivalue - the integer values to return
2775f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
27762d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
27772d747510SLisandro Dalcin 
27782d747510SLisandro Dalcin   Level: beginner
27792d747510SLisandro Dalcin 
27802d747510SLisandro Dalcin   Notes:
27812d747510SLisandro Dalcin   The array can be passed as
2782f1a722f8SMatthew G. Knepley .vb
27832d747510SLisandro Dalcin   a comma separated list:                                 0,1,2,3,4,5,6,7
27842d747510SLisandro Dalcin   a range (start-end+1):                                  0-8
27852d747510SLisandro Dalcin   a range with given increment (start-end+1:inc):         0-7:2
27862d747510SLisandro Dalcin   a combination of values and ranges separated by commas: 0,1-8,8-15:2
2787f1a722f8SMatthew G. Knepley .ve
27882d747510SLisandro Dalcin 
27892d747510SLisandro Dalcin   There must be no intervening spaces between the values.
27902d747510SLisandro Dalcin 
2791db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2792db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2793db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2794c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2795db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2796db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
27972d747510SLisandro Dalcin @*/
27989371c9d4SSatish Balay PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set) {
27992d747510SLisandro Dalcin   const char *svalue;
28002d747510SLisandro Dalcin   char       *value;
28012d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
28022d747510SLisandro Dalcin   size_t      len;
28032d747510SLisandro Dalcin   PetscBool   flag, foundrange;
28042d747510SLisandro Dalcin   PetscToken  token;
28052d747510SLisandro Dalcin 
28062d747510SLisandro Dalcin   PetscFunctionBegin;
28072d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
28082d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
28092d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
28102d747510SLisandro Dalcin 
28119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28129371c9d4SSatish Balay   if (!flag || !svalue) {
28139371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28149371c9d4SSatish Balay     *nmax = 0;
28159371c9d4SSatish Balay     PetscFunctionReturn(0);
28169371c9d4SSatish Balay   }
28172d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28189566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28199566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28202d747510SLisandro Dalcin   while (value && n < *nmax) {
28212d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
28222d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
28239566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value, &len));
28242d747510SLisandro Dalcin     if (value[0] == '-') i = 2;
28252d747510SLisandro Dalcin     else i = 1;
28262d747510SLisandro Dalcin     for (; i < (int)len; i++) {
28272d747510SLisandro Dalcin       if (value[i] == '-') {
2828cc73adaaSBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
28292d747510SLisandro Dalcin         value[i] = 0;
28302d747510SLisandro Dalcin 
28319566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value, &start));
28322d747510SLisandro Dalcin         inc = 1;
28332d747510SLisandro Dalcin         j   = i + 1;
28342d747510SLisandro Dalcin         for (; j < (int)len; j++) {
28352d747510SLisandro Dalcin           if (value[j] == ':') {
28362d747510SLisandro Dalcin             value[j] = 0;
28372d747510SLisandro Dalcin 
28389566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value + j + 1, &inc));
283908401ef6SPierre Jolivet             PetscCheck(inc > 0, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry,%s cannot have negative increment", n, value + j + 1);
28402d747510SLisandro Dalcin             break;
28412d747510SLisandro Dalcin           }
28422d747510SLisandro Dalcin         }
28439566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
284408401ef6SPierre 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);
28452d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
2846cc73adaaSBarry Smith         PetscCheck(n + nvalues <= *nmax, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, not enough space left in array (%" PetscInt_FMT ") to contain entire range from %" PetscInt_FMT " to %" PetscInt_FMT, n, *nmax - n, start, end);
28472d747510SLisandro Dalcin         for (; start < end; start += inc) {
28489371c9d4SSatish Balay           *ivalue = start;
28499371c9d4SSatish Balay           ivalue++;
28509371c9d4SSatish Balay           n++;
28512d747510SLisandro Dalcin         }
28522d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
28532d747510SLisandro Dalcin         break;
28542d747510SLisandro Dalcin       }
28552d747510SLisandro Dalcin     }
28562d747510SLisandro Dalcin     if (!foundrange) {
28579566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
28582d747510SLisandro Dalcin       ivalue++;
28592d747510SLisandro Dalcin       n++;
28602d747510SLisandro Dalcin     }
28619566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
28622d747510SLisandro Dalcin   }
28639566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28642d747510SLisandro Dalcin   *nmax = n;
28652d747510SLisandro Dalcin   PetscFunctionReturn(0);
28662d747510SLisandro Dalcin }
28672d747510SLisandro Dalcin 
28682d747510SLisandro Dalcin /*@C
28692d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
2870f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
28712d747510SLisandro Dalcin 
28722d747510SLisandro Dalcin   Not Collective
28732d747510SLisandro Dalcin 
28742d747510SLisandro Dalcin   Input Parameters:
28752d747510SLisandro Dalcin + options - options database, use NULL for default global database
28762d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
28776b867d5aSJose E. Roman - name - the option one is seeking
28786b867d5aSJose E. Roman 
28792d747510SLisandro Dalcin   Output Parameters:
28802d747510SLisandro Dalcin + dvalue - the double values to return
2881f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
28822d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
28832d747510SLisandro Dalcin 
28842d747510SLisandro Dalcin   Level: beginner
28852d747510SLisandro Dalcin 
2886db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2887db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2888db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2889c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2890db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2891db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
28922d747510SLisandro Dalcin @*/
28939371c9d4SSatish Balay PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set) {
28942d747510SLisandro Dalcin   const char *svalue;
28952d747510SLisandro Dalcin   char       *value;
28962d747510SLisandro Dalcin   PetscInt    n = 0;
28972d747510SLisandro Dalcin   PetscBool   flag;
28982d747510SLisandro Dalcin   PetscToken  token;
28992d747510SLisandro Dalcin 
29002d747510SLisandro Dalcin   PetscFunctionBegin;
29012d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
29022d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
29032d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
29042d747510SLisandro Dalcin 
29059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29069371c9d4SSatish Balay   if (!flag || !svalue) {
29079371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29089371c9d4SSatish Balay     *nmax = 0;
29099371c9d4SSatish Balay     PetscFunctionReturn(0);
29109371c9d4SSatish Balay   }
29112d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29129566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29139566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29142d747510SLisandro Dalcin   while (value && n < *nmax) {
29159566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
29169566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29172d747510SLisandro Dalcin     n++;
29182d747510SLisandro Dalcin   }
29199566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29202d747510SLisandro Dalcin   *nmax = n;
29212d747510SLisandro Dalcin   PetscFunctionReturn(0);
29222d747510SLisandro Dalcin }
29232d747510SLisandro Dalcin 
29242d747510SLisandro Dalcin /*@C
29252d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
2926f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
29272d747510SLisandro Dalcin 
29282d747510SLisandro Dalcin   Not Collective
29292d747510SLisandro Dalcin 
29302d747510SLisandro Dalcin   Input Parameters:
29312d747510SLisandro Dalcin + options - options database, use NULL for default global database
29322d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
29336b867d5aSJose E. Roman - name - the option one is seeking
29346b867d5aSJose E. Roman 
29352d747510SLisandro Dalcin   Output Parameters:
29362d747510SLisandro Dalcin + dvalue - the scalar values to return
2937f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
29382d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
29392d747510SLisandro Dalcin 
29402d747510SLisandro Dalcin   Level: beginner
29412d747510SLisandro Dalcin 
2942db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2943db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2944db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2945c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2946db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2947db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29482d747510SLisandro Dalcin @*/
29499371c9d4SSatish Balay PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set) {
29502d747510SLisandro Dalcin   const char *svalue;
29512d747510SLisandro Dalcin   char       *value;
29522d747510SLisandro Dalcin   PetscInt    n = 0;
29532d747510SLisandro Dalcin   PetscBool   flag;
29542d747510SLisandro Dalcin   PetscToken  token;
29552d747510SLisandro Dalcin 
29562d747510SLisandro Dalcin   PetscFunctionBegin;
29572d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2958064a246eSJacob Faibussowitsch   PetscValidScalarPointer(dvalue, 4);
29592d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
29602d747510SLisandro Dalcin 
29619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29629371c9d4SSatish Balay   if (!flag || !svalue) {
29639371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29649371c9d4SSatish Balay     *nmax = 0;
29659371c9d4SSatish Balay     PetscFunctionReturn(0);
29669371c9d4SSatish Balay   }
29672d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29689566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29699566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29702d747510SLisandro Dalcin   while (value && n < *nmax) {
29719566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value, dvalue++));
29729566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29732d747510SLisandro Dalcin     n++;
29742d747510SLisandro Dalcin   }
29759566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29762d747510SLisandro Dalcin   *nmax = n;
29772d747510SLisandro Dalcin   PetscFunctionReturn(0);
29782d747510SLisandro Dalcin }
297914ce751eSBarry Smith 
2980e5c89e4eSSatish Balay /*@C
2981e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
2982f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
2983e5c89e4eSSatish Balay 
2984e5c89e4eSSatish Balay   Not Collective
2985e5c89e4eSSatish Balay 
2986e5c89e4eSSatish Balay   Input Parameters:
29875c9cc608SHong Zhang + options - options database, use NULL for default global database
2988c5929fdfSBarry Smith . pre - string to prepend to name or NULL
29896b867d5aSJose E. Roman - name - the option one is seeking
29906b867d5aSJose E. Roman 
2991e7b76fa7SPatrick Sanan   Output Parameters:
2992e5c89e4eSSatish Balay + strings - location to copy strings
2993f1a722f8SMatthew G. Knepley . nmax - On input maximum number of strings, on output the actual number of strings found
299496ef3cdfSSatish Balay - set - PETSC_TRUE if found, else PETSC_FALSE
2995e5c89e4eSSatish Balay 
2996e5c89e4eSSatish Balay   Level: beginner
2997e5c89e4eSSatish Balay 
2998e5c89e4eSSatish Balay   Notes:
2999e7b76fa7SPatrick Sanan   The nmax parameter is used for both input and output.
3000e7b76fa7SPatrick Sanan 
3001e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
3002e5c89e4eSSatish Balay   strings returned by this function.
3003e5c89e4eSSatish Balay 
3004e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3005e5c89e4eSSatish Balay   returned. The Fortran interface for this routine is not supported.
3006e5c89e4eSSatish Balay 
3007db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3008db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3009db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3010c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3011db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3012db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3013e5c89e4eSSatish Balay @*/
30149371c9d4SSatish Balay PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set) {
30152d747510SLisandro Dalcin   const char *svalue;
3016e5c89e4eSSatish Balay   char       *value;
30172d747510SLisandro Dalcin   PetscInt    n = 0;
3018ace3abfcSBarry Smith   PetscBool   flag;
30199c9d3cfdSBarry Smith   PetscToken  token;
3020e5c89e4eSSatish Balay 
3021e5c89e4eSSatish Balay   PetscFunctionBegin;
30222d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
30232d747510SLisandro Dalcin   PetscValidPointer(strings, 4);
30242d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
3025e5c89e4eSSatish Balay 
30269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30279371c9d4SSatish Balay   if (!flag || !svalue) {
30289371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30299371c9d4SSatish Balay     *nmax = 0;
30309371c9d4SSatish Balay     PetscFunctionReturn(0);
30319371c9d4SSatish Balay   }
30322d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30339566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30349566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30352d747510SLisandro Dalcin   while (value && n < *nmax) {
30369566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
30379566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3038e5c89e4eSSatish Balay     n++;
3039e5c89e4eSSatish Balay   }
30409566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3041e5c89e4eSSatish Balay   *nmax = n;
3042e5c89e4eSSatish Balay   PetscFunctionReturn(0);
3043e5c89e4eSSatish Balay }
304406824ed3SPatrick Sanan 
304506824ed3SPatrick Sanan /*@C
304606824ed3SPatrick Sanan    PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one
304706824ed3SPatrick Sanan 
304806824ed3SPatrick Sanan    Prints a deprecation warning, unless an option is supplied to suppress.
304906824ed3SPatrick Sanan 
30501c9f3c13SBarry Smith    Logically Collective
305106824ed3SPatrick Sanan 
305206824ed3SPatrick Sanan    Input Parameters:
30539503aa97SPatrick Sanan +  pre - string to prepend to name or NULL
305406824ed3SPatrick Sanan .  oldname - the old, deprecated option
305506824ed3SPatrick Sanan .  newname - the new option, or NULL if option is purely removed
30569f3a6782SPatrick Sanan .  version - a string describing the version of first deprecation, e.g. "3.9"
30579f3a6782SPatrick Sanan -  info - additional information string, or NULL.
305806824ed3SPatrick Sanan 
305906824ed3SPatrick Sanan    Options Database Keys:
306006824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
306106824ed3SPatrick Sanan 
306206824ed3SPatrick Sanan    Notes:
30631c9f3c13SBarry Smith    Must be called between PetscOptionsBegin() (or PetscObjectOptionsBegin()) and PetscOptionsEnd().
30641c9f3c13SBarry Smith    Only the proces of rank zero that owns the PetscOptionsItems are argument (managed by PetscOptionsBegin() or
30651c9f3c13SBarry Smith    PetscObjectOptionsBegin() prints the information
3066b40114eaSPatrick Sanan    If newname is provided, the old option is replaced. Otherwise, it remains
3067b40114eaSPatrick Sanan    in the options database.
30689f3a6782SPatrick Sanan    If an option is not replaced, the info argument should be used to advise the user
30699f3a6782SPatrick Sanan    on how to proceed.
30709f3a6782SPatrick Sanan    There is a limit on the length of the warning printed, so very long strings
30719f3a6782SPatrick Sanan    provided as info may be truncated.
307206824ed3SPatrick Sanan 
307306824ed3SPatrick Sanan    Level: developer
307406824ed3SPatrick Sanan 
3075db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
307606824ed3SPatrick Sanan 
307706824ed3SPatrick Sanan @*/
30789371c9d4SSatish Balay PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[]) {
307906824ed3SPatrick Sanan   PetscBool         found, quiet;
308006824ed3SPatrick Sanan   const char       *value;
308106824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
30829f3a6782SPatrick Sanan   char              msg[4096];
3083b0bdc838SStefano Zampini   char             *prefix  = NULL;
3084b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3085b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
308606824ed3SPatrick Sanan 
308706824ed3SPatrick Sanan   PetscFunctionBegin;
308806824ed3SPatrick Sanan   PetscValidCharPointer(oldname, 2);
308906824ed3SPatrick Sanan   PetscValidCharPointer(version, 4);
3090b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3091b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3092b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3093b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3094b0bdc838SStefano Zampini   }
30959566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
309606824ed3SPatrick Sanan   if (found) {
309706824ed3SPatrick Sanan     if (newname) {
30981baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
30999566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options, newname, value));
31001baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
31019566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3102b40114eaSPatrick Sanan     }
310306824ed3SPatrick Sanan     quiet = PETSC_FALSE;
31049566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
310506824ed3SPatrick Sanan     if (!quiet) {
31069566063dSJacob Faibussowitsch       PetscCall(PetscStrcpy(msg, "** PETSc DEPRECATION WARNING ** : the option "));
31079566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, oldname));
31089566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, " is deprecated as of version "));
31099566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, version));
31109566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, " and will be removed in a future release."));
311106824ed3SPatrick Sanan       if (newname) {
31129566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, " Please use the option "));
31139566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, newname));
31149566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, " instead."));
311506824ed3SPatrick Sanan       }
31169f3a6782SPatrick Sanan       if (info) {
31179566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, " "));
31189566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, info));
31199f3a6782SPatrick Sanan       }
31209566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, " (Silence this warning with "));
31219566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, quietopt));
31229566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, ")\n"));
31239566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
312406824ed3SPatrick Sanan     }
312506824ed3SPatrick Sanan   }
312606824ed3SPatrick Sanan   PetscFunctionReturn(0);
312706824ed3SPatrick Sanan }
3128