xref: /petsc/src/sys/objects/options.c (revision cf53795e253c8c9d9d0fbcef4cffd37d916c4e81)
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   */
34d71ae5a4SJacob Faibussowitsch static inline int PetscToLower(int c)
35d71ae5a4SJacob Faibussowitsch {
362d747510SLisandro Dalcin   return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
372d747510SLisandro Dalcin }
382d747510SLisandro Dalcin 
392d747510SLisandro Dalcin /* Bob Jenkins's one at a time hash function (case-insensitive) */
40d71ae5a4SJacob Faibussowitsch static inline unsigned int PetscOptHash(const char key[])
41d71ae5a4SJacob Faibussowitsch {
422d747510SLisandro Dalcin   unsigned int hash = 0;
432d747510SLisandro Dalcin   while (*key) {
442d747510SLisandro Dalcin     hash += PetscToLower(*key++);
452d747510SLisandro Dalcin     hash += hash << 10;
462d747510SLisandro Dalcin     hash ^= hash >> 6;
472d747510SLisandro Dalcin   }
482d747510SLisandro Dalcin   hash += hash << 3;
492d747510SLisandro Dalcin   hash ^= hash >> 11;
502d747510SLisandro Dalcin   hash += hash << 15;
512d747510SLisandro Dalcin   return hash;
522d747510SLisandro Dalcin }
532d747510SLisandro Dalcin 
54d71ae5a4SJacob Faibussowitsch static inline int PetscOptEqual(const char a[], const char b[])
55d71ae5a4SJacob Faibussowitsch {
562d747510SLisandro Dalcin   return !PetscOptNameCmp(a, b);
572d747510SLisandro Dalcin }
582d747510SLisandro Dalcin 
592d747510SLisandro Dalcin KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
602d747510SLisandro Dalcin 
61e5c89e4eSSatish Balay /*
623fc1eb6aSBarry Smith     This table holds all the options set by the user. For simplicity, we use a static size database
63e5c89e4eSSatish Balay */
64c5c1f447SLisandro Dalcin #define MAXOPTNAME         PETSC_MAX_OPTION_NAME
65e5c89e4eSSatish Balay #define MAXOPTIONS         512
66e5c89e4eSSatish Balay #define MAXALIASES         25
6774e0666dSJed Brown #define MAXPREFIXES        25
682d747510SLisandro Dalcin #define MAXOPTIONSMONITORS 5
69e5c89e4eSSatish Balay 
704416b707SBarry Smith struct _n_PetscOptions {
713de2bfdfSBarry Smith   PetscOptions previous;
722d747510SLisandro Dalcin   int          N;                  /* number of options */
732d747510SLisandro Dalcin   char        *names[MAXOPTIONS];  /* option names */
742d747510SLisandro Dalcin   char        *values[MAXOPTIONS]; /* option values */
752d747510SLisandro Dalcin   PetscBool    used[MAXOPTIONS];   /* flag option use */
76c5b5d8d5SVaclav Hapla   PetscBool    precedentProcessed;
77081c24baSBoyana Norris 
782d747510SLisandro Dalcin   /* Hash table */
792d747510SLisandro Dalcin   khash_t(HO) *ht;
802d747510SLisandro Dalcin 
812d747510SLisandro Dalcin   /* Prefixes */
822d747510SLisandro Dalcin   int  prefixind;
832d747510SLisandro Dalcin   int  prefixstack[MAXPREFIXES];
842d747510SLisandro Dalcin   char prefix[MAXOPTNAME];
852d747510SLisandro Dalcin 
862d747510SLisandro Dalcin   /* Aliases */
872d747510SLisandro Dalcin   int   Naliases;             /* number or aliases */
882d747510SLisandro Dalcin   char *aliases1[MAXALIASES]; /* aliased */
892d747510SLisandro Dalcin   char *aliases2[MAXALIASES]; /* aliasee */
902d747510SLisandro Dalcin 
912d747510SLisandro Dalcin   /* Help */
922d747510SLisandro Dalcin   PetscBool help;       /* flag whether "-help" is in the database */
93d314f959SVaclav Hapla   PetscBool help_intro; /* flag whether "-help intro" is in the database */
942d747510SLisandro Dalcin 
952d747510SLisandro Dalcin   /* Monitors */
96c5b5d8d5SVaclav Hapla   PetscBool monitorFromOptions, monitorCancel;
97081c24baSBoyana Norris   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], void *); /* returns control to user after */
98c2efdce3SBarry Smith   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void **);                     /* */
99081c24baSBoyana Norris   void    *monitorcontext[MAXOPTIONSMONITORS];                                       /* to pass arbitrary user data into monitor */
100081c24baSBoyana Norris   PetscInt numbermonitors;                                                           /* to, for instance, detect options being set */
1014416b707SBarry Smith };
102e5c89e4eSSatish Balay 
103b4205f0bSBarry Smith static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
1042d747510SLisandro Dalcin 
105c5b5d8d5SVaclav Hapla /* list of options which preceed others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
106660278c0SBarry Smith /* these options can only take boolean values, the code will crash if given a non-boolean value */
107660278c0SBarry Smith static const char *precedentOptions[] = {"-petsc_ci", "-options_monitor", "-options_monitor_cancel", "-help", "-skip_petscrc"};
1089371c9d4SSatish Balay enum PetscPrecedentOption {
1099371c9d4SSatish Balay   PO_CI_ENABLE,
1109371c9d4SSatish Balay   PO_OPTIONS_MONITOR,
1119371c9d4SSatish Balay   PO_OPTIONS_MONITOR_CANCEL,
1129371c9d4SSatish Balay   PO_HELP,
1139371c9d4SSatish Balay   PO_SKIP_PETSCRC,
1149371c9d4SSatish Balay   PO_NUM
1159371c9d4SSatish Balay };
116c5b5d8d5SVaclav Hapla 
117c5b5d8d5SVaclav Hapla static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions, const char[], const char[], int *);
118c5b5d8d5SVaclav Hapla 
119081c24baSBoyana Norris /*
120081c24baSBoyana Norris     Options events monitor
121081c24baSBoyana Norris */
122d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsMonitor(PetscOptions options, const char name[], const char value[])
123d71ae5a4SJacob Faibussowitsch {
124e5c89e4eSSatish Balay   PetscFunctionBegin;
125c5b5d8d5SVaclav Hapla   if (!value) value = "";
1269566063dSJacob Faibussowitsch   if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name, value, NULL));
1279566063dSJacob Faibussowitsch   for (PetscInt i = 0; i < options->numbermonitors; i++) PetscCall((*options->monitor[i])(name, value, options->monitorcontext[i]));
128e5c89e4eSSatish Balay   PetscFunctionReturn(0);
129e5c89e4eSSatish Balay }
130e5c89e4eSSatish Balay 
1312d747510SLisandro Dalcin /*@
1322d747510SLisandro Dalcin    PetscOptionsCreate - Creates an empty options database.
133e5c89e4eSSatish Balay 
1341c9f3c13SBarry Smith    Logically collective
1351c9f3c13SBarry Smith 
136e5c89e4eSSatish Balay    Output Parameter:
1372d747510SLisandro Dalcin .  options - Options database object
138e5c89e4eSSatish Balay 
139e5c89e4eSSatish Balay    Level: advanced
140e5c89e4eSSatish Balay 
141811af0c4SBarry Smith    Note:
142811af0c4SBarry Smith    Though PETSc has a concept of multiple options database the current code uses a single default `PetscOptions` object
143811af0c4SBarry Smith 
144811af0c4SBarry Smith    Developer Notes:
145811af0c4SBarry Smith    We may want eventually to pass a `MPI_Comm` to determine the ownership of the object
146811af0c4SBarry Smith 
147811af0c4SBarry Smith    This object never got developed after being introduced, it is not clear that supporting multiple `PetscOptions` objects is useful
1481c9f3c13SBarry Smith 
149db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
150e5c89e4eSSatish Balay @*/
151d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreate(PetscOptions *options)
152d71ae5a4SJacob Faibussowitsch {
15339a651e2SJacob Faibussowitsch   PetscFunctionBegin;
15439a651e2SJacob Faibussowitsch   PetscValidPointer(options, 1);
1552d747510SLisandro Dalcin   *options = (PetscOptions)calloc(1, sizeof(**options));
15639a651e2SJacob Faibussowitsch   PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
15739a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1582d747510SLisandro Dalcin }
1592d747510SLisandro Dalcin 
1602d747510SLisandro Dalcin /*@
1612d747510SLisandro Dalcin     PetscOptionsDestroy - Destroys an option database.
1622d747510SLisandro Dalcin 
163811af0c4SBarry Smith     Logically collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
1641c9f3c13SBarry Smith 
1652d747510SLisandro Dalcin   Input Parameter:
166811af0c4SBarry Smith .  options - the `PetscOptions` object
1672d747510SLisandro Dalcin 
1683de2bfdfSBarry Smith    Level: advanced
1692d747510SLisandro Dalcin 
170db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
1712d747510SLisandro Dalcin @*/
172d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
173d71ae5a4SJacob Faibussowitsch {
174362febeeSStefano Zampini   PetscFunctionBegin;
17539a651e2SJacob Faibussowitsch   if (!*options) PetscFunctionReturn(0);
1765f80ce2aSJacob 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()");
1779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsClear(*options));
1782d747510SLisandro Dalcin   /* XXX what about monitors ? */
1792800570dSLisandro Dalcin   free(*options);
1802d747510SLisandro Dalcin   *options = NULL;
181e5c89e4eSSatish Balay   PetscFunctionReturn(0);
182e5c89e4eSSatish Balay }
183e5c89e4eSSatish Balay 
1842d747510SLisandro Dalcin /*
1852d747510SLisandro Dalcin     PetscOptionsCreateDefault - Creates the default global options database
1862d747510SLisandro Dalcin */
187d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreateDefault(void)
188d71ae5a4SJacob Faibussowitsch {
18939a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1909566063dSJacob Faibussowitsch   if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
19139a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1922d747510SLisandro Dalcin }
1932d747510SLisandro Dalcin 
194b4205f0bSBarry Smith /*@
195811af0c4SBarry Smith       PetscOptionsPush - Push a new `PetscOptions` object as the default provider of options
1961c9f3c13SBarry Smith                          Allows using different parts of a code to use different options databases
197b4205f0bSBarry Smith 
198b4205f0bSBarry Smith   Logically Collective
199b4205f0bSBarry Smith 
200b4205f0bSBarry Smith   Input Parameter:
201811af0c4SBarry Smith .   opt - the options obtained with `PetscOptionsCreate()`
202b4205f0bSBarry Smith 
203b4205f0bSBarry Smith   Notes:
204811af0c4SBarry Smith   Use `PetscOptionsPop()` to return to the previous default options database
2051c9f3c13SBarry Smith 
206811af0c4SBarry Smith   The collectivity of this routine is complex; only the MPI ranks that call this routine will
2071c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
2081c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
2091c9f3c13SBarry Smith   on different ranks.
210b4205f0bSBarry Smith 
211811af0c4SBarry Smith   Developer Note:
212811af0c4SBarry Smith   Though this functionality has been provided it has never been used in PETSc and might be removed.
213811af0c4SBarry Smith 
2143de2bfdfSBarry Smith    Level: advanced
2153de2bfdfSBarry Smith 
216db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
217b4205f0bSBarry Smith @*/
218d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPush(PetscOptions opt)
219d71ae5a4SJacob Faibussowitsch {
220b4205f0bSBarry Smith   PetscFunctionBegin;
2219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsCreateDefault());
222b4205f0bSBarry Smith   opt->previous  = defaultoptions;
223b4205f0bSBarry Smith   defaultoptions = opt;
224b4205f0bSBarry Smith   PetscFunctionReturn(0);
225b4205f0bSBarry Smith }
226b4205f0bSBarry Smith 
227b4205f0bSBarry Smith /*@
228811af0c4SBarry Smith       PetscOptionsPop - Pop the most recent `PetscOptionsPush() `to return to the previous default options
229b4205f0bSBarry Smith 
230811af0c4SBarry Smith       Logically collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
231b4205f0bSBarry Smith 
2323de2bfdfSBarry Smith    Level: advanced
2333de2bfdfSBarry Smith 
234db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
235b4205f0bSBarry Smith @*/
236d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPop(void)
237d71ae5a4SJacob Faibussowitsch {
2383de2bfdfSBarry Smith   PetscOptions current = defaultoptions;
2393de2bfdfSBarry Smith 
240b4205f0bSBarry Smith   PetscFunctionBegin;
24128b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing default options");
24228b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions->previous, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscOptionsPop() called too many times");
243b4205f0bSBarry Smith   defaultoptions    = defaultoptions->previous;
2443de2bfdfSBarry Smith   current->previous = NULL;
245b4205f0bSBarry Smith   PetscFunctionReturn(0);
246b4205f0bSBarry Smith }
247b4205f0bSBarry Smith 
2482d747510SLisandro Dalcin /*
2492d747510SLisandro Dalcin     PetscOptionsDestroyDefault - Destroys the default global options database
2502d747510SLisandro Dalcin */
251d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroyDefault(void)
252d71ae5a4SJacob Faibussowitsch {
25339a651e2SJacob Faibussowitsch   PetscFunctionBegin;
25439a651e2SJacob Faibussowitsch   if (!defaultoptions) PetscFunctionReturn(0);
2553de2bfdfSBarry Smith   /* Destroy any options that the user forgot to pop */
2563de2bfdfSBarry Smith   while (defaultoptions->previous) {
25739a651e2SJacob Faibussowitsch     PetscOptions tmp = defaultoptions;
25839a651e2SJacob Faibussowitsch 
2599566063dSJacob Faibussowitsch     PetscCall(PetscOptionsPop());
2609566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDestroy(&tmp));
2613de2bfdfSBarry Smith   }
2629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDestroy(&defaultoptions));
26339a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
264e5c89e4eSSatish Balay }
265e5c89e4eSSatish Balay 
26694ef8ddeSSatish Balay /*@C
2677cd08cecSJed Brown    PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
2683fc1eb6aSBarry Smith 
269447722d5SBarry Smith    Not collective
2701c9f3c13SBarry Smith 
2713fc1eb6aSBarry Smith    Input Parameter:
2722d747510SLisandro Dalcin .  key - string to check if valid
2733fc1eb6aSBarry Smith 
2743fc1eb6aSBarry Smith    Output Parameter:
275811af0c4SBarry Smith .  valid - `PETSC_TRUE` if a valid key
2763fc1eb6aSBarry Smith 
277f6680f47SSatish Balay    Level: intermediate
2783fc1eb6aSBarry Smith @*/
279d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid)
280d71ae5a4SJacob Faibussowitsch {
281f603b5e9SToby Isaac   char *ptr;
2827c5db45bSBarry Smith 
28396fc60bcSBarry Smith   PetscFunctionBegin;
2842d747510SLisandro Dalcin   if (key) PetscValidCharPointer(key, 1);
285dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(valid, 2);
2862d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2872d747510SLisandro Dalcin   if (!key) PetscFunctionReturn(0);
2882d747510SLisandro Dalcin   if (key[0] != '-') PetscFunctionReturn(0);
2892d747510SLisandro Dalcin   if (key[1] == '-') key++;
290c850d057SPierre Jolivet   if (!isalpha((int)key[1])) PetscFunctionReturn(0);
2912d747510SLisandro Dalcin   (void)strtod(key, &ptr);
292c850d057SPierre Jolivet   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(0);
2932d747510SLisandro Dalcin   *valid = PETSC_TRUE;
29496fc60bcSBarry Smith   PetscFunctionReturn(0);
29596fc60bcSBarry Smith }
29696fc60bcSBarry Smith 
297e5c89e4eSSatish Balay /*@C
298e5c89e4eSSatish Balay    PetscOptionsInsertString - Inserts options into the database from a string
299e5c89e4eSSatish Balay 
3001c9f3c13SBarry Smith    Logically Collective
301e5c89e4eSSatish Balay 
302d8d19677SJose E. Roman    Input Parameters:
303080f0011SToby Isaac +  options - options object
304080f0011SToby Isaac -  in_str - string that contains options separated by blanks
305e5c89e4eSSatish Balay 
306e5c89e4eSSatish Balay    Level: intermediate
307e5c89e4eSSatish Balay 
308811af0c4SBarry Smith   The collectivity of this routine is complex; only the MPI ranks that call this routine will
3091c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
3101c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
3111c9f3c13SBarry Smith   on different ranks.
3121c9f3c13SBarry Smith 
313e5c89e4eSSatish Balay    Contributed by Boyana Norris
314e5c89e4eSSatish Balay 
315db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
316db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
317db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
318c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
319db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
320db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
321e5c89e4eSSatish Balay @*/
322d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[])
323d71ae5a4SJacob Faibussowitsch {
324d06005cbSLisandro Dalcin   MPI_Comm   comm = PETSC_COMM_SELF;
325d06005cbSLisandro Dalcin   char      *first, *second;
3269c9d3cfdSBarry Smith   PetscToken token;
327e5c89e4eSSatish Balay 
328e5c89e4eSSatish Balay   PetscFunctionBegin;
3299566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(in_str, ' ', &token));
3309566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &first));
33196fc60bcSBarry Smith   while (first) {
332d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
3339566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
3349566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
3359566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
3369566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
3379566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
3389566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(first, &key));
339d06005cbSLisandro Dalcin     if (!key) {
3409566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
341d06005cbSLisandro Dalcin     } else if (isfile) {
3429566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3439566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, second, PETSC_TRUE));
3449566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
345d06005cbSLisandro Dalcin     } else if (isfileyaml) {
3469566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3479566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, second, PETSC_TRUE));
3489566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
349d06005cbSLisandro Dalcin     } else if (isstringyaml) {
3509566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3519566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options, second));
3529566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
353d06005cbSLisandro Dalcin     } else if (ispush) {
3549566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3559566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, second));
3569566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
3579db968c8SJed Brown     } else if (ispop) {
3589566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
3599566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
360d06005cbSLisandro Dalcin     } else {
3619566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3629566063dSJacob Faibussowitsch       PetscCall(PetscOptionsValidKey(second, &key));
36396fc60bcSBarry Smith       if (!key) {
3649566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, first, second));
3659566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &first));
36696fc60bcSBarry Smith       } else {
3679566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, first, NULL));
36896fc60bcSBarry Smith         first = second;
36996fc60bcSBarry Smith       }
370e5c89e4eSSatish Balay     }
371e5c89e4eSSatish Balay   }
3729566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
373e5c89e4eSSatish Balay   PetscFunctionReturn(0);
374e5c89e4eSSatish Balay }
375e5c89e4eSSatish Balay 
3763fc1eb6aSBarry Smith /*
3773fc1eb6aSBarry Smith     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
3783fc1eb6aSBarry Smith */
379d71ae5a4SJacob Faibussowitsch static char *Petscgetline(FILE *f)
380d71ae5a4SJacob Faibussowitsch {
3815fa91da5SBarry Smith   size_t size = 0;
3825fa91da5SBarry Smith   size_t len  = 0;
3835fa91da5SBarry Smith   size_t last = 0;
3840298fd71SBarry Smith   char  *buf  = NULL;
3855fa91da5SBarry Smith 
38602c9f0b5SLisandro Dalcin   if (feof(f)) return NULL;
3875fa91da5SBarry Smith   do {
3885fa91da5SBarry Smith     size += 1024;                             /* BUFSIZ is defined as "the optimal read size for this platform" */
3896e0c8459SSatish Balay     buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
3905fa91da5SBarry Smith     /* Actually do the read. Note that fgets puts a terminal '\0' on the
3915fa91da5SBarry Smith     end of the string, so we make sure we overwrite this */
392e86f3e45SDave May     if (!fgets(buf + len, 1024, f)) buf[len] = 0;
3935fa91da5SBarry Smith     PetscStrlen(buf, &len);
3945fa91da5SBarry Smith     last = len - 1;
3955fa91da5SBarry Smith   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
39608ac41f7SSatish Balay   if (len) return buf;
3975fa91da5SBarry Smith   free(buf);
39802c9f0b5SLisandro Dalcin   return NULL;
3995fa91da5SBarry Smith }
4005fa91da5SBarry Smith 
401d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml)
402d71ae5a4SJacob Faibussowitsch {
403be10d61cSLisandro Dalcin   char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
404e5c89e4eSSatish Balay 
405be10d61cSLisandro Dalcin   PetscFunctionBegin;
406362febeeSStefano Zampini   *yaml = PETSC_FALSE;
4079566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
4089566063dSJacob Faibussowitsch   PetscCall(PetscFixFilename(fname, path));
4099566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(path, ":yaml", yaml));
410be10d61cSLisandro Dalcin   if (*yaml) {
4119566063dSJacob Faibussowitsch     PetscCall(PetscStrrchr(path, ':', &tail));
412be10d61cSLisandro Dalcin     tail[-1] = 0; /* remove ":yaml" suffix from path */
413be10d61cSLisandro Dalcin   }
4149566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
415a1d2f846SLisandro Dalcin   /* check for standard YAML and JSON filename extensions */
4169566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
4179566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
4189566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
419a1d2f846SLisandro Dalcin   if (!*yaml) { /* check file contents */
420a1d2f846SLisandro Dalcin     PetscMPIInt rank;
4219566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
422dd400576SPatrick Sanan     if (rank == 0) {
423a1d2f846SLisandro Dalcin       FILE *fh = fopen(filename, "r");
424a1d2f846SLisandro Dalcin       if (fh) {
425a1d2f846SLisandro Dalcin         char buf[6] = "";
426a1d2f846SLisandro Dalcin         if (fread(buf, 1, 6, fh) > 0) {
4279566063dSJacob Faibussowitsch           PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml));          /* check for '%YAML' tag */
4289566063dSJacob Faibussowitsch           if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
429a1d2f846SLisandro Dalcin         }
430a1d2f846SLisandro Dalcin         (void)fclose(fh);
431a1d2f846SLisandro Dalcin       }
432a1d2f846SLisandro Dalcin     }
4339566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(yaml, 1, MPIU_BOOL, 0, comm));
434a1d2f846SLisandro Dalcin   }
435be10d61cSLisandro Dalcin   PetscFunctionReturn(0);
436be10d61cSLisandro Dalcin }
437e5c89e4eSSatish Balay 
438d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
439d71ae5a4SJacob Faibussowitsch {
4408c0b561eSLisandro Dalcin   char       *string, *vstring = NULL, *astring = NULL, *packed = NULL;
4417fb43599SVaclav Hapla   char       *tokens[4];
44213e3f751SJed Brown   size_t      i, len, bytes;
443e5c89e4eSSatish Balay   FILE       *fd;
4447fb43599SVaclav Hapla   PetscToken  token = NULL;
445ed9cf6e9SBarry Smith   int         err;
446581bbe83SVaclav Hapla   char       *cmatch;
447581bbe83SVaclav Hapla   const char  cmt  = '#';
4489210b8eaSVaclav Hapla   PetscInt    line = 1;
4493a018368SJed Brown   PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
4509210b8eaSVaclav Hapla   PetscBool   isdir, alias = PETSC_FALSE, valid;
451e5c89e4eSSatish Balay 
452e5c89e4eSSatish Balay   PetscFunctionBegin;
4539566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tokens, sizeof(tokens)));
4549566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
455dd400576SPatrick Sanan   if (rank == 0) {
4568c0b561eSLisandro Dalcin     char fpath[PETSC_MAX_PATH_LEN];
4578c0b561eSLisandro Dalcin     char fname[PETSC_MAX_PATH_LEN];
45805c7dedfSBarry Smith 
4599566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
4609566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
4618c0b561eSLisandro Dalcin 
462e5c89e4eSSatish Balay     fd = fopen(fname, "r");
4639566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname, 'r', &isdir));
46408401ef6SPierre Jolivet     PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
465ad38b122SPatrick Sanan     if (fd && !isdir) {
4663a018368SJed Brown       PetscSegBuffer vseg, aseg;
4679566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4689566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4693a018368SJed Brown 
4709b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4719566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
472e24ecc5dSJed Brown 
4735fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4744704e885SBarry Smith         /* eliminate comments from each line */
4759566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
47690f79514SSatish Balay         if (cmatch) *cmatch = 0;
4779566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4785981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
479e5c89e4eSSatish Balay         for (i = 0; i < len; i++) {
480ad540459SPierre Jolivet           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
481e5c89e4eSSatish Balay         }
4829566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4839566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4847fb43599SVaclav Hapla         if (!tokens[0]) {
48502b0d46eSSatish Balay           goto destroy;
4867fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
4879566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
48890f79514SSatish Balay         }
48948a46eb9SPierre Jolivet         for (i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
4907fb43599SVaclav Hapla         if (!tokens[0]) {
4912662f744SSatish Balay           goto destroy;
4927fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
4939566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
49428b400f6SJacob 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]);
4959566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
4969566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
4979566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
498e24ecc5dSJed Brown           vstring[len] = ' ';
4997fb43599SVaclav Hapla           if (tokens[1]) {
5009566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
50128b400f6SJacob 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]);
5029566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5039566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
504e24ecc5dSJed Brown             vstring[0] = '"';
5059566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
506e24ecc5dSJed Brown             vstring[len + 1] = '"';
507e24ecc5dSJed Brown             vstring[len + 2] = ' ';
50809192fe3SBarry Smith           }
50990f79514SSatish Balay         } else {
5109566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
5119210b8eaSVaclav Hapla           if (alias) {
5129566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
51328b400f6SJacob 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]);
51408401ef6SPierre 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]);
5159566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
51628b400f6SJacob 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]);
5179566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5189566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5199566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
520e24ecc5dSJed Brown             astring[len] = ' ';
521e24ecc5dSJed Brown 
5229566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5239566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5249566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
525e24ecc5dSJed Brown             astring[len] = ' ';
52698921bdaSJacob 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]);
5279210b8eaSVaclav Hapla         }
5289210b8eaSVaclav Hapla         {
5299210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
53028b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
531e5c89e4eSSatish Balay         }
53202b0d46eSSatish Balay       destroy:
5334b40f50bSBarry Smith         free(string);
5349566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5359210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5369210b8eaSVaclav Hapla         line++;
537e5c89e4eSSatish Balay       }
538ed9cf6e9SBarry Smith       err = fclose(fd);
53928b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5409566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5419566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5429566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
543e24ecc5dSJed Brown       astring[0] = 0;
5449566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5459566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5469566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
547e24ecc5dSJed Brown       vstring[0] = 0;
5489566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5499566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5509566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5519566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5529566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
55328b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5549b754dc9SBarry Smith   }
55505c7dedfSBarry Smith 
5563a018368SJed Brown   counts[0] = acnt;
5573a018368SJed Brown   counts[1] = cnt;
5584201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
55928b400f6SJacob 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/");
5603a018368SJed Brown   acnt = counts[0];
5613a018368SJed Brown   cnt  = counts[1];
56248a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5633a018368SJed Brown   if (acnt || cnt) {
5649566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5653a018368SJed Brown     astring = packed;
5663a018368SJed Brown     vstring = packed + acnt + 1;
5673a018368SJed Brown   }
5683a018368SJed Brown 
5699b754dc9SBarry Smith   if (acnt) {
5709566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5719566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5727fb43599SVaclav Hapla     while (tokens[0]) {
5739566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5749566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5759566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5769b754dc9SBarry Smith     }
5779566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5789b754dc9SBarry Smith   }
5799b754dc9SBarry Smith 
5801baa6e33SBarry Smith   if (cnt) PetscCall(PetscOptionsInsertString(options, vstring));
5819566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
582e5c89e4eSSatish Balay   PetscFunctionReturn(0);
583e5c89e4eSSatish Balay }
584e5c89e4eSSatish Balay 
585d06005cbSLisandro Dalcin /*@C
586be10d61cSLisandro Dalcin      PetscOptionsInsertFile - Inserts options into the database from a file.
587be10d61cSLisandro Dalcin 
588be10d61cSLisandro Dalcin      Collective
589be10d61cSLisandro Dalcin 
590d8d19677SJose E. Roman   Input Parameters:
591811af0c4SBarry Smith +   comm - the processes that will share the options (usually `PETSC_COMM_WORLD`)
592be10d61cSLisandro Dalcin .   options - options database, use NULL for default global database
593be10d61cSLisandro Dalcin .   file - name of file,
594be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
595be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
596811af0c4SBarry Smith -   require - if `PETSC_TRUE` will generate an error if the file does not exist
597be10d61cSLisandro Dalcin 
598be10d61cSLisandro Dalcin   Notes:
599be10d61cSLisandro Dalcin    Use  # for lines that are comments and which should be ignored.
600811af0c4SBarry Smith    Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
601be10d61cSLisandro 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
602be10d61cSLisandro Dalcin    calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().
603811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks in comm will
604be10d61cSLisandro Dalcin    have the affect of these options. If some processes that create objects call this routine and others do
605be10d61cSLisandro Dalcin    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
606be10d61cSLisandro Dalcin    on different ranks.
607be10d61cSLisandro Dalcin 
608be10d61cSLisandro Dalcin   Level: developer
609be10d61cSLisandro Dalcin 
610db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
611db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
612db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
613c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
614db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
615db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
616be10d61cSLisandro Dalcin @*/
617d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
618d71ae5a4SJacob Faibussowitsch {
619be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
620be10d61cSLisandro Dalcin   PetscBool yaml;
621be10d61cSLisandro Dalcin 
622be10d61cSLisandro Dalcin   PetscFunctionBegin;
6239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
624be10d61cSLisandro Dalcin   if (yaml) {
6259566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
626be10d61cSLisandro Dalcin   } else {
6279566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
628be10d61cSLisandro Dalcin   }
629be10d61cSLisandro Dalcin   PetscFunctionReturn(0);
630be10d61cSLisandro Dalcin }
631be10d61cSLisandro Dalcin 
632be10d61cSLisandro Dalcin /*@C
633d06005cbSLisandro Dalcin    PetscOptionsInsertArgs - Inserts options into the database from a array of strings
634d06005cbSLisandro Dalcin 
635d06005cbSLisandro Dalcin    Logically Collective
636d06005cbSLisandro Dalcin 
637d8d19677SJose E. Roman    Input Parameters:
638d06005cbSLisandro Dalcin +  options - options object
6396aad120cSJose E. Roman .  argc - the array length
640d06005cbSLisandro Dalcin -  args - the string array
641d06005cbSLisandro Dalcin 
642d06005cbSLisandro Dalcin    Level: intermediate
643d06005cbSLisandro Dalcin 
644db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
645d06005cbSLisandro Dalcin @*/
646d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, char *args[])
647d71ae5a4SJacob Faibussowitsch {
648d06005cbSLisandro Dalcin   MPI_Comm     comm  = PETSC_COMM_WORLD;
649d06005cbSLisandro Dalcin   int          left  = PetscMax(argc, 0);
650d06005cbSLisandro Dalcin   char *const *eargs = args;
65185079163SJed Brown 
65285079163SJed Brown   PetscFunctionBegin;
65385079163SJed Brown   while (left) {
654d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6559566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6569566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6579566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6589566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6599566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6609566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
661093de6efSBarry Smith     if (!key) {
6629371c9d4SSatish Balay       eargs++;
6639371c9d4SSatish Balay       left--;
664d06005cbSLisandro Dalcin     } else if (isfile) {
665cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6669566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6679371c9d4SSatish Balay       eargs += 2;
6689371c9d4SSatish Balay       left -= 2;
669d06005cbSLisandro Dalcin     } else if (isfileyaml) {
670cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6719566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6729371c9d4SSatish Balay       eargs += 2;
6739371c9d4SSatish Balay       left -= 2;
674d06005cbSLisandro Dalcin     } else if (isstringyaml) {
675cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6769566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options, eargs[1]));
6779371c9d4SSatish Balay       eargs += 2;
6789371c9d4SSatish Balay       left -= 2;
679d06005cbSLisandro Dalcin     } else if (ispush) {
68008401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
681cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6829566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6839371c9d4SSatish Balay       eargs += 2;
6849371c9d4SSatish Balay       left -= 2;
685d06005cbSLisandro Dalcin     } else if (ispop) {
6869566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
6879371c9d4SSatish Balay       eargs++;
6889371c9d4SSatish Balay       left--;
6897935c3d8SJed Brown     } else {
6907935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
6919566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
69298b6bf53SJed Brown       if (left < 2 || nextiskey) {
6939566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, eargs[0], NULL));
6949371c9d4SSatish Balay         eargs++;
6959371c9d4SSatish Balay         left--;
69685079163SJed Brown       } else {
6979566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, eargs[0], eargs[1]));
6989371c9d4SSatish Balay         eargs += 2;
6999371c9d4SSatish Balay         left -= 2;
70085079163SJed Brown       }
70185079163SJed Brown     }
7027935c3d8SJed Brown   }
70385079163SJed Brown   PetscFunctionReturn(0);
70485079163SJed Brown }
70585079163SJed Brown 
706d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], PetscBool set[], PetscBool *flg)
707d71ae5a4SJacob Faibussowitsch {
708c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
709c5b5d8d5SVaclav Hapla   if (set[opt]) {
7109566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
711c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
712c5b5d8d5SVaclav Hapla   PetscFunctionReturn(0);
713c5b5d8d5SVaclav Hapla }
714c5b5d8d5SVaclav Hapla 
715660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
716d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
717d71ae5a4SJacob Faibussowitsch {
718c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
719c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
720c5b5d8d5SVaclav Hapla   size_t             o;
721c5b5d8d5SVaclav Hapla   int                a;
722c5b5d8d5SVaclav Hapla   const char       **val;
7230c99d500SBarry Smith   char             **cval;
724660278c0SBarry Smith   PetscBool         *set, unneeded;
725c5b5d8d5SVaclav Hapla 
726c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7270c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7280c99d500SBarry Smith   val = (const char **)cval;
729c5b5d8d5SVaclav Hapla 
730c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
73148a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
732c5b5d8d5SVaclav Hapla 
733a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
734c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
735c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
736c5b5d8d5SVaclav Hapla 
7379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
738c5b5d8d5SVaclav Hapla     if (!valid) continue;
739c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7409566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
741c5b5d8d5SVaclav Hapla       if (eq) {
742c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
743c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
744c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
745c5b5d8d5SVaclav Hapla         break;
746c5b5d8d5SVaclav Hapla       }
747c5b5d8d5SVaclav Hapla     }
748c5b5d8d5SVaclav Hapla   }
749c5b5d8d5SVaclav Hapla 
750c5b5d8d5SVaclav Hapla   /* Process flags */
7519566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
752d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7539566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
754660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
755660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
756660278c0SBarry Smith   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a));
7579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
760c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
761c5b5d8d5SVaclav Hapla 
762c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
763660278c0SBarry Smith   for (o = 1; o < n; o++) {
764c5b5d8d5SVaclav Hapla     if (set[o]) {
7659566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a));
766d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
767c5b5d8d5SVaclav Hapla     }
768c5b5d8d5SVaclav Hapla   }
7690c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
770c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
771c5b5d8d5SVaclav Hapla   PetscFunctionReturn(0);
772c5b5d8d5SVaclav Hapla }
773c5b5d8d5SVaclav Hapla 
774d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
775d71ae5a4SJacob Faibussowitsch {
77639a651e2SJacob Faibussowitsch   PetscFunctionBegin;
77739a651e2SJacob Faibussowitsch   PetscValidBoolPointer(flg, 3);
778c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
779c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
78039a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
781c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
782c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7839566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
784c5b5d8d5SVaclav Hapla         if (*flg) break;
785c5b5d8d5SVaclav Hapla       }
786c5b5d8d5SVaclav Hapla     }
787c5b5d8d5SVaclav Hapla   }
78839a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
789c5b5d8d5SVaclav Hapla }
79085079163SJed Brown 
791e5c89e4eSSatish Balay /*@C
792e5c89e4eSSatish Balay    PetscOptionsInsert - Inserts into the options database from the command line,
793e5c89e4eSSatish Balay                         the environmental variable and a file.
794e5c89e4eSSatish Balay 
795811af0c4SBarry Smith    Collective on `PETSC_COMM_WORLD`
7961c9f3c13SBarry Smith 
797e5c89e4eSSatish Balay    Input Parameters:
798c5929fdfSBarry Smith +  options - options database or NULL for the default global database
799c5929fdfSBarry Smith .  argc - count of number of command line arguments
800e5c89e4eSSatish Balay .  args - the command line arguments
801be10d61cSLisandro Dalcin -  file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
802be10d61cSLisandro Dalcin           Use NULL or empty string to not check for code specific file.
803be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
804c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
805e5c89e4eSSatish Balay 
806081c24baSBoyana Norris    Options Database Keys:
807d06005cbSLisandro Dalcin +   -options_file <filename> - read options from a file
808d06005cbSLisandro Dalcin -   -options_file_yaml <filename> - read options from a YAML file
809c5b5d8d5SVaclav Hapla 
810811af0c4SBarry Smith    Notes:
811811af0c4SBarry Smith    Since PetscOptionsInsert() is automatically called by `PetscInitialize()`,
812811af0c4SBarry Smith    the user does not typically need to call this routine. `PetscOptionsInsert()`
813811af0c4SBarry Smith    can be called several times, adding additional entries into the database.
814811af0c4SBarry Smith 
815811af0c4SBarry Smith    See `PetscInitialize()` for options related to option database monitoring.
816081c24baSBoyana Norris 
817e5c89e4eSSatish Balay    Level: advanced
818e5c89e4eSSatish Balay 
819db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
820db781477SPatrick Sanan           `PetscInitialize()`
821e5c89e4eSSatish Balay @*/
822d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[])
823d71ae5a4SJacob Faibussowitsch {
824d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
825e5c89e4eSSatish Balay   PetscMPIInt rank;
826c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
827c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
828e5c89e4eSSatish Balay 
829e5c89e4eSSatish Balay   PetscFunctionBegin;
83008401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8319566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
832e5c89e4eSSatish Balay 
833c5b5d8d5SVaclav Hapla   if (!options) {
8349566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
835c5b5d8d5SVaclav Hapla     options = defaultoptions;
836c5b5d8d5SVaclav Hapla   }
837c5b5d8d5SVaclav Hapla   if (hasArgs) {
838c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8399566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
840660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
841c5b5d8d5SVaclav Hapla   }
8424b09e917SBarry Smith   if (file && file[0]) {
8439566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
844c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8459566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
846321366bcSBarry Smith   }
847c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
848be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8499566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8509566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
8519566063dSJacob Faibussowitsch     if (filename[0]) PetscCall(PetscStrcat(filename, "/.petscrc"));
8529566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8539566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8549566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
855e5c89e4eSSatish Balay   }
856e5c89e4eSSatish Balay 
8572d747510SLisandro Dalcin   /* insert environment options */
858e5c89e4eSSatish Balay   {
8592d747510SLisandro Dalcin     char  *eoptions = NULL;
860e5c89e4eSSatish Balay     size_t len      = 0;
861dd400576SPatrick Sanan     if (rank == 0) {
862e5c89e4eSSatish Balay       eoptions = (char *)getenv("PETSC_OPTIONS");
8639566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
864e5c89e4eSSatish Balay     }
8659566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
866e5c89e4eSSatish Balay     if (len) {
8679566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8689566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
86996fc60bcSBarry Smith       if (rank) eoptions[len] = 0;
8709566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertString(options, eoptions));
8719566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
872e5c89e4eSSatish Balay     }
873e5c89e4eSSatish Balay   }
874e5c89e4eSSatish Balay 
875d06005cbSLisandro Dalcin   /* insert YAML environment options */
87656a31166SBarry Smith   {
8779fc438c3SToby Isaac     char  *eoptions = NULL;
8789fc438c3SToby Isaac     size_t len      = 0;
879dd400576SPatrick Sanan     if (rank == 0) {
8809fc438c3SToby Isaac       eoptions = (char *)getenv("PETSC_OPTIONS_YAML");
8819566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
8829fc438c3SToby Isaac     }
8839566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8849fc438c3SToby Isaac     if (len) {
8859566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8869566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
8879fc438c3SToby Isaac       if (rank) eoptions[len] = 0;
8889566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options, eoptions));
8899566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
8909fc438c3SToby Isaac     }
8919fc438c3SToby Isaac   }
8923bcbd388SSean Farley 
893c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
8949566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, *args + 1));
895660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
896e5c89e4eSSatish Balay   PetscFunctionReturn(0);
897e5c89e4eSSatish Balay }
898e5c89e4eSSatish Balay 
899660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
900660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
9019371c9d4SSatish Balay static const char *PetscCIOptions[] = {
9029371c9d4SSatish Balay   "malloc_debug",
903660278c0SBarry Smith   "malloc_dump",
904660278c0SBarry Smith   "malloc_test",
905660278c0SBarry Smith   "nox",
906660278c0SBarry Smith   "nox_warning",
907660278c0SBarry Smith   "display",
908660278c0SBarry Smith   "saws_port_auto_select",
909660278c0SBarry Smith   "saws_port_auto_select_silent",
910660278c0SBarry Smith   "vecscatter_mpi1",
911660278c0SBarry Smith   "check_pointer_intensity",
912660278c0SBarry Smith   "cuda_initialize",
913660278c0SBarry Smith   "error_output_stdout",
914660278c0SBarry Smith   "use_gpu_aware_mpi",
915660278c0SBarry Smith   "checkfunctionlist",
916660278c0SBarry Smith   "petsc_ci",
917660278c0SBarry Smith   "petsc_ci_portable_error_output",
918660278c0SBarry Smith };
919660278c0SBarry Smith 
920d71ae5a4SJacob Faibussowitsch static PetscBool PetscCIOption(const char *name)
921d71ae5a4SJacob Faibussowitsch {
922660278c0SBarry Smith   PetscInt  idx;
923660278c0SBarry Smith   PetscBool found;
924660278c0SBarry Smith 
925660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
926660278c0SBarry Smith   PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found);
927660278c0SBarry Smith   return found;
928660278c0SBarry Smith }
929660278c0SBarry Smith 
930e5c89e4eSSatish Balay /*@C
93188c29154SBarry Smith    PetscOptionsView - Prints the options that have been loaded. This is
932e5c89e4eSSatish Balay    useful for debugging purposes.
933e5c89e4eSSatish Balay 
934c3339decSBarry Smith    Logically Collective
935e5c89e4eSSatish Balay 
936d8d19677SJose E. Roman    Input Parameters:
937a2b725a8SWilliam Gropp +  options - options database, use NULL for default global database
938811af0c4SBarry Smith -  viewer - must be an `PETSCVIEWERASCII` viewer
939e5c89e4eSSatish Balay 
940e5c89e4eSSatish Balay    Options Database Key:
941811af0c4SBarry Smith .  -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
942e5c89e4eSSatish Balay 
943811af0c4SBarry Smith    Note:
944811af0c4SBarry Smith    Only the rank zero process of the `MPI_Comm` used to create view prints the option values. Other processes
9451c9f3c13SBarry Smith    may have different values but they are not printed.
9461c9f3c13SBarry Smith 
947e5c89e4eSSatish Balay    Level: advanced
948e5c89e4eSSatish Balay 
949db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
950e5c89e4eSSatish Balay @*/
951d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
952d71ae5a4SJacob Faibussowitsch {
953660278c0SBarry Smith   PetscInt  i, N = 0;
95488c29154SBarry Smith   PetscBool isascii;
955e5c89e4eSSatish Balay 
956e5c89e4eSSatish Balay   PetscFunctionBegin;
9572d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
958c5929fdfSBarry Smith   options = options ? options : defaultoptions;
95988c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9609566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
96128b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
96288c29154SBarry Smith 
963660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
964660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
965660278c0SBarry Smith     N++;
966660278c0SBarry Smith   }
967660278c0SBarry Smith 
968660278c0SBarry Smith   if (!N) {
9699566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9702d747510SLisandro Dalcin     PetscFunctionReturn(0);
97130694fe9SBarry Smith   }
9722d747510SLisandro Dalcin 
9739566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
974e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
975660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
976e5c89e4eSSatish Balay     if (options->values[i]) {
9779566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s\n", options->names[i], options->values[i]));
978e5c89e4eSSatish Balay     } else {
9799566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s\n", options->names[i]));
980e5c89e4eSSatish Balay     }
981e5c89e4eSSatish Balay   }
9829566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
983e5c89e4eSSatish Balay   PetscFunctionReturn(0);
984e5c89e4eSSatish Balay }
985e5c89e4eSSatish Balay 
986e11779c2SBarry Smith /*
987e11779c2SBarry Smith    Called by error handlers to print options used in run
988e11779c2SBarry Smith */
989d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftError(void)
990d71ae5a4SJacob Faibussowitsch {
991f4bc716fSBarry Smith   PetscInt i, nopt = 0;
992f4bc716fSBarry Smith 
993f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
994f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
995f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
996f4bc716fSBarry Smith       nopt++;
997f4bc716fSBarry Smith     }
998f4bc716fSBarry Smith   }
999f4bc716fSBarry Smith   if (nopt) {
1000f4bc716fSBarry 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");
1001f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
1002f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
1003f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
1004f4bc716fSBarry Smith         if (defaultoptions->values[i]) (*PetscErrorPrintf)("Option left: name:-%s value: %s\n", defaultoptions->names[i], defaultoptions->values[i]);
1005f4bc716fSBarry Smith         else (*PetscErrorPrintf)("Option left: name:-%s (no value)\n", defaultoptions->names[i]);
1006f4bc716fSBarry Smith       }
1007f4bc716fSBarry Smith     }
1008f4bc716fSBarry Smith   }
1009f4bc716fSBarry Smith   return 0;
1010f4bc716fSBarry Smith }
1011f4bc716fSBarry Smith 
1012d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1013d71ae5a4SJacob Faibussowitsch {
1014660278c0SBarry Smith   PetscInt     i, N = 0;
10154416b707SBarry Smith   PetscOptions options = defaultoptions;
1016e11779c2SBarry Smith 
1017660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
1018660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1019660278c0SBarry Smith     N++;
1020660278c0SBarry Smith   }
1021660278c0SBarry Smith 
1022660278c0SBarry Smith   if (N) {
1023e11779c2SBarry Smith     (*PetscErrorPrintf)("PETSc Option Table entries:\n");
1024e11779c2SBarry Smith   } else {
1025e11779c2SBarry Smith     (*PetscErrorPrintf)("No PETSc Option Table entries\n");
1026e11779c2SBarry Smith   }
1027e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1028660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1029e11779c2SBarry Smith     if (options->values[i]) {
1030e11779c2SBarry Smith       (*PetscErrorPrintf)("-%s %s\n", options->names[i], options->values[i]);
1031e11779c2SBarry Smith     } else {
1032e11779c2SBarry Smith       (*PetscErrorPrintf)("-%s\n", options->names[i]);
1033e11779c2SBarry Smith     }
1034e11779c2SBarry Smith   }
1035f4bc716fSBarry Smith   return 0;
1036e11779c2SBarry Smith }
1037e11779c2SBarry Smith 
1038e5c89e4eSSatish Balay /*@C
103974e0666dSJed Brown    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
104074e0666dSJed Brown 
10411c9f3c13SBarry Smith    Logically Collective
104274e0666dSJed Brown 
1043d8d19677SJose E. Roman    Input Parameters:
1044c5929fdfSBarry Smith +  options - options database, or NULL for the default global database
1045c5929fdfSBarry Smith -  prefix - The string to append to the existing prefix
10469db968c8SJed Brown 
10479db968c8SJed Brown    Options Database Keys:
10489db968c8SJed Brown +   -prefix_push <some_prefix_> - push the given prefix
10499db968c8SJed Brown -   -prefix_pop - pop the last prefix
10509db968c8SJed Brown 
10519db968c8SJed Brown    Notes:
10529db968c8SJed Brown    It is common to use this in conjunction with -options_file as in
10539db968c8SJed Brown 
10549db968c8SJed Brown $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10559db968c8SJed Brown 
10569db968c8SJed Brown    where the files no longer require all options to be prefixed with -system2_.
105774e0666dSJed Brown 
1058811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
10591c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
10601c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10611c9f3c13SBarry Smith    on different ranks.
10621c9f3c13SBarry Smith 
106374e0666dSJed Brown    Level: advanced
106474e0666dSJed Brown 
1065db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
106674e0666dSJed Brown @*/
1067d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1068d71ae5a4SJacob Faibussowitsch {
106974e0666dSJed Brown   size_t    n;
107074e0666dSJed Brown   PetscInt  start;
10712d747510SLisandro Dalcin   char      key[MAXOPTNAME + 1];
10722d747510SLisandro Dalcin   PetscBool valid;
107374e0666dSJed Brown 
107474e0666dSJed Brown   PetscFunctionBegin;
1075064a246eSJacob Faibussowitsch   PetscValidCharPointer(prefix, 2);
1076c5929fdfSBarry Smith   options = options ? options : defaultoptions;
107708401ef6SPierre 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);
10782d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10799566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10809566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10818bf569ecSLisandro 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 */
108228b400f6SJacob 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" : "");
108374e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10849566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
108508401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10869566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
108774e0666dSJed Brown   options->prefixstack[options->prefixind++] = start + n;
108874e0666dSJed Brown   PetscFunctionReturn(0);
108974e0666dSJed Brown }
109074e0666dSJed Brown 
1091c5929fdfSBarry Smith /*@C
1092811af0c4SBarry Smith    PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
109374e0666dSJed Brown 
1094811af0c4SBarry Smith    Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
109574e0666dSJed Brown 
1096811af0c4SBarry Smith   Input Parameter:
1097c5929fdfSBarry Smith .  options - options database, or NULL for the default global database
1098c5929fdfSBarry Smith 
109974e0666dSJed Brown    Level: advanced
110074e0666dSJed Brown 
1101db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
110274e0666dSJed Brown @*/
1103d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1104d71ae5a4SJacob Faibussowitsch {
110574e0666dSJed Brown   PetscInt offset;
110674e0666dSJed Brown 
110774e0666dSJed Brown   PetscFunctionBegin;
1108c5929fdfSBarry Smith   options = options ? options : defaultoptions;
110908401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
111074e0666dSJed Brown   options->prefixind--;
111174e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
111274e0666dSJed Brown   options->prefix[offset] = 0;
111374e0666dSJed Brown   PetscFunctionReturn(0);
111474e0666dSJed Brown }
111574e0666dSJed Brown 
1116a542b6e8SBarry Smith /*@C
1117a542b6e8SBarry Smith     PetscOptionsClear - Removes all options form the database leaving it empty.
1118a542b6e8SBarry Smith 
11191c9f3c13SBarry Smith     Logically Collective
11201c9f3c13SBarry Smith 
1121811af0c4SBarry Smith   Input Parameter:
1122c5929fdfSBarry Smith .  options - options database, use NULL for the default global database
1123c5929fdfSBarry Smith 
1124811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
11251c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
11261c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11271c9f3c13SBarry Smith    on different ranks.
11281c9f3c13SBarry Smith 
1129a542b6e8SBarry Smith    Level: developer
1130a542b6e8SBarry Smith 
1131db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1132a542b6e8SBarry Smith @*/
1133d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClear(PetscOptions options)
1134d71ae5a4SJacob Faibussowitsch {
1135a542b6e8SBarry Smith   PetscInt i;
1136a542b6e8SBarry Smith 
113739a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1138c5929fdfSBarry Smith   options = options ? options : defaultoptions;
113939a651e2SJacob Faibussowitsch   if (!options) PetscFunctionReturn(0);
11402d747510SLisandro Dalcin 
1141a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1142a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1143a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1144a542b6e8SBarry Smith   }
11452d747510SLisandro Dalcin   options->N = 0;
11462d747510SLisandro Dalcin 
1147a542b6e8SBarry Smith   for (i = 0; i < options->Naliases; i++) {
1148a542b6e8SBarry Smith     free(options->aliases1[i]);
1149a542b6e8SBarry Smith     free(options->aliases2[i]);
1150a542b6e8SBarry Smith   }
1151a542b6e8SBarry Smith   options->Naliases = 0;
1152a542b6e8SBarry Smith 
11532d747510SLisandro Dalcin   /* destroy hash table */
11542d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11552d747510SLisandro Dalcin   options->ht = NULL;
11560eb63584SBarry Smith 
11572d747510SLisandro Dalcin   options->prefixind = 0;
11582d747510SLisandro Dalcin   options->prefix[0] = 0;
11592d747510SLisandro Dalcin   options->help      = PETSC_FALSE;
116039a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
11614416b707SBarry Smith }
11624416b707SBarry Smith 
11632d747510SLisandro Dalcin /*@C
11642d747510SLisandro Dalcin    PetscOptionsSetAlias - Makes a key and alias for another key
11652d747510SLisandro Dalcin 
11661c9f3c13SBarry Smith    Logically Collective
11672d747510SLisandro Dalcin 
11682d747510SLisandro Dalcin    Input Parameters:
11692d747510SLisandro Dalcin +  options - options database, or NULL for default global database
11702d747510SLisandro Dalcin .  newname - the alias
11712d747510SLisandro Dalcin -  oldname - the name that alias will refer to
11722d747510SLisandro Dalcin 
11732d747510SLisandro Dalcin    Level: advanced
11742d747510SLisandro Dalcin 
1175811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
11761c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
11771c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11781c9f3c13SBarry Smith    on different ranks.
11791c9f3c13SBarry Smith 
1180c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1181c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1182db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1183c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1184db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1185db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
11862d747510SLisandro Dalcin @*/
1187d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1188d71ae5a4SJacob Faibussowitsch {
11892d747510SLisandro Dalcin   PetscInt  n;
11902d747510SLisandro Dalcin   size_t    len;
11919210b8eaSVaclav Hapla   PetscBool valid;
11922d747510SLisandro Dalcin 
11932d747510SLisandro Dalcin   PetscFunctionBegin;
11942d747510SLisandro Dalcin   PetscValidCharPointer(newname, 2);
11952d747510SLisandro Dalcin   PetscValidCharPointer(oldname, 3);
11962d747510SLisandro Dalcin   options = options ? options : defaultoptions;
11979566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
119828b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
11999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
120028b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
12012d747510SLisandro Dalcin 
12022d747510SLisandro Dalcin   n = options->Naliases;
120308401ef6SPierre 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);
12042d747510SLisandro Dalcin 
12059371c9d4SSatish Balay   newname++;
12069371c9d4SSatish Balay   oldname++;
12079566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
12082d747510SLisandro Dalcin   options->aliases1[n] = (char *)malloc((len + 1) * sizeof(char));
12099566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(options->aliases1[n], newname));
12109566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
12112d747510SLisandro Dalcin   options->aliases2[n] = (char *)malloc((len + 1) * sizeof(char));
12129566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(options->aliases2[n], oldname));
12132d747510SLisandro Dalcin   options->Naliases++;
12142d747510SLisandro Dalcin   PetscFunctionReturn(0);
12152d747510SLisandro Dalcin }
12164416b707SBarry Smith 
1217e5c89e4eSSatish Balay /*@C
1218e5c89e4eSSatish Balay    PetscOptionsSetValue - Sets an option name-value pair in the options
1219e5c89e4eSSatish Balay    database, overriding whatever is already present.
1220e5c89e4eSSatish Balay 
12211c9f3c13SBarry Smith    Logically Collective
1222e5c89e4eSSatish Balay 
1223e5c89e4eSSatish Balay    Input Parameters:
1224c5929fdfSBarry Smith +  options - options database, use NULL for the default global database
1225c5929fdfSBarry Smith .  name - name of option, this SHOULD have the - prepended
12262d747510SLisandro Dalcin -  value - the option value (not used for all options, so can be NULL)
1227e5c89e4eSSatish Balay 
1228e5c89e4eSSatish Balay    Level: intermediate
1229e5c89e4eSSatish Balay 
1230e5c89e4eSSatish Balay    Note:
1231811af0c4SBarry Smith    This function can be called BEFORE `PetscInitialize()`
1232d49172ceSBarry Smith 
1233811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
12341c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
12351c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12361c9f3c13SBarry Smith    on different ranks.
12371c9f3c13SBarry Smith 
12382d747510SLisandro Dalcin    Developers Note: Uses malloc() directly because PETSc may not be initialized yet.
1239b0250c70SBarry Smith 
1240db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1241e5c89e4eSSatish Balay @*/
1242d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1243d71ae5a4SJacob Faibussowitsch {
124439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL));
124639a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1247c5b5d8d5SVaclav Hapla }
1248c5b5d8d5SVaclav Hapla 
1249d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos)
1250d71ae5a4SJacob Faibussowitsch {
1251e5c89e4eSSatish Balay   size_t    len;
12522d747510SLisandro Dalcin   int       N, n, i;
1253e5c89e4eSSatish Balay   char    **names;
12542d747510SLisandro Dalcin   char      fullname[MAXOPTNAME] = "";
1255c5b5d8d5SVaclav Hapla   PetscBool flg;
1256e5c89e4eSSatish Balay 
125739a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12587272c0d2SVaclav Hapla   if (!options) {
12599566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12607272c0d2SVaclav Hapla     options = defaultoptions;
1261c5929fdfSBarry Smith   }
126239a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
12632d747510SLisandro Dalcin 
12649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
126539a651e2SJacob Faibussowitsch   if (flg) PetscFunctionReturn(0);
1266e5c89e4eSSatish Balay 
12672d747510SLisandro Dalcin   name++; /* skip starting dash */
12682d747510SLisandro Dalcin 
126974e0666dSJed Brown   if (options->prefixind > 0) {
1270d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
12712d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
127289ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
12732d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
127474e0666dSJed Brown     name                           = fullname;
127574e0666dSJed Brown   }
127674e0666dSJed Brown 
127774e0666dSJed Brown   /* check against aliases */
1278e5c89e4eSSatish Balay   N = options->Naliases;
1279e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
12802d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
12819371c9d4SSatish Balay     if (!result) {
12829371c9d4SSatish Balay       name = options->aliases2[i];
12839371c9d4SSatish Balay       break;
12849371c9d4SSatish Balay     }
1285e5c89e4eSSatish Balay   }
1286e5c89e4eSSatish Balay 
12872d747510SLisandro Dalcin   /* slow search */
12882d747510SLisandro Dalcin   N = n = options->N;
1289e5c89e4eSSatish Balay   names = options->names;
1290e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
12912d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
12922d747510SLisandro Dalcin     if (!result) {
12939371c9d4SSatish Balay       n = i;
12949371c9d4SSatish Balay       goto setvalue;
12952d747510SLisandro Dalcin     } else if (result > 0) {
12969371c9d4SSatish Balay       n = i;
12979371c9d4SSatish Balay       break;
1298e5c89e4eSSatish Balay     }
1299e5c89e4eSSatish Balay   }
130039a651e2SJacob 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);
130139a651e2SJacob Faibussowitsch 
13022d747510SLisandro Dalcin   /* shift remaining values up 1 */
1303e5c89e4eSSatish Balay   for (i = N; i > n; i--) {
13045e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1305e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1306e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
1307e5c89e4eSSatish Balay   }
13082d747510SLisandro Dalcin   options->names[n]  = NULL;
13092d747510SLisandro Dalcin   options->values[n] = NULL;
13102d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
13112d747510SLisandro Dalcin   options->N++;
13122d747510SLisandro Dalcin 
13132d747510SLisandro Dalcin   /* destroy hash table */
13142d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13152d747510SLisandro Dalcin   options->ht = NULL;
13162d747510SLisandro Dalcin 
13172d747510SLisandro Dalcin   /* set new name */
131870d8d27cSBarry Smith   len               = strlen(name);
13195e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
132039a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1321d49172ceSBarry Smith   strcpy(options->names[n], name);
13222d747510SLisandro Dalcin 
13232d747510SLisandro Dalcin setvalue:
13242d747510SLisandro Dalcin   /* set new value */
13252d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1326d49172ceSBarry Smith   len = value ? strlen(value) : 0;
13275e8c5e88SLisandro Dalcin   if (len) {
1328e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1329d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1330d49172ceSBarry Smith     strcpy(options->values[n], value);
13312d747510SLisandro Dalcin   } else {
13322d747510SLisandro Dalcin     options->values[n] = NULL;
13332d747510SLisandro Dalcin   }
13342d747510SLisandro Dalcin 
133591ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
133691ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
133791ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1338d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
133991ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
134091ad3481SVaclav Hapla   }
134191ad3481SVaclav Hapla 
13429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsMonitor(options, name, value));
1343c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
134439a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1345e5c89e4eSSatish Balay }
1346e5c89e4eSSatish Balay 
1347e5c89e4eSSatish Balay /*@C
1348e5c89e4eSSatish Balay    PetscOptionsClearValue - Clears an option name-value pair in the options
1349e5c89e4eSSatish Balay    database, overriding whatever is already present.
1350e5c89e4eSSatish Balay 
13511c9f3c13SBarry Smith    Logically Collective
1352e5c89e4eSSatish Balay 
1353d8d19677SJose E. Roman    Input Parameters:
1354c5929fdfSBarry Smith +  options - options database, use NULL for the default global database
1355a2b725a8SWilliam Gropp -  name - name of option, this SHOULD have the - prepended
1356e5c89e4eSSatish Balay 
1357e5c89e4eSSatish Balay    Level: intermediate
1358e5c89e4eSSatish Balay 
1359811af0c4SBarry Smith    Note:
1360811af0c4SBarry Smith    The collectivity of this routine is complex; only the MPI ranks that call this routine will
13611c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
13621c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
13631c9f3c13SBarry Smith    on different ranks.
13641c9f3c13SBarry Smith 
1365db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1366e5c89e4eSSatish Balay @*/
1367d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1368d71ae5a4SJacob Faibussowitsch {
13692d747510SLisandro Dalcin   int    N, n, i;
13702d747510SLisandro Dalcin   char **names;
1371e5c89e4eSSatish Balay 
1372e5c89e4eSSatish Balay   PetscFunctionBegin;
1373c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1374cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1375c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
13762d747510SLisandro Dalcin 
13772d747510SLisandro Dalcin   name++; /* skip starting dash */
13782d747510SLisandro Dalcin 
13792d747510SLisandro Dalcin   /* slow search */
13802d747510SLisandro Dalcin   N = n = options->N;
1381e5c89e4eSSatish Balay   names = options->names;
1382e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
13832d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13842d747510SLisandro Dalcin     if (!result) {
13859371c9d4SSatish Balay       n = i;
13869371c9d4SSatish Balay       break;
13872d747510SLisandro Dalcin     } else if (result > 0) {
13889371c9d4SSatish Balay       n = N;
13899371c9d4SSatish Balay       break;
1390e5c89e4eSSatish Balay     }
13912d747510SLisandro Dalcin   }
13922d747510SLisandro Dalcin   if (n == N) PetscFunctionReturn(0); /* it was not present */
1393e5c89e4eSSatish Balay 
13942d747510SLisandro Dalcin   /* remove name and value */
13952d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
13962d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1397e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1398e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
13995e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1400e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1401e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
1402e5c89e4eSSatish Balay   }
1403e5c89e4eSSatish Balay   options->N--;
14042d747510SLisandro Dalcin 
14052d747510SLisandro Dalcin   /* destroy hash table */
14062d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
14072d747510SLisandro Dalcin   options->ht = NULL;
14082d747510SLisandro Dalcin 
14099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsMonitor(options, name, NULL));
1410e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1411e5c89e4eSSatish Balay }
1412e5c89e4eSSatish Balay 
1413e5c89e4eSSatish Balay /*@C
14142d747510SLisandro Dalcin    PetscOptionsFindPair - Gets an option name-value pair from the options database.
1415e5c89e4eSSatish Balay 
14162d747510SLisandro Dalcin    Not Collective
1417e5c89e4eSSatish Balay 
1418e5c89e4eSSatish Balay    Input Parameters:
14192d747510SLisandro Dalcin +  options - options database, use NULL for the default global database
14202d747510SLisandro Dalcin .  pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
14212d747510SLisandro Dalcin -  name - name of option, this SHOULD have the "-" prepended
1422e5c89e4eSSatish Balay 
14232d747510SLisandro Dalcin    Output Parameters:
14242d747510SLisandro Dalcin +  value - the option value (optional, not used for all options)
14252d747510SLisandro Dalcin -  set - whether the option is set (optional)
1426e5c89e4eSSatish Balay 
1427811af0c4SBarry Smith    Note:
14289666a313SBarry Smith    Each process may find different values or no value depending on how options were inserted into the database
14291c9f3c13SBarry Smith 
14302d747510SLisandro Dalcin    Level: developer
14312d747510SLisandro Dalcin 
1432db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1433e5c89e4eSSatish Balay @*/
1434d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1435d71ae5a4SJacob Faibussowitsch {
14362d747510SLisandro Dalcin   char      buf[MAXOPTNAME];
1437daabea38SBarry Smith   PetscBool usehashtable = PETSC_TRUE;
14382d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1439e5c89e4eSSatish Balay 
1440e5c89e4eSSatish Balay   PetscFunctionBegin;
1441c5929fdfSBarry Smith   options = options ? options : defaultoptions;
144208401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1443cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1444e5c89e4eSSatish Balay 
14452d747510SLisandro Dalcin   name++; /* skip starting dash */
1446e5c89e4eSSatish Balay 
14477cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
14482d747510SLisandro Dalcin   if (pre && pre[0]) {
14492d747510SLisandro Dalcin     char *ptr = buf;
14509371c9d4SSatish Balay     if (name[0] == '-') {
14519371c9d4SSatish Balay       *ptr++ = '-';
14529371c9d4SSatish Balay       name++;
14539371c9d4SSatish Balay     }
14549566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
14559566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
14562d747510SLisandro Dalcin     name = buf;
14577cd08cecSJed Brown   }
14582d747510SLisandro Dalcin 
145976bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
14602f828895SJed Brown     PetscBool valid;
14612d747510SLisandro Dalcin     char      key[MAXOPTNAME + 1] = "-";
14629566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
14639566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
146428b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
14652f828895SJed Brown   }
1466e5c89e4eSSatish Balay 
14672d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
14682d747510SLisandro Dalcin     int          i, ret;
14692d747510SLisandro Dalcin     khiter_t     it;
14702d747510SLisandro Dalcin     khash_t(HO) *ht;
14712d747510SLisandro Dalcin     ht = kh_init(HO);
147228b400f6SJacob Faibussowitsch     PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
14732d747510SLisandro Dalcin     ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
147428b400f6SJacob Faibussowitsch     PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
14752d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
14762d747510SLisandro Dalcin       it = kh_put(HO, ht, options->names[i], &ret);
147708401ef6SPierre Jolivet       PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
14782d747510SLisandro Dalcin       kh_val(ht, it) = i;
14792d747510SLisandro Dalcin     }
14802d747510SLisandro Dalcin     options->ht = ht;
14812d747510SLisandro Dalcin   }
14822d747510SLisandro Dalcin 
14839371c9d4SSatish Balay   if (usehashtable) { /* fast search */
14842d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
14852d747510SLisandro Dalcin     khiter_t     it = kh_get(HO, ht, name);
14862d747510SLisandro Dalcin     if (it != kh_end(ht)) {
14872d747510SLisandro Dalcin       int i            = kh_val(ht, it);
1488e5c89e4eSSatish Balay       options->used[i] = PETSC_TRUE;
14892d747510SLisandro Dalcin       if (value) *value = options->values[i];
14902d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
14912d747510SLisandro Dalcin       PetscFunctionReturn(0);
14922d747510SLisandro Dalcin     }
14939371c9d4SSatish Balay   } else { /* slow search */
14942d747510SLisandro Dalcin     int i, N = options->N;
14952d747510SLisandro Dalcin     for (i = 0; i < N; i++) {
1496daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i], name);
14972d747510SLisandro Dalcin       if (!result) {
14982d747510SLisandro Dalcin         options->used[i] = PETSC_TRUE;
14992d747510SLisandro Dalcin         if (value) *value = options->values[i];
15002d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
15012d747510SLisandro Dalcin         PetscFunctionReturn(0);
15022d747510SLisandro Dalcin       } else if (result > 0) {
1503e5c89e4eSSatish Balay         break;
1504e5c89e4eSSatish Balay       }
1505e5c89e4eSSatish Balay     }
15062d747510SLisandro Dalcin   }
15072d747510SLisandro Dalcin 
15082d747510SLisandro Dalcin   /*
15092d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
15102d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
15112d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
15122d747510SLisandro Dalcin    */
15132d747510SLisandro Dalcin   if (matchnumbers) {
15142d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1515e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
15162d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
15172d747510SLisandro Dalcin       if (name[i] == '_') {
15182d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
15192d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
15202d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1521e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1522e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1523e5c89e4eSSatish Balay           }
15242d747510SLisandro Dalcin           i = j - 1;
1525e5c89e4eSSatish Balay           break;
1526e5c89e4eSSatish Balay         }
1527e5c89e4eSSatish Balay       }
1528e5c89e4eSSatish Balay     }
1529e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
15302d747510SLisandro Dalcin       PetscBool found;
15312d747510SLisandro Dalcin       char      opt[MAXOPTNAME + 1] = "-", tmp[MAXOPTNAME];
15329566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
15339566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15349566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
15359566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
15369371c9d4SSatish Balay       if (found) {
15379371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
15389371c9d4SSatish Balay         PetscFunctionReturn(0);
15399371c9d4SSatish Balay       }
1540e5c89e4eSSatish Balay     }
1541e5c89e4eSSatish Balay   }
15422d747510SLisandro Dalcin 
15432d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
1544e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1545e5c89e4eSSatish Balay }
1546e5c89e4eSSatish Balay 
1547d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
1548d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1549d71ae5a4SJacob Faibussowitsch {
15502d747510SLisandro Dalcin   char buf[MAXOPTNAME];
1551d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1552514bf10dSMatthew G Knepley 
1553514bf10dSMatthew G Knepley   PetscFunctionBegin;
1554c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1555cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1556cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1557514bf10dSMatthew G Knepley 
15582d747510SLisandro Dalcin   name++; /* skip starting dash */
1559514bf10dSMatthew G Knepley 
1560514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
15612d747510SLisandro Dalcin   if (pre && pre[0]) {
15622d747510SLisandro Dalcin     char *ptr = buf;
15639371c9d4SSatish Balay     if (name[0] == '-') {
15649371c9d4SSatish Balay       *ptr++ = '-';
15659371c9d4SSatish Balay       name++;
15669371c9d4SSatish Balay     }
15679566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) + (size_t)(ptr - buf)));
15689566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
15692d747510SLisandro Dalcin     name = buf;
1570514bf10dSMatthew G Knepley   }
15712d747510SLisandro Dalcin 
157276bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1573514bf10dSMatthew G Knepley     PetscBool valid;
15742d747510SLisandro Dalcin     char      key[MAXOPTNAME + 1] = "-";
15759566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
15769566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
157728b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1578514bf10dSMatthew G Knepley   }
1579514bf10dSMatthew G Knepley 
1580d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1581d6ced9c0SMatthew G. Knepley   {
1582d6ced9c0SMatthew G. Knepley     int i, j;
1583d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1584d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1585d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1586d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1587d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1588d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1589d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1590d6ced9c0SMatthew G. Knepley           }
1591d6ced9c0SMatthew G. Knepley           i = j - 1;
1592d6ced9c0SMatthew G. Knepley           break;
1593d6ced9c0SMatthew G. Knepley         }
1594d6ced9c0SMatthew G. Knepley       }
1595d6ced9c0SMatthew G. Knepley     }
1596d6ced9c0SMatthew G. Knepley   }
1597d6ced9c0SMatthew G. Knepley 
15982d747510SLisandro Dalcin   { /* slow search */
1599d6ced9c0SMatthew G. Knepley     int       c, i;
16002d747510SLisandro Dalcin     size_t    len;
16012d747510SLisandro Dalcin     PetscBool match;
1602d6ced9c0SMatthew G. Knepley 
1603d6ced9c0SMatthew G. Knepley     for (c = -1; c < numCnt; ++c) {
1604d6ced9c0SMatthew G. Knepley       char opt[MAXOPTNAME + 1] = "", tmp[MAXOPTNAME];
1605d6ced9c0SMatthew G. Knepley 
1606d6ced9c0SMatthew G. Knepley       if (c < 0) {
16079566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(opt, name));
1608d6ced9c0SMatthew G. Knepley       } else {
16099566063dSJacob Faibussowitsch         PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[c] + 1), sizeof(tmp))));
16109566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
16119566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt)));
1612d6ced9c0SMatthew G. Knepley       }
16139566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(opt, &len));
16142d747510SLisandro Dalcin       for (i = 0; i < options->N; i++) {
16159566063dSJacob Faibussowitsch         PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1616514bf10dSMatthew G Knepley         if (match) {
1617514bf10dSMatthew G Knepley           options->used[i] = PETSC_TRUE;
16182d747510SLisandro Dalcin           if (value) *value = options->values[i];
16192d747510SLisandro Dalcin           if (set) *set = PETSC_TRUE;
16202d747510SLisandro Dalcin           PetscFunctionReturn(0);
1621514bf10dSMatthew G Knepley         }
1622514bf10dSMatthew G Knepley       }
16232d747510SLisandro Dalcin     }
1624d6ced9c0SMatthew G. Knepley   }
16252d747510SLisandro Dalcin 
16262d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
1627514bf10dSMatthew G Knepley   PetscFunctionReturn(0);
1628514bf10dSMatthew G Knepley }
1629514bf10dSMatthew G Knepley 
1630e5c89e4eSSatish Balay /*@C
1631e5c89e4eSSatish Balay    PetscOptionsReject - Generates an error if a certain option is given.
1632e5c89e4eSSatish Balay 
16331c9f3c13SBarry Smith    Not Collective
1634e5c89e4eSSatish Balay 
1635e5c89e4eSSatish Balay    Input Parameters:
16365c9cc608SHong Zhang +  options - options database, use NULL for default global database
16372d747510SLisandro Dalcin .  pre - the option prefix (may be NULL)
16382d747510SLisandro Dalcin .  name - the option name one is seeking
16390298fd71SBarry Smith -  mess - error message (may be NULL)
1640e5c89e4eSSatish Balay 
1641e5c89e4eSSatish Balay    Level: advanced
1642e5c89e4eSSatish Balay 
1643c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1644db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1645db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1646c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1647db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1648db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1649e5c89e4eSSatish Balay @*/
1650d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1651d71ae5a4SJacob Faibussowitsch {
1652ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1653e5c89e4eSSatish Balay 
1654e5c89e4eSSatish Balay   PetscFunctionBegin;
16559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1656e5c89e4eSSatish Balay   if (flag) {
165708401ef6SPierre 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);
1658f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1659e5c89e4eSSatish Balay   }
1660e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1661e5c89e4eSSatish Balay }
1662e5c89e4eSSatish Balay 
1663e5c89e4eSSatish Balay /*@C
16642d747510SLisandro Dalcin    PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
16652d747510SLisandro Dalcin 
16662d747510SLisandro Dalcin    Not Collective
16672d747510SLisandro Dalcin 
1668811af0c4SBarry Smith    Input Parameter:
16692d747510SLisandro Dalcin .  options - options database, use NULL for default global database
16702d747510SLisandro Dalcin 
1671811af0c4SBarry Smith    Output Parameter:
1672811af0c4SBarry Smith .  set - `PETSC_TRUE` if found else `PETSC_FALSE`.
16732d747510SLisandro Dalcin 
16742d747510SLisandro Dalcin    Level: advanced
16752d747510SLisandro Dalcin 
1676db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
16772d747510SLisandro Dalcin @*/
1678d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1679d71ae5a4SJacob Faibussowitsch {
16802d747510SLisandro Dalcin   PetscFunctionBegin;
1681dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
16822d747510SLisandro Dalcin   options = options ? options : defaultoptions;
16832d747510SLisandro Dalcin   *set    = options->help;
16842d747510SLisandro Dalcin   PetscFunctionReturn(0);
16852d747510SLisandro Dalcin }
16862d747510SLisandro Dalcin 
1687d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1688d71ae5a4SJacob Faibussowitsch {
1689d314f959SVaclav Hapla   PetscFunctionBegin;
1690dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
1691d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1692d314f959SVaclav Hapla   *set    = options->help_intro;
1693d314f959SVaclav Hapla   PetscFunctionReturn(0);
1694d314f959SVaclav Hapla }
1695d314f959SVaclav Hapla 
16962d747510SLisandro Dalcin /*@C
1697e24fcbf7SPierre 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
1698e24fcbf7SPierre Jolivet                       if its value is set to false.
1699e5c89e4eSSatish Balay 
1700e5c89e4eSSatish Balay    Not Collective
1701e5c89e4eSSatish Balay 
1702e5c89e4eSSatish Balay    Input Parameters:
17035c9cc608SHong Zhang +  options - options database, use NULL for default global database
17043de71b31SHong Zhang .  pre - string to prepend to the name or NULL
17053de71b31SHong Zhang -  name - the option one is seeking
1706e5c89e4eSSatish Balay 
1707811af0c4SBarry Smith    Output Parameter:
1708811af0c4SBarry Smith .  set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1709e5c89e4eSSatish Balay 
1710e5c89e4eSSatish Balay    Level: beginner
1711e5c89e4eSSatish Balay 
1712811af0c4SBarry Smith    Note:
1713811af0c4SBarry Smith    In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
171490d69ab7SBarry Smith 
1715db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1716db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1717db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1718c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1719db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1720db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1721e5c89e4eSSatish Balay @*/
1722d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1723d71ae5a4SJacob Faibussowitsch {
17242d747510SLisandro Dalcin   const char *value;
1725ace3abfcSBarry Smith   PetscBool   flag;
1726e5c89e4eSSatish Balay 
1727e5c89e4eSSatish Balay   PetscFunctionBegin;
17289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
172996ef3cdfSSatish Balay   if (set) *set = flag;
1730e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1731e5c89e4eSSatish Balay }
1732e5c89e4eSSatish Balay 
1733e5c89e4eSSatish Balay /*@C
17342d747510SLisandro Dalcin    PetscOptionsGetAll - Lists all the options the program was run with in a single string.
17352d747510SLisandro Dalcin 
17362d747510SLisandro Dalcin    Not Collective
17372d747510SLisandro Dalcin 
1738fd292e60Sprj-    Input Parameter:
17392d747510SLisandro Dalcin .  options - the options database, use NULL for the default global database
17402d747510SLisandro Dalcin 
17412d747510SLisandro Dalcin    Output Parameter:
17422d747510SLisandro Dalcin .  copts - pointer where string pointer is stored
17432d747510SLisandro Dalcin 
17442d747510SLisandro Dalcin    Notes:
1745811af0c4SBarry Smith     The array and each entry in the array should be freed with `PetscFree()`
1746811af0c4SBarry Smith 
17471c9f3c13SBarry Smith     Each process may have different values depending on how the options were inserted into the database
17482d747510SLisandro Dalcin 
17492d747510SLisandro Dalcin    Level: advanced
17502d747510SLisandro Dalcin 
1751db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
17522d747510SLisandro Dalcin @*/
1753d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[])
1754d71ae5a4SJacob Faibussowitsch {
17552d747510SLisandro Dalcin   PetscInt i;
17562d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
17572d747510SLisandro Dalcin   char    *coptions = NULL;
17582d747510SLisandro Dalcin 
17592d747510SLisandro Dalcin   PetscFunctionBegin;
17602d747510SLisandro Dalcin   PetscValidPointer(copts, 2);
17612d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17622d747510SLisandro Dalcin   /* count the length of the required string */
17632d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
17649566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
17652d747510SLisandro Dalcin     len += 2 + lent;
17662d747510SLisandro Dalcin     if (options->values[i]) {
17679566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
17682d747510SLisandro Dalcin       len += 1 + lent;
17692d747510SLisandro Dalcin     }
17702d747510SLisandro Dalcin   }
17719566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
17722d747510SLisandro Dalcin   coptions[0] = 0;
17732d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
17749566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions, "-"));
17759566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions, options->names[i]));
17769566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions, " "));
17772d747510SLisandro Dalcin     if (options->values[i]) {
17789566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(coptions, options->values[i]));
17799566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(coptions, " "));
17802d747510SLisandro Dalcin     }
17812d747510SLisandro Dalcin   }
17822d747510SLisandro Dalcin   *copts = coptions;
17832d747510SLisandro Dalcin   PetscFunctionReturn(0);
17842d747510SLisandro Dalcin }
17852d747510SLisandro Dalcin 
17862d747510SLisandro Dalcin /*@C
17872d747510SLisandro Dalcin    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
17882d747510SLisandro Dalcin 
17892d747510SLisandro Dalcin    Not Collective
17902d747510SLisandro Dalcin 
1791d8d19677SJose E. Roman    Input Parameters:
17922d747510SLisandro Dalcin +  options - options database, use NULL for default global database
17932d747510SLisandro Dalcin -  name - string name of option
17942d747510SLisandro Dalcin 
17952d747510SLisandro Dalcin    Output Parameter:
1796811af0c4SBarry Smith .  used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
17972d747510SLisandro Dalcin 
17982d747510SLisandro Dalcin    Level: advanced
17992d747510SLisandro Dalcin 
1800811af0c4SBarry Smith    Note:
18019666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
18021c9f3c13SBarry Smith    on the given process
18031c9f3c13SBarry Smith 
1804db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
18052d747510SLisandro Dalcin @*/
1806d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1807d71ae5a4SJacob Faibussowitsch {
18082d747510SLisandro Dalcin   PetscInt i;
18092d747510SLisandro Dalcin 
18102d747510SLisandro Dalcin   PetscFunctionBegin;
18112d747510SLisandro Dalcin   PetscValidCharPointer(name, 2);
1812dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(used, 3);
18132d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18142d747510SLisandro Dalcin   *used   = PETSC_FALSE;
18152d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18169566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
18172d747510SLisandro Dalcin     if (*used) {
18182d747510SLisandro Dalcin       *used = options->used[i];
18192d747510SLisandro Dalcin       break;
18202d747510SLisandro Dalcin     }
18212d747510SLisandro Dalcin   }
18222d747510SLisandro Dalcin   PetscFunctionReturn(0);
18232d747510SLisandro Dalcin }
18242d747510SLisandro Dalcin 
1825487a658cSBarry Smith /*@
18262d747510SLisandro Dalcin    PetscOptionsAllUsed - Returns a count of the number of options in the
18272d747510SLisandro Dalcin    database that have never been selected.
18282d747510SLisandro Dalcin 
18292d747510SLisandro Dalcin    Not Collective
18302d747510SLisandro Dalcin 
18312d747510SLisandro Dalcin    Input Parameter:
18322d747510SLisandro Dalcin .  options - options database, use NULL for default global database
18332d747510SLisandro Dalcin 
18342d747510SLisandro Dalcin    Output Parameter:
18352d747510SLisandro Dalcin .  N - count of options not used
18362d747510SLisandro Dalcin 
18372d747510SLisandro Dalcin    Level: advanced
18382d747510SLisandro Dalcin 
1839811af0c4SBarry Smith    Note:
18409666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
18411c9f3c13SBarry Smith    on the given process
18421c9f3c13SBarry Smith 
1843db781477SPatrick Sanan .seealso: `PetscOptionsView()`
18442d747510SLisandro Dalcin @*/
1845d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1846d71ae5a4SJacob Faibussowitsch {
18472d747510SLisandro Dalcin   PetscInt i, n = 0;
18482d747510SLisandro Dalcin 
18492d747510SLisandro Dalcin   PetscFunctionBegin;
18502d747510SLisandro Dalcin   PetscValidIntPointer(N, 2);
18512d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18522d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18532d747510SLisandro Dalcin     if (!options->used[i]) n++;
18542d747510SLisandro Dalcin   }
18552d747510SLisandro Dalcin   *N = n;
18562d747510SLisandro Dalcin   PetscFunctionReturn(0);
18572d747510SLisandro Dalcin }
18582d747510SLisandro Dalcin 
1859487a658cSBarry Smith /*@
18602d747510SLisandro Dalcin    PetscOptionsLeft - Prints to screen any options that were set and never used.
18612d747510SLisandro Dalcin 
18622d747510SLisandro Dalcin    Not Collective
18632d747510SLisandro Dalcin 
18642d747510SLisandro Dalcin    Input Parameter:
18652d747510SLisandro Dalcin .  options - options database; use NULL for default global database
18662d747510SLisandro Dalcin 
18672d747510SLisandro Dalcin    Options Database Key:
1868811af0c4SBarry Smith .  -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
18692d747510SLisandro Dalcin 
18703de2bfdfSBarry Smith    Notes:
1871811af0c4SBarry Smith       This is rarely used directly, it is called by `PetscFinalize()` in debug more or if -options_left
18721c9f3c13SBarry Smith       is passed otherwise to help users determine possible mistakes in their usage of options. This
1873811af0c4SBarry Smith       only prints values on process zero of `PETSC_COMM_WORLD`.
1874811af0c4SBarry Smith 
1875811af0c4SBarry Smith       Other processes depending the objects
18761c9f3c13SBarry Smith       used may have different options that are left unused.
18773de2bfdfSBarry Smith 
18782d747510SLisandro Dalcin    Level: advanced
18792d747510SLisandro Dalcin 
1880db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
18812d747510SLisandro Dalcin @*/
1882d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeft(PetscOptions options)
1883d71ae5a4SJacob Faibussowitsch {
18842d747510SLisandro Dalcin   PetscInt     i;
18853de2bfdfSBarry Smith   PetscInt     cnt = 0;
18863de2bfdfSBarry Smith   PetscOptions toptions;
18872d747510SLisandro Dalcin 
18882d747510SLisandro Dalcin   PetscFunctionBegin;
18893de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
18903de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
18913de2bfdfSBarry Smith     if (!toptions->used[i]) {
1892660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
18933de2bfdfSBarry Smith       if (toptions->values[i]) {
18949566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s value: %s\n", toptions->names[i], toptions->values[i]));
18952d747510SLisandro Dalcin       } else {
18969566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value)\n", toptions->names[i]));
18972d747510SLisandro Dalcin       }
18982d747510SLisandro Dalcin     }
18992d747510SLisandro Dalcin   }
19003de2bfdfSBarry Smith   if (!options) {
19013de2bfdfSBarry Smith     toptions = defaultoptions;
19023de2bfdfSBarry Smith     while (toptions->previous) {
19033de2bfdfSBarry Smith       cnt++;
19043de2bfdfSBarry Smith       toptions = toptions->previous;
19053de2bfdfSBarry Smith     }
190648a46eb9SPierre 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));
19073de2bfdfSBarry Smith   }
19082d747510SLisandro Dalcin   PetscFunctionReturn(0);
19092d747510SLisandro Dalcin }
19102d747510SLisandro Dalcin 
19112d747510SLisandro Dalcin /*@C
19122d747510SLisandro Dalcin    PetscOptionsLeftGet - Returns all options that were set and never used.
19132d747510SLisandro Dalcin 
19142d747510SLisandro Dalcin    Not Collective
19152d747510SLisandro Dalcin 
19162d747510SLisandro Dalcin    Input Parameter:
19172d747510SLisandro Dalcin .  options - options database, use NULL for default global database
19182d747510SLisandro Dalcin 
1919d8d19677SJose E. Roman    Output Parameters:
1920a2b725a8SWilliam Gropp +  N - count of options not used
19212d747510SLisandro Dalcin .  names - names of options not used
1922a2b725a8SWilliam Gropp -  values - values of options not used
19232d747510SLisandro Dalcin 
19242d747510SLisandro Dalcin    Level: advanced
19252d747510SLisandro Dalcin 
19262d747510SLisandro Dalcin    Notes:
1927811af0c4SBarry Smith    Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1928811af0c4SBarry Smith 
1929811af0c4SBarry Smith    The value returned may be different on each process and depends on which options have been processed
19301c9f3c13SBarry Smith    on the given process
19312d747510SLisandro Dalcin 
1932db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
19332d747510SLisandro Dalcin @*/
1934d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
1935d71ae5a4SJacob Faibussowitsch {
19362d747510SLisandro Dalcin   PetscInt i, n;
19372d747510SLisandro Dalcin 
19382d747510SLisandro Dalcin   PetscFunctionBegin;
19392d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
19402d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
19412d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
19422d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19432d747510SLisandro Dalcin 
19442d747510SLisandro Dalcin   /* The number of unused PETSc options */
19452d747510SLisandro Dalcin   n = 0;
19462d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1947660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
19482d747510SLisandro Dalcin     if (!options->used[i]) n++;
19492d747510SLisandro Dalcin   }
1950ad540459SPierre Jolivet   if (N) *N = n;
19519566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
19529566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
19532d747510SLisandro Dalcin 
19542d747510SLisandro Dalcin   n = 0;
19552d747510SLisandro Dalcin   if (names || values) {
19562d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
19572d747510SLisandro Dalcin       if (!options->used[i]) {
1958660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
19592d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
19602d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
19612d747510SLisandro Dalcin         n++;
19622d747510SLisandro Dalcin       }
19632d747510SLisandro Dalcin     }
19642d747510SLisandro Dalcin   }
19652d747510SLisandro Dalcin   PetscFunctionReturn(0);
19662d747510SLisandro Dalcin }
19672d747510SLisandro Dalcin 
19682d747510SLisandro Dalcin /*@C
1969811af0c4SBarry Smith    PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
19702d747510SLisandro Dalcin 
19712d747510SLisandro Dalcin    Not Collective
19722d747510SLisandro Dalcin 
1973d8d19677SJose E. Roman    Input Parameters:
1974a2b725a8SWilliam Gropp +  options - options database, use NULL for default global database
19752d747510SLisandro Dalcin .  names - names of options not used
1976a2b725a8SWilliam Gropp -  values - values of options not used
19772d747510SLisandro Dalcin 
19782d747510SLisandro Dalcin    Level: advanced
19792d747510SLisandro Dalcin 
1980db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
19812d747510SLisandro Dalcin @*/
1982d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
1983d71ae5a4SJacob Faibussowitsch {
19842d747510SLisandro Dalcin   PetscFunctionBegin;
19852d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
19862d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
19872d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
1988ad540459SPierre Jolivet   if (N) *N = 0;
19899566063dSJacob Faibussowitsch   if (names) PetscCall(PetscFree(*names));
19909566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
19912d747510SLisandro Dalcin   PetscFunctionReturn(0);
19922d747510SLisandro Dalcin }
19932d747510SLisandro Dalcin 
19942d747510SLisandro Dalcin /*@C
1995811af0c4SBarry Smith    PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
19962d747510SLisandro Dalcin 
1997c3339decSBarry Smith    Logically Collective
19982d747510SLisandro Dalcin 
19992d747510SLisandro Dalcin    Input Parameters:
20002d747510SLisandro Dalcin +  name  - option name string
20012d747510SLisandro Dalcin .  value - option value string
20029060e2f9SVaclav Hapla -  ctx - an ASCII viewer or NULL
20032d747510SLisandro Dalcin 
20042d747510SLisandro Dalcin    Level: intermediate
20052d747510SLisandro Dalcin 
20069666a313SBarry Smith    Notes:
2007811af0c4SBarry Smith      If ctx is NULL, `PetscPrintf()` is used.
2008811af0c4SBarry Smith      The first MPI rank in the `PetscViewer` viewer actually prints the values, other
20091c9f3c13SBarry Smith      processes may have different values set
20101c9f3c13SBarry Smith 
2011811af0c4SBarry Smith      If `PetscCIEnabled` then do not print the test harness options
2012660278c0SBarry Smith 
2013db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
20142d747510SLisandro Dalcin @*/
2015d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], void *ctx)
2016d71ae5a4SJacob Faibussowitsch {
20172d747510SLisandro Dalcin   PetscFunctionBegin;
2018660278c0SBarry Smith   if (PetscCIOption(name)) PetscFunctionReturn(0);
2019660278c0SBarry Smith 
20209060e2f9SVaclav Hapla   if (ctx) {
20219060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
20222d747510SLisandro Dalcin     if (!value) {
20239566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
20242d747510SLisandro Dalcin     } else if (!value[0]) {
20259566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value)\n", name));
20262d747510SLisandro Dalcin     } else {
20279566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s\n", name, value));
20282d747510SLisandro Dalcin     }
20299060e2f9SVaclav Hapla   } else {
20309060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
20319060e2f9SVaclav Hapla     if (!value) {
20329566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
20339060e2f9SVaclav Hapla     } else if (!value[0]) {
20349566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Setting option: %s (no value)\n", name));
20359060e2f9SVaclav Hapla     } else {
20369566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Setting option: %s = %s\n", name, value));
20379060e2f9SVaclav Hapla     }
20389060e2f9SVaclav Hapla   }
20392d747510SLisandro Dalcin   PetscFunctionReturn(0);
20402d747510SLisandro Dalcin }
20412d747510SLisandro Dalcin 
20422d747510SLisandro Dalcin /*@C
20432d747510SLisandro Dalcin    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
20442d747510SLisandro Dalcin    modified the PETSc options database.
20452d747510SLisandro Dalcin 
20462d747510SLisandro Dalcin    Not Collective
20472d747510SLisandro Dalcin 
20482d747510SLisandro Dalcin    Input Parameters:
20492d747510SLisandro Dalcin +  monitor - pointer to function (if this is NULL, it turns off monitoring
20502d747510SLisandro Dalcin .  mctx    - [optional] context for private data for the
20512d747510SLisandro Dalcin              monitor routine (use NULL if no context is desired)
20522d747510SLisandro Dalcin -  monitordestroy - [optional] routine that frees monitor context
20532d747510SLisandro Dalcin           (may be NULL)
20542d747510SLisandro Dalcin 
20552d747510SLisandro Dalcin    Calling Sequence of monitor:
20562d747510SLisandro Dalcin $     monitor (const char name[], const char value[], void *mctx)
20572d747510SLisandro Dalcin 
20582d747510SLisandro Dalcin +  name - option name string
20592d747510SLisandro Dalcin .  value - option value string
2060811af0c4SBarry Smith -  mctx  - optional monitoring context, as set by `PetscOptionsMonitorSet()`
20612d747510SLisandro Dalcin 
20622d747510SLisandro Dalcin    Options Database Keys:
2063811af0c4SBarry Smith    See `PetscInitialize()` for options related to option database monitoring.
20642d747510SLisandro Dalcin 
20652d747510SLisandro Dalcin    Notes:
20662d747510SLisandro Dalcin    The default is to do nothing.  To print the name and value of options
2067811af0c4SBarry Smith    being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
20682d747510SLisandro Dalcin    with a null monitoring context.
20692d747510SLisandro Dalcin 
20702d747510SLisandro Dalcin    Several different monitoring routines may be set by calling
2071811af0c4SBarry Smith    `PetscOptionsMonitorSet()` multiple times; all will be called in the
20722d747510SLisandro Dalcin    order in which they were set.
20732d747510SLisandro Dalcin 
20749060e2f9SVaclav Hapla    Level: intermediate
20752d747510SLisandro Dalcin 
2076db781477SPatrick Sanan .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
20772d747510SLisandro Dalcin @*/
2078d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void *), void *mctx, PetscErrorCode (*monitordestroy)(void **))
2079d71ae5a4SJacob Faibussowitsch {
20802d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
20812d747510SLisandro Dalcin 
20822d747510SLisandro Dalcin   PetscFunctionBegin;
2083c5b5d8d5SVaclav Hapla   if (options->monitorCancel) PetscFunctionReturn(0);
208408401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
20852d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
20862d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
20872d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void *)mctx;
20882d747510SLisandro Dalcin   PetscFunctionReturn(0);
20892d747510SLisandro Dalcin }
20902d747510SLisandro Dalcin 
20912d747510SLisandro Dalcin /*
20922d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
209363fe8743SVaclav Hapla      Empty string is considered as true.
20942d747510SLisandro Dalcin */
2095d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2096d71ae5a4SJacob Faibussowitsch {
20972d747510SLisandro Dalcin   PetscBool istrue, isfalse;
20982d747510SLisandro Dalcin   size_t    len;
20992d747510SLisandro Dalcin 
21002d747510SLisandro Dalcin   PetscFunctionBegin;
210163fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
21029566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
21039371c9d4SSatish Balay   if (!len) {
21049371c9d4SSatish Balay     *a = PETSC_TRUE;
21059371c9d4SSatish Balay     PetscFunctionReturn(0);
21069371c9d4SSatish Balay   }
21079566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
21089371c9d4SSatish Balay   if (istrue) {
21099371c9d4SSatish Balay     *a = PETSC_TRUE;
21109371c9d4SSatish Balay     PetscFunctionReturn(0);
21119371c9d4SSatish Balay   }
21129566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
21139371c9d4SSatish Balay   if (istrue) {
21149371c9d4SSatish Balay     *a = PETSC_TRUE;
21159371c9d4SSatish Balay     PetscFunctionReturn(0);
21169371c9d4SSatish Balay   }
21179566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
21189371c9d4SSatish Balay   if (istrue) {
21199371c9d4SSatish Balay     *a = PETSC_TRUE;
21209371c9d4SSatish Balay     PetscFunctionReturn(0);
21219371c9d4SSatish Balay   }
21229566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
21239371c9d4SSatish Balay   if (istrue) {
21249371c9d4SSatish Balay     *a = PETSC_TRUE;
21259371c9d4SSatish Balay     PetscFunctionReturn(0);
21269371c9d4SSatish Balay   }
21279566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
21289371c9d4SSatish Balay   if (isfalse) {
21299371c9d4SSatish Balay     *a = PETSC_FALSE;
21309371c9d4SSatish Balay     PetscFunctionReturn(0);
21319371c9d4SSatish Balay   }
21329566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
21339371c9d4SSatish Balay   if (isfalse) {
21349371c9d4SSatish Balay     *a = PETSC_FALSE;
21359371c9d4SSatish Balay     PetscFunctionReturn(0);
21369371c9d4SSatish Balay   }
21379566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
21389371c9d4SSatish Balay   if (isfalse) {
21399371c9d4SSatish Balay     *a = PETSC_FALSE;
21409371c9d4SSatish Balay     PetscFunctionReturn(0);
21419371c9d4SSatish Balay   }
21429566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
21439371c9d4SSatish Balay   if (isfalse) {
21449371c9d4SSatish Balay     *a = PETSC_FALSE;
21459371c9d4SSatish Balay     PetscFunctionReturn(0);
21469371c9d4SSatish Balay   }
214798921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
21482d747510SLisandro Dalcin }
21492d747510SLisandro Dalcin 
21502d747510SLisandro Dalcin /*
21512d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
21522d747510SLisandro Dalcin */
2153d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2154d71ae5a4SJacob Faibussowitsch {
21552d747510SLisandro Dalcin   size_t    len;
21562d747510SLisandro Dalcin   PetscBool decide, tdefault, mouse;
21572d747510SLisandro Dalcin 
21582d747510SLisandro Dalcin   PetscFunctionBegin;
21599566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
21605f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
21612d747510SLisandro Dalcin 
21629566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
216348a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
21649566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
216548a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
21669566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
21672d747510SLisandro Dalcin 
21682d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
21692d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
21702d747510SLisandro Dalcin   else if (mouse) *a = -1;
21712d747510SLisandro Dalcin   else {
21722d747510SLisandro Dalcin     char *endptr;
21732d747510SLisandro Dalcin     long  strtolval;
21742d747510SLisandro Dalcin 
21752d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2176cc73adaaSBarry 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);
21772d747510SLisandro Dalcin 
21782d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
21792d747510SLisandro Dalcin     (void)strtolval;
21802d747510SLisandro Dalcin     *a = atoll(name);
21812d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
21822d747510SLisandro Dalcin     (void)strtolval;
21832d747510SLisandro Dalcin     *a = _atoi64(name);
21842d747510SLisandro Dalcin #else
21852d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
21862d747510SLisandro Dalcin #endif
21872d747510SLisandro Dalcin   }
21882d747510SLisandro Dalcin   PetscFunctionReturn(0);
21892d747510SLisandro Dalcin }
21902d747510SLisandro Dalcin 
21912d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
21922d747510SLisandro Dalcin   #include <quadmath.h>
21932d747510SLisandro Dalcin #endif
21942d747510SLisandro Dalcin 
2195d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2196d71ae5a4SJacob Faibussowitsch {
21972d747510SLisandro Dalcin   PetscFunctionBegin;
21982d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
21992d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
22002d747510SLisandro Dalcin #else
22012d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
22022d747510SLisandro Dalcin #endif
22032d747510SLisandro Dalcin   PetscFunctionReturn(0);
22042d747510SLisandro Dalcin }
22052d747510SLisandro Dalcin 
2206d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2207d71ae5a4SJacob Faibussowitsch {
22082d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
22092d747510SLisandro Dalcin   char     *ptr;
22102d747510SLisandro Dalcin   PetscReal strtoval;
22112d747510SLisandro Dalcin 
22122d747510SLisandro Dalcin   PetscFunctionBegin;
22139566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
22142d747510SLisandro Dalcin   if (ptr == name) {
22152d747510SLisandro Dalcin     strtoval = 1.;
22162d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
22172d747510SLisandro Dalcin     if (name[0] == 'i') {
22182d747510SLisandro Dalcin       ptr++;
22192d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
22202d747510SLisandro Dalcin       ptr += 2;
22212d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
22222d747510SLisandro Dalcin       strtoval = -1.;
22232d747510SLisandro Dalcin       ptr += 2;
22242d747510SLisandro Dalcin     }
22252d747510SLisandro Dalcin   } else if (*ptr == 'i') {
22262d747510SLisandro Dalcin     hasi = PETSC_TRUE;
22272d747510SLisandro Dalcin     ptr++;
22282d747510SLisandro Dalcin   }
22292d747510SLisandro Dalcin   *endptr      = ptr;
22302d747510SLisandro Dalcin   *isImaginary = hasi;
22312d747510SLisandro Dalcin   if (hasi) {
22322d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
223398921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
22342d747510SLisandro Dalcin #else
22352d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
22362d747510SLisandro Dalcin #endif
22372d747510SLisandro Dalcin   } else {
22382d747510SLisandro Dalcin     *a = strtoval;
22392d747510SLisandro Dalcin   }
22402d747510SLisandro Dalcin   PetscFunctionReturn(0);
22412d747510SLisandro Dalcin }
22422d747510SLisandro Dalcin 
22432d747510SLisandro Dalcin /*
22442d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
22452d747510SLisandro Dalcin */
2246d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2247d71ae5a4SJacob Faibussowitsch {
22482d747510SLisandro Dalcin   size_t    len;
22492d747510SLisandro Dalcin   PetscBool match;
22502d747510SLisandro Dalcin   char     *endptr;
22512d747510SLisandro Dalcin 
22522d747510SLisandro Dalcin   PetscFunctionBegin;
22539566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
225428b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
22552d747510SLisandro Dalcin 
22569566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
22579566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
22589371c9d4SSatish Balay   if (match) {
22599371c9d4SSatish Balay     *a = PETSC_DEFAULT;
22609371c9d4SSatish Balay     PetscFunctionReturn(0);
22619371c9d4SSatish Balay   }
22622d747510SLisandro Dalcin 
22639566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
22649566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
22659371c9d4SSatish Balay   if (match) {
22669371c9d4SSatish Balay     *a = PETSC_DECIDE;
22679371c9d4SSatish Balay     PetscFunctionReturn(0);
22689371c9d4SSatish Balay   }
22692d747510SLisandro Dalcin 
22709566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
227139a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
22722d747510SLisandro Dalcin   PetscFunctionReturn(0);
22732d747510SLisandro Dalcin }
22742d747510SLisandro Dalcin 
2275d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2276d71ae5a4SJacob Faibussowitsch {
22772d747510SLisandro Dalcin   PetscBool   imag1;
22782d747510SLisandro Dalcin   size_t      len;
22792d747510SLisandro Dalcin   PetscScalar val = 0.;
22802d747510SLisandro Dalcin   char       *ptr = NULL;
22812d747510SLisandro Dalcin 
22822d747510SLisandro Dalcin   PetscFunctionBegin;
22839566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
228428b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22859566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
22862d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
22872d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
22882d747510SLisandro Dalcin     PetscBool   imag2;
22892d747510SLisandro Dalcin     PetscScalar val2;
22902d747510SLisandro Dalcin 
22919566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
229239a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
22932d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
22942d747510SLisandro Dalcin   }
22952d747510SLisandro Dalcin #endif
229639a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
22972d747510SLisandro Dalcin   *a = val;
22982d747510SLisandro Dalcin   PetscFunctionReturn(0);
22992d747510SLisandro Dalcin }
23002d747510SLisandro Dalcin 
23012d747510SLisandro Dalcin /*@C
23022d747510SLisandro Dalcin    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
23032d747510SLisandro Dalcin             option in the database.
2304e5c89e4eSSatish Balay 
2305e5c89e4eSSatish Balay    Not Collective
2306e5c89e4eSSatish Balay 
2307e5c89e4eSSatish Balay    Input Parameters:
23085c9cc608SHong Zhang +  options - options database, use NULL for default global database
2309c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2310e5c89e4eSSatish Balay -  name - the option one is seeking
2311e5c89e4eSSatish Balay 
2312d8d19677SJose E. Roman    Output Parameters:
23132d747510SLisandro Dalcin +  ivalue - the logical value to return
2314811af0c4SBarry Smith -  set - `PETSC_TRUE`  if found, else `PETSC_FALSE`
2315e5c89e4eSSatish Balay 
2316e5c89e4eSSatish Balay    Level: beginner
2317e5c89e4eSSatish Balay 
231895452b02SPatrick Sanan    Notes:
2319811af0c4SBarry Smith        TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`
2320811af0c4SBarry Smith        FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
23212d747510SLisandro Dalcin 
2322811af0c4SBarry 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
23232d747510SLisandro Dalcin      is equivalent to -requested_bool true
23242d747510SLisandro Dalcin 
23252d747510SLisandro Dalcin        If the user does not supply the option at all ivalue is NOT changed. Thus
23262efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
23272efd9cb1SBarry Smith 
2328db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2329db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2330db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2331c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2332db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2333db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2334e5c89e4eSSatish Balay @*/
2335d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2336d71ae5a4SJacob Faibussowitsch {
23372d747510SLisandro Dalcin   const char *value;
2338ace3abfcSBarry Smith   PetscBool   flag;
2339e5c89e4eSSatish Balay 
2340e5c89e4eSSatish Balay   PetscFunctionBegin;
23412d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2342064a246eSJacob Faibussowitsch   if (ivalue) PetscValidBoolPointer(ivalue, 4);
23439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2344e5c89e4eSSatish Balay   if (flag) {
234596ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
23469566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
23472d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2348e5c89e4eSSatish Balay   } else {
234996ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2350e5c89e4eSSatish Balay   }
2351e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2352e5c89e4eSSatish Balay }
2353e5c89e4eSSatish Balay 
2354e5c89e4eSSatish Balay /*@C
2355e5c89e4eSSatish Balay    PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2356e5c89e4eSSatish Balay 
2357e5c89e4eSSatish Balay    Not Collective
2358e5c89e4eSSatish Balay 
2359e5c89e4eSSatish Balay    Input Parameters:
23605c9cc608SHong Zhang +  options - options database, use NULL for default global database
2361c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2362e5c89e4eSSatish Balay .  opt - option name
2363a264d7a6SBarry Smith .  list - the possible choices (one of these must be selected, anything else is invalid)
2364a2b725a8SWilliam Gropp -  ntext - number of choices
2365e5c89e4eSSatish Balay 
2366d8d19677SJose E. Roman    Output Parameters:
23672efd9cb1SBarry Smith +  value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2368811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2369e5c89e4eSSatish Balay 
2370e5c89e4eSSatish Balay    Level: intermediate
2371e5c89e4eSSatish Balay 
237295452b02SPatrick Sanan    Notes:
237395452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
23742efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
23752efd9cb1SBarry Smith 
2376811af0c4SBarry Smith    See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2377e5c89e4eSSatish Balay 
2378db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2379db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2380db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2381c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2382db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2383db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2384e5c89e4eSSatish Balay @*/
2385d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscInt ntext, PetscInt *value, PetscBool *set)
2386d71ae5a4SJacob Faibussowitsch {
238758b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2388e5c89e4eSSatish Balay   char     *svalue;
2389ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2390e5c89e4eSSatish Balay   PetscInt  i;
2391e5c89e4eSSatish Balay 
2392e5c89e4eSSatish Balay   PetscFunctionBegin;
23932d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
2394e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
23959566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2396e5c89e4eSSatish Balay     if (alen > len) len = alen;
239758b0ac4eSStefano Zampini     tlen += len + 1;
2398e5c89e4eSSatish Balay   }
2399e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
24009566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
24019566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2402e5c89e4eSSatish Balay   if (aset) {
24039566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
240458b0ac4eSStefano Zampini     if (!flg) {
240558b0ac4eSStefano Zampini       char *avail, *pavl;
240658b0ac4eSStefano Zampini 
24079566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
240858b0ac4eSStefano Zampini       pavl = avail;
240958b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
24109566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(list[i], &alen));
24119566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(pavl, list[i]));
241258b0ac4eSStefano Zampini         pavl += alen;
24139566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(pavl, " "));
241458b0ac4eSStefano Zampini         pavl += 1;
241558b0ac4eSStefano Zampini       }
24169566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
241798921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
241858b0ac4eSStefano Zampini     }
2419fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2420a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
24219566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
2422e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2423e5c89e4eSSatish Balay }
2424e5c89e4eSSatish Balay 
2425e5c89e4eSSatish Balay /*@C
2426e5c89e4eSSatish Balay    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2427e5c89e4eSSatish Balay 
2428e5c89e4eSSatish Balay    Not Collective
2429e5c89e4eSSatish Balay 
2430e5c89e4eSSatish Balay    Input Parameters:
24315c9cc608SHong Zhang +  options - options database, use NULL for default global database
2432c5929fdfSBarry Smith .  pre - option prefix or NULL
2433e5c89e4eSSatish Balay .  opt - option name
24346b867d5aSJose E. Roman -  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2435e5c89e4eSSatish Balay 
2436d8d19677SJose E. Roman    Output Parameters:
2437e5c89e4eSSatish Balay +  value - the  value to return
2438811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2439e5c89e4eSSatish Balay 
2440e5c89e4eSSatish Balay    Level: beginner
2441e5c89e4eSSatish Balay 
244295452b02SPatrick Sanan    Notes:
244395452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
24442efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2445e5c89e4eSSatish Balay 
2446811af0c4SBarry Smith           List is usually something like `PCASMTypes` or some other predefined list of enum names
2447e5c89e4eSSatish Balay 
2448db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2449db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2450db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2451db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2452c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2453db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2454db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2455e5c89e4eSSatish Balay @*/
2456d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscEnum *value, PetscBool *set)
2457d71ae5a4SJacob Faibussowitsch {
245869a24498SJed Brown   PetscInt  ntext = 0, tval;
2459ace3abfcSBarry Smith   PetscBool fset;
2460e5c89e4eSSatish Balay 
2461e5c89e4eSSatish Balay   PetscFunctionBegin;
24622d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
2463ad540459SPierre 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");
246408401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2465e5c89e4eSSatish Balay   ntext -= 3;
24669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
246769a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2468809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2469809ceb46SBarry Smith   if (set) *set = fset;
2470e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2471e5c89e4eSSatish Balay }
2472e5c89e4eSSatish Balay 
2473e5c89e4eSSatish Balay /*@C
24742d747510SLisandro Dalcin    PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2475e5c89e4eSSatish Balay 
2476e5c89e4eSSatish Balay    Not Collective
2477e5c89e4eSSatish Balay 
2478e5c89e4eSSatish Balay    Input Parameters:
24795c9cc608SHong Zhang +  options - options database, use NULL for default global database
2480c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2481e5c89e4eSSatish Balay -  name - the option one is seeking
2482e5c89e4eSSatish Balay 
2483d8d19677SJose E. Roman    Output Parameters:
24842d747510SLisandro Dalcin +  ivalue - the integer value to return
2485811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2486e5c89e4eSSatish Balay 
2487e5c89e4eSSatish Balay    Level: beginner
2488e5c89e4eSSatish Balay 
2489e5c89e4eSSatish Balay    Notes:
24902d747510SLisandro Dalcin    If the user does not supply the option ivalue is NOT changed. Thus
24912efd9cb1SBarry Smith    you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
24925c07ccb8SBarry Smith 
2493db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2494db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2495db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2496db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2497c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2498db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2499db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2500e5c89e4eSSatish Balay @*/
2501d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2502d71ae5a4SJacob Faibussowitsch {
25032d747510SLisandro Dalcin   const char *value;
25042d747510SLisandro Dalcin   PetscBool   flag;
2505e5c89e4eSSatish Balay 
2506e5c89e4eSSatish Balay   PetscFunctionBegin;
25072d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
25082d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
25099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2510e5c89e4eSSatish Balay   if (flag) {
251134a9cc2cSBarry Smith     if (!value) {
25122d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
251334a9cc2cSBarry Smith     } else {
25142d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
25159566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2516e5c89e4eSSatish Balay     }
2517e5c89e4eSSatish Balay   } else {
251896ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2519e5c89e4eSSatish Balay   }
2520e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2521e5c89e4eSSatish Balay }
2522e5c89e4eSSatish Balay 
2523e2446a98SMatthew Knepley /*@C
2524e5c89e4eSSatish Balay    PetscOptionsGetReal - Gets the double precision value for a particular
2525e5c89e4eSSatish Balay    option in the database.
2526e5c89e4eSSatish Balay 
2527e5c89e4eSSatish Balay    Not Collective
2528e5c89e4eSSatish Balay 
2529e5c89e4eSSatish Balay    Input Parameters:
25305c9cc608SHong Zhang +  options - options database, use NULL for default global database
2531c5929fdfSBarry Smith .  pre - string to prepend to each name or NULL
2532e5c89e4eSSatish Balay -  name - the option one is seeking
2533e5c89e4eSSatish Balay 
2534d8d19677SJose E. Roman    Output Parameters:
2535e5c89e4eSSatish Balay +  dvalue - the double value to return
2536811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2537e5c89e4eSSatish Balay 
2538811af0c4SBarry Smith    Note:
253995452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
25402efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2541e4974155SBarry Smith 
2542e5c89e4eSSatish Balay    Level: beginner
2543e5c89e4eSSatish Balay 
2544db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2545c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2546db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2547c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2548db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2549db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2550e5c89e4eSSatish Balay @*/
2551d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2552d71ae5a4SJacob Faibussowitsch {
25532d747510SLisandro Dalcin   const char *value;
2554ace3abfcSBarry Smith   PetscBool   flag;
2555e5c89e4eSSatish Balay 
2556e5c89e4eSSatish Balay   PetscFunctionBegin;
25572d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
25582d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
25599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2560e5c89e4eSSatish Balay   if (flag) {
2561a297a907SKarl Rupp     if (!value) {
2562a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2563a297a907SKarl Rupp     } else {
2564a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
25659566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2566a297a907SKarl Rupp     }
2567e5c89e4eSSatish Balay   } else {
256896ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2569e5c89e4eSSatish Balay   }
2570e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2571e5c89e4eSSatish Balay }
2572e5c89e4eSSatish Balay 
2573e5c89e4eSSatish Balay /*@C
2574e5c89e4eSSatish Balay    PetscOptionsGetScalar - Gets the scalar value for a particular
2575e5c89e4eSSatish Balay    option in the database.
2576e5c89e4eSSatish Balay 
2577e5c89e4eSSatish Balay    Not Collective
2578e5c89e4eSSatish Balay 
2579e5c89e4eSSatish Balay    Input Parameters:
25805c9cc608SHong Zhang +  options - options database, use NULL for default global database
2581c5929fdfSBarry Smith .  pre - string to prepend to each name or NULL
2582e5c89e4eSSatish Balay -  name - the option one is seeking
2583e5c89e4eSSatish Balay 
2584d8d19677SJose E. Roman    Output Parameters:
2585e5c89e4eSSatish Balay +  dvalue - the double value to return
2586811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2587e5c89e4eSSatish Balay 
2588e5c89e4eSSatish Balay    Level: beginner
2589e5c89e4eSSatish Balay 
2590e5c89e4eSSatish Balay    Usage:
2591eb4ae41dSBarry Smith    A complex number 2+3i must be specified with NO spaces
2592e5c89e4eSSatish Balay 
2593811af0c4SBarry Smith    Note:
259495452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
25952efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2596e4974155SBarry Smith 
2597db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2598db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2599db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2600c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2601db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2602db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2603e5c89e4eSSatish Balay @*/
2604d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2605d71ae5a4SJacob Faibussowitsch {
26062d747510SLisandro Dalcin   const char *value;
2607ace3abfcSBarry Smith   PetscBool   flag;
2608e5c89e4eSSatish Balay 
2609e5c89e4eSSatish Balay   PetscFunctionBegin;
26102d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
26112d747510SLisandro Dalcin   PetscValidScalarPointer(dvalue, 4);
26129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2613e5c89e4eSSatish Balay   if (flag) {
2614e5c89e4eSSatish Balay     if (!value) {
261596ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2616e5c89e4eSSatish Balay     } else {
2617e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
26189566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2619e5c89e4eSSatish Balay #else
26209566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2621e5c89e4eSSatish Balay #endif
262296ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2623e5c89e4eSSatish Balay     }
2624e5c89e4eSSatish Balay   } else { /* flag */
262596ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2626e5c89e4eSSatish Balay   }
2627e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2628e5c89e4eSSatish Balay }
2629e5c89e4eSSatish Balay 
2630e5c89e4eSSatish Balay /*@C
2631e5c89e4eSSatish Balay    PetscOptionsGetString - Gets the string value for a particular option in
2632e5c89e4eSSatish Balay    the database.
2633e5c89e4eSSatish Balay 
2634e5c89e4eSSatish Balay    Not Collective
2635e5c89e4eSSatish Balay 
2636e5c89e4eSSatish Balay    Input Parameters:
26375c9cc608SHong Zhang +  options - options database, use NULL for default global database
2638c5929fdfSBarry Smith .  pre - string to prepend to name or NULL
2639e5c89e4eSSatish Balay .  name - the option one is seeking
2640bcbf2dc5SJed Brown -  len - maximum length of the string including null termination
2641e5c89e4eSSatish Balay 
2642e5c89e4eSSatish Balay    Output Parameters:
2643e5c89e4eSSatish Balay +  string - location to copy string
2644811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2645e5c89e4eSSatish Balay 
2646e5c89e4eSSatish Balay    Level: beginner
2647e5c89e4eSSatish Balay 
2648e5c89e4eSSatish Balay    Fortran Note:
2649e5c89e4eSSatish Balay    The Fortran interface is slightly different from the C/C++
2650e5c89e4eSSatish Balay    interface (len is not used).  Sample usage in Fortran follows
2651e5c89e4eSSatish Balay .vb
2652e5c89e4eSSatish Balay       character *20    string
265393e6ba5cSBarry Smith       PetscErrorCode   ierr
265493e6ba5cSBarry Smith       PetscBool        set
26551b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2656e5c89e4eSSatish Balay .ve
2657e5c89e4eSSatish Balay 
2658811af0c4SBarry Smith    Note:
2659811af0c4SBarry 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`
2660e4974155SBarry Smith 
26612efd9cb1SBarry Smith            If the user does not use the option then the string is not changed. Thus
26622efd9cb1SBarry Smith            you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
26632efd9cb1SBarry Smith 
2664f3dea69dSBarry 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).
2665f3dea69dSBarry Smith 
2666db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2667db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2668db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2669c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2670db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2671db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2672e5c89e4eSSatish Balay @*/
2673d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set)
2674d71ae5a4SJacob Faibussowitsch {
26752d747510SLisandro Dalcin   const char *value;
2676ace3abfcSBarry Smith   PetscBool   flag;
2677e5c89e4eSSatish Balay 
2678e5c89e4eSSatish Balay   PetscFunctionBegin;
26792d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
26802d747510SLisandro Dalcin   PetscValidCharPointer(string, 4);
26819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2682e5c89e4eSSatish Balay   if (!flag) {
268396ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2684e5c89e4eSSatish Balay   } else {
268596ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
26869566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
26879566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2688e5c89e4eSSatish Balay   }
2689e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2690e5c89e4eSSatish Balay }
2691e5c89e4eSSatish Balay 
2692d71ae5a4SJacob Faibussowitsch char *PetscOptionsGetStringMatlab(PetscOptions options, const char pre[], const char name[])
2693d71ae5a4SJacob Faibussowitsch {
26942d747510SLisandro Dalcin   const char *value;
269514ce751eSBarry Smith   PetscBool   flag;
269614ce751eSBarry Smith 
269714ce751eSBarry Smith   PetscFunctionBegin;
269839a651e2SJacob Faibussowitsch   if (PetscOptionsFindPair(options, pre, name, &value, &flag)) PetscFunctionReturn(NULL);
26992d747510SLisandro Dalcin   if (flag) PetscFunctionReturn((char *)value);
270039a651e2SJacob Faibussowitsch   PetscFunctionReturn(NULL);
270114ce751eSBarry Smith }
270214ce751eSBarry Smith 
27032d747510SLisandro Dalcin /*@C
27042d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2705f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
27062d747510SLisandro Dalcin 
27072d747510SLisandro Dalcin   Not Collective
27082d747510SLisandro Dalcin 
27092d747510SLisandro Dalcin   Input Parameters:
27102d747510SLisandro Dalcin + options - options database, use NULL for default global database
27112d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
27126b867d5aSJose E. Roman - name - the option one is seeking
27136b867d5aSJose E. Roman 
2714d8d19677SJose E. Roman   Output Parameters:
27152d747510SLisandro Dalcin + dvalue - the integer values to return
2716f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2717811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
27182d747510SLisandro Dalcin 
27192d747510SLisandro Dalcin   Level: beginner
27202d747510SLisandro Dalcin 
2721811af0c4SBarry Smith   Note:
2722f1a722f8SMatthew 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
27232d747510SLisandro Dalcin 
2724db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2725db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2726db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2727c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2728db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2729db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
27302d747510SLisandro Dalcin @*/
2731d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2732d71ae5a4SJacob Faibussowitsch {
27332d747510SLisandro Dalcin   const char *svalue;
27342d747510SLisandro Dalcin   char       *value;
27352d747510SLisandro Dalcin   PetscInt    n = 0;
27362d747510SLisandro Dalcin   PetscBool   flag;
27372d747510SLisandro Dalcin   PetscToken  token;
27382d747510SLisandro Dalcin 
27392d747510SLisandro Dalcin   PetscFunctionBegin;
27402d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2741064a246eSJacob Faibussowitsch   PetscValidBoolPointer(dvalue, 4);
27422d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
27432d747510SLisandro Dalcin 
27449566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
27459371c9d4SSatish Balay   if (!flag || !svalue) {
27469371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
27479371c9d4SSatish Balay     *nmax = 0;
27489371c9d4SSatish Balay     PetscFunctionReturn(0);
27499371c9d4SSatish Balay   }
27502d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
27519566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
27529566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
27532d747510SLisandro Dalcin   while (value && n < *nmax) {
27549566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
27559566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
27562d747510SLisandro Dalcin     dvalue++;
27572d747510SLisandro Dalcin     n++;
27582d747510SLisandro Dalcin   }
27599566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
27602d747510SLisandro Dalcin   *nmax = n;
27612d747510SLisandro Dalcin   PetscFunctionReturn(0);
27622d747510SLisandro Dalcin }
27632d747510SLisandro Dalcin 
27642d747510SLisandro Dalcin /*@C
27652d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
27662d747510SLisandro Dalcin 
27672d747510SLisandro Dalcin   Not Collective
27682d747510SLisandro Dalcin 
27692d747510SLisandro Dalcin   Input Parameters:
27702d747510SLisandro Dalcin + options - options database, use NULL for default global database
27712d747510SLisandro Dalcin . pre - option prefix or NULL
27722d747510SLisandro Dalcin . name - option name
27736b867d5aSJose E. Roman - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
27746b867d5aSJose E. Roman 
27752d747510SLisandro Dalcin   Output Parameters:
27762d747510SLisandro Dalcin + ivalue - the  enum values to return
2777f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2778811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
27792d747510SLisandro Dalcin 
27802d747510SLisandro Dalcin   Level: beginner
27812d747510SLisandro Dalcin 
27822d747510SLisandro Dalcin   Notes:
27832d747510SLisandro Dalcin   The array must be passed as a comma separated list.
27842d747510SLisandro Dalcin 
27852d747510SLisandro Dalcin   There must be no intervening spaces between the values.
27862d747510SLisandro Dalcin 
2787811af0c4SBarry Smith   list is usually something like `PCASMTypes` or some other predefined list of enum names.
27882d747510SLisandro Dalcin 
2789db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2790db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2791db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, `PetscOptionsName()`,
2792c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2793db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2794db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
27952d747510SLisandro Dalcin @*/
2796d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const *list, PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
2797d71ae5a4SJacob Faibussowitsch {
27982d747510SLisandro Dalcin   const char *svalue;
27992d747510SLisandro Dalcin   char       *value;
28002d747510SLisandro Dalcin   PetscInt    n = 0;
28012d747510SLisandro Dalcin   PetscEnum   evalue;
28022d747510SLisandro Dalcin   PetscBool   flag;
28032d747510SLisandro Dalcin   PetscToken  token;
28042d747510SLisandro Dalcin 
28052d747510SLisandro Dalcin   PetscFunctionBegin;
28062d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
28072d747510SLisandro Dalcin   PetscValidPointer(list, 4);
28082d747510SLisandro Dalcin   PetscValidPointer(ivalue, 5);
28092d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 6);
28102d747510SLisandro Dalcin 
28119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28129371c9d4SSatish Balay   if (!flag || !svalue) {
28139371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28149371c9d4SSatish Balay     *nmax = 0;
28159371c9d4SSatish Balay     PetscFunctionReturn(0);
28169371c9d4SSatish Balay   }
28172d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28189566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28199566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28202d747510SLisandro Dalcin   while (value && n < *nmax) {
28219566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
282228b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
28232d747510SLisandro Dalcin     ivalue[n++] = evalue;
28249566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
28252d747510SLisandro Dalcin   }
28269566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28272d747510SLisandro Dalcin   *nmax = n;
28282d747510SLisandro Dalcin   PetscFunctionReturn(0);
28292d747510SLisandro Dalcin }
28302d747510SLisandro Dalcin 
28312d747510SLisandro Dalcin /*@C
2832f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
28332d747510SLisandro Dalcin 
28342d747510SLisandro Dalcin   Not Collective
28352d747510SLisandro Dalcin 
28362d747510SLisandro Dalcin   Input Parameters:
28372d747510SLisandro Dalcin + options - options database, use NULL for default global database
28382d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
28396b867d5aSJose E. Roman - name - the option one is seeking
28406b867d5aSJose E. Roman 
2841d8d19677SJose E. Roman   Output Parameters:
28422d747510SLisandro Dalcin + ivalue - the integer values to return
2843f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2844811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
28452d747510SLisandro Dalcin 
28462d747510SLisandro Dalcin   Level: beginner
28472d747510SLisandro Dalcin 
28482d747510SLisandro Dalcin   Notes:
28492d747510SLisandro Dalcin   The array can be passed as
2850811af0c4SBarry Smith +  a comma separated list -                                 0,1,2,3,4,5,6,7
2851811af0c4SBarry Smith .  a range (start\-end+1) -                                 0-8
2852811af0c4SBarry Smith .  a range with given increment (start\-end+1:inc) -        0-7:2
2853811af0c4SBarry Smith -  a combination of values and ranges separated by commas - 0,1-8,8-15:2
28542d747510SLisandro Dalcin 
28552d747510SLisandro Dalcin   There must be no intervening spaces between the values.
28562d747510SLisandro Dalcin 
2857db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2858db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2859db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2860c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2861db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2862db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
28632d747510SLisandro Dalcin @*/
2864d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
2865d71ae5a4SJacob Faibussowitsch {
28662d747510SLisandro Dalcin   const char *svalue;
28672d747510SLisandro Dalcin   char       *value;
28682d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
28692d747510SLisandro Dalcin   size_t      len;
28702d747510SLisandro Dalcin   PetscBool   flag, foundrange;
28712d747510SLisandro Dalcin   PetscToken  token;
28722d747510SLisandro Dalcin 
28732d747510SLisandro Dalcin   PetscFunctionBegin;
28742d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
28752d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
28762d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
28772d747510SLisandro Dalcin 
28789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28799371c9d4SSatish Balay   if (!flag || !svalue) {
28809371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28819371c9d4SSatish Balay     *nmax = 0;
28829371c9d4SSatish Balay     PetscFunctionReturn(0);
28839371c9d4SSatish Balay   }
28842d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28859566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28869566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28872d747510SLisandro Dalcin   while (value && n < *nmax) {
28882d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
28892d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
28909566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value, &len));
28912d747510SLisandro Dalcin     if (value[0] == '-') i = 2;
28922d747510SLisandro Dalcin     else i = 1;
28932d747510SLisandro Dalcin     for (; i < (int)len; i++) {
28942d747510SLisandro Dalcin       if (value[i] == '-') {
2895cc73adaaSBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
28962d747510SLisandro Dalcin         value[i] = 0;
28972d747510SLisandro Dalcin 
28989566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value, &start));
28992d747510SLisandro Dalcin         inc = 1;
29002d747510SLisandro Dalcin         j   = i + 1;
29012d747510SLisandro Dalcin         for (; j < (int)len; j++) {
29022d747510SLisandro Dalcin           if (value[j] == ':') {
29032d747510SLisandro Dalcin             value[j] = 0;
29042d747510SLisandro Dalcin 
29059566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value + j + 1, &inc));
290608401ef6SPierre 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);
29072d747510SLisandro Dalcin             break;
29082d747510SLisandro Dalcin           }
29092d747510SLisandro Dalcin         }
29109566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
291108401ef6SPierre 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);
29122d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
2913cc73adaaSBarry 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);
29142d747510SLisandro Dalcin         for (; start < end; start += inc) {
29159371c9d4SSatish Balay           *ivalue = start;
29169371c9d4SSatish Balay           ivalue++;
29179371c9d4SSatish Balay           n++;
29182d747510SLisandro Dalcin         }
29192d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
29202d747510SLisandro Dalcin         break;
29212d747510SLisandro Dalcin       }
29222d747510SLisandro Dalcin     }
29232d747510SLisandro Dalcin     if (!foundrange) {
29249566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
29252d747510SLisandro Dalcin       ivalue++;
29262d747510SLisandro Dalcin       n++;
29272d747510SLisandro Dalcin     }
29289566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29292d747510SLisandro Dalcin   }
29309566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29312d747510SLisandro Dalcin   *nmax = n;
29322d747510SLisandro Dalcin   PetscFunctionReturn(0);
29332d747510SLisandro Dalcin }
29342d747510SLisandro Dalcin 
29352d747510SLisandro Dalcin /*@C
29362d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
2937f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
29382d747510SLisandro Dalcin 
29392d747510SLisandro Dalcin   Not Collective
29402d747510SLisandro Dalcin 
29412d747510SLisandro Dalcin   Input Parameters:
29422d747510SLisandro Dalcin + options - options database, use NULL for default global database
29432d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
29446b867d5aSJose E. Roman - name - the option one is seeking
29456b867d5aSJose E. Roman 
29462d747510SLisandro Dalcin   Output Parameters:
29472d747510SLisandro Dalcin + dvalue - the double values to return
2948f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2949811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
29502d747510SLisandro Dalcin 
29512d747510SLisandro Dalcin   Level: beginner
29522d747510SLisandro Dalcin 
2953db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2954db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2955db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2956c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2957db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2958db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29592d747510SLisandro Dalcin @*/
2960d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
2961d71ae5a4SJacob Faibussowitsch {
29622d747510SLisandro Dalcin   const char *svalue;
29632d747510SLisandro Dalcin   char       *value;
29642d747510SLisandro Dalcin   PetscInt    n = 0;
29652d747510SLisandro Dalcin   PetscBool   flag;
29662d747510SLisandro Dalcin   PetscToken  token;
29672d747510SLisandro Dalcin 
29682d747510SLisandro Dalcin   PetscFunctionBegin;
29692d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
29702d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
29712d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
29722d747510SLisandro Dalcin 
29739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29749371c9d4SSatish Balay   if (!flag || !svalue) {
29759371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29769371c9d4SSatish Balay     *nmax = 0;
29779371c9d4SSatish Balay     PetscFunctionReturn(0);
29789371c9d4SSatish Balay   }
29792d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29809566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29819566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29822d747510SLisandro Dalcin   while (value && n < *nmax) {
29839566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
29849566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29852d747510SLisandro Dalcin     n++;
29862d747510SLisandro Dalcin   }
29879566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29882d747510SLisandro Dalcin   *nmax = n;
29892d747510SLisandro Dalcin   PetscFunctionReturn(0);
29902d747510SLisandro Dalcin }
29912d747510SLisandro Dalcin 
29922d747510SLisandro Dalcin /*@C
29932d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
2994f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
29952d747510SLisandro Dalcin 
29962d747510SLisandro Dalcin   Not Collective
29972d747510SLisandro Dalcin 
29982d747510SLisandro Dalcin   Input Parameters:
29992d747510SLisandro Dalcin + options - options database, use NULL for default global database
30002d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
30016b867d5aSJose E. Roman - name - the option one is seeking
30026b867d5aSJose E. Roman 
30032d747510SLisandro Dalcin   Output Parameters:
30042d747510SLisandro Dalcin + dvalue - the scalar values to return
3005f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3006811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
30072d747510SLisandro Dalcin 
30082d747510SLisandro Dalcin   Level: beginner
30092d747510SLisandro Dalcin 
3010db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3011db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3012db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3013c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3014db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3015db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30162d747510SLisandro Dalcin @*/
3017d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3018d71ae5a4SJacob Faibussowitsch {
30192d747510SLisandro Dalcin   const char *svalue;
30202d747510SLisandro Dalcin   char       *value;
30212d747510SLisandro Dalcin   PetscInt    n = 0;
30222d747510SLisandro Dalcin   PetscBool   flag;
30232d747510SLisandro Dalcin   PetscToken  token;
30242d747510SLisandro Dalcin 
30252d747510SLisandro Dalcin   PetscFunctionBegin;
30262d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
3027064a246eSJacob Faibussowitsch   PetscValidScalarPointer(dvalue, 4);
30282d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
30292d747510SLisandro Dalcin 
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(PetscOptionsStringToScalar(value, dvalue++));
30419566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30422d747510SLisandro Dalcin     n++;
30432d747510SLisandro Dalcin   }
30449566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30452d747510SLisandro Dalcin   *nmax = n;
30462d747510SLisandro Dalcin   PetscFunctionReturn(0);
30472d747510SLisandro Dalcin }
304814ce751eSBarry Smith 
3049e5c89e4eSSatish Balay /*@C
3050e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
3051f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
3052e5c89e4eSSatish Balay 
3053*cf53795eSBarry Smith   Not Collective; No Fortran Support
3054e5c89e4eSSatish Balay 
3055e5c89e4eSSatish Balay   Input Parameters:
30565c9cc608SHong Zhang + options - options database, use NULL for default global database
3057c5929fdfSBarry Smith . pre - string to prepend to name or NULL
30586b867d5aSJose E. Roman - name - the option one is seeking
30596b867d5aSJose E. Roman 
3060e7b76fa7SPatrick Sanan   Output Parameters:
3061e5c89e4eSSatish Balay + strings - location to copy strings
3062f1a722f8SMatthew G. Knepley . nmax - On input maximum number of strings, on output the actual number of strings found
3063811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3064e5c89e4eSSatish Balay 
3065e5c89e4eSSatish Balay   Level: beginner
3066e5c89e4eSSatish Balay 
3067e5c89e4eSSatish Balay   Notes:
3068e7b76fa7SPatrick Sanan   The nmax parameter is used for both input and output.
3069e7b76fa7SPatrick Sanan 
3070e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
3071e5c89e4eSSatish Balay   strings returned by this function.
3072e5c89e4eSSatish Balay 
3073e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3074*cf53795eSBarry Smith   returned.
3075e5c89e4eSSatish Balay 
3076db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3077db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3078db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3079c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3080db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3081db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3082e5c89e4eSSatish Balay @*/
3083d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set)
3084d71ae5a4SJacob Faibussowitsch {
30852d747510SLisandro Dalcin   const char *svalue;
3086e5c89e4eSSatish Balay   char       *value;
30872d747510SLisandro Dalcin   PetscInt    n = 0;
3088ace3abfcSBarry Smith   PetscBool   flag;
30899c9d3cfdSBarry Smith   PetscToken  token;
3090e5c89e4eSSatish Balay 
3091e5c89e4eSSatish Balay   PetscFunctionBegin;
30922d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
30932d747510SLisandro Dalcin   PetscValidPointer(strings, 4);
30942d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
3095e5c89e4eSSatish Balay 
30969566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30979371c9d4SSatish Balay   if (!flag || !svalue) {
30989371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30999371c9d4SSatish Balay     *nmax = 0;
31009371c9d4SSatish Balay     PetscFunctionReturn(0);
31019371c9d4SSatish Balay   }
31022d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31039566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31049566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31052d747510SLisandro Dalcin   while (value && n < *nmax) {
31069566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
31079566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3108e5c89e4eSSatish Balay     n++;
3109e5c89e4eSSatish Balay   }
31109566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3111e5c89e4eSSatish Balay   *nmax = n;
3112e5c89e4eSSatish Balay   PetscFunctionReturn(0);
3113e5c89e4eSSatish Balay }
311406824ed3SPatrick Sanan 
311506824ed3SPatrick Sanan /*@C
311606824ed3SPatrick Sanan    PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one
311706824ed3SPatrick Sanan 
311806824ed3SPatrick Sanan    Prints a deprecation warning, unless an option is supplied to suppress.
311906824ed3SPatrick Sanan 
31201c9f3c13SBarry Smith    Logically Collective
312106824ed3SPatrick Sanan 
312206824ed3SPatrick Sanan    Input Parameters:
31239503aa97SPatrick Sanan +  pre - string to prepend to name or NULL
312406824ed3SPatrick Sanan .  oldname - the old, deprecated option
312506824ed3SPatrick Sanan .  newname - the new option, or NULL if option is purely removed
31269f3a6782SPatrick Sanan .  version - a string describing the version of first deprecation, e.g. "3.9"
31279f3a6782SPatrick Sanan -  info - additional information string, or NULL.
312806824ed3SPatrick Sanan 
3129811af0c4SBarry Smith    Options Database Key:
313006824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
313106824ed3SPatrick Sanan 
313206824ed3SPatrick Sanan    Notes:
3133811af0c4SBarry Smith    Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
3134811af0c4SBarry Smith    Only the proces of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3135811af0c4SBarry Smith    `PetscObjectOptionsBegin()` prints the information
3136b40114eaSPatrick Sanan    If newname is provided, the old option is replaced. Otherwise, it remains
3137b40114eaSPatrick Sanan    in the options database.
31389f3a6782SPatrick Sanan    If an option is not replaced, the info argument should be used to advise the user
31399f3a6782SPatrick Sanan    on how to proceed.
31409f3a6782SPatrick Sanan    There is a limit on the length of the warning printed, so very long strings
31419f3a6782SPatrick Sanan    provided as info may be truncated.
314206824ed3SPatrick Sanan 
314306824ed3SPatrick Sanan    Level: developer
314406824ed3SPatrick Sanan 
3145db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
314606824ed3SPatrick Sanan @*/
3147d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3148d71ae5a4SJacob Faibussowitsch {
314906824ed3SPatrick Sanan   PetscBool         found, quiet;
315006824ed3SPatrick Sanan   const char       *value;
315106824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
31529f3a6782SPatrick Sanan   char              msg[4096];
3153b0bdc838SStefano Zampini   char             *prefix  = NULL;
3154b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3155b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
315606824ed3SPatrick Sanan 
315706824ed3SPatrick Sanan   PetscFunctionBegin;
315806824ed3SPatrick Sanan   PetscValidCharPointer(oldname, 2);
315906824ed3SPatrick Sanan   PetscValidCharPointer(version, 4);
3160b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3161b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3162b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3163b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3164b0bdc838SStefano Zampini   }
31659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
316606824ed3SPatrick Sanan   if (found) {
316706824ed3SPatrick Sanan     if (newname) {
31681baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
31699566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options, newname, value));
31701baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
31719566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3172b40114eaSPatrick Sanan     }
317306824ed3SPatrick Sanan     quiet = PETSC_FALSE;
31749566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
317506824ed3SPatrick Sanan     if (!quiet) {
31769566063dSJacob Faibussowitsch       PetscCall(PetscStrcpy(msg, "** PETSc DEPRECATION WARNING ** : the option "));
31779566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, oldname));
31789566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, " is deprecated as of version "));
31799566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, version));
31809566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, " and will be removed in a future release."));
318106824ed3SPatrick Sanan       if (newname) {
31829566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, " Please use the option "));
31839566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, newname));
31849566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, " instead."));
318506824ed3SPatrick Sanan       }
31869f3a6782SPatrick Sanan       if (info) {
31879566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, " "));
31889566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg, info));
31899f3a6782SPatrick Sanan       }
31909566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, " (Silence this warning with "));
31919566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, quietopt));
31929566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg, ")\n"));
31939566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
319406824ed3SPatrick Sanan     }
319506824ed3SPatrick Sanan   }
319606824ed3SPatrick Sanan   PetscFunctionReturn(0);
319706824ed3SPatrick Sanan }
3198