xref: /petsc/src/sys/objects/options.c (revision 811af0c4b09a35de4306c442f88bd09fdc09897d)
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 
137*811af0c4SBarry Smith    Note:
138*811af0c4SBarry Smith    Though PETSc has a concept of multiple options database the current code uses a single default `PetscOptions` object
139*811af0c4SBarry Smith 
140*811af0c4SBarry Smith    Developer Notes:
141*811af0c4SBarry Smith    We may want eventually to pass a `MPI_Comm` to determine the ownership of the object
142*811af0c4SBarry Smith 
143*811af0c4SBarry Smith    This object never got developed after being introduced, it is not clear that supporting multiple `PetscOptions` objects is useful
1441c9f3c13SBarry Smith 
145db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
146e5c89e4eSSatish Balay @*/
1479371c9d4SSatish Balay PetscErrorCode PetscOptionsCreate(PetscOptions *options) {
14839a651e2SJacob Faibussowitsch   PetscFunctionBegin;
14939a651e2SJacob Faibussowitsch   PetscValidPointer(options, 1);
1502d747510SLisandro Dalcin   *options = (PetscOptions)calloc(1, sizeof(**options));
15139a651e2SJacob Faibussowitsch   PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
15239a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1532d747510SLisandro Dalcin }
1542d747510SLisandro Dalcin 
1552d747510SLisandro Dalcin /*@
1562d747510SLisandro Dalcin     PetscOptionsDestroy - Destroys an option database.
1572d747510SLisandro Dalcin 
158*811af0c4SBarry Smith     Logically collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
1591c9f3c13SBarry Smith 
1602d747510SLisandro Dalcin   Input Parameter:
161*811af0c4SBarry Smith .  options - the `PetscOptions` object
1622d747510SLisandro Dalcin 
1633de2bfdfSBarry Smith    Level: advanced
1642d747510SLisandro Dalcin 
165db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
1662d747510SLisandro Dalcin @*/
1679371c9d4SSatish Balay PetscErrorCode PetscOptionsDestroy(PetscOptions *options) {
168362febeeSStefano Zampini   PetscFunctionBegin;
16939a651e2SJacob Faibussowitsch   if (!*options) PetscFunctionReturn(0);
1705f80ce2aSJacob 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()");
1719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsClear(*options));
1722d747510SLisandro Dalcin   /* XXX what about monitors ? */
1732800570dSLisandro Dalcin   free(*options);
1742d747510SLisandro Dalcin   *options = NULL;
175e5c89e4eSSatish Balay   PetscFunctionReturn(0);
176e5c89e4eSSatish Balay }
177e5c89e4eSSatish Balay 
1782d747510SLisandro Dalcin /*
1792d747510SLisandro Dalcin     PetscOptionsCreateDefault - Creates the default global options database
1802d747510SLisandro Dalcin */
1819371c9d4SSatish Balay PetscErrorCode PetscOptionsCreateDefault(void) {
18239a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1839566063dSJacob Faibussowitsch   if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
18439a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1852d747510SLisandro Dalcin }
1862d747510SLisandro Dalcin 
187b4205f0bSBarry Smith /*@
188*811af0c4SBarry Smith       PetscOptionsPush - Push a new `PetscOptions` object as the default provider of options
1891c9f3c13SBarry Smith                          Allows using different parts of a code to use different options databases
190b4205f0bSBarry Smith 
191b4205f0bSBarry Smith   Logically Collective
192b4205f0bSBarry Smith 
193b4205f0bSBarry Smith   Input Parameter:
194*811af0c4SBarry Smith .   opt - the options obtained with `PetscOptionsCreate()`
195b4205f0bSBarry Smith 
196b4205f0bSBarry Smith   Notes:
197*811af0c4SBarry Smith   Use `PetscOptionsPop()` to return to the previous default options database
1981c9f3c13SBarry Smith 
199*811af0c4SBarry Smith   The collectivity of this routine is complex; only the MPI ranks that call this routine will
2001c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
2011c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
2021c9f3c13SBarry Smith   on different ranks.
203b4205f0bSBarry Smith 
204*811af0c4SBarry Smith   Developer Note:
205*811af0c4SBarry Smith   Though this functionality has been provided it has never been used in PETSc and might be removed.
206*811af0c4SBarry Smith 
2073de2bfdfSBarry Smith    Level: advanced
2083de2bfdfSBarry Smith 
209db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
210b4205f0bSBarry Smith @*/
2119371c9d4SSatish Balay PetscErrorCode PetscOptionsPush(PetscOptions opt) {
212b4205f0bSBarry Smith   PetscFunctionBegin;
2139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsCreateDefault());
214b4205f0bSBarry Smith   opt->previous  = defaultoptions;
215b4205f0bSBarry Smith   defaultoptions = opt;
216b4205f0bSBarry Smith   PetscFunctionReturn(0);
217b4205f0bSBarry Smith }
218b4205f0bSBarry Smith 
219b4205f0bSBarry Smith /*@
220*811af0c4SBarry Smith       PetscOptionsPop - Pop the most recent `PetscOptionsPush() `to return to the previous default options
221b4205f0bSBarry Smith 
222*811af0c4SBarry Smith       Logically collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
223b4205f0bSBarry Smith 
2243de2bfdfSBarry Smith    Level: advanced
2253de2bfdfSBarry Smith 
226db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
227b4205f0bSBarry Smith @*/
2289371c9d4SSatish Balay PetscErrorCode PetscOptionsPop(void) {
2293de2bfdfSBarry Smith   PetscOptions current = defaultoptions;
2303de2bfdfSBarry Smith 
231b4205f0bSBarry Smith   PetscFunctionBegin;
23228b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing default options");
23328b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions->previous, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscOptionsPop() called too many times");
234b4205f0bSBarry Smith   defaultoptions    = defaultoptions->previous;
2353de2bfdfSBarry Smith   current->previous = NULL;
236b4205f0bSBarry Smith   PetscFunctionReturn(0);
237b4205f0bSBarry Smith }
238b4205f0bSBarry Smith 
2392d747510SLisandro Dalcin /*
2402d747510SLisandro Dalcin     PetscOptionsDestroyDefault - Destroys the default global options database
2412d747510SLisandro Dalcin */
2429371c9d4SSatish Balay PetscErrorCode PetscOptionsDestroyDefault(void) {
24339a651e2SJacob Faibussowitsch   PetscFunctionBegin;
24439a651e2SJacob Faibussowitsch   if (!defaultoptions) PetscFunctionReturn(0);
2453de2bfdfSBarry Smith   /* Destroy any options that the user forgot to pop */
2463de2bfdfSBarry Smith   while (defaultoptions->previous) {
24739a651e2SJacob Faibussowitsch     PetscOptions tmp = defaultoptions;
24839a651e2SJacob Faibussowitsch 
2499566063dSJacob Faibussowitsch     PetscCall(PetscOptionsPop());
2509566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDestroy(&tmp));
2513de2bfdfSBarry Smith   }
2529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDestroy(&defaultoptions));
25339a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
254e5c89e4eSSatish Balay }
255e5c89e4eSSatish Balay 
25694ef8ddeSSatish Balay /*@C
2577cd08cecSJed Brown    PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
2583fc1eb6aSBarry Smith 
259447722d5SBarry Smith    Not collective
2601c9f3c13SBarry Smith 
2613fc1eb6aSBarry Smith    Input Parameter:
2622d747510SLisandro Dalcin .  key - string to check if valid
2633fc1eb6aSBarry Smith 
2643fc1eb6aSBarry Smith    Output Parameter:
265*811af0c4SBarry Smith .  valid - `PETSC_TRUE` if a valid key
2663fc1eb6aSBarry Smith 
267f6680f47SSatish Balay    Level: intermediate
2683fc1eb6aSBarry Smith @*/
2699371c9d4SSatish Balay PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid) {
270f603b5e9SToby Isaac   char *ptr;
2717c5db45bSBarry Smith 
27296fc60bcSBarry Smith   PetscFunctionBegin;
2732d747510SLisandro Dalcin   if (key) PetscValidCharPointer(key, 1);
274dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(valid, 2);
2752d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2762d747510SLisandro Dalcin   if (!key) PetscFunctionReturn(0);
2772d747510SLisandro Dalcin   if (key[0] != '-') PetscFunctionReturn(0);
2782d747510SLisandro Dalcin   if (key[1] == '-') key++;
279c850d057SPierre Jolivet   if (!isalpha((int)key[1])) PetscFunctionReturn(0);
2802d747510SLisandro Dalcin   (void)strtod(key, &ptr);
281c850d057SPierre Jolivet   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(0);
2822d747510SLisandro Dalcin   *valid = PETSC_TRUE;
28396fc60bcSBarry Smith   PetscFunctionReturn(0);
28496fc60bcSBarry Smith }
28596fc60bcSBarry Smith 
286e5c89e4eSSatish Balay /*@C
287e5c89e4eSSatish Balay    PetscOptionsInsertString - Inserts options into the database from a string
288e5c89e4eSSatish Balay 
2891c9f3c13SBarry Smith    Logically Collective
290e5c89e4eSSatish Balay 
291d8d19677SJose E. Roman    Input Parameters:
292080f0011SToby Isaac +  options - options object
293080f0011SToby Isaac -  in_str - string that contains options separated by blanks
294e5c89e4eSSatish Balay 
295e5c89e4eSSatish Balay    Level: intermediate
296e5c89e4eSSatish Balay 
297*811af0c4SBarry Smith   The collectivity of this routine is complex; only the MPI ranks that call this routine will
2981c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
2991c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
3001c9f3c13SBarry Smith   on different ranks.
3011c9f3c13SBarry Smith 
302e5c89e4eSSatish Balay    Contributed by Boyana Norris
303e5c89e4eSSatish Balay 
304db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
305db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
306db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
307c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
308db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
309db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
310e5c89e4eSSatish Balay @*/
3119371c9d4SSatish Balay PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[]) {
312d06005cbSLisandro Dalcin   MPI_Comm   comm = PETSC_COMM_SELF;
313d06005cbSLisandro Dalcin   char      *first, *second;
3149c9d3cfdSBarry Smith   PetscToken token;
315e5c89e4eSSatish Balay 
316e5c89e4eSSatish Balay   PetscFunctionBegin;
3179566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(in_str, ' ', &token));
3189566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &first));
31996fc60bcSBarry Smith   while (first) {
320d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
3219566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
3229566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
3239566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
3249566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
3259566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
3269566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(first, &key));
327d06005cbSLisandro Dalcin     if (!key) {
3289566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
329d06005cbSLisandro Dalcin     } else if (isfile) {
3309566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3319566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, second, PETSC_TRUE));
3329566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
333d06005cbSLisandro Dalcin     } else if (isfileyaml) {
3349566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3359566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, second, PETSC_TRUE));
3369566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
337d06005cbSLisandro Dalcin     } else if (isstringyaml) {
3389566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3399566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options, second));
3409566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
341d06005cbSLisandro Dalcin     } else if (ispush) {
3429566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3439566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, second));
3449566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
3459db968c8SJed Brown     } else if (ispop) {
3469566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
3479566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
348d06005cbSLisandro Dalcin     } else {
3499566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3509566063dSJacob Faibussowitsch       PetscCall(PetscOptionsValidKey(second, &key));
35196fc60bcSBarry Smith       if (!key) {
3529566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, first, second));
3539566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &first));
35496fc60bcSBarry Smith       } else {
3559566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, first, NULL));
35696fc60bcSBarry Smith         first = second;
35796fc60bcSBarry Smith       }
358e5c89e4eSSatish Balay     }
359e5c89e4eSSatish Balay   }
3609566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
361e5c89e4eSSatish Balay   PetscFunctionReturn(0);
362e5c89e4eSSatish Balay }
363e5c89e4eSSatish Balay 
3643fc1eb6aSBarry Smith /*
3653fc1eb6aSBarry Smith     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
3663fc1eb6aSBarry Smith */
3679371c9d4SSatish Balay static char *Petscgetline(FILE *f) {
3685fa91da5SBarry Smith   size_t size = 0;
3695fa91da5SBarry Smith   size_t len  = 0;
3705fa91da5SBarry Smith   size_t last = 0;
3710298fd71SBarry Smith   char  *buf  = NULL;
3725fa91da5SBarry Smith 
37302c9f0b5SLisandro Dalcin   if (feof(f)) return NULL;
3745fa91da5SBarry Smith   do {
3755fa91da5SBarry Smith     size += 1024;                             /* BUFSIZ is defined as "the optimal read size for this platform" */
3766e0c8459SSatish Balay     buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
3775fa91da5SBarry Smith     /* Actually do the read. Note that fgets puts a terminal '\0' on the
3785fa91da5SBarry Smith     end of the string, so we make sure we overwrite this */
379e86f3e45SDave May     if (!fgets(buf + len, 1024, f)) buf[len] = 0;
3805fa91da5SBarry Smith     PetscStrlen(buf, &len);
3815fa91da5SBarry Smith     last = len - 1;
3825fa91da5SBarry Smith   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
38308ac41f7SSatish Balay   if (len) return buf;
3845fa91da5SBarry Smith   free(buf);
38502c9f0b5SLisandro Dalcin   return NULL;
3865fa91da5SBarry Smith }
3875fa91da5SBarry Smith 
3889371c9d4SSatish Balay static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml) {
389be10d61cSLisandro Dalcin   char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
390e5c89e4eSSatish Balay 
391be10d61cSLisandro Dalcin   PetscFunctionBegin;
392362febeeSStefano Zampini   *yaml = PETSC_FALSE;
3939566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
3949566063dSJacob Faibussowitsch   PetscCall(PetscFixFilename(fname, path));
3959566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(path, ":yaml", yaml));
396be10d61cSLisandro Dalcin   if (*yaml) {
3979566063dSJacob Faibussowitsch     PetscCall(PetscStrrchr(path, ':', &tail));
398be10d61cSLisandro Dalcin     tail[-1] = 0; /* remove ":yaml" suffix from path */
399be10d61cSLisandro Dalcin   }
4009566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
401a1d2f846SLisandro Dalcin   /* check for standard YAML and JSON filename extensions */
4029566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
4039566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
4049566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
405a1d2f846SLisandro Dalcin   if (!*yaml) { /* check file contents */
406a1d2f846SLisandro Dalcin     PetscMPIInt rank;
4079566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
408dd400576SPatrick Sanan     if (rank == 0) {
409a1d2f846SLisandro Dalcin       FILE *fh = fopen(filename, "r");
410a1d2f846SLisandro Dalcin       if (fh) {
411a1d2f846SLisandro Dalcin         char buf[6] = "";
412a1d2f846SLisandro Dalcin         if (fread(buf, 1, 6, fh) > 0) {
4139566063dSJacob Faibussowitsch           PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml));          /* check for '%YAML' tag */
4149566063dSJacob Faibussowitsch           if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
415a1d2f846SLisandro Dalcin         }
416a1d2f846SLisandro Dalcin         (void)fclose(fh);
417a1d2f846SLisandro Dalcin       }
418a1d2f846SLisandro Dalcin     }
4199566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(yaml, 1, MPIU_BOOL, 0, comm));
420a1d2f846SLisandro Dalcin   }
421be10d61cSLisandro Dalcin   PetscFunctionReturn(0);
422be10d61cSLisandro Dalcin }
423e5c89e4eSSatish Balay 
4249371c9d4SSatish Balay static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require) {
4258c0b561eSLisandro Dalcin   char       *string, *vstring = NULL, *astring = NULL, *packed = NULL;
4267fb43599SVaclav Hapla   char       *tokens[4];
42713e3f751SJed Brown   size_t      i, len, bytes;
428e5c89e4eSSatish Balay   FILE       *fd;
4297fb43599SVaclav Hapla   PetscToken  token = NULL;
430ed9cf6e9SBarry Smith   int         err;
431581bbe83SVaclav Hapla   char       *cmatch;
432581bbe83SVaclav Hapla   const char  cmt  = '#';
4339210b8eaSVaclav Hapla   PetscInt    line = 1;
4343a018368SJed Brown   PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
4359210b8eaSVaclav Hapla   PetscBool   isdir, alias = PETSC_FALSE, valid;
436e5c89e4eSSatish Balay 
437e5c89e4eSSatish Balay   PetscFunctionBegin;
4389566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tokens, sizeof(tokens)));
4399566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
440dd400576SPatrick Sanan   if (rank == 0) {
4418c0b561eSLisandro Dalcin     char fpath[PETSC_MAX_PATH_LEN];
4428c0b561eSLisandro Dalcin     char fname[PETSC_MAX_PATH_LEN];
44305c7dedfSBarry Smith 
4449566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
4459566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
4468c0b561eSLisandro Dalcin 
447e5c89e4eSSatish Balay     fd = fopen(fname, "r");
4489566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname, 'r', &isdir));
44908401ef6SPierre Jolivet     PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
450ad38b122SPatrick Sanan     if (fd && !isdir) {
4513a018368SJed Brown       PetscSegBuffer vseg, aseg;
4529566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4539566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4543a018368SJed Brown 
4559b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4569566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
457e24ecc5dSJed Brown 
4585fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4594704e885SBarry Smith         /* eliminate comments from each line */
4609566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
46190f79514SSatish Balay         if (cmatch) *cmatch = 0;
4629566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4635981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
464e5c89e4eSSatish Balay         for (i = 0; i < len; i++) {
465ad540459SPierre Jolivet           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
466e5c89e4eSSatish Balay         }
4679566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4689566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4697fb43599SVaclav Hapla         if (!tokens[0]) {
47002b0d46eSSatish Balay           goto destroy;
4717fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
4729566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
47390f79514SSatish Balay         }
47448a46eb9SPierre Jolivet         for (i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
4757fb43599SVaclav Hapla         if (!tokens[0]) {
4762662f744SSatish Balay           goto destroy;
4777fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
4789566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
47928b400f6SJacob 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]);
4809566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
4819566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
4829566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
483e24ecc5dSJed Brown           vstring[len] = ' ';
4847fb43599SVaclav Hapla           if (tokens[1]) {
4859566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
48628b400f6SJacob 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]);
4879566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
4889566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
489e24ecc5dSJed Brown             vstring[0] = '"';
4909566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
491e24ecc5dSJed Brown             vstring[len + 1] = '"';
492e24ecc5dSJed Brown             vstring[len + 2] = ' ';
49309192fe3SBarry Smith           }
49490f79514SSatish Balay         } else {
4959566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
4969210b8eaSVaclav Hapla           if (alias) {
4979566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
49828b400f6SJacob 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]);
49908401ef6SPierre 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]);
5009566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
50128b400f6SJacob 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]);
5029566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5039566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5049566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
505e24ecc5dSJed Brown             astring[len] = ' ';
506e24ecc5dSJed Brown 
5079566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5089566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5099566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
510e24ecc5dSJed Brown             astring[len] = ' ';
51198921bdaSJacob 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]);
5129210b8eaSVaclav Hapla         }
5139210b8eaSVaclav Hapla         {
5149210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
51528b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
516e5c89e4eSSatish Balay         }
51702b0d46eSSatish Balay       destroy:
5184b40f50bSBarry Smith         free(string);
5199566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5209210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5219210b8eaSVaclav Hapla         line++;
522e5c89e4eSSatish Balay       }
523ed9cf6e9SBarry Smith       err = fclose(fd);
52428b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5259566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5269566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5279566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
528e24ecc5dSJed Brown       astring[0] = 0;
5299566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5309566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5319566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
532e24ecc5dSJed Brown       vstring[0] = 0;
5339566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5349566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5359566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5369566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5379566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
53828b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5399b754dc9SBarry Smith   }
54005c7dedfSBarry Smith 
5413a018368SJed Brown   counts[0] = acnt;
5423a018368SJed Brown   counts[1] = cnt;
5434201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
54428b400f6SJacob 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/");
5453a018368SJed Brown   acnt = counts[0];
5463a018368SJed Brown   cnt  = counts[1];
54748a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5483a018368SJed Brown   if (acnt || cnt) {
5499566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5503a018368SJed Brown     astring = packed;
5513a018368SJed Brown     vstring = packed + acnt + 1;
5523a018368SJed Brown   }
5533a018368SJed Brown 
5549b754dc9SBarry Smith   if (acnt) {
5559566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5569566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5577fb43599SVaclav Hapla     while (tokens[0]) {
5589566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5599566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5609566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5619b754dc9SBarry Smith     }
5629566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5639b754dc9SBarry Smith   }
5649b754dc9SBarry Smith 
5651baa6e33SBarry Smith   if (cnt) PetscCall(PetscOptionsInsertString(options, vstring));
5669566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
567e5c89e4eSSatish Balay   PetscFunctionReturn(0);
568e5c89e4eSSatish Balay }
569e5c89e4eSSatish Balay 
570d06005cbSLisandro Dalcin /*@C
571be10d61cSLisandro Dalcin      PetscOptionsInsertFile - Inserts options into the database from a file.
572be10d61cSLisandro Dalcin 
573be10d61cSLisandro Dalcin      Collective
574be10d61cSLisandro Dalcin 
575d8d19677SJose E. Roman   Input Parameters:
576*811af0c4SBarry Smith +   comm - the processes that will share the options (usually `PETSC_COMM_WORLD`)
577be10d61cSLisandro Dalcin .   options - options database, use NULL for default global database
578be10d61cSLisandro Dalcin .   file - name of file,
579be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
580be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
581*811af0c4SBarry Smith -   require - if `PETSC_TRUE` will generate an error if the file does not exist
582be10d61cSLisandro Dalcin 
583be10d61cSLisandro Dalcin   Notes:
584be10d61cSLisandro Dalcin    Use  # for lines that are comments and which should be ignored.
585*811af0c4SBarry Smith    Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
586be10d61cSLisandro 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
587be10d61cSLisandro Dalcin    calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().
588*811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks in comm will
589be10d61cSLisandro Dalcin    have the affect of these options. If some processes that create objects call this routine and others do
590be10d61cSLisandro Dalcin    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
591be10d61cSLisandro Dalcin    on different ranks.
592be10d61cSLisandro Dalcin 
593be10d61cSLisandro Dalcin   Level: developer
594be10d61cSLisandro Dalcin 
595db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
596db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
597db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
598c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
599db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
600db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
601be10d61cSLisandro Dalcin @*/
6029371c9d4SSatish Balay PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require) {
603be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
604be10d61cSLisandro Dalcin   PetscBool yaml;
605be10d61cSLisandro Dalcin 
606be10d61cSLisandro Dalcin   PetscFunctionBegin;
6079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
608be10d61cSLisandro Dalcin   if (yaml) {
6099566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
610be10d61cSLisandro Dalcin   } else {
6119566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
612be10d61cSLisandro Dalcin   }
613be10d61cSLisandro Dalcin   PetscFunctionReturn(0);
614be10d61cSLisandro Dalcin }
615be10d61cSLisandro Dalcin 
616be10d61cSLisandro Dalcin /*@C
617d06005cbSLisandro Dalcin    PetscOptionsInsertArgs - Inserts options into the database from a array of strings
618d06005cbSLisandro Dalcin 
619d06005cbSLisandro Dalcin    Logically Collective
620d06005cbSLisandro Dalcin 
621d8d19677SJose E. Roman    Input Parameters:
622d06005cbSLisandro Dalcin +  options - options object
6236aad120cSJose E. Roman .  argc - the array length
624d06005cbSLisandro Dalcin -  args - the string array
625d06005cbSLisandro Dalcin 
626d06005cbSLisandro Dalcin    Level: intermediate
627d06005cbSLisandro Dalcin 
628db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
629d06005cbSLisandro Dalcin @*/
6309371c9d4SSatish Balay PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, char *args[]) {
631d06005cbSLisandro Dalcin   MPI_Comm     comm  = PETSC_COMM_WORLD;
632d06005cbSLisandro Dalcin   int          left  = PetscMax(argc, 0);
633d06005cbSLisandro Dalcin   char *const *eargs = args;
63485079163SJed Brown 
63585079163SJed Brown   PetscFunctionBegin;
63685079163SJed Brown   while (left) {
637d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6389566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6399566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6409566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6419566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6429566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6439566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
644093de6efSBarry Smith     if (!key) {
6459371c9d4SSatish Balay       eargs++;
6469371c9d4SSatish Balay       left--;
647d06005cbSLisandro Dalcin     } else if (isfile) {
648cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6499566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6509371c9d4SSatish Balay       eargs += 2;
6519371c9d4SSatish Balay       left -= 2;
652d06005cbSLisandro Dalcin     } else if (isfileyaml) {
653cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6549566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6559371c9d4SSatish Balay       eargs += 2;
6569371c9d4SSatish Balay       left -= 2;
657d06005cbSLisandro Dalcin     } else if (isstringyaml) {
658cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6599566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options, eargs[1]));
6609371c9d4SSatish Balay       eargs += 2;
6619371c9d4SSatish Balay       left -= 2;
662d06005cbSLisandro Dalcin     } else if (ispush) {
66308401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
664cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6659566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6669371c9d4SSatish Balay       eargs += 2;
6679371c9d4SSatish Balay       left -= 2;
668d06005cbSLisandro Dalcin     } else if (ispop) {
6699566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
6709371c9d4SSatish Balay       eargs++;
6719371c9d4SSatish Balay       left--;
6727935c3d8SJed Brown     } else {
6737935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
6749566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
67598b6bf53SJed Brown       if (left < 2 || nextiskey) {
6769566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, eargs[0], NULL));
6779371c9d4SSatish Balay         eargs++;
6789371c9d4SSatish Balay         left--;
67985079163SJed Brown       } else {
6809566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, eargs[0], eargs[1]));
6819371c9d4SSatish Balay         eargs += 2;
6829371c9d4SSatish Balay         left -= 2;
68385079163SJed Brown       }
68485079163SJed Brown     }
6857935c3d8SJed Brown   }
68685079163SJed Brown   PetscFunctionReturn(0);
68785079163SJed Brown }
68885079163SJed Brown 
6899371c9d4SSatish Balay static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], PetscBool set[], PetscBool *flg) {
690c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
691c5b5d8d5SVaclav Hapla   if (set[opt]) {
6929566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
693c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
694c5b5d8d5SVaclav Hapla   PetscFunctionReturn(0);
695c5b5d8d5SVaclav Hapla }
696c5b5d8d5SVaclav Hapla 
697660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
6989371c9d4SSatish Balay static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set) {
699c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
700c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
701c5b5d8d5SVaclav Hapla   size_t             o;
702c5b5d8d5SVaclav Hapla   int                a;
703c5b5d8d5SVaclav Hapla   const char       **val;
7040c99d500SBarry Smith   char             **cval;
705660278c0SBarry Smith   PetscBool         *set, unneeded;
706c5b5d8d5SVaclav Hapla 
707c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7080c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7090c99d500SBarry Smith   val = (const char **)cval;
710c5b5d8d5SVaclav Hapla 
711c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
71248a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
713c5b5d8d5SVaclav Hapla 
714a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
715c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
716c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
717c5b5d8d5SVaclav Hapla 
7189566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
719c5b5d8d5SVaclav Hapla     if (!valid) continue;
720c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7219566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
722c5b5d8d5SVaclav Hapla       if (eq) {
723c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
724c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
725c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
726c5b5d8d5SVaclav Hapla         break;
727c5b5d8d5SVaclav Hapla       }
728c5b5d8d5SVaclav Hapla     }
729c5b5d8d5SVaclav Hapla   }
730c5b5d8d5SVaclav Hapla 
731c5b5d8d5SVaclav Hapla   /* Process flags */
7329566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
733d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7349566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
735660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
736660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
737660278c0SBarry Smith   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a));
7389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7409566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
741c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
742c5b5d8d5SVaclav Hapla 
743c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
744660278c0SBarry Smith   for (o = 1; o < n; o++) {
745c5b5d8d5SVaclav Hapla     if (set[o]) {
7469566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a));
747d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
748c5b5d8d5SVaclav Hapla     }
749c5b5d8d5SVaclav Hapla   }
7500c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
751c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
752c5b5d8d5SVaclav Hapla   PetscFunctionReturn(0);
753c5b5d8d5SVaclav Hapla }
754c5b5d8d5SVaclav Hapla 
7559371c9d4SSatish Balay static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg) {
75639a651e2SJacob Faibussowitsch   PetscFunctionBegin;
75739a651e2SJacob Faibussowitsch   PetscValidBoolPointer(flg, 3);
758c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
759c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
76039a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
761c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
762c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7639566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
764c5b5d8d5SVaclav Hapla         if (*flg) break;
765c5b5d8d5SVaclav Hapla       }
766c5b5d8d5SVaclav Hapla     }
767c5b5d8d5SVaclav Hapla   }
76839a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
769c5b5d8d5SVaclav Hapla }
77085079163SJed Brown 
771e5c89e4eSSatish Balay /*@C
772e5c89e4eSSatish Balay    PetscOptionsInsert - Inserts into the options database from the command line,
773e5c89e4eSSatish Balay                         the environmental variable and a file.
774e5c89e4eSSatish Balay 
775*811af0c4SBarry Smith    Collective on `PETSC_COMM_WORLD`
7761c9f3c13SBarry Smith 
777e5c89e4eSSatish Balay    Input Parameters:
778c5929fdfSBarry Smith +  options - options database or NULL for the default global database
779c5929fdfSBarry Smith .  argc - count of number of command line arguments
780e5c89e4eSSatish Balay .  args - the command line arguments
781be10d61cSLisandro Dalcin -  file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
782be10d61cSLisandro Dalcin           Use NULL or empty string to not check for code specific file.
783be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
784c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
785e5c89e4eSSatish Balay 
786081c24baSBoyana Norris    Options Database Keys:
787d06005cbSLisandro Dalcin +   -options_file <filename> - read options from a file
788d06005cbSLisandro Dalcin -   -options_file_yaml <filename> - read options from a YAML file
789c5b5d8d5SVaclav Hapla 
790*811af0c4SBarry Smith    Notes:
791*811af0c4SBarry Smith    Since PetscOptionsInsert() is automatically called by `PetscInitialize()`,
792*811af0c4SBarry Smith    the user does not typically need to call this routine. `PetscOptionsInsert()`
793*811af0c4SBarry Smith    can be called several times, adding additional entries into the database.
794*811af0c4SBarry Smith 
795*811af0c4SBarry Smith    See `PetscInitialize()` for options related to option database monitoring.
796081c24baSBoyana Norris 
797e5c89e4eSSatish Balay    Level: advanced
798e5c89e4eSSatish Balay 
799db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
800db781477SPatrick Sanan           `PetscInitialize()`
801e5c89e4eSSatish Balay @*/
8029371c9d4SSatish Balay PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[]) {
803d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
804e5c89e4eSSatish Balay   PetscMPIInt rank;
805c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
806c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
807e5c89e4eSSatish Balay 
808e5c89e4eSSatish Balay   PetscFunctionBegin;
80908401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8109566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
811e5c89e4eSSatish Balay 
812c5b5d8d5SVaclav Hapla   if (!options) {
8139566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
814c5b5d8d5SVaclav Hapla     options = defaultoptions;
815c5b5d8d5SVaclav Hapla   }
816c5b5d8d5SVaclav Hapla   if (hasArgs) {
817c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8189566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
819660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
820c5b5d8d5SVaclav Hapla   }
8214b09e917SBarry Smith   if (file && file[0]) {
8229566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
823c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8249566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
825321366bcSBarry Smith   }
826c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
827be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8289566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8299566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
8309566063dSJacob Faibussowitsch     if (filename[0]) PetscCall(PetscStrcat(filename, "/.petscrc"));
8319566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8329566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8339566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
834e5c89e4eSSatish Balay   }
835e5c89e4eSSatish Balay 
8362d747510SLisandro Dalcin   /* insert environment options */
837e5c89e4eSSatish Balay   {
8382d747510SLisandro Dalcin     char  *eoptions = NULL;
839e5c89e4eSSatish Balay     size_t len      = 0;
840dd400576SPatrick Sanan     if (rank == 0) {
841e5c89e4eSSatish Balay       eoptions = (char *)getenv("PETSC_OPTIONS");
8429566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
843e5c89e4eSSatish Balay     }
8449566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
845e5c89e4eSSatish Balay     if (len) {
8469566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8479566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
84896fc60bcSBarry Smith       if (rank) eoptions[len] = 0;
8499566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertString(options, eoptions));
8509566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
851e5c89e4eSSatish Balay     }
852e5c89e4eSSatish Balay   }
853e5c89e4eSSatish Balay 
854d06005cbSLisandro Dalcin   /* insert YAML environment options */
85556a31166SBarry Smith   {
8569fc438c3SToby Isaac     char  *eoptions = NULL;
8579fc438c3SToby Isaac     size_t len      = 0;
858dd400576SPatrick Sanan     if (rank == 0) {
8599fc438c3SToby Isaac       eoptions = (char *)getenv("PETSC_OPTIONS_YAML");
8609566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
8619fc438c3SToby Isaac     }
8629566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8639fc438c3SToby Isaac     if (len) {
8649566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8659566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
8669fc438c3SToby Isaac       if (rank) eoptions[len] = 0;
8679566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options, eoptions));
8689566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
8699fc438c3SToby Isaac     }
8709fc438c3SToby Isaac   }
8713bcbd388SSean Farley 
872c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
8739566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, *args + 1));
874660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
875e5c89e4eSSatish Balay   PetscFunctionReturn(0);
876e5c89e4eSSatish Balay }
877e5c89e4eSSatish Balay 
878660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
879660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
8809371c9d4SSatish Balay static const char *PetscCIOptions[] = {
8819371c9d4SSatish Balay   "malloc_debug",
882660278c0SBarry Smith   "malloc_dump",
883660278c0SBarry Smith   "malloc_test",
884660278c0SBarry Smith   "nox",
885660278c0SBarry Smith   "nox_warning",
886660278c0SBarry Smith   "display",
887660278c0SBarry Smith   "saws_port_auto_select",
888660278c0SBarry Smith   "saws_port_auto_select_silent",
889660278c0SBarry Smith   "vecscatter_mpi1",
890660278c0SBarry Smith   "check_pointer_intensity",
891660278c0SBarry Smith   "cuda_initialize",
892660278c0SBarry Smith   "error_output_stdout",
893660278c0SBarry Smith   "use_gpu_aware_mpi",
894660278c0SBarry Smith   "checkfunctionlist",
895660278c0SBarry Smith   "petsc_ci",
896660278c0SBarry Smith   "petsc_ci_portable_error_output",
897660278c0SBarry Smith };
898660278c0SBarry Smith 
8999371c9d4SSatish Balay static PetscBool PetscCIOption(const char *name) {
900660278c0SBarry Smith   PetscInt  idx;
901660278c0SBarry Smith   PetscBool found;
902660278c0SBarry Smith 
903660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
904660278c0SBarry Smith   PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found);
905660278c0SBarry Smith   return found;
906660278c0SBarry Smith }
907660278c0SBarry Smith 
908e5c89e4eSSatish Balay /*@C
90988c29154SBarry Smith    PetscOptionsView - Prints the options that have been loaded. This is
910e5c89e4eSSatish Balay    useful for debugging purposes.
911e5c89e4eSSatish Balay 
912*811af0c4SBarry Smith    Logically Collective on viewer
913e5c89e4eSSatish Balay 
914d8d19677SJose E. Roman    Input Parameters:
915a2b725a8SWilliam Gropp +  options - options database, use NULL for default global database
916*811af0c4SBarry Smith -  viewer - must be an `PETSCVIEWERASCII` viewer
917e5c89e4eSSatish Balay 
918e5c89e4eSSatish Balay    Options Database Key:
919*811af0c4SBarry Smith .  -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
920e5c89e4eSSatish Balay 
921*811af0c4SBarry Smith    Note:
922*811af0c4SBarry Smith    Only the rank zero process of the `MPI_Comm` used to create view prints the option values. Other processes
9231c9f3c13SBarry Smith    may have different values but they are not printed.
9241c9f3c13SBarry Smith 
925e5c89e4eSSatish Balay    Level: advanced
926e5c89e4eSSatish Balay 
927db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
928e5c89e4eSSatish Balay @*/
9299371c9d4SSatish Balay PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer) {
930660278c0SBarry Smith   PetscInt  i, N = 0;
93188c29154SBarry Smith   PetscBool isascii;
932e5c89e4eSSatish Balay 
933e5c89e4eSSatish Balay   PetscFunctionBegin;
9342d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
935c5929fdfSBarry Smith   options = options ? options : defaultoptions;
93688c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9379566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
93828b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
93988c29154SBarry Smith 
940660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
941660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
942660278c0SBarry Smith     N++;
943660278c0SBarry Smith   }
944660278c0SBarry Smith 
945660278c0SBarry Smith   if (!N) {
9469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9472d747510SLisandro Dalcin     PetscFunctionReturn(0);
94830694fe9SBarry Smith   }
9492d747510SLisandro Dalcin 
9509566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
951e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
952660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
953e5c89e4eSSatish Balay     if (options->values[i]) {
9549566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s\n", options->names[i], options->values[i]));
955e5c89e4eSSatish Balay     } else {
9569566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s\n", options->names[i]));
957e5c89e4eSSatish Balay     }
958e5c89e4eSSatish Balay   }
9599566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
960e5c89e4eSSatish Balay   PetscFunctionReturn(0);
961e5c89e4eSSatish Balay }
962e5c89e4eSSatish Balay 
963e11779c2SBarry Smith /*
964e11779c2SBarry Smith    Called by error handlers to print options used in run
965e11779c2SBarry Smith */
9669371c9d4SSatish Balay PetscErrorCode PetscOptionsLeftError(void) {
967f4bc716fSBarry Smith   PetscInt i, nopt = 0;
968f4bc716fSBarry Smith 
969f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
970f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
971f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
972f4bc716fSBarry Smith       nopt++;
973f4bc716fSBarry Smith     }
974f4bc716fSBarry Smith   }
975f4bc716fSBarry Smith   if (nopt) {
976f4bc716fSBarry 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");
977f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
978f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
979f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
980f4bc716fSBarry Smith         if (defaultoptions->values[i]) (*PetscErrorPrintf)("Option left: name:-%s value: %s\n", defaultoptions->names[i], defaultoptions->values[i]);
981f4bc716fSBarry Smith         else (*PetscErrorPrintf)("Option left: name:-%s (no value)\n", defaultoptions->names[i]);
982f4bc716fSBarry Smith       }
983f4bc716fSBarry Smith     }
984f4bc716fSBarry Smith   }
985f4bc716fSBarry Smith   return 0;
986f4bc716fSBarry Smith }
987f4bc716fSBarry Smith 
9889371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void) {
989660278c0SBarry Smith   PetscInt     i, N = 0;
9904416b707SBarry Smith   PetscOptions options = defaultoptions;
991e11779c2SBarry Smith 
992660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
993660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
994660278c0SBarry Smith     N++;
995660278c0SBarry Smith   }
996660278c0SBarry Smith 
997660278c0SBarry Smith   if (N) {
998e11779c2SBarry Smith     (*PetscErrorPrintf)("PETSc Option Table entries:\n");
999e11779c2SBarry Smith   } else {
1000e11779c2SBarry Smith     (*PetscErrorPrintf)("No PETSc Option Table entries\n");
1001e11779c2SBarry Smith   }
1002e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1003660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1004e11779c2SBarry Smith     if (options->values[i]) {
1005e11779c2SBarry Smith       (*PetscErrorPrintf)("-%s %s\n", options->names[i], options->values[i]);
1006e11779c2SBarry Smith     } else {
1007e11779c2SBarry Smith       (*PetscErrorPrintf)("-%s\n", options->names[i]);
1008e11779c2SBarry Smith     }
1009e11779c2SBarry Smith   }
1010f4bc716fSBarry Smith   return 0;
1011e11779c2SBarry Smith }
1012e11779c2SBarry Smith 
1013e5c89e4eSSatish Balay /*@C
101474e0666dSJed Brown    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
101574e0666dSJed Brown 
10161c9f3c13SBarry Smith    Logically Collective
101774e0666dSJed Brown 
1018d8d19677SJose E. Roman    Input Parameters:
1019c5929fdfSBarry Smith +  options - options database, or NULL for the default global database
1020c5929fdfSBarry Smith -  prefix - The string to append to the existing prefix
10219db968c8SJed Brown 
10229db968c8SJed Brown    Options Database Keys:
10239db968c8SJed Brown +   -prefix_push <some_prefix_> - push the given prefix
10249db968c8SJed Brown -   -prefix_pop - pop the last prefix
10259db968c8SJed Brown 
10269db968c8SJed Brown    Notes:
10279db968c8SJed Brown    It is common to use this in conjunction with -options_file as in
10289db968c8SJed Brown 
10299db968c8SJed Brown $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10309db968c8SJed Brown 
10319db968c8SJed Brown    where the files no longer require all options to be prefixed with -system2_.
103274e0666dSJed Brown 
1033*811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
10341c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
10351c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10361c9f3c13SBarry Smith    on different ranks.
10371c9f3c13SBarry Smith 
103874e0666dSJed Brown    Level: advanced
103974e0666dSJed Brown 
1040db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
104174e0666dSJed Brown @*/
10429371c9d4SSatish Balay PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[]) {
104374e0666dSJed Brown   size_t    n;
104474e0666dSJed Brown   PetscInt  start;
10452d747510SLisandro Dalcin   char      key[MAXOPTNAME + 1];
10462d747510SLisandro Dalcin   PetscBool valid;
104774e0666dSJed Brown 
104874e0666dSJed Brown   PetscFunctionBegin;
1049064a246eSJacob Faibussowitsch   PetscValidCharPointer(prefix, 2);
1050c5929fdfSBarry Smith   options = options ? options : defaultoptions;
105108401ef6SPierre 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);
10522d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10539566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10558bf569ecSLisandro 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 */
105628b400f6SJacob 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" : "");
105774e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10589566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
105908401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10609566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
106174e0666dSJed Brown   options->prefixstack[options->prefixind++] = start + n;
106274e0666dSJed Brown   PetscFunctionReturn(0);
106374e0666dSJed Brown }
106474e0666dSJed Brown 
1065c5929fdfSBarry Smith /*@C
1066*811af0c4SBarry Smith    PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
106774e0666dSJed Brown 
1068*811af0c4SBarry Smith    Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
106974e0666dSJed Brown 
1070*811af0c4SBarry Smith   Input Parameter:
1071c5929fdfSBarry Smith .  options - options database, or NULL for the default global database
1072c5929fdfSBarry Smith 
107374e0666dSJed Brown    Level: advanced
107474e0666dSJed Brown 
1075db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
107674e0666dSJed Brown @*/
10779371c9d4SSatish Balay PetscErrorCode PetscOptionsPrefixPop(PetscOptions options) {
107874e0666dSJed Brown   PetscInt offset;
107974e0666dSJed Brown 
108074e0666dSJed Brown   PetscFunctionBegin;
1081c5929fdfSBarry Smith   options = options ? options : defaultoptions;
108208401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
108374e0666dSJed Brown   options->prefixind--;
108474e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
108574e0666dSJed Brown   options->prefix[offset] = 0;
108674e0666dSJed Brown   PetscFunctionReturn(0);
108774e0666dSJed Brown }
108874e0666dSJed Brown 
1089a542b6e8SBarry Smith /*@C
1090a542b6e8SBarry Smith     PetscOptionsClear - Removes all options form the database leaving it empty.
1091a542b6e8SBarry Smith 
10921c9f3c13SBarry Smith     Logically Collective
10931c9f3c13SBarry Smith 
1094*811af0c4SBarry Smith   Input Parameter:
1095c5929fdfSBarry Smith .  options - options database, use NULL for the default global database
1096c5929fdfSBarry Smith 
1097*811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
10981c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
10991c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11001c9f3c13SBarry Smith    on different ranks.
11011c9f3c13SBarry Smith 
1102a542b6e8SBarry Smith    Level: developer
1103a542b6e8SBarry Smith 
1104db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1105a542b6e8SBarry Smith @*/
11069371c9d4SSatish Balay PetscErrorCode PetscOptionsClear(PetscOptions options) {
1107a542b6e8SBarry Smith   PetscInt i;
1108a542b6e8SBarry Smith 
110939a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1110c5929fdfSBarry Smith   options = options ? options : defaultoptions;
111139a651e2SJacob Faibussowitsch   if (!options) PetscFunctionReturn(0);
11122d747510SLisandro Dalcin 
1113a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1114a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1115a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1116a542b6e8SBarry Smith   }
11172d747510SLisandro Dalcin   options->N = 0;
11182d747510SLisandro Dalcin 
1119a542b6e8SBarry Smith   for (i = 0; i < options->Naliases; i++) {
1120a542b6e8SBarry Smith     free(options->aliases1[i]);
1121a542b6e8SBarry Smith     free(options->aliases2[i]);
1122a542b6e8SBarry Smith   }
1123a542b6e8SBarry Smith   options->Naliases = 0;
1124a542b6e8SBarry Smith 
11252d747510SLisandro Dalcin   /* destroy hash table */
11262d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11272d747510SLisandro Dalcin   options->ht = NULL;
11280eb63584SBarry Smith 
11292d747510SLisandro Dalcin   options->prefixind = 0;
11302d747510SLisandro Dalcin   options->prefix[0] = 0;
11312d747510SLisandro Dalcin   options->help      = PETSC_FALSE;
113239a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
11334416b707SBarry Smith }
11344416b707SBarry Smith 
11352d747510SLisandro Dalcin /*@C
11362d747510SLisandro Dalcin    PetscOptionsSetAlias - Makes a key and alias for another key
11372d747510SLisandro Dalcin 
11381c9f3c13SBarry Smith    Logically Collective
11392d747510SLisandro Dalcin 
11402d747510SLisandro Dalcin    Input Parameters:
11412d747510SLisandro Dalcin +  options - options database, or NULL for default global database
11422d747510SLisandro Dalcin .  newname - the alias
11432d747510SLisandro Dalcin -  oldname - the name that alias will refer to
11442d747510SLisandro Dalcin 
11452d747510SLisandro Dalcin    Level: advanced
11462d747510SLisandro Dalcin 
1147*811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
11481c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
11491c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11501c9f3c13SBarry Smith    on different ranks.
11511c9f3c13SBarry Smith 
1152c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1153c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1154db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1155c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1156db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1157db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
11582d747510SLisandro Dalcin @*/
11599371c9d4SSatish Balay PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[]) {
11602d747510SLisandro Dalcin   PetscInt  n;
11612d747510SLisandro Dalcin   size_t    len;
11629210b8eaSVaclav Hapla   PetscBool valid;
11632d747510SLisandro Dalcin 
11642d747510SLisandro Dalcin   PetscFunctionBegin;
11652d747510SLisandro Dalcin   PetscValidCharPointer(newname, 2);
11662d747510SLisandro Dalcin   PetscValidCharPointer(oldname, 3);
11672d747510SLisandro Dalcin   options = options ? options : defaultoptions;
11689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
116928b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
11709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
117128b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
11722d747510SLisandro Dalcin 
11732d747510SLisandro Dalcin   n = options->Naliases;
117408401ef6SPierre 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);
11752d747510SLisandro Dalcin 
11769371c9d4SSatish Balay   newname++;
11779371c9d4SSatish Balay   oldname++;
11789566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
11792d747510SLisandro Dalcin   options->aliases1[n] = (char *)malloc((len + 1) * sizeof(char));
11809566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(options->aliases1[n], newname));
11819566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
11822d747510SLisandro Dalcin   options->aliases2[n] = (char *)malloc((len + 1) * sizeof(char));
11839566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(options->aliases2[n], oldname));
11842d747510SLisandro Dalcin   options->Naliases++;
11852d747510SLisandro Dalcin   PetscFunctionReturn(0);
11862d747510SLisandro Dalcin }
11874416b707SBarry Smith 
1188e5c89e4eSSatish Balay /*@C
1189e5c89e4eSSatish Balay    PetscOptionsSetValue - Sets an option name-value pair in the options
1190e5c89e4eSSatish Balay    database, overriding whatever is already present.
1191e5c89e4eSSatish Balay 
11921c9f3c13SBarry Smith    Logically Collective
1193e5c89e4eSSatish Balay 
1194e5c89e4eSSatish Balay    Input Parameters:
1195c5929fdfSBarry Smith +  options - options database, use NULL for the default global database
1196c5929fdfSBarry Smith .  name - name of option, this SHOULD have the - prepended
11972d747510SLisandro Dalcin -  value - the option value (not used for all options, so can be NULL)
1198e5c89e4eSSatish Balay 
1199e5c89e4eSSatish Balay    Level: intermediate
1200e5c89e4eSSatish Balay 
1201e5c89e4eSSatish Balay    Note:
1202*811af0c4SBarry Smith    This function can be called BEFORE `PetscInitialize()`
1203d49172ceSBarry Smith 
1204*811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
12051c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
12061c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12071c9f3c13SBarry Smith    on different ranks.
12081c9f3c13SBarry Smith 
12092d747510SLisandro Dalcin    Developers Note: Uses malloc() directly because PETSc may not be initialized yet.
1210b0250c70SBarry Smith 
1211db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1212e5c89e4eSSatish Balay @*/
12139371c9d4SSatish Balay PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[]) {
121439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL));
121639a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1217c5b5d8d5SVaclav Hapla }
1218c5b5d8d5SVaclav Hapla 
12199371c9d4SSatish Balay static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos) {
1220e5c89e4eSSatish Balay   size_t    len;
12212d747510SLisandro Dalcin   int       N, n, i;
1222e5c89e4eSSatish Balay   char    **names;
12232d747510SLisandro Dalcin   char      fullname[MAXOPTNAME] = "";
1224c5b5d8d5SVaclav Hapla   PetscBool flg;
1225e5c89e4eSSatish Balay 
122639a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12277272c0d2SVaclav Hapla   if (!options) {
12289566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12297272c0d2SVaclav Hapla     options = defaultoptions;
1230c5929fdfSBarry Smith   }
123139a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
12322d747510SLisandro Dalcin 
12339566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
123439a651e2SJacob Faibussowitsch   if (flg) PetscFunctionReturn(0);
1235e5c89e4eSSatish Balay 
12362d747510SLisandro Dalcin   name++; /* skip starting dash */
12372d747510SLisandro Dalcin 
123874e0666dSJed Brown   if (options->prefixind > 0) {
1239d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
12402d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
124189ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
12422d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
124374e0666dSJed Brown     name                           = fullname;
124474e0666dSJed Brown   }
124574e0666dSJed Brown 
124674e0666dSJed Brown   /* check against aliases */
1247e5c89e4eSSatish Balay   N = options->Naliases;
1248e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
12492d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
12509371c9d4SSatish Balay     if (!result) {
12519371c9d4SSatish Balay       name = options->aliases2[i];
12529371c9d4SSatish Balay       break;
12539371c9d4SSatish Balay     }
1254e5c89e4eSSatish Balay   }
1255e5c89e4eSSatish Balay 
12562d747510SLisandro Dalcin   /* slow search */
12572d747510SLisandro Dalcin   N = n = options->N;
1258e5c89e4eSSatish Balay   names = options->names;
1259e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
12602d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
12612d747510SLisandro Dalcin     if (!result) {
12629371c9d4SSatish Balay       n = i;
12639371c9d4SSatish Balay       goto setvalue;
12642d747510SLisandro Dalcin     } else if (result > 0) {
12659371c9d4SSatish Balay       n = i;
12669371c9d4SSatish Balay       break;
1267e5c89e4eSSatish Balay     }
1268e5c89e4eSSatish Balay   }
126939a651e2SJacob 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);
127039a651e2SJacob Faibussowitsch 
12712d747510SLisandro Dalcin   /* shift remaining values up 1 */
1272e5c89e4eSSatish Balay   for (i = N; i > n; i--) {
12735e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1274e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1275e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
1276e5c89e4eSSatish Balay   }
12772d747510SLisandro Dalcin   options->names[n]  = NULL;
12782d747510SLisandro Dalcin   options->values[n] = NULL;
12792d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
12802d747510SLisandro Dalcin   options->N++;
12812d747510SLisandro Dalcin 
12822d747510SLisandro Dalcin   /* destroy hash table */
12832d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
12842d747510SLisandro Dalcin   options->ht = NULL;
12852d747510SLisandro Dalcin 
12862d747510SLisandro Dalcin   /* set new name */
128770d8d27cSBarry Smith   len               = strlen(name);
12885e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
128939a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1290d49172ceSBarry Smith   strcpy(options->names[n], name);
12912d747510SLisandro Dalcin 
12922d747510SLisandro Dalcin setvalue:
12932d747510SLisandro Dalcin   /* set new value */
12942d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1295d49172ceSBarry Smith   len = value ? strlen(value) : 0;
12965e8c5e88SLisandro Dalcin   if (len) {
1297e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1298d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1299d49172ceSBarry Smith     strcpy(options->values[n], value);
13002d747510SLisandro Dalcin   } else {
13012d747510SLisandro Dalcin     options->values[n] = NULL;
13022d747510SLisandro Dalcin   }
13032d747510SLisandro Dalcin 
130491ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
130591ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
130691ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1307d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
130891ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
130991ad3481SVaclav Hapla   }
131091ad3481SVaclav Hapla 
13119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsMonitor(options, name, value));
1312c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
131339a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1314e5c89e4eSSatish Balay }
1315e5c89e4eSSatish Balay 
1316e5c89e4eSSatish Balay /*@C
1317e5c89e4eSSatish Balay    PetscOptionsClearValue - Clears an option name-value pair in the options
1318e5c89e4eSSatish Balay    database, overriding whatever is already present.
1319e5c89e4eSSatish Balay 
13201c9f3c13SBarry Smith    Logically Collective
1321e5c89e4eSSatish Balay 
1322d8d19677SJose E. Roman    Input Parameters:
1323c5929fdfSBarry Smith +  options - options database, use NULL for the default global database
1324a2b725a8SWilliam Gropp -  name - name of option, this SHOULD have the - prepended
1325e5c89e4eSSatish Balay 
1326e5c89e4eSSatish Balay    Level: intermediate
1327e5c89e4eSSatish Balay 
1328*811af0c4SBarry Smith    Note:
1329*811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
13301c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
13311c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
13321c9f3c13SBarry Smith    on different ranks.
13331c9f3c13SBarry Smith 
1334db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1335e5c89e4eSSatish Balay @*/
13369371c9d4SSatish Balay PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[]) {
13372d747510SLisandro Dalcin   int    N, n, i;
13382d747510SLisandro Dalcin   char **names;
1339e5c89e4eSSatish Balay 
1340e5c89e4eSSatish Balay   PetscFunctionBegin;
1341c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1342cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1343c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
13442d747510SLisandro Dalcin 
13452d747510SLisandro Dalcin   name++; /* skip starting dash */
13462d747510SLisandro Dalcin 
13472d747510SLisandro Dalcin   /* slow search */
13482d747510SLisandro Dalcin   N = n = options->N;
1349e5c89e4eSSatish Balay   names = options->names;
1350e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
13512d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13522d747510SLisandro Dalcin     if (!result) {
13539371c9d4SSatish Balay       n = i;
13549371c9d4SSatish Balay       break;
13552d747510SLisandro Dalcin     } else if (result > 0) {
13569371c9d4SSatish Balay       n = N;
13579371c9d4SSatish Balay       break;
1358e5c89e4eSSatish Balay     }
13592d747510SLisandro Dalcin   }
13602d747510SLisandro Dalcin   if (n == N) PetscFunctionReturn(0); /* it was not present */
1361e5c89e4eSSatish Balay 
13622d747510SLisandro Dalcin   /* remove name and value */
13632d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
13642d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1365e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1366e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
13675e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1368e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1369e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
1370e5c89e4eSSatish Balay   }
1371e5c89e4eSSatish Balay   options->N--;
13722d747510SLisandro Dalcin 
13732d747510SLisandro Dalcin   /* destroy hash table */
13742d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13752d747510SLisandro Dalcin   options->ht = NULL;
13762d747510SLisandro Dalcin 
13779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsMonitor(options, name, NULL));
1378e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1379e5c89e4eSSatish Balay }
1380e5c89e4eSSatish Balay 
1381e5c89e4eSSatish Balay /*@C
13822d747510SLisandro Dalcin    PetscOptionsFindPair - Gets an option name-value pair from the options database.
1383e5c89e4eSSatish Balay 
13842d747510SLisandro Dalcin    Not Collective
1385e5c89e4eSSatish Balay 
1386e5c89e4eSSatish Balay    Input Parameters:
13872d747510SLisandro Dalcin +  options - options database, use NULL for the default global database
13882d747510SLisandro Dalcin .  pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
13892d747510SLisandro Dalcin -  name - name of option, this SHOULD have the "-" prepended
1390e5c89e4eSSatish Balay 
13912d747510SLisandro Dalcin    Output Parameters:
13922d747510SLisandro Dalcin +  value - the option value (optional, not used for all options)
13932d747510SLisandro Dalcin -  set - whether the option is set (optional)
1394e5c89e4eSSatish Balay 
1395*811af0c4SBarry Smith    Note:
13969666a313SBarry Smith    Each process may find different values or no value depending on how options were inserted into the database
13971c9f3c13SBarry Smith 
13982d747510SLisandro Dalcin    Level: developer
13992d747510SLisandro Dalcin 
1400db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1401e5c89e4eSSatish Balay @*/
14029371c9d4SSatish Balay PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set) {
14032d747510SLisandro Dalcin   char      buf[MAXOPTNAME];
1404daabea38SBarry Smith   PetscBool usehashtable = PETSC_TRUE;
14052d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1406e5c89e4eSSatish Balay 
1407e5c89e4eSSatish Balay   PetscFunctionBegin;
1408c5929fdfSBarry Smith   options = options ? options : defaultoptions;
140908401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1410cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1411e5c89e4eSSatish Balay 
14122d747510SLisandro Dalcin   name++; /* skip starting dash */
1413e5c89e4eSSatish Balay 
14147cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
14152d747510SLisandro Dalcin   if (pre && pre[0]) {
14162d747510SLisandro Dalcin     char *ptr = buf;
14179371c9d4SSatish Balay     if (name[0] == '-') {
14189371c9d4SSatish Balay       *ptr++ = '-';
14199371c9d4SSatish Balay       name++;
14209371c9d4SSatish Balay     }
14219566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
14229566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
14232d747510SLisandro Dalcin     name = buf;
14247cd08cecSJed Brown   }
14252d747510SLisandro Dalcin 
142676bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
14272f828895SJed Brown     PetscBool valid;
14282d747510SLisandro Dalcin     char      key[MAXOPTNAME + 1] = "-";
14299566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
14309566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
143128b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
14322f828895SJed Brown   }
1433e5c89e4eSSatish Balay 
14342d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
14352d747510SLisandro Dalcin     int      i, ret;
14362d747510SLisandro Dalcin     khiter_t it;
14372d747510SLisandro Dalcin     khash_t(HO) * ht;
14382d747510SLisandro Dalcin     ht = kh_init(HO);
143928b400f6SJacob Faibussowitsch     PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
14402d747510SLisandro Dalcin     ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
144128b400f6SJacob Faibussowitsch     PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
14422d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
14432d747510SLisandro Dalcin       it = kh_put(HO, ht, options->names[i], &ret);
144408401ef6SPierre Jolivet       PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
14452d747510SLisandro Dalcin       kh_val(ht, it) = i;
14462d747510SLisandro Dalcin     }
14472d747510SLisandro Dalcin     options->ht = ht;
14482d747510SLisandro Dalcin   }
14492d747510SLisandro Dalcin 
14509371c9d4SSatish Balay   if (usehashtable) { /* fast search */
14512d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
14522d747510SLisandro Dalcin     khiter_t it     = kh_get(HO, ht, name);
14532d747510SLisandro Dalcin     if (it != kh_end(ht)) {
14542d747510SLisandro Dalcin       int i            = kh_val(ht, it);
1455e5c89e4eSSatish Balay       options->used[i] = PETSC_TRUE;
14562d747510SLisandro Dalcin       if (value) *value = options->values[i];
14572d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
14582d747510SLisandro Dalcin       PetscFunctionReturn(0);
14592d747510SLisandro Dalcin     }
14609371c9d4SSatish Balay   } else { /* slow search */
14612d747510SLisandro Dalcin     int i, N = options->N;
14622d747510SLisandro Dalcin     for (i = 0; i < N; i++) {
1463daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i], name);
14642d747510SLisandro Dalcin       if (!result) {
14652d747510SLisandro Dalcin         options->used[i] = PETSC_TRUE;
14662d747510SLisandro Dalcin         if (value) *value = options->values[i];
14672d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
14682d747510SLisandro Dalcin         PetscFunctionReturn(0);
14692d747510SLisandro Dalcin       } else if (result > 0) {
1470e5c89e4eSSatish Balay         break;
1471e5c89e4eSSatish Balay       }
1472e5c89e4eSSatish Balay     }
14732d747510SLisandro Dalcin   }
14742d747510SLisandro Dalcin 
14752d747510SLisandro Dalcin   /*
14762d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
14772d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
14782d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
14792d747510SLisandro Dalcin    */
14802d747510SLisandro Dalcin   if (matchnumbers) {
14812d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1482e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
14832d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
14842d747510SLisandro Dalcin       if (name[i] == '_') {
14852d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
14862d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
14872d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1488e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1489e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1490e5c89e4eSSatish Balay           }
14912d747510SLisandro Dalcin           i = j - 1;
1492e5c89e4eSSatish Balay           break;
1493e5c89e4eSSatish Balay         }
1494e5c89e4eSSatish Balay       }
1495e5c89e4eSSatish Balay     }
1496e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
14972d747510SLisandro Dalcin       PetscBool found;
14982d747510SLisandro Dalcin       char      opt[MAXOPTNAME + 1] = "-", tmp[MAXOPTNAME];
14999566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
15009566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15019566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
15029566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
15039371c9d4SSatish Balay       if (found) {
15049371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
15059371c9d4SSatish Balay         PetscFunctionReturn(0);
15069371c9d4SSatish Balay       }
1507e5c89e4eSSatish Balay     }
1508e5c89e4eSSatish Balay   }
15092d747510SLisandro Dalcin 
15102d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
1511e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1512e5c89e4eSSatish Balay }
1513e5c89e4eSSatish Balay 
1514d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
15159371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set) {
15162d747510SLisandro Dalcin   char buf[MAXOPTNAME];
1517d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1518514bf10dSMatthew G Knepley 
1519514bf10dSMatthew G Knepley   PetscFunctionBegin;
1520c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1521cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1522cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1523514bf10dSMatthew G Knepley 
15242d747510SLisandro Dalcin   name++; /* skip starting dash */
1525514bf10dSMatthew G Knepley 
1526514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
15272d747510SLisandro Dalcin   if (pre && pre[0]) {
15282d747510SLisandro Dalcin     char *ptr = buf;
15299371c9d4SSatish Balay     if (name[0] == '-') {
15309371c9d4SSatish Balay       *ptr++ = '-';
15319371c9d4SSatish Balay       name++;
15329371c9d4SSatish Balay     }
15339566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) + (size_t)(ptr - buf)));
15349566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
15352d747510SLisandro Dalcin     name = buf;
1536514bf10dSMatthew G Knepley   }
15372d747510SLisandro Dalcin 
153876bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1539514bf10dSMatthew G Knepley     PetscBool valid;
15402d747510SLisandro Dalcin     char      key[MAXOPTNAME + 1] = "-";
15419566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
15429566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
154328b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1544514bf10dSMatthew G Knepley   }
1545514bf10dSMatthew G Knepley 
1546d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1547d6ced9c0SMatthew G. Knepley   {
1548d6ced9c0SMatthew G. Knepley     int i, j;
1549d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1550d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1551d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1552d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1553d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1554d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1555d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1556d6ced9c0SMatthew G. Knepley           }
1557d6ced9c0SMatthew G. Knepley           i = j - 1;
1558d6ced9c0SMatthew G. Knepley           break;
1559d6ced9c0SMatthew G. Knepley         }
1560d6ced9c0SMatthew G. Knepley       }
1561d6ced9c0SMatthew G. Knepley     }
1562d6ced9c0SMatthew G. Knepley   }
1563d6ced9c0SMatthew G. Knepley 
15642d747510SLisandro Dalcin   { /* slow search */
1565d6ced9c0SMatthew G. Knepley     int       c, i;
15662d747510SLisandro Dalcin     size_t    len;
15672d747510SLisandro Dalcin     PetscBool match;
1568d6ced9c0SMatthew G. Knepley 
1569d6ced9c0SMatthew G. Knepley     for (c = -1; c < numCnt; ++c) {
1570d6ced9c0SMatthew G. Knepley       char opt[MAXOPTNAME + 1] = "", tmp[MAXOPTNAME];
1571d6ced9c0SMatthew G. Knepley 
1572d6ced9c0SMatthew G. Knepley       if (c < 0) {
15739566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(opt, name));
1574d6ced9c0SMatthew G. Knepley       } else {
15759566063dSJacob Faibussowitsch         PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[c] + 1), sizeof(tmp))));
15769566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15779566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt)));
1578d6ced9c0SMatthew G. Knepley       }
15799566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(opt, &len));
15802d747510SLisandro Dalcin       for (i = 0; i < options->N; i++) {
15819566063dSJacob Faibussowitsch         PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1582514bf10dSMatthew G Knepley         if (match) {
1583514bf10dSMatthew G Knepley           options->used[i] = PETSC_TRUE;
15842d747510SLisandro Dalcin           if (value) *value = options->values[i];
15852d747510SLisandro Dalcin           if (set) *set = PETSC_TRUE;
15862d747510SLisandro Dalcin           PetscFunctionReturn(0);
1587514bf10dSMatthew G Knepley         }
1588514bf10dSMatthew G Knepley       }
15892d747510SLisandro Dalcin     }
1590d6ced9c0SMatthew G. Knepley   }
15912d747510SLisandro Dalcin 
15922d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
1593514bf10dSMatthew G Knepley   PetscFunctionReturn(0);
1594514bf10dSMatthew G Knepley }
1595514bf10dSMatthew G Knepley 
1596e5c89e4eSSatish Balay /*@C
1597e5c89e4eSSatish Balay    PetscOptionsReject - Generates an error if a certain option is given.
1598e5c89e4eSSatish Balay 
15991c9f3c13SBarry Smith    Not Collective
1600e5c89e4eSSatish Balay 
1601e5c89e4eSSatish Balay    Input Parameters:
16025c9cc608SHong Zhang +  options - options database, use NULL for default global database
16032d747510SLisandro Dalcin .  pre - the option prefix (may be NULL)
16042d747510SLisandro Dalcin .  name - the option name one is seeking
16050298fd71SBarry Smith -  mess - error message (may be NULL)
1606e5c89e4eSSatish Balay 
1607e5c89e4eSSatish Balay    Level: advanced
1608e5c89e4eSSatish Balay 
1609c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1610db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1611db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1612c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1613db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1614db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1615e5c89e4eSSatish Balay @*/
16169371c9d4SSatish Balay PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[]) {
1617ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1618e5c89e4eSSatish Balay 
1619e5c89e4eSSatish Balay   PetscFunctionBegin;
16209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1621e5c89e4eSSatish Balay   if (flag) {
162208401ef6SPierre 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);
1623f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1624e5c89e4eSSatish Balay   }
1625e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1626e5c89e4eSSatish Balay }
1627e5c89e4eSSatish Balay 
1628e5c89e4eSSatish Balay /*@C
16292d747510SLisandro Dalcin    PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
16302d747510SLisandro Dalcin 
16312d747510SLisandro Dalcin    Not Collective
16322d747510SLisandro Dalcin 
1633*811af0c4SBarry Smith    Input Parameter:
16342d747510SLisandro Dalcin .  options - options database, use NULL for default global database
16352d747510SLisandro Dalcin 
1636*811af0c4SBarry Smith    Output Parameter:
1637*811af0c4SBarry Smith .  set - `PETSC_TRUE` if found else `PETSC_FALSE`.
16382d747510SLisandro Dalcin 
16392d747510SLisandro Dalcin    Level: advanced
16402d747510SLisandro Dalcin 
1641db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
16422d747510SLisandro Dalcin @*/
16439371c9d4SSatish Balay PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set) {
16442d747510SLisandro Dalcin   PetscFunctionBegin;
1645dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
16462d747510SLisandro Dalcin   options = options ? options : defaultoptions;
16472d747510SLisandro Dalcin   *set    = options->help;
16482d747510SLisandro Dalcin   PetscFunctionReturn(0);
16492d747510SLisandro Dalcin }
16502d747510SLisandro Dalcin 
16519371c9d4SSatish Balay PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set) {
1652d314f959SVaclav Hapla   PetscFunctionBegin;
1653dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
1654d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1655d314f959SVaclav Hapla   *set    = options->help_intro;
1656d314f959SVaclav Hapla   PetscFunctionReturn(0);
1657d314f959SVaclav Hapla }
1658d314f959SVaclav Hapla 
16592d747510SLisandro Dalcin /*@C
1660e24fcbf7SPierre 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
1661e24fcbf7SPierre Jolivet                       if its value is set to false.
1662e5c89e4eSSatish Balay 
1663e5c89e4eSSatish Balay    Not Collective
1664e5c89e4eSSatish Balay 
1665e5c89e4eSSatish Balay    Input Parameters:
16665c9cc608SHong Zhang +  options - options database, use NULL for default global database
16673de71b31SHong Zhang .  pre - string to prepend to the name or NULL
16683de71b31SHong Zhang -  name - the option one is seeking
1669e5c89e4eSSatish Balay 
1670*811af0c4SBarry Smith    Output Parameter:
1671*811af0c4SBarry Smith .  set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1672e5c89e4eSSatish Balay 
1673e5c89e4eSSatish Balay    Level: beginner
1674e5c89e4eSSatish Balay 
1675*811af0c4SBarry Smith    Note:
1676*811af0c4SBarry Smith    In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
167790d69ab7SBarry Smith 
1678db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1679db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1680db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1681c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1682db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1683db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1684e5c89e4eSSatish Balay @*/
16859371c9d4SSatish Balay PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set) {
16862d747510SLisandro Dalcin   const char *value;
1687ace3abfcSBarry Smith   PetscBool   flag;
1688e5c89e4eSSatish Balay 
1689e5c89e4eSSatish Balay   PetscFunctionBegin;
16909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
169196ef3cdfSSatish Balay   if (set) *set = flag;
1692e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1693e5c89e4eSSatish Balay }
1694e5c89e4eSSatish Balay 
1695e5c89e4eSSatish Balay /*@C
16962d747510SLisandro Dalcin    PetscOptionsGetAll - Lists all the options the program was run with in a single string.
16972d747510SLisandro Dalcin 
16982d747510SLisandro Dalcin    Not Collective
16992d747510SLisandro Dalcin 
1700fd292e60Sprj-    Input Parameter:
17012d747510SLisandro Dalcin .  options - the options database, use NULL for the default global database
17022d747510SLisandro Dalcin 
17032d747510SLisandro Dalcin    Output Parameter:
17042d747510SLisandro Dalcin .  copts - pointer where string pointer is stored
17052d747510SLisandro Dalcin 
17062d747510SLisandro Dalcin    Notes:
1707*811af0c4SBarry Smith     The array and each entry in the array should be freed with `PetscFree()`
1708*811af0c4SBarry Smith 
17091c9f3c13SBarry Smith     Each process may have different values depending on how the options were inserted into the database
17102d747510SLisandro Dalcin 
17112d747510SLisandro Dalcin    Level: advanced
17122d747510SLisandro Dalcin 
1713db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
17142d747510SLisandro Dalcin @*/
17159371c9d4SSatish Balay PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[]) {
17162d747510SLisandro Dalcin   PetscInt i;
17172d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
17182d747510SLisandro Dalcin   char    *coptions = NULL;
17192d747510SLisandro Dalcin 
17202d747510SLisandro Dalcin   PetscFunctionBegin;
17212d747510SLisandro Dalcin   PetscValidPointer(copts, 2);
17222d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17232d747510SLisandro Dalcin   /* count the length of the required string */
17242d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
17259566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
17262d747510SLisandro Dalcin     len += 2 + lent;
17272d747510SLisandro Dalcin     if (options->values[i]) {
17289566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
17292d747510SLisandro Dalcin       len += 1 + lent;
17302d747510SLisandro Dalcin     }
17312d747510SLisandro Dalcin   }
17329566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
17332d747510SLisandro Dalcin   coptions[0] = 0;
17342d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
17359566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions, "-"));
17369566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions, options->names[i]));
17379566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions, " "));
17382d747510SLisandro Dalcin     if (options->values[i]) {
17399566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(coptions, options->values[i]));
17409566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(coptions, " "));
17412d747510SLisandro Dalcin     }
17422d747510SLisandro Dalcin   }
17432d747510SLisandro Dalcin   *copts = coptions;
17442d747510SLisandro Dalcin   PetscFunctionReturn(0);
17452d747510SLisandro Dalcin }
17462d747510SLisandro Dalcin 
17472d747510SLisandro Dalcin /*@C
17482d747510SLisandro Dalcin    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
17492d747510SLisandro Dalcin 
17502d747510SLisandro Dalcin    Not Collective
17512d747510SLisandro Dalcin 
1752d8d19677SJose E. Roman    Input Parameters:
17532d747510SLisandro Dalcin +  options - options database, use NULL for default global database
17542d747510SLisandro Dalcin -  name - string name of option
17552d747510SLisandro Dalcin 
17562d747510SLisandro Dalcin    Output Parameter:
1757*811af0c4SBarry Smith .  used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
17582d747510SLisandro Dalcin 
17592d747510SLisandro Dalcin    Level: advanced
17602d747510SLisandro Dalcin 
1761*811af0c4SBarry Smith    Note:
17629666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
17631c9f3c13SBarry Smith    on the given process
17641c9f3c13SBarry Smith 
1765db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
17662d747510SLisandro Dalcin @*/
17679371c9d4SSatish Balay PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used) {
17682d747510SLisandro Dalcin   PetscInt i;
17692d747510SLisandro Dalcin 
17702d747510SLisandro Dalcin   PetscFunctionBegin;
17712d747510SLisandro Dalcin   PetscValidCharPointer(name, 2);
1772dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(used, 3);
17732d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17742d747510SLisandro Dalcin   *used   = PETSC_FALSE;
17752d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
17769566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
17772d747510SLisandro Dalcin     if (*used) {
17782d747510SLisandro Dalcin       *used = options->used[i];
17792d747510SLisandro Dalcin       break;
17802d747510SLisandro Dalcin     }
17812d747510SLisandro Dalcin   }
17822d747510SLisandro Dalcin   PetscFunctionReturn(0);
17832d747510SLisandro Dalcin }
17842d747510SLisandro Dalcin 
1785487a658cSBarry Smith /*@
17862d747510SLisandro Dalcin    PetscOptionsAllUsed - Returns a count of the number of options in the
17872d747510SLisandro Dalcin    database that have never been selected.
17882d747510SLisandro Dalcin 
17892d747510SLisandro Dalcin    Not Collective
17902d747510SLisandro Dalcin 
17912d747510SLisandro Dalcin    Input Parameter:
17922d747510SLisandro Dalcin .  options - options database, use NULL for default global database
17932d747510SLisandro Dalcin 
17942d747510SLisandro Dalcin    Output Parameter:
17952d747510SLisandro Dalcin .  N - count of options not used
17962d747510SLisandro Dalcin 
17972d747510SLisandro Dalcin    Level: advanced
17982d747510SLisandro Dalcin 
1799*811af0c4SBarry Smith    Note:
18009666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
18011c9f3c13SBarry Smith    on the given process
18021c9f3c13SBarry Smith 
1803db781477SPatrick Sanan .seealso: `PetscOptionsView()`
18042d747510SLisandro Dalcin @*/
18059371c9d4SSatish Balay PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N) {
18062d747510SLisandro Dalcin   PetscInt i, n = 0;
18072d747510SLisandro Dalcin 
18082d747510SLisandro Dalcin   PetscFunctionBegin;
18092d747510SLisandro Dalcin   PetscValidIntPointer(N, 2);
18102d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18112d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18122d747510SLisandro Dalcin     if (!options->used[i]) n++;
18132d747510SLisandro Dalcin   }
18142d747510SLisandro Dalcin   *N = n;
18152d747510SLisandro Dalcin   PetscFunctionReturn(0);
18162d747510SLisandro Dalcin }
18172d747510SLisandro Dalcin 
1818487a658cSBarry Smith /*@
18192d747510SLisandro Dalcin    PetscOptionsLeft - Prints to screen any options that were set and never used.
18202d747510SLisandro Dalcin 
18212d747510SLisandro Dalcin    Not Collective
18222d747510SLisandro Dalcin 
18232d747510SLisandro Dalcin    Input Parameter:
18242d747510SLisandro Dalcin .  options - options database; use NULL for default global database
18252d747510SLisandro Dalcin 
18262d747510SLisandro Dalcin    Options Database Key:
1827*811af0c4SBarry Smith .  -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
18282d747510SLisandro Dalcin 
18293de2bfdfSBarry Smith    Notes:
1830*811af0c4SBarry Smith       This is rarely used directly, it is called by `PetscFinalize()` in debug more or if -options_left
18311c9f3c13SBarry Smith       is passed otherwise to help users determine possible mistakes in their usage of options. This
1832*811af0c4SBarry Smith       only prints values on process zero of `PETSC_COMM_WORLD`.
1833*811af0c4SBarry Smith 
1834*811af0c4SBarry Smith       Other processes depending the objects
18351c9f3c13SBarry Smith       used may have different options that are left unused.
18363de2bfdfSBarry Smith 
18372d747510SLisandro Dalcin    Level: advanced
18382d747510SLisandro Dalcin 
1839db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
18402d747510SLisandro Dalcin @*/
18419371c9d4SSatish Balay PetscErrorCode PetscOptionsLeft(PetscOptions options) {
18422d747510SLisandro Dalcin   PetscInt     i;
18433de2bfdfSBarry Smith   PetscInt     cnt = 0;
18443de2bfdfSBarry Smith   PetscOptions toptions;
18452d747510SLisandro Dalcin 
18462d747510SLisandro Dalcin   PetscFunctionBegin;
18473de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
18483de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
18493de2bfdfSBarry Smith     if (!toptions->used[i]) {
1850660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
18513de2bfdfSBarry Smith       if (toptions->values[i]) {
18529566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s value: %s\n", toptions->names[i], toptions->values[i]));
18532d747510SLisandro Dalcin       } else {
18549566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value)\n", toptions->names[i]));
18552d747510SLisandro Dalcin       }
18562d747510SLisandro Dalcin     }
18572d747510SLisandro Dalcin   }
18583de2bfdfSBarry Smith   if (!options) {
18593de2bfdfSBarry Smith     toptions = defaultoptions;
18603de2bfdfSBarry Smith     while (toptions->previous) {
18613de2bfdfSBarry Smith       cnt++;
18623de2bfdfSBarry Smith       toptions = toptions->previous;
18633de2bfdfSBarry Smith     }
186448a46eb9SPierre 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));
18653de2bfdfSBarry Smith   }
18662d747510SLisandro Dalcin   PetscFunctionReturn(0);
18672d747510SLisandro Dalcin }
18682d747510SLisandro Dalcin 
18692d747510SLisandro Dalcin /*@C
18702d747510SLisandro Dalcin    PetscOptionsLeftGet - Returns all options that were set and never used.
18712d747510SLisandro Dalcin 
18722d747510SLisandro Dalcin    Not Collective
18732d747510SLisandro Dalcin 
18742d747510SLisandro Dalcin    Input Parameter:
18752d747510SLisandro Dalcin .  options - options database, use NULL for default global database
18762d747510SLisandro Dalcin 
1877d8d19677SJose E. Roman    Output Parameters:
1878a2b725a8SWilliam Gropp +  N - count of options not used
18792d747510SLisandro Dalcin .  names - names of options not used
1880a2b725a8SWilliam Gropp -  values - values of options not used
18812d747510SLisandro Dalcin 
18822d747510SLisandro Dalcin    Level: advanced
18832d747510SLisandro Dalcin 
18842d747510SLisandro Dalcin    Notes:
1885*811af0c4SBarry Smith    Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1886*811af0c4SBarry Smith 
1887*811af0c4SBarry Smith    The value returned may be different on each process and depends on which options have been processed
18881c9f3c13SBarry Smith    on the given process
18892d747510SLisandro Dalcin 
1890db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
18912d747510SLisandro Dalcin @*/
18929371c9d4SSatish Balay PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[]) {
18932d747510SLisandro Dalcin   PetscInt i, n;
18942d747510SLisandro Dalcin 
18952d747510SLisandro Dalcin   PetscFunctionBegin;
18962d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
18972d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
18982d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
18992d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19002d747510SLisandro Dalcin 
19012d747510SLisandro Dalcin   /* The number of unused PETSc options */
19022d747510SLisandro Dalcin   n = 0;
19032d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1904660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
19052d747510SLisandro Dalcin     if (!options->used[i]) n++;
19062d747510SLisandro Dalcin   }
1907ad540459SPierre Jolivet   if (N) *N = n;
19089566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
19099566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
19102d747510SLisandro Dalcin 
19112d747510SLisandro Dalcin   n = 0;
19122d747510SLisandro Dalcin   if (names || values) {
19132d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
19142d747510SLisandro Dalcin       if (!options->used[i]) {
1915660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
19162d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
19172d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
19182d747510SLisandro Dalcin         n++;
19192d747510SLisandro Dalcin       }
19202d747510SLisandro Dalcin     }
19212d747510SLisandro Dalcin   }
19222d747510SLisandro Dalcin   PetscFunctionReturn(0);
19232d747510SLisandro Dalcin }
19242d747510SLisandro Dalcin 
19252d747510SLisandro Dalcin /*@C
1926*811af0c4SBarry Smith    PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
19272d747510SLisandro Dalcin 
19282d747510SLisandro Dalcin    Not Collective
19292d747510SLisandro Dalcin 
1930d8d19677SJose E. Roman    Input Parameters:
1931a2b725a8SWilliam Gropp +  options - options database, use NULL for default global database
19322d747510SLisandro Dalcin .  names - names of options not used
1933a2b725a8SWilliam Gropp -  values - values of options not used
19342d747510SLisandro Dalcin 
19352d747510SLisandro Dalcin    Level: advanced
19362d747510SLisandro Dalcin 
1937db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
19382d747510SLisandro Dalcin @*/
19399371c9d4SSatish Balay PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[]) {
19402d747510SLisandro Dalcin   PetscFunctionBegin;
19412d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
19422d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
19432d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
1944ad540459SPierre Jolivet   if (N) *N = 0;
19459566063dSJacob Faibussowitsch   if (names) PetscCall(PetscFree(*names));
19469566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
19472d747510SLisandro Dalcin   PetscFunctionReturn(0);
19482d747510SLisandro Dalcin }
19492d747510SLisandro Dalcin 
19502d747510SLisandro Dalcin /*@C
1951*811af0c4SBarry Smith    PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
19522d747510SLisandro Dalcin 
19531c9f3c13SBarry Smith    Logically Collective on ctx
19542d747510SLisandro Dalcin 
19552d747510SLisandro Dalcin    Input Parameters:
19562d747510SLisandro Dalcin +  name  - option name string
19572d747510SLisandro Dalcin .  value - option value string
19589060e2f9SVaclav Hapla -  ctx - an ASCII viewer or NULL
19592d747510SLisandro Dalcin 
19602d747510SLisandro Dalcin    Level: intermediate
19612d747510SLisandro Dalcin 
19629666a313SBarry Smith    Notes:
1963*811af0c4SBarry Smith      If ctx is NULL, `PetscPrintf()` is used.
1964*811af0c4SBarry Smith      The first MPI rank in the `PetscViewer` viewer actually prints the values, other
19651c9f3c13SBarry Smith      processes may have different values set
19661c9f3c13SBarry Smith 
1967*811af0c4SBarry Smith      If `PetscCIEnabled` then do not print the test harness options
1968660278c0SBarry Smith 
1969db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
19702d747510SLisandro Dalcin @*/
19719371c9d4SSatish Balay PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], void *ctx) {
19722d747510SLisandro Dalcin   PetscFunctionBegin;
1973660278c0SBarry Smith   if (PetscCIOption(name)) PetscFunctionReturn(0);
1974660278c0SBarry Smith 
19759060e2f9SVaclav Hapla   if (ctx) {
19769060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
19772d747510SLisandro Dalcin     if (!value) {
19789566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
19792d747510SLisandro Dalcin     } else if (!value[0]) {
19809566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value)\n", name));
19812d747510SLisandro Dalcin     } else {
19829566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s\n", name, value));
19832d747510SLisandro Dalcin     }
19849060e2f9SVaclav Hapla   } else {
19859060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
19869060e2f9SVaclav Hapla     if (!value) {
19879566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
19889060e2f9SVaclav Hapla     } else if (!value[0]) {
19899566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Setting option: %s (no value)\n", name));
19909060e2f9SVaclav Hapla     } else {
19919566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Setting option: %s = %s\n", name, value));
19929060e2f9SVaclav Hapla     }
19939060e2f9SVaclav Hapla   }
19942d747510SLisandro Dalcin   PetscFunctionReturn(0);
19952d747510SLisandro Dalcin }
19962d747510SLisandro Dalcin 
19972d747510SLisandro Dalcin /*@C
19982d747510SLisandro Dalcin    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
19992d747510SLisandro Dalcin    modified the PETSc options database.
20002d747510SLisandro Dalcin 
20012d747510SLisandro Dalcin    Not Collective
20022d747510SLisandro Dalcin 
20032d747510SLisandro Dalcin    Input Parameters:
20042d747510SLisandro Dalcin +  monitor - pointer to function (if this is NULL, it turns off monitoring
20052d747510SLisandro Dalcin .  mctx    - [optional] context for private data for the
20062d747510SLisandro Dalcin              monitor routine (use NULL if no context is desired)
20072d747510SLisandro Dalcin -  monitordestroy - [optional] routine that frees monitor context
20082d747510SLisandro Dalcin           (may be NULL)
20092d747510SLisandro Dalcin 
20102d747510SLisandro Dalcin    Calling Sequence of monitor:
20112d747510SLisandro Dalcin $     monitor (const char name[], const char value[], void *mctx)
20122d747510SLisandro Dalcin 
20132d747510SLisandro Dalcin +  name - option name string
20142d747510SLisandro Dalcin .  value - option value string
2015*811af0c4SBarry Smith -  mctx  - optional monitoring context, as set by `PetscOptionsMonitorSet()`
20162d747510SLisandro Dalcin 
20172d747510SLisandro Dalcin    Options Database Keys:
2018*811af0c4SBarry Smith    See `PetscInitialize()` for options related to option database monitoring.
20192d747510SLisandro Dalcin 
20202d747510SLisandro Dalcin    Notes:
20212d747510SLisandro Dalcin    The default is to do nothing.  To print the name and value of options
2022*811af0c4SBarry Smith    being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
20232d747510SLisandro Dalcin    with a null monitoring context.
20242d747510SLisandro Dalcin 
20252d747510SLisandro Dalcin    Several different monitoring routines may be set by calling
2026*811af0c4SBarry Smith    `PetscOptionsMonitorSet()` multiple times; all will be called in the
20272d747510SLisandro Dalcin    order in which they were set.
20282d747510SLisandro Dalcin 
20299060e2f9SVaclav Hapla    Level: intermediate
20302d747510SLisandro Dalcin 
2031db781477SPatrick Sanan .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
20322d747510SLisandro Dalcin @*/
20339371c9d4SSatish Balay PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) {
20342d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
20352d747510SLisandro Dalcin 
20362d747510SLisandro Dalcin   PetscFunctionBegin;
2037c5b5d8d5SVaclav Hapla   if (options->monitorCancel) PetscFunctionReturn(0);
203808401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
20392d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
20402d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
20412d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void *)mctx;
20422d747510SLisandro Dalcin   PetscFunctionReturn(0);
20432d747510SLisandro Dalcin }
20442d747510SLisandro Dalcin 
20452d747510SLisandro Dalcin /*
20462d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
204763fe8743SVaclav Hapla      Empty string is considered as true.
20482d747510SLisandro Dalcin */
20499371c9d4SSatish Balay PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a) {
20502d747510SLisandro Dalcin   PetscBool istrue, isfalse;
20512d747510SLisandro Dalcin   size_t    len;
20522d747510SLisandro Dalcin 
20532d747510SLisandro Dalcin   PetscFunctionBegin;
205463fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
20559566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
20569371c9d4SSatish Balay   if (!len) {
20579371c9d4SSatish Balay     *a = PETSC_TRUE;
20589371c9d4SSatish Balay     PetscFunctionReturn(0);
20599371c9d4SSatish Balay   }
20609566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
20619371c9d4SSatish Balay   if (istrue) {
20629371c9d4SSatish Balay     *a = PETSC_TRUE;
20639371c9d4SSatish Balay     PetscFunctionReturn(0);
20649371c9d4SSatish Balay   }
20659566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
20669371c9d4SSatish Balay   if (istrue) {
20679371c9d4SSatish Balay     *a = PETSC_TRUE;
20689371c9d4SSatish Balay     PetscFunctionReturn(0);
20699371c9d4SSatish Balay   }
20709566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
20719371c9d4SSatish Balay   if (istrue) {
20729371c9d4SSatish Balay     *a = PETSC_TRUE;
20739371c9d4SSatish Balay     PetscFunctionReturn(0);
20749371c9d4SSatish Balay   }
20759566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
20769371c9d4SSatish Balay   if (istrue) {
20779371c9d4SSatish Balay     *a = PETSC_TRUE;
20789371c9d4SSatish Balay     PetscFunctionReturn(0);
20799371c9d4SSatish Balay   }
20809566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
20819371c9d4SSatish Balay   if (isfalse) {
20829371c9d4SSatish Balay     *a = PETSC_FALSE;
20839371c9d4SSatish Balay     PetscFunctionReturn(0);
20849371c9d4SSatish Balay   }
20859566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
20869371c9d4SSatish Balay   if (isfalse) {
20879371c9d4SSatish Balay     *a = PETSC_FALSE;
20889371c9d4SSatish Balay     PetscFunctionReturn(0);
20899371c9d4SSatish Balay   }
20909566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
20919371c9d4SSatish Balay   if (isfalse) {
20929371c9d4SSatish Balay     *a = PETSC_FALSE;
20939371c9d4SSatish Balay     PetscFunctionReturn(0);
20949371c9d4SSatish Balay   }
20959566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
20969371c9d4SSatish Balay   if (isfalse) {
20979371c9d4SSatish Balay     *a = PETSC_FALSE;
20989371c9d4SSatish Balay     PetscFunctionReturn(0);
20999371c9d4SSatish Balay   }
210098921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
21012d747510SLisandro Dalcin }
21022d747510SLisandro Dalcin 
21032d747510SLisandro Dalcin /*
21042d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
21052d747510SLisandro Dalcin */
21069371c9d4SSatish Balay PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a) {
21072d747510SLisandro Dalcin   size_t    len;
21082d747510SLisandro Dalcin   PetscBool decide, tdefault, mouse;
21092d747510SLisandro Dalcin 
21102d747510SLisandro Dalcin   PetscFunctionBegin;
21119566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
21125f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
21132d747510SLisandro Dalcin 
21149566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
211548a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
21169566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
211748a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
21189566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
21192d747510SLisandro Dalcin 
21202d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
21212d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
21222d747510SLisandro Dalcin   else if (mouse) *a = -1;
21232d747510SLisandro Dalcin   else {
21242d747510SLisandro Dalcin     char *endptr;
21252d747510SLisandro Dalcin     long  strtolval;
21262d747510SLisandro Dalcin 
21272d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2128cc73adaaSBarry 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);
21292d747510SLisandro Dalcin 
21302d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
21312d747510SLisandro Dalcin     (void)strtolval;
21322d747510SLisandro Dalcin     *a = atoll(name);
21332d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
21342d747510SLisandro Dalcin     (void)strtolval;
21352d747510SLisandro Dalcin     *a = _atoi64(name);
21362d747510SLisandro Dalcin #else
21372d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
21382d747510SLisandro Dalcin #endif
21392d747510SLisandro Dalcin   }
21402d747510SLisandro Dalcin   PetscFunctionReturn(0);
21412d747510SLisandro Dalcin }
21422d747510SLisandro Dalcin 
21432d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
21442d747510SLisandro Dalcin #include <quadmath.h>
21452d747510SLisandro Dalcin #endif
21462d747510SLisandro Dalcin 
21479371c9d4SSatish Balay static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr) {
21482d747510SLisandro Dalcin   PetscFunctionBegin;
21492d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
21502d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
21512d747510SLisandro Dalcin #else
21522d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
21532d747510SLisandro Dalcin #endif
21542d747510SLisandro Dalcin   PetscFunctionReturn(0);
21552d747510SLisandro Dalcin }
21562d747510SLisandro Dalcin 
21579371c9d4SSatish Balay static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary) {
21582d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
21592d747510SLisandro Dalcin   char     *ptr;
21602d747510SLisandro Dalcin   PetscReal strtoval;
21612d747510SLisandro Dalcin 
21622d747510SLisandro Dalcin   PetscFunctionBegin;
21639566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
21642d747510SLisandro Dalcin   if (ptr == name) {
21652d747510SLisandro Dalcin     strtoval = 1.;
21662d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
21672d747510SLisandro Dalcin     if (name[0] == 'i') {
21682d747510SLisandro Dalcin       ptr++;
21692d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
21702d747510SLisandro Dalcin       ptr += 2;
21712d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
21722d747510SLisandro Dalcin       strtoval = -1.;
21732d747510SLisandro Dalcin       ptr += 2;
21742d747510SLisandro Dalcin     }
21752d747510SLisandro Dalcin   } else if (*ptr == 'i') {
21762d747510SLisandro Dalcin     hasi = PETSC_TRUE;
21772d747510SLisandro Dalcin     ptr++;
21782d747510SLisandro Dalcin   }
21792d747510SLisandro Dalcin   *endptr      = ptr;
21802d747510SLisandro Dalcin   *isImaginary = hasi;
21812d747510SLisandro Dalcin   if (hasi) {
21822d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
218398921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
21842d747510SLisandro Dalcin #else
21852d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
21862d747510SLisandro Dalcin #endif
21872d747510SLisandro Dalcin   } else {
21882d747510SLisandro Dalcin     *a = strtoval;
21892d747510SLisandro Dalcin   }
21902d747510SLisandro Dalcin   PetscFunctionReturn(0);
21912d747510SLisandro Dalcin }
21922d747510SLisandro Dalcin 
21932d747510SLisandro Dalcin /*
21942d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
21952d747510SLisandro Dalcin */
21969371c9d4SSatish Balay PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a) {
21972d747510SLisandro Dalcin   size_t    len;
21982d747510SLisandro Dalcin   PetscBool match;
21992d747510SLisandro Dalcin   char     *endptr;
22002d747510SLisandro Dalcin 
22012d747510SLisandro Dalcin   PetscFunctionBegin;
22029566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
220328b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
22042d747510SLisandro Dalcin 
22059566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
22069566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
22079371c9d4SSatish Balay   if (match) {
22089371c9d4SSatish Balay     *a = PETSC_DEFAULT;
22099371c9d4SSatish Balay     PetscFunctionReturn(0);
22109371c9d4SSatish Balay   }
22112d747510SLisandro Dalcin 
22129566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
22139566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
22149371c9d4SSatish Balay   if (match) {
22159371c9d4SSatish Balay     *a = PETSC_DECIDE;
22169371c9d4SSatish Balay     PetscFunctionReturn(0);
22179371c9d4SSatish Balay   }
22182d747510SLisandro Dalcin 
22199566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
222039a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
22212d747510SLisandro Dalcin   PetscFunctionReturn(0);
22222d747510SLisandro Dalcin }
22232d747510SLisandro Dalcin 
22249371c9d4SSatish Balay PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a) {
22252d747510SLisandro Dalcin   PetscBool   imag1;
22262d747510SLisandro Dalcin   size_t      len;
22272d747510SLisandro Dalcin   PetscScalar val = 0.;
22282d747510SLisandro Dalcin   char       *ptr = NULL;
22292d747510SLisandro Dalcin 
22302d747510SLisandro Dalcin   PetscFunctionBegin;
22319566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
223228b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22339566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
22342d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
22352d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
22362d747510SLisandro Dalcin     PetscBool   imag2;
22372d747510SLisandro Dalcin     PetscScalar val2;
22382d747510SLisandro Dalcin 
22399566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
224039a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
22412d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
22422d747510SLisandro Dalcin   }
22432d747510SLisandro Dalcin #endif
224439a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
22452d747510SLisandro Dalcin   *a = val;
22462d747510SLisandro Dalcin   PetscFunctionReturn(0);
22472d747510SLisandro Dalcin }
22482d747510SLisandro Dalcin 
22492d747510SLisandro Dalcin /*@C
22502d747510SLisandro Dalcin    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
22512d747510SLisandro Dalcin             option in the database.
2252e5c89e4eSSatish Balay 
2253e5c89e4eSSatish Balay    Not Collective
2254e5c89e4eSSatish Balay 
2255e5c89e4eSSatish Balay    Input Parameters:
22565c9cc608SHong Zhang +  options - options database, use NULL for default global database
2257c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2258e5c89e4eSSatish Balay -  name - the option one is seeking
2259e5c89e4eSSatish Balay 
2260d8d19677SJose E. Roman    Output Parameters:
22612d747510SLisandro Dalcin +  ivalue - the logical value to return
2262*811af0c4SBarry Smith -  set - `PETSC_TRUE`  if found, else `PETSC_FALSE`
2263e5c89e4eSSatish Balay 
2264e5c89e4eSSatish Balay    Level: beginner
2265e5c89e4eSSatish Balay 
226695452b02SPatrick Sanan    Notes:
2267*811af0c4SBarry Smith        TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`
2268*811af0c4SBarry Smith        FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
22692d747510SLisandro Dalcin 
2270*811af0c4SBarry Smith       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
22712d747510SLisandro Dalcin      is equivalent to -requested_bool true
22722d747510SLisandro Dalcin 
22732d747510SLisandro Dalcin        If the user does not supply the option at all ivalue is NOT changed. Thus
22742efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
22752efd9cb1SBarry Smith 
2276db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2277db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2278db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2279c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2280db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2281db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2282e5c89e4eSSatish Balay @*/
22839371c9d4SSatish Balay PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set) {
22842d747510SLisandro Dalcin   const char *value;
2285ace3abfcSBarry Smith   PetscBool   flag;
2286e5c89e4eSSatish Balay 
2287e5c89e4eSSatish Balay   PetscFunctionBegin;
22882d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2289064a246eSJacob Faibussowitsch   if (ivalue) PetscValidBoolPointer(ivalue, 4);
22909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2291e5c89e4eSSatish Balay   if (flag) {
229296ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
22939566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
22942d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2295e5c89e4eSSatish Balay   } else {
229696ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2297e5c89e4eSSatish Balay   }
2298e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2299e5c89e4eSSatish Balay }
2300e5c89e4eSSatish Balay 
2301e5c89e4eSSatish Balay /*@C
2302e5c89e4eSSatish Balay    PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2303e5c89e4eSSatish Balay 
2304e5c89e4eSSatish Balay    Not Collective
2305e5c89e4eSSatish Balay 
2306e5c89e4eSSatish Balay    Input Parameters:
23075c9cc608SHong Zhang +  options - options database, use NULL for default global database
2308c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2309e5c89e4eSSatish Balay .  opt - option name
2310a264d7a6SBarry Smith .  list - the possible choices (one of these must be selected, anything else is invalid)
2311a2b725a8SWilliam Gropp -  ntext - number of choices
2312e5c89e4eSSatish Balay 
2313d8d19677SJose E. Roman    Output Parameters:
23142efd9cb1SBarry Smith +  value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2315*811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2316e5c89e4eSSatish Balay 
2317e5c89e4eSSatish Balay    Level: intermediate
2318e5c89e4eSSatish Balay 
231995452b02SPatrick Sanan    Notes:
232095452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
23212efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
23222efd9cb1SBarry Smith 
2323*811af0c4SBarry Smith    See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2324e5c89e4eSSatish Balay 
2325db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2326db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2327db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2328c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2329db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2330db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2331e5c89e4eSSatish Balay @*/
23329371c9d4SSatish Balay PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscInt ntext, PetscInt *value, PetscBool *set) {
233358b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2334e5c89e4eSSatish Balay   char     *svalue;
2335ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2336e5c89e4eSSatish Balay   PetscInt  i;
2337e5c89e4eSSatish Balay 
2338e5c89e4eSSatish Balay   PetscFunctionBegin;
23392d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
2340e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
23419566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2342e5c89e4eSSatish Balay     if (alen > len) len = alen;
234358b0ac4eSStefano Zampini     tlen += len + 1;
2344e5c89e4eSSatish Balay   }
2345e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
23469566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
23479566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2348e5c89e4eSSatish Balay   if (aset) {
23499566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
235058b0ac4eSStefano Zampini     if (!flg) {
235158b0ac4eSStefano Zampini       char *avail, *pavl;
235258b0ac4eSStefano Zampini 
23539566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
235458b0ac4eSStefano Zampini       pavl = avail;
235558b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
23569566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(list[i], &alen));
23579566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(pavl, list[i]));
235858b0ac4eSStefano Zampini         pavl += alen;
23599566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(pavl, " "));
236058b0ac4eSStefano Zampini         pavl += 1;
236158b0ac4eSStefano Zampini       }
23629566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
236398921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
236458b0ac4eSStefano Zampini     }
2365fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2366a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
23679566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
2368e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2369e5c89e4eSSatish Balay }
2370e5c89e4eSSatish Balay 
2371e5c89e4eSSatish Balay /*@C
2372e5c89e4eSSatish Balay    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2373e5c89e4eSSatish Balay 
2374e5c89e4eSSatish Balay    Not Collective
2375e5c89e4eSSatish Balay 
2376e5c89e4eSSatish Balay    Input Parameters:
23775c9cc608SHong Zhang +  options - options database, use NULL for default global database
2378c5929fdfSBarry Smith .  pre - option prefix or NULL
2379e5c89e4eSSatish Balay .  opt - option name
23806b867d5aSJose E. Roman -  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2381e5c89e4eSSatish Balay 
2382d8d19677SJose E. Roman    Output Parameters:
2383e5c89e4eSSatish Balay +  value - the  value to return
2384*811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2385e5c89e4eSSatish Balay 
2386e5c89e4eSSatish Balay    Level: beginner
2387e5c89e4eSSatish Balay 
238895452b02SPatrick Sanan    Notes:
238995452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
23902efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2391e5c89e4eSSatish Balay 
2392*811af0c4SBarry Smith           List is usually something like `PCASMTypes` or some other predefined list of enum names
2393e5c89e4eSSatish Balay 
2394db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2395db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2396db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2397db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2398c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2399db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2400db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2401e5c89e4eSSatish Balay @*/
24029371c9d4SSatish Balay PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscEnum *value, PetscBool *set) {
240369a24498SJed Brown   PetscInt  ntext = 0, tval;
2404ace3abfcSBarry Smith   PetscBool fset;
2405e5c89e4eSSatish Balay 
2406e5c89e4eSSatish Balay   PetscFunctionBegin;
24072d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
2408ad540459SPierre Jolivet   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");
240908401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2410e5c89e4eSSatish Balay   ntext -= 3;
24119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
241269a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2413809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2414809ceb46SBarry Smith   if (set) *set = fset;
2415e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2416e5c89e4eSSatish Balay }
2417e5c89e4eSSatish Balay 
2418e5c89e4eSSatish Balay /*@C
24192d747510SLisandro Dalcin    PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2420e5c89e4eSSatish Balay 
2421e5c89e4eSSatish Balay    Not Collective
2422e5c89e4eSSatish Balay 
2423e5c89e4eSSatish Balay    Input Parameters:
24245c9cc608SHong Zhang +  options - options database, use NULL for default global database
2425c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2426e5c89e4eSSatish Balay -  name - the option one is seeking
2427e5c89e4eSSatish Balay 
2428d8d19677SJose E. Roman    Output Parameters:
24292d747510SLisandro Dalcin +  ivalue - the integer value to return
2430*811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2431e5c89e4eSSatish Balay 
2432e5c89e4eSSatish Balay    Level: beginner
2433e5c89e4eSSatish Balay 
2434e5c89e4eSSatish Balay    Notes:
24352d747510SLisandro Dalcin    If the user does not supply the option ivalue is NOT changed. Thus
24362efd9cb1SBarry Smith    you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
24375c07ccb8SBarry Smith 
2438db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2439db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2440db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2441db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2442c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2443db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2444db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2445e5c89e4eSSatish Balay @*/
24469371c9d4SSatish Balay PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set) {
24472d747510SLisandro Dalcin   const char *value;
24482d747510SLisandro Dalcin   PetscBool   flag;
2449e5c89e4eSSatish Balay 
2450e5c89e4eSSatish Balay   PetscFunctionBegin;
24512d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
24522d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
24539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2454e5c89e4eSSatish Balay   if (flag) {
245534a9cc2cSBarry Smith     if (!value) {
24562d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
245734a9cc2cSBarry Smith     } else {
24582d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
24599566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2460e5c89e4eSSatish Balay     }
2461e5c89e4eSSatish Balay   } else {
246296ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2463e5c89e4eSSatish Balay   }
2464e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2465e5c89e4eSSatish Balay }
2466e5c89e4eSSatish Balay 
2467e2446a98SMatthew Knepley /*@C
2468e5c89e4eSSatish Balay    PetscOptionsGetReal - Gets the double precision value for a particular
2469e5c89e4eSSatish Balay    option in the database.
2470e5c89e4eSSatish Balay 
2471e5c89e4eSSatish Balay    Not Collective
2472e5c89e4eSSatish Balay 
2473e5c89e4eSSatish Balay    Input Parameters:
24745c9cc608SHong Zhang +  options - options database, use NULL for default global database
2475c5929fdfSBarry Smith .  pre - string to prepend to each name or NULL
2476e5c89e4eSSatish Balay -  name - the option one is seeking
2477e5c89e4eSSatish Balay 
2478d8d19677SJose E. Roman    Output Parameters:
2479e5c89e4eSSatish Balay +  dvalue - the double value to return
2480*811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2481e5c89e4eSSatish Balay 
2482*811af0c4SBarry Smith    Note:
248395452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
24842efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2485e4974155SBarry Smith 
2486e5c89e4eSSatish Balay    Level: beginner
2487e5c89e4eSSatish Balay 
2488db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2489c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2490db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2491c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2492db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2493db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2494e5c89e4eSSatish Balay @*/
24959371c9d4SSatish Balay PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set) {
24962d747510SLisandro Dalcin   const char *value;
2497ace3abfcSBarry Smith   PetscBool   flag;
2498e5c89e4eSSatish Balay 
2499e5c89e4eSSatish Balay   PetscFunctionBegin;
25002d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
25012d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
25029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2503e5c89e4eSSatish Balay   if (flag) {
2504a297a907SKarl Rupp     if (!value) {
2505a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2506a297a907SKarl Rupp     } else {
2507a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
25089566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2509a297a907SKarl Rupp     }
2510e5c89e4eSSatish Balay   } else {
251196ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2512e5c89e4eSSatish Balay   }
2513e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2514e5c89e4eSSatish Balay }
2515e5c89e4eSSatish Balay 
2516e5c89e4eSSatish Balay /*@C
2517e5c89e4eSSatish Balay    PetscOptionsGetScalar - Gets the scalar value for a particular
2518e5c89e4eSSatish Balay    option in the database.
2519e5c89e4eSSatish Balay 
2520e5c89e4eSSatish Balay    Not Collective
2521e5c89e4eSSatish Balay 
2522e5c89e4eSSatish Balay    Input Parameters:
25235c9cc608SHong Zhang +  options - options database, use NULL for default global database
2524c5929fdfSBarry Smith .  pre - string to prepend to each name or NULL
2525e5c89e4eSSatish Balay -  name - the option one is seeking
2526e5c89e4eSSatish Balay 
2527d8d19677SJose E. Roman    Output Parameters:
2528e5c89e4eSSatish Balay +  dvalue - the double value to return
2529*811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2530e5c89e4eSSatish Balay 
2531e5c89e4eSSatish Balay    Level: beginner
2532e5c89e4eSSatish Balay 
2533e5c89e4eSSatish Balay    Usage:
2534eb4ae41dSBarry Smith    A complex number 2+3i must be specified with NO spaces
2535e5c89e4eSSatish Balay 
2536*811af0c4SBarry Smith    Note:
253795452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
25382efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2539e4974155SBarry Smith 
2540db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2541db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2542db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2543c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2544db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2545db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2546e5c89e4eSSatish Balay @*/
25479371c9d4SSatish Balay PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set) {
25482d747510SLisandro Dalcin   const char *value;
2549ace3abfcSBarry Smith   PetscBool   flag;
2550e5c89e4eSSatish Balay 
2551e5c89e4eSSatish Balay   PetscFunctionBegin;
25522d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
25532d747510SLisandro Dalcin   PetscValidScalarPointer(dvalue, 4);
25549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2555e5c89e4eSSatish Balay   if (flag) {
2556e5c89e4eSSatish Balay     if (!value) {
255796ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2558e5c89e4eSSatish Balay     } else {
2559e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
25609566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2561e5c89e4eSSatish Balay #else
25629566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2563e5c89e4eSSatish Balay #endif
256496ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2565e5c89e4eSSatish Balay     }
2566e5c89e4eSSatish Balay   } else { /* flag */
256796ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2568e5c89e4eSSatish Balay   }
2569e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2570e5c89e4eSSatish Balay }
2571e5c89e4eSSatish Balay 
2572e5c89e4eSSatish Balay /*@C
2573e5c89e4eSSatish Balay    PetscOptionsGetString - Gets the string value for a particular option in
2574e5c89e4eSSatish Balay    the database.
2575e5c89e4eSSatish Balay 
2576e5c89e4eSSatish Balay    Not Collective
2577e5c89e4eSSatish Balay 
2578e5c89e4eSSatish Balay    Input Parameters:
25795c9cc608SHong Zhang +  options - options database, use NULL for default global database
2580c5929fdfSBarry Smith .  pre - string to prepend to name or NULL
2581e5c89e4eSSatish Balay .  name - the option one is seeking
2582bcbf2dc5SJed Brown -  len - maximum length of the string including null termination
2583e5c89e4eSSatish Balay 
2584e5c89e4eSSatish Balay    Output Parameters:
2585e5c89e4eSSatish Balay +  string - location to copy string
2586*811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2587e5c89e4eSSatish Balay 
2588e5c89e4eSSatish Balay    Level: beginner
2589e5c89e4eSSatish Balay 
2590e5c89e4eSSatish Balay    Fortran Note:
2591e5c89e4eSSatish Balay    The Fortran interface is slightly different from the C/C++
2592e5c89e4eSSatish Balay    interface (len is not used).  Sample usage in Fortran follows
2593e5c89e4eSSatish Balay .vb
2594e5c89e4eSSatish Balay       character *20    string
259593e6ba5cSBarry Smith       PetscErrorCode   ierr
259693e6ba5cSBarry Smith       PetscBool        set
25971b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2598e5c89e4eSSatish Balay .ve
2599e5c89e4eSSatish Balay 
2600*811af0c4SBarry Smith    Note:
2601*811af0c4SBarry Smith     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`
2602e4974155SBarry Smith 
26032efd9cb1SBarry Smith            If the user does not use the option then the string is not changed. Thus
26042efd9cb1SBarry Smith            you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
26052efd9cb1SBarry Smith 
2606f3dea69dSBarry 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).
2607f3dea69dSBarry Smith 
2608db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2609db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2610db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2611c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2612db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2613db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2614e5c89e4eSSatish Balay @*/
26159371c9d4SSatish Balay PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set) {
26162d747510SLisandro Dalcin   const char *value;
2617ace3abfcSBarry Smith   PetscBool   flag;
2618e5c89e4eSSatish Balay 
2619e5c89e4eSSatish Balay   PetscFunctionBegin;
26202d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
26212d747510SLisandro Dalcin   PetscValidCharPointer(string, 4);
26229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2623e5c89e4eSSatish Balay   if (!flag) {
262496ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2625e5c89e4eSSatish Balay   } else {
262696ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
26279566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
26289566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2629e5c89e4eSSatish Balay   }
2630e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2631e5c89e4eSSatish Balay }
2632e5c89e4eSSatish Balay 
26339371c9d4SSatish Balay char *PetscOptionsGetStringMatlab(PetscOptions options, const char pre[], const char name[]) {
26342d747510SLisandro Dalcin   const char *value;
263514ce751eSBarry Smith   PetscBool   flag;
263614ce751eSBarry Smith 
263714ce751eSBarry Smith   PetscFunctionBegin;
263839a651e2SJacob Faibussowitsch   if (PetscOptionsFindPair(options, pre, name, &value, &flag)) PetscFunctionReturn(NULL);
26392d747510SLisandro Dalcin   if (flag) PetscFunctionReturn((char *)value);
264039a651e2SJacob Faibussowitsch   PetscFunctionReturn(NULL);
264114ce751eSBarry Smith }
264214ce751eSBarry Smith 
26432d747510SLisandro Dalcin /*@C
26442d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2645f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
26462d747510SLisandro Dalcin 
26472d747510SLisandro Dalcin   Not Collective
26482d747510SLisandro Dalcin 
26492d747510SLisandro Dalcin   Input Parameters:
26502d747510SLisandro Dalcin + options - options database, use NULL for default global database
26512d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
26526b867d5aSJose E. Roman - name - the option one is seeking
26536b867d5aSJose E. Roman 
2654d8d19677SJose E. Roman   Output Parameters:
26552d747510SLisandro Dalcin + dvalue - the integer values to return
2656f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2657*811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
26582d747510SLisandro Dalcin 
26592d747510SLisandro Dalcin   Level: beginner
26602d747510SLisandro Dalcin 
2661*811af0c4SBarry Smith   Note:
2662f1a722f8SMatthew 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
26632d747510SLisandro Dalcin 
2664db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2665db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2666db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2667c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2668db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2669db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
26702d747510SLisandro Dalcin @*/
26719371c9d4SSatish Balay PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set) {
26722d747510SLisandro Dalcin   const char *svalue;
26732d747510SLisandro Dalcin   char       *value;
26742d747510SLisandro Dalcin   PetscInt    n = 0;
26752d747510SLisandro Dalcin   PetscBool   flag;
26762d747510SLisandro Dalcin   PetscToken  token;
26772d747510SLisandro Dalcin 
26782d747510SLisandro Dalcin   PetscFunctionBegin;
26792d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2680064a246eSJacob Faibussowitsch   PetscValidBoolPointer(dvalue, 4);
26812d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
26822d747510SLisandro Dalcin 
26839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
26849371c9d4SSatish Balay   if (!flag || !svalue) {
26859371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
26869371c9d4SSatish Balay     *nmax = 0;
26879371c9d4SSatish Balay     PetscFunctionReturn(0);
26889371c9d4SSatish Balay   }
26892d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
26909566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
26919566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
26922d747510SLisandro Dalcin   while (value && n < *nmax) {
26939566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
26949566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
26952d747510SLisandro Dalcin     dvalue++;
26962d747510SLisandro Dalcin     n++;
26972d747510SLisandro Dalcin   }
26989566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
26992d747510SLisandro Dalcin   *nmax = n;
27002d747510SLisandro Dalcin   PetscFunctionReturn(0);
27012d747510SLisandro Dalcin }
27022d747510SLisandro Dalcin 
27032d747510SLisandro Dalcin /*@C
27042d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
27052d747510SLisandro Dalcin 
27062d747510SLisandro Dalcin   Not Collective
27072d747510SLisandro Dalcin 
27082d747510SLisandro Dalcin   Input Parameters:
27092d747510SLisandro Dalcin + options - options database, use NULL for default global database
27102d747510SLisandro Dalcin . pre - option prefix or NULL
27112d747510SLisandro Dalcin . name - option name
27126b867d5aSJose E. Roman - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
27136b867d5aSJose E. Roman 
27142d747510SLisandro Dalcin   Output Parameters:
27152d747510SLisandro Dalcin + ivalue - the  enum values to return
2716f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2717*811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
27182d747510SLisandro Dalcin 
27192d747510SLisandro Dalcin   Level: beginner
27202d747510SLisandro Dalcin 
27212d747510SLisandro Dalcin   Notes:
27222d747510SLisandro Dalcin   The array must be passed as a comma separated list.
27232d747510SLisandro Dalcin 
27242d747510SLisandro Dalcin   There must be no intervening spaces between the values.
27252d747510SLisandro Dalcin 
2726*811af0c4SBarry Smith   list is usually something like `PCASMTypes` or some other predefined list of enum names.
27272d747510SLisandro Dalcin 
2728db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2729db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2730db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, `PetscOptionsName()`,
2731c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2732db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2733db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
27342d747510SLisandro Dalcin @*/
27359371c9d4SSatish Balay PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const *list, PetscEnum ivalue[], PetscInt *nmax, PetscBool *set) {
27362d747510SLisandro Dalcin   const char *svalue;
27372d747510SLisandro Dalcin   char       *value;
27382d747510SLisandro Dalcin   PetscInt    n = 0;
27392d747510SLisandro Dalcin   PetscEnum   evalue;
27402d747510SLisandro Dalcin   PetscBool   flag;
27412d747510SLisandro Dalcin   PetscToken  token;
27422d747510SLisandro Dalcin 
27432d747510SLisandro Dalcin   PetscFunctionBegin;
27442d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
27452d747510SLisandro Dalcin   PetscValidPointer(list, 4);
27462d747510SLisandro Dalcin   PetscValidPointer(ivalue, 5);
27472d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 6);
27482d747510SLisandro Dalcin 
27499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
27509371c9d4SSatish Balay   if (!flag || !svalue) {
27519371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
27529371c9d4SSatish Balay     *nmax = 0;
27539371c9d4SSatish Balay     PetscFunctionReturn(0);
27549371c9d4SSatish Balay   }
27552d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
27569566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
27579566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
27582d747510SLisandro Dalcin   while (value && n < *nmax) {
27599566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
276028b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
27612d747510SLisandro Dalcin     ivalue[n++] = evalue;
27629566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
27632d747510SLisandro Dalcin   }
27649566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
27652d747510SLisandro Dalcin   *nmax = n;
27662d747510SLisandro Dalcin   PetscFunctionReturn(0);
27672d747510SLisandro Dalcin }
27682d747510SLisandro Dalcin 
27692d747510SLisandro Dalcin /*@C
2770f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
27712d747510SLisandro Dalcin 
27722d747510SLisandro Dalcin   Not Collective
27732d747510SLisandro Dalcin 
27742d747510SLisandro Dalcin   Input Parameters:
27752d747510SLisandro Dalcin + options - options database, use NULL for default global database
27762d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
27776b867d5aSJose E. Roman - name - the option one is seeking
27786b867d5aSJose E. Roman 
2779d8d19677SJose E. Roman   Output Parameters:
27802d747510SLisandro Dalcin + ivalue - the integer values to return
2781f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2782*811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
27832d747510SLisandro Dalcin 
27842d747510SLisandro Dalcin   Level: beginner
27852d747510SLisandro Dalcin 
27862d747510SLisandro Dalcin   Notes:
27872d747510SLisandro Dalcin   The array can be passed as
2788*811af0c4SBarry Smith +  a comma separated list -                                 0,1,2,3,4,5,6,7
2789*811af0c4SBarry Smith .  a range (start\-end+1) -                                 0-8
2790*811af0c4SBarry Smith .  a range with given increment (start\-end+1:inc) -        0-7:2
2791*811af0c4SBarry Smith -  a combination of values and ranges separated by commas - 0,1-8,8-15:2
27922d747510SLisandro Dalcin 
27932d747510SLisandro Dalcin   There must be no intervening spaces between the values.
27942d747510SLisandro Dalcin 
2795db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2796db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2797db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2798c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2799db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2800db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
28012d747510SLisandro Dalcin @*/
28029371c9d4SSatish Balay PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set) {
28032d747510SLisandro Dalcin   const char *svalue;
28042d747510SLisandro Dalcin   char       *value;
28052d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
28062d747510SLisandro Dalcin   size_t      len;
28072d747510SLisandro Dalcin   PetscBool   flag, foundrange;
28082d747510SLisandro Dalcin   PetscToken  token;
28092d747510SLisandro Dalcin 
28102d747510SLisandro Dalcin   PetscFunctionBegin;
28112d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
28122d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
28132d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
28142d747510SLisandro Dalcin 
28159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28169371c9d4SSatish Balay   if (!flag || !svalue) {
28179371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28189371c9d4SSatish Balay     *nmax = 0;
28199371c9d4SSatish Balay     PetscFunctionReturn(0);
28209371c9d4SSatish Balay   }
28212d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28229566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28239566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28242d747510SLisandro Dalcin   while (value && n < *nmax) {
28252d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
28262d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
28279566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value, &len));
28282d747510SLisandro Dalcin     if (value[0] == '-') i = 2;
28292d747510SLisandro Dalcin     else i = 1;
28302d747510SLisandro Dalcin     for (; i < (int)len; i++) {
28312d747510SLisandro Dalcin       if (value[i] == '-') {
2832cc73adaaSBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
28332d747510SLisandro Dalcin         value[i] = 0;
28342d747510SLisandro Dalcin 
28359566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value, &start));
28362d747510SLisandro Dalcin         inc = 1;
28372d747510SLisandro Dalcin         j   = i + 1;
28382d747510SLisandro Dalcin         for (; j < (int)len; j++) {
28392d747510SLisandro Dalcin           if (value[j] == ':') {
28402d747510SLisandro Dalcin             value[j] = 0;
28412d747510SLisandro Dalcin 
28429566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value + j + 1, &inc));
284308401ef6SPierre 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);
28442d747510SLisandro Dalcin             break;
28452d747510SLisandro Dalcin           }
28462d747510SLisandro Dalcin         }
28479566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
284808401ef6SPierre 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);
28492d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
2850cc73adaaSBarry 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);
28512d747510SLisandro Dalcin         for (; start < end; start += inc) {
28529371c9d4SSatish Balay           *ivalue = start;
28539371c9d4SSatish Balay           ivalue++;
28549371c9d4SSatish Balay           n++;
28552d747510SLisandro Dalcin         }
28562d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
28572d747510SLisandro Dalcin         break;
28582d747510SLisandro Dalcin       }
28592d747510SLisandro Dalcin     }
28602d747510SLisandro Dalcin     if (!foundrange) {
28619566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
28622d747510SLisandro Dalcin       ivalue++;
28632d747510SLisandro Dalcin       n++;
28642d747510SLisandro Dalcin     }
28659566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
28662d747510SLisandro Dalcin   }
28679566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28682d747510SLisandro Dalcin   *nmax = n;
28692d747510SLisandro Dalcin   PetscFunctionReturn(0);
28702d747510SLisandro Dalcin }
28712d747510SLisandro Dalcin 
28722d747510SLisandro Dalcin /*@C
28732d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
2874f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
28752d747510SLisandro Dalcin 
28762d747510SLisandro Dalcin   Not Collective
28772d747510SLisandro Dalcin 
28782d747510SLisandro Dalcin   Input Parameters:
28792d747510SLisandro Dalcin + options - options database, use NULL for default global database
28802d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
28816b867d5aSJose E. Roman - name - the option one is seeking
28826b867d5aSJose E. Roman 
28832d747510SLisandro Dalcin   Output Parameters:
28842d747510SLisandro Dalcin + dvalue - the double values to return
2885f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2886*811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
28872d747510SLisandro Dalcin 
28882d747510SLisandro Dalcin   Level: beginner
28892d747510SLisandro Dalcin 
2890db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2891db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2892db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2893c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2894db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2895db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
28962d747510SLisandro Dalcin @*/
28979371c9d4SSatish Balay PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set) {
28982d747510SLisandro Dalcin   const char *svalue;
28992d747510SLisandro Dalcin   char       *value;
29002d747510SLisandro Dalcin   PetscInt    n = 0;
29012d747510SLisandro Dalcin   PetscBool   flag;
29022d747510SLisandro Dalcin   PetscToken  token;
29032d747510SLisandro Dalcin 
29042d747510SLisandro Dalcin   PetscFunctionBegin;
29052d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
29062d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
29072d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
29082d747510SLisandro Dalcin 
29099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29109371c9d4SSatish Balay   if (!flag || !svalue) {
29119371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29129371c9d4SSatish Balay     *nmax = 0;
29139371c9d4SSatish Balay     PetscFunctionReturn(0);
29149371c9d4SSatish Balay   }
29152d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29169566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29179566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29182d747510SLisandro Dalcin   while (value && n < *nmax) {
29199566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
29209566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29212d747510SLisandro Dalcin     n++;
29222d747510SLisandro Dalcin   }
29239566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29242d747510SLisandro Dalcin   *nmax = n;
29252d747510SLisandro Dalcin   PetscFunctionReturn(0);
29262d747510SLisandro Dalcin }
29272d747510SLisandro Dalcin 
29282d747510SLisandro Dalcin /*@C
29292d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
2930f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
29312d747510SLisandro Dalcin 
29322d747510SLisandro Dalcin   Not Collective
29332d747510SLisandro Dalcin 
29342d747510SLisandro Dalcin   Input Parameters:
29352d747510SLisandro Dalcin + options - options database, use NULL for default global database
29362d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
29376b867d5aSJose E. Roman - name - the option one is seeking
29386b867d5aSJose E. Roman 
29392d747510SLisandro Dalcin   Output Parameters:
29402d747510SLisandro Dalcin + dvalue - the scalar values to return
2941f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2942*811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
29432d747510SLisandro Dalcin 
29442d747510SLisandro Dalcin   Level: beginner
29452d747510SLisandro Dalcin 
2946db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2947db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2948db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2949c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2950db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2951db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29522d747510SLisandro Dalcin @*/
29539371c9d4SSatish Balay PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set) {
29542d747510SLisandro Dalcin   const char *svalue;
29552d747510SLisandro Dalcin   char       *value;
29562d747510SLisandro Dalcin   PetscInt    n = 0;
29572d747510SLisandro Dalcin   PetscBool   flag;
29582d747510SLisandro Dalcin   PetscToken  token;
29592d747510SLisandro Dalcin 
29602d747510SLisandro Dalcin   PetscFunctionBegin;
29612d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2962064a246eSJacob Faibussowitsch   PetscValidScalarPointer(dvalue, 4);
29632d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
29642d747510SLisandro Dalcin 
29659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29669371c9d4SSatish Balay   if (!flag || !svalue) {
29679371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29689371c9d4SSatish Balay     *nmax = 0;
29699371c9d4SSatish Balay     PetscFunctionReturn(0);
29709371c9d4SSatish Balay   }
29712d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29729566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29739566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29742d747510SLisandro Dalcin   while (value && n < *nmax) {
29759566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value, dvalue++));
29769566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29772d747510SLisandro Dalcin     n++;
29782d747510SLisandro Dalcin   }
29799566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29802d747510SLisandro Dalcin   *nmax = n;
29812d747510SLisandro Dalcin   PetscFunctionReturn(0);
29822d747510SLisandro Dalcin }
298314ce751eSBarry Smith 
2984e5c89e4eSSatish Balay /*@C
2985e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
2986f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
2987e5c89e4eSSatish Balay 
2988e5c89e4eSSatish Balay   Not Collective
2989e5c89e4eSSatish Balay 
2990e5c89e4eSSatish Balay   Input Parameters:
29915c9cc608SHong Zhang + options - options database, use NULL for default global database
2992c5929fdfSBarry Smith . pre - string to prepend to name or NULL
29936b867d5aSJose E. Roman - name - the option one is seeking
29946b867d5aSJose E. Roman 
2995e7b76fa7SPatrick Sanan   Output Parameters:
2996e5c89e4eSSatish Balay + strings - location to copy strings
2997f1a722f8SMatthew G. Knepley . nmax - On input maximum number of strings, on output the actual number of strings found
2998*811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2999e5c89e4eSSatish Balay 
3000e5c89e4eSSatish Balay   Level: beginner
3001e5c89e4eSSatish Balay 
3002e5c89e4eSSatish Balay   Notes:
3003e7b76fa7SPatrick Sanan   The nmax parameter is used for both input and output.
3004e7b76fa7SPatrick Sanan 
3005e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
3006e5c89e4eSSatish Balay   strings returned by this function.
3007e5c89e4eSSatish Balay 
3008e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3009e5c89e4eSSatish Balay   returned. The Fortran interface for this routine is not supported.
3010e5c89e4eSSatish Balay 
3011db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3012db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3013db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3014c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3015db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3016db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3017e5c89e4eSSatish Balay @*/
30189371c9d4SSatish Balay PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set) {
30192d747510SLisandro Dalcin   const char *svalue;
3020e5c89e4eSSatish Balay   char       *value;
30212d747510SLisandro Dalcin   PetscInt    n = 0;
3022ace3abfcSBarry Smith   PetscBool   flag;
30239c9d3cfdSBarry Smith   PetscToken  token;
3024e5c89e4eSSatish Balay 
3025e5c89e4eSSatish Balay   PetscFunctionBegin;
30262d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
30272d747510SLisandro Dalcin   PetscValidPointer(strings, 4);
30282d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
3029e5c89e4eSSatish Balay 
30309566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30319371c9d4SSatish Balay   if (!flag || !svalue) {
30329371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30339371c9d4SSatish Balay     *nmax = 0;
30349371c9d4SSatish Balay     PetscFunctionReturn(0);
30359371c9d4SSatish Balay   }
30362d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30379566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30389566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30392d747510SLisandro Dalcin   while (value && n < *nmax) {
30409566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
30419566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3042e5c89e4eSSatish Balay     n++;
3043e5c89e4eSSatish Balay   }
30449566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3045e5c89e4eSSatish Balay   *nmax = n;
3046e5c89e4eSSatish Balay   PetscFunctionReturn(0);
3047e5c89e4eSSatish Balay }
304806824ed3SPatrick Sanan 
304906824ed3SPatrick Sanan /*@C
305006824ed3SPatrick Sanan    PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one
305106824ed3SPatrick Sanan 
305206824ed3SPatrick Sanan    Prints a deprecation warning, unless an option is supplied to suppress.
305306824ed3SPatrick Sanan 
30541c9f3c13SBarry Smith    Logically Collective
305506824ed3SPatrick Sanan 
305606824ed3SPatrick Sanan    Input Parameters:
30579503aa97SPatrick Sanan +  pre - string to prepend to name or NULL
305806824ed3SPatrick Sanan .  oldname - the old, deprecated option
305906824ed3SPatrick Sanan .  newname - the new option, or NULL if option is purely removed
30609f3a6782SPatrick Sanan .  version - a string describing the version of first deprecation, e.g. "3.9"
30619f3a6782SPatrick Sanan -  info - additional information string, or NULL.
306206824ed3SPatrick Sanan 
3063*811af0c4SBarry Smith    Options Database Key:
306406824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
306506824ed3SPatrick Sanan 
306606824ed3SPatrick Sanan    Notes:
3067*811af0c4SBarry Smith    Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
3068*811af0c4SBarry Smith    Only the proces of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3069*811af0c4SBarry Smith    `PetscObjectOptionsBegin()` prints the information
3070b40114eaSPatrick Sanan    If newname is provided, the old option is replaced. Otherwise, it remains
3071b40114eaSPatrick Sanan    in the options database.
30729f3a6782SPatrick Sanan    If an option is not replaced, the info argument should be used to advise the user
30739f3a6782SPatrick Sanan    on how to proceed.
30749f3a6782SPatrick Sanan    There is a limit on the length of the warning printed, so very long strings
30759f3a6782SPatrick Sanan    provided as info may be truncated.
307606824ed3SPatrick Sanan 
307706824ed3SPatrick Sanan    Level: developer
307806824ed3SPatrick Sanan 
3079db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
308006824ed3SPatrick Sanan @*/
30819371c9d4SSatish Balay PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[]) {
308206824ed3SPatrick Sanan   PetscBool         found, quiet;
308306824ed3SPatrick Sanan   const char       *value;
308406824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
30859f3a6782SPatrick Sanan   char              msg[4096];
3086b0bdc838SStefano Zampini   char             *prefix  = NULL;
3087b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3088b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
308906824ed3SPatrick Sanan 
309006824ed3SPatrick Sanan   PetscFunctionBegin;
309106824ed3SPatrick Sanan   PetscValidCharPointer(oldname, 2);
309206824ed3SPatrick Sanan   PetscValidCharPointer(version, 4);
3093b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3094b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3095b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3096b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3097b0bdc838SStefano Zampini   }
30989566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
309906824ed3SPatrick Sanan   if (found) {
310006824ed3SPatrick Sanan     if (newname) {
31011baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
31029566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options, newname, value));
31031baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
31049566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3105b40114eaSPatrick Sanan     }
310606824ed3SPatrick Sanan     quiet = PETSC_FALSE;
31079566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
310806824ed3SPatrick Sanan     if (!quiet) {
31099566063dSJacob Faibussowitsch       PetscCall(PetscStrcpy(msg, "** PETSc DEPRECATION WARNING ** : the option "));
31109566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, oldname));
31119566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, " is deprecated as of version "));
31129566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, version));
31139566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, " and will be removed in a future release."));
311406824ed3SPatrick Sanan       if (newname) {
31159566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, " Please use the option "));
31169566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, newname));
31179566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, " instead."));
311806824ed3SPatrick Sanan       }
31199f3a6782SPatrick Sanan       if (info) {
31209566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, " "));
31219566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, info));
31229f3a6782SPatrick Sanan       }
31239566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, " (Silence this warning with "));
31249566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, quietopt));
31259566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, ")\n"));
31269566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
312706824ed3SPatrick Sanan     }
312806824ed3SPatrick Sanan   }
312906824ed3SPatrick Sanan   PetscFunctionReturn(0);
313006824ed3SPatrick Sanan }
3131