xref: /petsc/src/sys/objects/options.c (revision 7d44c3adfb2b65cbfb048a2ae6ccb621faa65e99)
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 
6174e0666dSJed Brown #define MAXPREFIXES        25
622d747510SLisandro Dalcin #define MAXOPTIONSMONITORS 5
63e5c89e4eSSatish Balay 
649355ec05SMatthew G. Knepley const char *PetscOptionSources[] = {"code", "command line", "file", "environment"};
659355ec05SMatthew G. Knepley 
669355ec05SMatthew G. Knepley // This table holds all the options set by the user
674416b707SBarry Smith struct _n_PetscOptions {
683de2bfdfSBarry Smith   PetscOptions previous;
699355ec05SMatthew G. Knepley 
702d747510SLisandro Dalcin   int                N;      /* number of options */
719355ec05SMatthew G. Knepley   int                Nalloc; /* number of allocated options */
729355ec05SMatthew G. Knepley   char             **names;  /* option names */
739355ec05SMatthew G. Knepley   char             **values; /* option values */
749355ec05SMatthew G. Knepley   PetscBool         *used;   /* flag option use */
759355ec05SMatthew G. Knepley   PetscOptionSource *source; /* source for option value */
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];
849355ec05SMatthew G. Knepley   char prefix[PETSC_MAX_OPTION_NAME];
852d747510SLisandro Dalcin 
862d747510SLisandro Dalcin   /* Aliases */
879355ec05SMatthew G. Knepley   int    Na;       /* number or aliases */
889355ec05SMatthew G. Knepley   int    Naalloc;  /* number of allocated aliases */
899355ec05SMatthew G. Knepley   char **aliases1; /* aliased */
909355ec05SMatthew G. Knepley   char **aliases2; /* aliasee */
912d747510SLisandro Dalcin 
922d747510SLisandro Dalcin   /* Help */
932d747510SLisandro Dalcin   PetscBool help;       /* flag whether "-help" is in the database */
94d314f959SVaclav Hapla   PetscBool help_intro; /* flag whether "-help intro" is in the database */
952d747510SLisandro Dalcin 
962d747510SLisandro Dalcin   /* Monitors */
97c5b5d8d5SVaclav Hapla   PetscBool monitorFromOptions, monitorCancel;
989355ec05SMatthew G. Knepley   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], PetscOptionSource, void *); /* returns control to user after */
999355ec05SMatthew G. Knepley   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void **);                                        /* callback for monitor destruction */
100081c24baSBoyana Norris   void    *monitorcontext[MAXOPTIONSMONITORS];                                                          /* to pass arbitrary user data into monitor */
101081c24baSBoyana Norris   PetscInt numbermonitors;                                                                              /* to, for instance, detect options being set */
1024416b707SBarry Smith };
103e5c89e4eSSatish Balay 
104b4205f0bSBarry Smith static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
1052d747510SLisandro Dalcin 
106aaa8cc7dSPierre Jolivet /* list of options which precede others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
107660278c0SBarry Smith /* these options can only take boolean values, the code will crash if given a non-boolean value */
108660278c0SBarry Smith static const char *precedentOptions[] = {"-petsc_ci", "-options_monitor", "-options_monitor_cancel", "-help", "-skip_petscrc"};
1099371c9d4SSatish Balay enum PetscPrecedentOption {
1109371c9d4SSatish Balay   PO_CI_ENABLE,
1119371c9d4SSatish Balay   PO_OPTIONS_MONITOR,
1129371c9d4SSatish Balay   PO_OPTIONS_MONITOR_CANCEL,
1139371c9d4SSatish Balay   PO_HELP,
1149371c9d4SSatish Balay   PO_SKIP_PETSCRC,
1159371c9d4SSatish Balay   PO_NUM
1169371c9d4SSatish Balay };
117c5b5d8d5SVaclav Hapla 
1189355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsSetValue_Private(PetscOptions, const char[], const char[], int *, PetscOptionSource);
1199355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsInsertStringYAML_Private(PetscOptions, const char[], PetscOptionSource);
120c5b5d8d5SVaclav Hapla 
121081c24baSBoyana Norris /*
122081c24baSBoyana Norris     Options events monitor
123081c24baSBoyana Norris */
1249355ec05SMatthew G. Knepley static PetscErrorCode PetscOptionsMonitor(PetscOptions options, const char name[], const char value[], PetscOptionSource source)
125d71ae5a4SJacob Faibussowitsch {
126e5c89e4eSSatish Balay   PetscFunctionBegin;
127c5b5d8d5SVaclav Hapla   if (!value) value = "";
1289355ec05SMatthew G. Knepley   if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name, value, source, NULL));
1299355ec05SMatthew G. Knepley   for (PetscInt i = 0; i < options->numbermonitors; i++) PetscCall((*options->monitor[i])(name, value, source, options->monitorcontext[i]));
1303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
131e5c89e4eSSatish Balay }
132e5c89e4eSSatish Balay 
1332d747510SLisandro Dalcin /*@
1342d747510SLisandro Dalcin    PetscOptionsCreate - Creates an empty options database.
135e5c89e4eSSatish Balay 
13620f4b53cSBarry Smith    Logically Collective
1371c9f3c13SBarry Smith 
138e5c89e4eSSatish Balay    Output Parameter:
1392d747510SLisandro Dalcin .  options - Options database object
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay    Level: advanced
142e5c89e4eSSatish Balay 
143811af0c4SBarry Smith    Note:
144811af0c4SBarry Smith    Though PETSc has a concept of multiple options database the current code uses a single default `PetscOptions` object
145811af0c4SBarry Smith 
146811af0c4SBarry Smith    Developer Notes:
147811af0c4SBarry Smith    We may want eventually to pass a `MPI_Comm` to determine the ownership of the object
148811af0c4SBarry Smith 
149811af0c4SBarry Smith    This object never got developed after being introduced, it is not clear that supporting multiple `PetscOptions` objects is useful
1501c9f3c13SBarry Smith 
151db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
152e5c89e4eSSatish Balay @*/
153d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreate(PetscOptions *options)
154d71ae5a4SJacob Faibussowitsch {
15539a651e2SJacob Faibussowitsch   PetscFunctionBegin;
15639a651e2SJacob Faibussowitsch   PetscValidPointer(options, 1);
1572d747510SLisandro Dalcin   *options = (PetscOptions)calloc(1, sizeof(**options));
15839a651e2SJacob Faibussowitsch   PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
1593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1602d747510SLisandro Dalcin }
1612d747510SLisandro Dalcin 
1622d747510SLisandro Dalcin /*@
1632d747510SLisandro Dalcin     PetscOptionsDestroy - Destroys an option database.
1642d747510SLisandro Dalcin 
16520f4b53cSBarry Smith     Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
1661c9f3c13SBarry Smith 
1672d747510SLisandro Dalcin   Input Parameter:
168811af0c4SBarry Smith .  options - the `PetscOptions` object
1692d747510SLisandro Dalcin 
1703de2bfdfSBarry Smith    Level: advanced
1712d747510SLisandro Dalcin 
172db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
1732d747510SLisandro Dalcin @*/
174d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
175d71ae5a4SJacob Faibussowitsch {
176362febeeSStefano Zampini   PetscFunctionBegin;
1773ba16761SJacob Faibussowitsch   if (!*options) PetscFunctionReturn(PETSC_SUCCESS);
1785f80ce2aSJacob 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()");
1799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsClear(*options));
1802d747510SLisandro Dalcin   /* XXX what about monitors ? */
1812800570dSLisandro Dalcin   free(*options);
1822d747510SLisandro Dalcin   *options = NULL;
1833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
184e5c89e4eSSatish Balay }
185e5c89e4eSSatish Balay 
1862d747510SLisandro Dalcin /*
1872d747510SLisandro Dalcin     PetscOptionsCreateDefault - Creates the default global options database
1882d747510SLisandro Dalcin */
189d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreateDefault(void)
190d71ae5a4SJacob Faibussowitsch {
19139a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1929566063dSJacob Faibussowitsch   if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
1933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1942d747510SLisandro Dalcin }
1952d747510SLisandro Dalcin 
196b4205f0bSBarry Smith /*@
197811af0c4SBarry Smith       PetscOptionsPush - Push a new `PetscOptions` object as the default provider of options
1981c9f3c13SBarry Smith                          Allows using different parts of a code to use different options databases
199b4205f0bSBarry Smith 
200b4205f0bSBarry Smith   Logically Collective
201b4205f0bSBarry Smith 
202b4205f0bSBarry Smith   Input Parameter:
203811af0c4SBarry Smith .   opt - the options obtained with `PetscOptionsCreate()`
204b4205f0bSBarry Smith 
20520f4b53cSBarry Smith    Level: advanced
20620f4b53cSBarry Smith 
207b4205f0bSBarry Smith   Notes:
208811af0c4SBarry Smith   Use `PetscOptionsPop()` to return to the previous default options database
2091c9f3c13SBarry Smith 
210811af0c4SBarry Smith   The collectivity of this routine is complex; only the MPI ranks that call this routine will
2111c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
2121c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
2131c9f3c13SBarry Smith   on different ranks.
214b4205f0bSBarry Smith 
215811af0c4SBarry Smith   Developer Note:
216811af0c4SBarry Smith   Though this functionality has been provided it has never been used in PETSc and might be removed.
217811af0c4SBarry Smith 
218db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
219b4205f0bSBarry Smith @*/
220d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPush(PetscOptions opt)
221d71ae5a4SJacob Faibussowitsch {
222b4205f0bSBarry Smith   PetscFunctionBegin;
2239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsCreateDefault());
224b4205f0bSBarry Smith   opt->previous  = defaultoptions;
225b4205f0bSBarry Smith   defaultoptions = opt;
2263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
227b4205f0bSBarry Smith }
228b4205f0bSBarry Smith 
229b4205f0bSBarry Smith /*@
230811af0c4SBarry Smith       PetscOptionsPop - Pop the most recent `PetscOptionsPush()` to return to the previous default options
231b4205f0bSBarry Smith 
23220f4b53cSBarry Smith       Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
233b4205f0bSBarry Smith 
2343de2bfdfSBarry Smith    Level: advanced
2353de2bfdfSBarry Smith 
236db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
237b4205f0bSBarry Smith @*/
238d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPop(void)
239d71ae5a4SJacob Faibussowitsch {
2403de2bfdfSBarry Smith   PetscOptions current = defaultoptions;
2413de2bfdfSBarry Smith 
242b4205f0bSBarry Smith   PetscFunctionBegin;
24328b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing default options");
24428b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions->previous, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscOptionsPop() called too many times");
245b4205f0bSBarry Smith   defaultoptions    = defaultoptions->previous;
2463de2bfdfSBarry Smith   current->previous = NULL;
2473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
248b4205f0bSBarry Smith }
249b4205f0bSBarry Smith 
2502d747510SLisandro Dalcin /*
2512d747510SLisandro Dalcin     PetscOptionsDestroyDefault - Destroys the default global options database
2522d747510SLisandro Dalcin */
253d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroyDefault(void)
254d71ae5a4SJacob Faibussowitsch {
25539a651e2SJacob Faibussowitsch   PetscFunctionBegin;
2563ba16761SJacob Faibussowitsch   if (!defaultoptions) PetscFunctionReturn(PETSC_SUCCESS);
2573de2bfdfSBarry Smith   /* Destroy any options that the user forgot to pop */
2583de2bfdfSBarry Smith   while (defaultoptions->previous) {
25939a651e2SJacob Faibussowitsch     PetscOptions tmp = defaultoptions;
26039a651e2SJacob Faibussowitsch 
2619566063dSJacob Faibussowitsch     PetscCall(PetscOptionsPop());
2629566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDestroy(&tmp));
2633de2bfdfSBarry Smith   }
2649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDestroy(&defaultoptions));
2653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
266e5c89e4eSSatish Balay }
267e5c89e4eSSatish Balay 
26894ef8ddeSSatish Balay /*@C
2697cd08cecSJed Brown    PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
2703fc1eb6aSBarry Smith 
27120f4b53cSBarry Smith    Not Collective
2721c9f3c13SBarry Smith 
2733fc1eb6aSBarry Smith    Input Parameter:
2742d747510SLisandro Dalcin .  key - string to check if valid
2753fc1eb6aSBarry Smith 
2763fc1eb6aSBarry Smith    Output Parameter:
277811af0c4SBarry Smith .  valid - `PETSC_TRUE` if a valid key
2783fc1eb6aSBarry Smith 
279f6680f47SSatish Balay    Level: intermediate
2803fc1eb6aSBarry Smith @*/
281d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid)
282d71ae5a4SJacob Faibussowitsch {
283f603b5e9SToby Isaac   char *ptr;
2847c5db45bSBarry Smith 
28596fc60bcSBarry Smith   PetscFunctionBegin;
2862d747510SLisandro Dalcin   if (key) PetscValidCharPointer(key, 1);
287dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(valid, 2);
2882d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2893ba16761SJacob Faibussowitsch   if (!key) PetscFunctionReturn(PETSC_SUCCESS);
2903ba16761SJacob Faibussowitsch   if (key[0] != '-') PetscFunctionReturn(PETSC_SUCCESS);
2912d747510SLisandro Dalcin   if (key[1] == '-') key++;
2923ba16761SJacob Faibussowitsch   if (!isalpha((int)key[1])) PetscFunctionReturn(PETSC_SUCCESS);
2932d747510SLisandro Dalcin   (void)strtod(key, &ptr);
2943ba16761SJacob Faibussowitsch   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(PETSC_SUCCESS);
2952d747510SLisandro Dalcin   *valid = PETSC_TRUE;
2963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29796fc60bcSBarry Smith }
29896fc60bcSBarry Smith 
2999355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsInsertString_Private(PetscOptions options, const char in_str[], PetscOptionSource source)
300d71ae5a4SJacob Faibussowitsch {
301d06005cbSLisandro Dalcin   MPI_Comm   comm = PETSC_COMM_SELF;
302d06005cbSLisandro Dalcin   char      *first, *second;
3039c9d3cfdSBarry Smith   PetscToken token;
304e5c89e4eSSatish Balay 
305e5c89e4eSSatish Balay   PetscFunctionBegin;
3069566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(in_str, ' ', &token));
3079566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &first));
30896fc60bcSBarry Smith   while (first) {
309d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
3109566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
3119566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
3129566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
3139566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
3149566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
3159566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(first, &key));
316d06005cbSLisandro Dalcin     if (!key) {
3179566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
318d06005cbSLisandro Dalcin     } else if (isfile) {
3199566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3209566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, second, PETSC_TRUE));
3219566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
322d06005cbSLisandro Dalcin     } else if (isfileyaml) {
3239566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3249566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, second, PETSC_TRUE));
3259566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
326d06005cbSLisandro Dalcin     } else if (isstringyaml) {
3279566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3289355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, second, source));
3299566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
330d06005cbSLisandro Dalcin     } else if (ispush) {
3319566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3329566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, second));
3339566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
3349db968c8SJed Brown     } else if (ispop) {
3359566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
3369566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
337d06005cbSLisandro Dalcin     } else {
3389566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3399566063dSJacob Faibussowitsch       PetscCall(PetscOptionsValidKey(second, &key));
34096fc60bcSBarry Smith       if (!key) {
3419355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, second, NULL, source));
3429566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &first));
34396fc60bcSBarry Smith       } else {
3449355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, NULL, NULL, source));
34596fc60bcSBarry Smith         first = second;
34696fc60bcSBarry Smith       }
347e5c89e4eSSatish Balay     }
348e5c89e4eSSatish Balay   }
3499566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
351e5c89e4eSSatish Balay }
352e5c89e4eSSatish Balay 
3539355ec05SMatthew G. Knepley /*@C
3549355ec05SMatthew G. Knepley    PetscOptionsInsertString - Inserts options into the database from a string
3559355ec05SMatthew G. Knepley 
3569355ec05SMatthew G. Knepley    Logically Collective
3579355ec05SMatthew G. Knepley 
3589355ec05SMatthew G. Knepley    Input Parameters:
3599355ec05SMatthew G. Knepley +  options - options object
3609355ec05SMatthew G. Knepley -  in_str - string that contains options separated by blanks
3619355ec05SMatthew G. Knepley 
3629355ec05SMatthew G. Knepley    Level: intermediate
3639355ec05SMatthew G. Knepley 
36420f4b53cSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
3659355ec05SMatthew G. Knepley   have the affect of these options. If some processes that create objects call this routine and others do
3669355ec05SMatthew G. Knepley   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
3679355ec05SMatthew G. Knepley   on different ranks.
3689355ec05SMatthew G. Knepley 
3699355ec05SMatthew G. Knepley    Contributed by Boyana Norris
3709355ec05SMatthew G. Knepley 
3719355ec05SMatthew G. Knepley .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
3729355ec05SMatthew G. Knepley           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3739355ec05SMatthew G. Knepley           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3749355ec05SMatthew G. Knepley           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3759355ec05SMatthew G. Knepley           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3769355ec05SMatthew G. Knepley           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
3779355ec05SMatthew G. Knepley @*/
3789355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[])
3799355ec05SMatthew G. Knepley {
3809355ec05SMatthew G. Knepley   PetscFunctionBegin;
3819355ec05SMatthew G. Knepley   PetscCall(PetscOptionsInsertString_Private(options, in_str, PETSC_OPT_CODE));
3823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3839355ec05SMatthew G. Knepley }
3849355ec05SMatthew G. Knepley 
3853fc1eb6aSBarry Smith /*
3863fc1eb6aSBarry Smith     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
3873fc1eb6aSBarry Smith */
388d71ae5a4SJacob Faibussowitsch static char *Petscgetline(FILE *f)
389d71ae5a4SJacob Faibussowitsch {
3905fa91da5SBarry Smith   size_t size = 0;
3915fa91da5SBarry Smith   size_t len  = 0;
3925fa91da5SBarry Smith   size_t last = 0;
3930298fd71SBarry Smith   char  *buf  = NULL;
3945fa91da5SBarry Smith 
39502c9f0b5SLisandro Dalcin   if (feof(f)) return NULL;
3965fa91da5SBarry Smith   do {
3975fa91da5SBarry Smith     size += 1024;                             /* BUFSIZ is defined as "the optimal read size for this platform" */
3986e0c8459SSatish Balay     buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
3995fa91da5SBarry Smith     /* Actually do the read. Note that fgets puts a terminal '\0' on the
4005fa91da5SBarry Smith     end of the string, so we make sure we overwrite this */
401e86f3e45SDave May     if (!fgets(buf + len, 1024, f)) buf[len] = 0;
4023ba16761SJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, PetscStrlen(buf, &len));
4035fa91da5SBarry Smith     last = len - 1;
4045fa91da5SBarry Smith   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
40508ac41f7SSatish Balay   if (len) return buf;
4065fa91da5SBarry Smith   free(buf);
40702c9f0b5SLisandro Dalcin   return NULL;
4085fa91da5SBarry Smith }
4095fa91da5SBarry Smith 
410d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml)
411d71ae5a4SJacob Faibussowitsch {
412be10d61cSLisandro Dalcin   char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
413e5c89e4eSSatish Balay 
414be10d61cSLisandro Dalcin   PetscFunctionBegin;
415362febeeSStefano Zampini   *yaml = PETSC_FALSE;
4169566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
4179566063dSJacob Faibussowitsch   PetscCall(PetscFixFilename(fname, path));
4189566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(path, ":yaml", yaml));
419be10d61cSLisandro Dalcin   if (*yaml) {
4209566063dSJacob Faibussowitsch     PetscCall(PetscStrrchr(path, ':', &tail));
421be10d61cSLisandro Dalcin     tail[-1] = 0; /* remove ":yaml" suffix from path */
422be10d61cSLisandro Dalcin   }
4239566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
424a1d2f846SLisandro Dalcin   /* check for standard YAML and JSON filename extensions */
4259566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
4269566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
4279566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
428a1d2f846SLisandro Dalcin   if (!*yaml) { /* check file contents */
429a1d2f846SLisandro Dalcin     PetscMPIInt rank;
4309566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
431dd400576SPatrick Sanan     if (rank == 0) {
432a1d2f846SLisandro Dalcin       FILE *fh = fopen(filename, "r");
433a1d2f846SLisandro Dalcin       if (fh) {
434a1d2f846SLisandro Dalcin         char buf[6] = "";
435a1d2f846SLisandro Dalcin         if (fread(buf, 1, 6, fh) > 0) {
4369566063dSJacob Faibussowitsch           PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml));          /* check for '%YAML' tag */
4379566063dSJacob Faibussowitsch           if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
438a1d2f846SLisandro Dalcin         }
439a1d2f846SLisandro Dalcin         (void)fclose(fh);
440a1d2f846SLisandro Dalcin       }
441a1d2f846SLisandro Dalcin     }
4429566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(yaml, 1, MPIU_BOOL, 0, comm));
443a1d2f846SLisandro Dalcin   }
4443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
445be10d61cSLisandro Dalcin }
446e5c89e4eSSatish Balay 
447d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
448d71ae5a4SJacob Faibussowitsch {
4498c0b561eSLisandro Dalcin   char       *string, *vstring = NULL, *astring = NULL, *packed = NULL;
4507fb43599SVaclav Hapla   char       *tokens[4];
45113e3f751SJed Brown   size_t      i, len, bytes;
452e5c89e4eSSatish Balay   FILE       *fd;
4537fb43599SVaclav Hapla   PetscToken  token = NULL;
454ed9cf6e9SBarry Smith   int         err;
455bbcf679cSJacob Faibussowitsch   char       *cmatch = NULL;
456581bbe83SVaclav Hapla   const char  cmt    = '#';
4579210b8eaSVaclav Hapla   PetscInt    line   = 1;
4583a018368SJed Brown   PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
4599210b8eaSVaclav Hapla   PetscBool   isdir, alias = PETSC_FALSE, valid;
460e5c89e4eSSatish Balay 
461e5c89e4eSSatish Balay   PetscFunctionBegin;
4629566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tokens, sizeof(tokens)));
4639566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
464dd400576SPatrick Sanan   if (rank == 0) {
4658c0b561eSLisandro Dalcin     char fpath[PETSC_MAX_PATH_LEN];
4668c0b561eSLisandro Dalcin     char fname[PETSC_MAX_PATH_LEN];
46705c7dedfSBarry Smith 
4689566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
4699566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
4708c0b561eSLisandro Dalcin 
471e5c89e4eSSatish Balay     fd = fopen(fname, "r");
4729566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname, 'r', &isdir));
47308401ef6SPierre Jolivet     PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
474ad38b122SPatrick Sanan     if (fd && !isdir) {
4753a018368SJed Brown       PetscSegBuffer vseg, aseg;
4769566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4779566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4783a018368SJed Brown 
4799b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4809566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
481e24ecc5dSJed Brown 
4825fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4834704e885SBarry Smith         /* eliminate comments from each line */
4849566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
48590f79514SSatish Balay         if (cmatch) *cmatch = 0;
4869566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4875981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
488e5c89e4eSSatish Balay         for (i = 0; i < len; i++) {
489ad540459SPierre Jolivet           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
490e5c89e4eSSatish Balay         }
4919566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4929566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4937fb43599SVaclav Hapla         if (!tokens[0]) {
49402b0d46eSSatish Balay           goto destroy;
4957fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
4969566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
49790f79514SSatish Balay         }
49848a46eb9SPierre Jolivet         for (i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
4997fb43599SVaclav Hapla         if (!tokens[0]) {
5002662f744SSatish Balay           goto destroy;
5017fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
5029566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
50328b400f6SJacob 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]);
5049566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
5059566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
5069566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
507e24ecc5dSJed Brown           vstring[len] = ' ';
5087fb43599SVaclav Hapla           if (tokens[1]) {
5099566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
51028b400f6SJacob 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]);
5119566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5129566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
513e24ecc5dSJed Brown             vstring[0] = '"';
5149566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
515e24ecc5dSJed Brown             vstring[len + 1] = '"';
516e24ecc5dSJed Brown             vstring[len + 2] = ' ';
51709192fe3SBarry Smith           }
51890f79514SSatish Balay         } else {
5199566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
5209210b8eaSVaclav Hapla           if (alias) {
5219566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
52228b400f6SJacob 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]);
52308401ef6SPierre 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]);
5249566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
52528b400f6SJacob 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]);
5269566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5279566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5289566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
529e24ecc5dSJed Brown             astring[len] = ' ';
530e24ecc5dSJed Brown 
5319566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5329566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5339566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
534e24ecc5dSJed Brown             astring[len] = ' ';
53598921bdaSJacob 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]);
5369210b8eaSVaclav Hapla         }
5379210b8eaSVaclav Hapla         {
5389210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
53928b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
540e5c89e4eSSatish Balay         }
54102b0d46eSSatish Balay       destroy:
5424b40f50bSBarry Smith         free(string);
5439566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5449210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5459210b8eaSVaclav Hapla         line++;
546e5c89e4eSSatish Balay       }
547ed9cf6e9SBarry Smith       err = fclose(fd);
54828b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5499566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5509566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5519566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
552e24ecc5dSJed Brown       astring[0] = 0;
5539566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5549566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5559566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
556e24ecc5dSJed Brown       vstring[0] = 0;
5579566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5589566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5599566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5609566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5619566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
56228b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5639b754dc9SBarry Smith   }
56405c7dedfSBarry Smith 
5653a018368SJed Brown   counts[0] = acnt;
5663a018368SJed Brown   counts[1] = cnt;
5674201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
56828b400f6SJacob 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/");
5693a018368SJed Brown   acnt = counts[0];
5703a018368SJed Brown   cnt  = counts[1];
57148a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5723a018368SJed Brown   if (acnt || cnt) {
5739566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5743a018368SJed Brown     astring = packed;
5753a018368SJed Brown     vstring = packed + acnt + 1;
5763a018368SJed Brown   }
5773a018368SJed Brown 
5789b754dc9SBarry Smith   if (acnt) {
5799566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5809566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5817fb43599SVaclav Hapla     while (tokens[0]) {
5829566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5839566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5849566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5859b754dc9SBarry Smith     }
5869566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5879b754dc9SBarry Smith   }
5889b754dc9SBarry Smith 
5899355ec05SMatthew G. Knepley   if (cnt) PetscCall(PetscOptionsInsertString_Private(options, vstring, PETSC_OPT_FILE));
5909566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
5913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
592e5c89e4eSSatish Balay }
593e5c89e4eSSatish Balay 
594d06005cbSLisandro Dalcin /*@C
595be10d61cSLisandro Dalcin      PetscOptionsInsertFile - Inserts options into the database from a file.
596be10d61cSLisandro Dalcin 
597be10d61cSLisandro Dalcin      Collective
598be10d61cSLisandro Dalcin 
599d8d19677SJose E. Roman   Input Parameters:
600811af0c4SBarry Smith +   comm - the processes that will share the options (usually `PETSC_COMM_WORLD`)
60120f4b53cSBarry Smith .   options - options database, use `NULL` for default global database
602be10d61cSLisandro Dalcin .   file - name of file,
603be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
604be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
605811af0c4SBarry Smith -   require - if `PETSC_TRUE` will generate an error if the file does not exist
606be10d61cSLisandro Dalcin 
60720f4b53cSBarry Smith   Level: developer
60820f4b53cSBarry Smith 
609be10d61cSLisandro Dalcin   Notes:
610be10d61cSLisandro Dalcin    Use  # for lines that are comments and which should be ignored.
611811af0c4SBarry Smith    Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
61221532e8aSBarry Smith    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
61321532e8aSBarry Smith    calls to `XXXSetFromOptions()`, it should not be used for options listed under PetscInitialize().
61421532e8aSBarry Smith    The collectivity of this routine is complex; only the MPI processes in comm will
61521532e8aSBarry Smith    have the effect of these options. If some processes that create objects call this routine and others do
616be10d61cSLisandro Dalcin    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
617be10d61cSLisandro Dalcin    on different ranks.
618be10d61cSLisandro Dalcin 
619db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
620db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
621db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
622c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
623db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
624db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
625be10d61cSLisandro Dalcin @*/
626d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
627d71ae5a4SJacob Faibussowitsch {
628be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
629be10d61cSLisandro Dalcin   PetscBool yaml;
630be10d61cSLisandro Dalcin 
631be10d61cSLisandro Dalcin   PetscFunctionBegin;
6329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
633be10d61cSLisandro Dalcin   if (yaml) {
6349566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
635be10d61cSLisandro Dalcin   } else {
6369566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
637be10d61cSLisandro Dalcin   }
6383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
639be10d61cSLisandro Dalcin }
640be10d61cSLisandro Dalcin 
641be10d61cSLisandro Dalcin /*@C
642d06005cbSLisandro Dalcin    PetscOptionsInsertArgs - Inserts options into the database from a array of strings
643d06005cbSLisandro Dalcin 
644d06005cbSLisandro Dalcin    Logically Collective
645d06005cbSLisandro Dalcin 
646d8d19677SJose E. Roman    Input Parameters:
647d06005cbSLisandro Dalcin +  options - options object
6486aad120cSJose E. Roman .  argc - the array length
649d06005cbSLisandro Dalcin -  args - the string array
650d06005cbSLisandro Dalcin 
651d06005cbSLisandro Dalcin    Level: intermediate
652d06005cbSLisandro Dalcin 
653db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
654d06005cbSLisandro Dalcin @*/
655d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, char *args[])
656d71ae5a4SJacob Faibussowitsch {
657d06005cbSLisandro Dalcin   MPI_Comm     comm  = PETSC_COMM_WORLD;
658d06005cbSLisandro Dalcin   int          left  = PetscMax(argc, 0);
659d06005cbSLisandro Dalcin   char *const *eargs = args;
66085079163SJed Brown 
66185079163SJed Brown   PetscFunctionBegin;
66285079163SJed Brown   while (left) {
663d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6649566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6659566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6669566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6679566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6689566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6699566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
670093de6efSBarry Smith     if (!key) {
6719371c9d4SSatish Balay       eargs++;
6729371c9d4SSatish Balay       left--;
673d06005cbSLisandro Dalcin     } else if (isfile) {
674cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6759566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6769371c9d4SSatish Balay       eargs += 2;
6779371c9d4SSatish Balay       left -= 2;
678d06005cbSLisandro Dalcin     } else if (isfileyaml) {
679cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6809566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6819371c9d4SSatish Balay       eargs += 2;
6829371c9d4SSatish Balay       left -= 2;
683d06005cbSLisandro Dalcin     } else if (isstringyaml) {
684cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6859355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
6869371c9d4SSatish Balay       eargs += 2;
6879371c9d4SSatish Balay       left -= 2;
688d06005cbSLisandro Dalcin     } else if (ispush) {
68908401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
690cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6919566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6929371c9d4SSatish Balay       eargs += 2;
6939371c9d4SSatish Balay       left -= 2;
694d06005cbSLisandro Dalcin     } else if (ispop) {
6959566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
6969371c9d4SSatish Balay       eargs++;
6979371c9d4SSatish Balay       left--;
6987935c3d8SJed Brown     } else {
6997935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
7009566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
70198b6bf53SJed Brown       if (left < 2 || nextiskey) {
7029355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
7039371c9d4SSatish Balay         eargs++;
7049371c9d4SSatish Balay         left--;
70585079163SJed Brown       } else {
7069355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
7079371c9d4SSatish Balay         eargs += 2;
7089371c9d4SSatish Balay         left -= 2;
70985079163SJed Brown       }
71085079163SJed Brown     }
7117935c3d8SJed Brown   }
7123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71385079163SJed Brown }
71485079163SJed Brown 
715d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], PetscBool set[], PetscBool *flg)
716d71ae5a4SJacob Faibussowitsch {
717c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
718c5b5d8d5SVaclav Hapla   if (set[opt]) {
7199566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
720c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
7213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
722c5b5d8d5SVaclav Hapla }
723c5b5d8d5SVaclav Hapla 
724660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
725d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
726d71ae5a4SJacob Faibussowitsch {
727c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
728c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
729c5b5d8d5SVaclav Hapla   size_t             o;
730c5b5d8d5SVaclav Hapla   int                a;
731c5b5d8d5SVaclav Hapla   const char       **val;
7320c99d500SBarry Smith   char             **cval;
733660278c0SBarry Smith   PetscBool         *set, unneeded;
734c5b5d8d5SVaclav Hapla 
735c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7360c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7370c99d500SBarry Smith   val = (const char **)cval;
738c5b5d8d5SVaclav Hapla 
739c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
74048a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
741c5b5d8d5SVaclav Hapla 
742a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
743c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
744c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
745c5b5d8d5SVaclav Hapla 
7469566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
747c5b5d8d5SVaclav Hapla     if (!valid) continue;
748c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7499566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
750c5b5d8d5SVaclav Hapla       if (eq) {
751c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
752c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
753c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
754c5b5d8d5SVaclav Hapla         break;
755c5b5d8d5SVaclav Hapla       }
756c5b5d8d5SVaclav Hapla     }
757c5b5d8d5SVaclav Hapla   }
758c5b5d8d5SVaclav Hapla 
759c5b5d8d5SVaclav Hapla   /* Process flags */
7609566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
761d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7629566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
763660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
764660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
7659355ec05SMatthew G. Knepley   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
7669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
769c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
770c5b5d8d5SVaclav Hapla 
771c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
772660278c0SBarry Smith   for (o = 1; o < n; o++) {
773c5b5d8d5SVaclav Hapla     if (set[o]) {
7749355ec05SMatthew G. Knepley       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
775d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
776c5b5d8d5SVaclav Hapla     }
777c5b5d8d5SVaclav Hapla   }
7780c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
779c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
7803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
781c5b5d8d5SVaclav Hapla }
782c5b5d8d5SVaclav Hapla 
783d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
784d71ae5a4SJacob Faibussowitsch {
78539a651e2SJacob Faibussowitsch   PetscFunctionBegin;
78639a651e2SJacob Faibussowitsch   PetscValidBoolPointer(flg, 3);
787c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
788c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
78939a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
790c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
791c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7929566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
793c5b5d8d5SVaclav Hapla         if (*flg) break;
794c5b5d8d5SVaclav Hapla       }
795c5b5d8d5SVaclav Hapla     }
796c5b5d8d5SVaclav Hapla   }
7973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
798c5b5d8d5SVaclav Hapla }
79985079163SJed Brown 
800e5c89e4eSSatish Balay /*@C
801e5c89e4eSSatish Balay    PetscOptionsInsert - Inserts into the options database from the command line,
802e5c89e4eSSatish Balay                         the environmental variable and a file.
803e5c89e4eSSatish Balay 
804811af0c4SBarry Smith    Collective on `PETSC_COMM_WORLD`
8051c9f3c13SBarry Smith 
806e5c89e4eSSatish Balay    Input Parameters:
80720f4b53cSBarry Smith +  options - options database or `NULL` for the default global database
808c5929fdfSBarry Smith .  argc - count of number of command line arguments
809e5c89e4eSSatish Balay .  args - the command line arguments
810be10d61cSLisandro Dalcin -  file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
81120f4b53cSBarry Smith           Use `NULL` or empty string to not check for code specific file.
812be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
813c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
814e5c89e4eSSatish Balay 
815081c24baSBoyana Norris    Options Database Keys:
816d06005cbSLisandro Dalcin +   -options_file <filename> - read options from a file
817d06005cbSLisandro Dalcin -   -options_file_yaml <filename> - read options from a YAML file
818c5b5d8d5SVaclav Hapla 
81920f4b53cSBarry Smith    Level: advanced
82020f4b53cSBarry Smith 
821811af0c4SBarry Smith    Notes:
82220f4b53cSBarry Smith    Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
823811af0c4SBarry Smith    the user does not typically need to call this routine. `PetscOptionsInsert()`
824811af0c4SBarry Smith    can be called several times, adding additional entries into the database.
825811af0c4SBarry Smith 
826811af0c4SBarry Smith    See `PetscInitialize()` for options related to option database monitoring.
827081c24baSBoyana Norris 
828db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
829db781477SPatrick Sanan           `PetscInitialize()`
830e5c89e4eSSatish Balay @*/
831d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[])
832d71ae5a4SJacob Faibussowitsch {
833d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
834e5c89e4eSSatish Balay   PetscMPIInt rank;
835c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
836c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
837e5c89e4eSSatish Balay 
838e5c89e4eSSatish Balay   PetscFunctionBegin;
83908401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8409566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
841e5c89e4eSSatish Balay 
842c5b5d8d5SVaclav Hapla   if (!options) {
8439566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
844c5b5d8d5SVaclav Hapla     options = defaultoptions;
845c5b5d8d5SVaclav Hapla   }
846c5b5d8d5SVaclav Hapla   if (hasArgs) {
847c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8489566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
849660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
850c5b5d8d5SVaclav Hapla   }
8514b09e917SBarry Smith   if (file && file[0]) {
8529566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
853c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8549566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
855321366bcSBarry Smith   }
856c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
857be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8589566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8599566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
860c6a7a370SJeremy L Thompson     if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
8619566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8629566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8639566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
864e5c89e4eSSatish Balay   }
865e5c89e4eSSatish Balay 
8662d747510SLisandro Dalcin   /* insert environment options */
867e5c89e4eSSatish Balay   {
8682d747510SLisandro Dalcin     char  *eoptions = NULL;
869e5c89e4eSSatish Balay     size_t len      = 0;
870dd400576SPatrick Sanan     if (rank == 0) {
871e5c89e4eSSatish Balay       eoptions = (char *)getenv("PETSC_OPTIONS");
8729566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
873e5c89e4eSSatish Balay     }
8749566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
875e5c89e4eSSatish Balay     if (len) {
8769566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8779566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
87896fc60bcSBarry Smith       if (rank) eoptions[len] = 0;
8799355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8809566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
881e5c89e4eSSatish Balay     }
882e5c89e4eSSatish Balay   }
883e5c89e4eSSatish Balay 
884d06005cbSLisandro Dalcin   /* insert YAML environment options */
88556a31166SBarry Smith   {
8869fc438c3SToby Isaac     char  *eoptions = NULL;
8879fc438c3SToby Isaac     size_t len      = 0;
888dd400576SPatrick Sanan     if (rank == 0) {
8899fc438c3SToby Isaac       eoptions = (char *)getenv("PETSC_OPTIONS_YAML");
8909566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
8919fc438c3SToby Isaac     }
8929566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8939fc438c3SToby Isaac     if (len) {
8949566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8959566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
8969fc438c3SToby Isaac       if (rank) eoptions[len] = 0;
8979355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8989566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
8999fc438c3SToby Isaac     }
9009fc438c3SToby Isaac   }
9013bcbd388SSean Farley 
902c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
9039566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, *args + 1));
904660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
9053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
906e5c89e4eSSatish Balay }
907e5c89e4eSSatish Balay 
908660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
909660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
9109371c9d4SSatish Balay static const char *PetscCIOptions[] = {
9119371c9d4SSatish Balay   "malloc_debug",
912660278c0SBarry Smith   "malloc_dump",
913660278c0SBarry Smith   "malloc_test",
9141f4c7579SBarry Smith   "malloc",
915660278c0SBarry Smith   "nox",
916660278c0SBarry Smith   "nox_warning",
917660278c0SBarry Smith   "display",
918660278c0SBarry Smith   "saws_port_auto_select",
919660278c0SBarry Smith   "saws_port_auto_select_silent",
920660278c0SBarry Smith   "vecscatter_mpi1",
921660278c0SBarry Smith   "check_pointer_intensity",
922660278c0SBarry Smith   "cuda_initialize",
923660278c0SBarry Smith   "error_output_stdout",
924660278c0SBarry Smith   "use_gpu_aware_mpi",
925660278c0SBarry Smith   "checkfunctionlist",
9263872ee93SStefano Zampini   "fp_trap",
927660278c0SBarry Smith   "petsc_ci",
928660278c0SBarry Smith   "petsc_ci_portable_error_output",
929660278c0SBarry Smith };
930660278c0SBarry Smith 
931d71ae5a4SJacob Faibussowitsch static PetscBool PetscCIOption(const char *name)
932d71ae5a4SJacob Faibussowitsch {
933660278c0SBarry Smith   PetscInt  idx;
934660278c0SBarry Smith   PetscBool found;
935660278c0SBarry Smith 
936660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
9373ba16761SJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
938660278c0SBarry Smith   return found;
939660278c0SBarry Smith }
940660278c0SBarry Smith 
941e5c89e4eSSatish Balay /*@C
94288c29154SBarry Smith    PetscOptionsView - Prints the options that have been loaded. This is
943e5c89e4eSSatish Balay    useful for debugging purposes.
944e5c89e4eSSatish Balay 
945c3339decSBarry Smith    Logically Collective
946e5c89e4eSSatish Balay 
947d8d19677SJose E. Roman    Input Parameters:
94820f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
949811af0c4SBarry Smith -  viewer - must be an `PETSCVIEWERASCII` viewer
950e5c89e4eSSatish Balay 
951e5c89e4eSSatish Balay    Options Database Key:
952811af0c4SBarry Smith .  -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
953e5c89e4eSSatish Balay 
95420f4b53cSBarry Smith    Level: advanced
95520f4b53cSBarry Smith 
956811af0c4SBarry Smith    Note:
95721532e8aSBarry Smith    Only the MPI rank 0 of the `MPI_Comm` used to create view prints the option values. Other processes
9581c9f3c13SBarry Smith    may have different values but they are not printed.
9591c9f3c13SBarry Smith 
960db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
961e5c89e4eSSatish Balay @*/
962d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
963d71ae5a4SJacob Faibussowitsch {
964660278c0SBarry Smith   PetscInt  i, N = 0;
96588c29154SBarry Smith   PetscBool isascii;
966e5c89e4eSSatish Balay 
967e5c89e4eSSatish Balay   PetscFunctionBegin;
9682d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
969c5929fdfSBarry Smith   options = options ? options : defaultoptions;
97088c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9719566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
97228b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
97388c29154SBarry Smith 
974660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
975660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
976660278c0SBarry Smith     N++;
977660278c0SBarry Smith   }
978660278c0SBarry Smith 
979660278c0SBarry Smith   if (!N) {
9809566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9813ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
98230694fe9SBarry Smith   }
9832d747510SLisandro Dalcin 
9849566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
985e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
986660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
987e5c89e4eSSatish Balay     if (options->values[i]) {
9889355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
989e5c89e4eSSatish Balay     } else {
9909355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
991e5c89e4eSSatish Balay     }
9929355ec05SMatthew G. Knepley     PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
993e5c89e4eSSatish Balay   }
9949566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
9953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
996e5c89e4eSSatish Balay }
997e5c89e4eSSatish Balay 
998e11779c2SBarry Smith /*
999e11779c2SBarry Smith    Called by error handlers to print options used in run
1000e11779c2SBarry Smith */
1001d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftError(void)
1002d71ae5a4SJacob Faibussowitsch {
1003f4bc716fSBarry Smith   PetscInt i, nopt = 0;
1004f4bc716fSBarry Smith 
1005f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
1006f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
1007f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
1008f4bc716fSBarry Smith       nopt++;
1009f4bc716fSBarry Smith     }
1010f4bc716fSBarry Smith   }
1011f4bc716fSBarry Smith   if (nopt) {
1012*7d44c3adSBarry Smith     PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
1013f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
1014f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
1015f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
10163ba16761SJacob Faibussowitsch         if (defaultoptions->values[i]) PetscCall((*PetscErrorPrintf)("  Option left: name:-%s value: %s source: %s\n", defaultoptions->names[i], defaultoptions->values[i], PetscOptionSources[defaultoptions->source[i]]));
10173ba16761SJacob Faibussowitsch         else PetscCall((*PetscErrorPrintf)("  Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
1018f4bc716fSBarry Smith       }
1019f4bc716fSBarry Smith     }
1020f4bc716fSBarry Smith   }
10213ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1022f4bc716fSBarry Smith }
1023f4bc716fSBarry Smith 
1024d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1025d71ae5a4SJacob Faibussowitsch {
1026660278c0SBarry Smith   PetscInt     i, N = 0;
10274416b707SBarry Smith   PetscOptions options = defaultoptions;
1028e11779c2SBarry Smith 
1029660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
1030660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1031660278c0SBarry Smith     N++;
1032660278c0SBarry Smith   }
1033660278c0SBarry Smith 
1034660278c0SBarry Smith   if (N) {
10353ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1036e11779c2SBarry Smith   } else {
10373ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1038e11779c2SBarry Smith   }
1039e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1040660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1041e11779c2SBarry Smith     if (options->values[i]) {
10423ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1043e11779c2SBarry Smith     } else {
10443ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1045e11779c2SBarry Smith     }
1046e11779c2SBarry Smith   }
10473ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1048e11779c2SBarry Smith }
1049e11779c2SBarry Smith 
1050e5c89e4eSSatish Balay /*@C
105174e0666dSJed Brown    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
105274e0666dSJed Brown 
10531c9f3c13SBarry Smith    Logically Collective
105474e0666dSJed Brown 
1055d8d19677SJose E. Roman    Input Parameters:
105620f4b53cSBarry Smith +  options - options database, or `NULL` for the default global database
1057c5929fdfSBarry Smith -  prefix - The string to append to the existing prefix
10589db968c8SJed Brown 
10599db968c8SJed Brown    Options Database Keys:
10609db968c8SJed Brown +   -prefix_push <some_prefix_> - push the given prefix
10619db968c8SJed Brown -   -prefix_pop - pop the last prefix
10629db968c8SJed Brown 
106320f4b53cSBarry Smith    Level: advanced
106420f4b53cSBarry Smith 
10659db968c8SJed Brown    Notes:
106621532e8aSBarry Smith    It is common to use this in conjunction with `-options_file` as in
10679db968c8SJed Brown 
10689db968c8SJed Brown $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10699db968c8SJed Brown 
107021532e8aSBarry Smith    where the files no longer require all options to be prefixed with `-system2_`.
107174e0666dSJed Brown 
107221532e8aSBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
10731c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
10741c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10751c9f3c13SBarry Smith    on different ranks.
10761c9f3c13SBarry Smith 
1077db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
107874e0666dSJed Brown @*/
1079d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1080d71ae5a4SJacob Faibussowitsch {
108174e0666dSJed Brown   size_t    n;
108274e0666dSJed Brown   PetscInt  start;
10839355ec05SMatthew G. Knepley   char      key[PETSC_MAX_OPTION_NAME + 1];
10842d747510SLisandro Dalcin   PetscBool valid;
108574e0666dSJed Brown 
108674e0666dSJed Brown   PetscFunctionBegin;
1087064a246eSJacob Faibussowitsch   PetscValidCharPointer(prefix, 2);
1088c5929fdfSBarry Smith   options = options ? options : defaultoptions;
108908401ef6SPierre 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);
10902d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10919566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10938bf569ecSLisandro 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 */
109428b400f6SJacob 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" : "");
109574e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10969566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
109708401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10989566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
109974e0666dSJed Brown   options->prefixstack[options->prefixind++] = start + n;
11003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
110174e0666dSJed Brown }
110274e0666dSJed Brown 
1103c5929fdfSBarry Smith /*@C
1104811af0c4SBarry Smith    PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
110574e0666dSJed Brown 
1106811af0c4SBarry Smith    Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
110774e0666dSJed Brown 
1108811af0c4SBarry Smith   Input Parameter:
110920f4b53cSBarry Smith .  options - options database, or `NULL` for the default global database
1110c5929fdfSBarry Smith 
111174e0666dSJed Brown    Level: advanced
111274e0666dSJed Brown 
1113db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
111474e0666dSJed Brown @*/
1115d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1116d71ae5a4SJacob Faibussowitsch {
111774e0666dSJed Brown   PetscInt offset;
111874e0666dSJed Brown 
111974e0666dSJed Brown   PetscFunctionBegin;
1120c5929fdfSBarry Smith   options = options ? options : defaultoptions;
112108401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
112274e0666dSJed Brown   options->prefixind--;
112374e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
112474e0666dSJed Brown   options->prefix[offset] = 0;
11253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
112674e0666dSJed Brown }
112774e0666dSJed Brown 
1128a542b6e8SBarry Smith /*@C
1129a542b6e8SBarry Smith     PetscOptionsClear - Removes all options form the database leaving it empty.
1130a542b6e8SBarry Smith 
11311c9f3c13SBarry Smith     Logically Collective
11321c9f3c13SBarry Smith 
1133811af0c4SBarry Smith   Input Parameter:
113420f4b53cSBarry Smith .  options - options database, use `NULL` for the default global database
1135c5929fdfSBarry Smith 
113620f4b53cSBarry Smith    Level: developer
113720f4b53cSBarry Smith 
113820f4b53cSBarry Smith    Note:
113921532e8aSBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
11401c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
11411c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11421c9f3c13SBarry Smith    on different ranks.
11431c9f3c13SBarry Smith 
1144db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1145a542b6e8SBarry Smith @*/
1146d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClear(PetscOptions options)
1147d71ae5a4SJacob Faibussowitsch {
1148a542b6e8SBarry Smith   PetscInt i;
1149a542b6e8SBarry Smith 
115039a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1151c5929fdfSBarry Smith   options = options ? options : defaultoptions;
11523ba16761SJacob Faibussowitsch   if (!options) PetscFunctionReturn(PETSC_SUCCESS);
11532d747510SLisandro Dalcin 
1154a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1155a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1156a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1157a542b6e8SBarry Smith   }
11582d747510SLisandro Dalcin   options->N = 0;
11599355ec05SMatthew G. Knepley   free(options->names);
11609355ec05SMatthew G. Knepley   free(options->values);
11619355ec05SMatthew G. Knepley   free(options->used);
11629355ec05SMatthew G. Knepley   free(options->source);
11639355ec05SMatthew G. Knepley   options->names  = NULL;
11649355ec05SMatthew G. Knepley   options->values = NULL;
11659355ec05SMatthew G. Knepley   options->used   = NULL;
11669355ec05SMatthew G. Knepley   options->source = NULL;
11679355ec05SMatthew G. Knepley   options->Nalloc = 0;
11682d747510SLisandro Dalcin 
11699355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
1170a542b6e8SBarry Smith     free(options->aliases1[i]);
1171a542b6e8SBarry Smith     free(options->aliases2[i]);
1172a542b6e8SBarry Smith   }
11739355ec05SMatthew G. Knepley   options->Na = 0;
11749355ec05SMatthew G. Knepley   free(options->aliases1);
11759355ec05SMatthew G. Knepley   free(options->aliases2);
11769355ec05SMatthew G. Knepley   options->aliases1 = options->aliases2 = NULL;
11779355ec05SMatthew G. Knepley   options->Naalloc                      = 0;
1178a542b6e8SBarry Smith 
11792d747510SLisandro Dalcin   /* destroy hash table */
11802d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11812d747510SLisandro Dalcin   options->ht = NULL;
11820eb63584SBarry Smith 
11832d747510SLisandro Dalcin   options->prefixind  = 0;
11842d747510SLisandro Dalcin   options->prefix[0]  = 0;
11852d747510SLisandro Dalcin   options->help       = PETSC_FALSE;
11869355ec05SMatthew G. Knepley   options->help_intro = PETSC_FALSE;
11873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11884416b707SBarry Smith }
11894416b707SBarry Smith 
11902d747510SLisandro Dalcin /*@C
11912d747510SLisandro Dalcin    PetscOptionsSetAlias - Makes a key and alias for another key
11922d747510SLisandro Dalcin 
11931c9f3c13SBarry Smith    Logically Collective
11942d747510SLisandro Dalcin 
11952d747510SLisandro Dalcin    Input Parameters:
119620f4b53cSBarry Smith +  options - options database, or `NULL` for default global database
11972d747510SLisandro Dalcin .  newname - the alias
11982d747510SLisandro Dalcin -  oldname - the name that alias will refer to
11992d747510SLisandro Dalcin 
12002d747510SLisandro Dalcin    Level: advanced
12012d747510SLisandro Dalcin 
120220f4b53cSBarry Smith    Note:
120321532e8aSBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
12041c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
12051c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12061c9f3c13SBarry Smith    on different ranks.
12071c9f3c13SBarry Smith 
1208c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1209c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1210db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1211c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1212db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1213db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
12142d747510SLisandro Dalcin @*/
1215d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1216d71ae5a4SJacob Faibussowitsch {
12172d747510SLisandro Dalcin   size_t    len;
12189210b8eaSVaclav Hapla   PetscBool valid;
12192d747510SLisandro Dalcin 
12202d747510SLisandro Dalcin   PetscFunctionBegin;
12212d747510SLisandro Dalcin   PetscValidCharPointer(newname, 2);
12222d747510SLisandro Dalcin   PetscValidCharPointer(oldname, 3);
12232d747510SLisandro Dalcin   options = options ? options : defaultoptions;
12249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
122528b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
12269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
122728b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
12282d747510SLisandro Dalcin 
12299355ec05SMatthew G. Knepley   if (options->Na == options->Naalloc) {
12309355ec05SMatthew G. Knepley     char **tmpA1, **tmpA2;
12312d747510SLisandro Dalcin 
12329355ec05SMatthew G. Knepley     options->Naalloc = PetscMax(4, options->Naalloc * 2);
12339355ec05SMatthew G. Knepley     tmpA1            = (char **)malloc(options->Naalloc * sizeof(char *));
12349355ec05SMatthew G. Knepley     tmpA2            = (char **)malloc(options->Naalloc * sizeof(char *));
12359355ec05SMatthew G. Knepley     for (int i = 0; i < options->Na; ++i) {
12369355ec05SMatthew G. Knepley       tmpA1[i] = options->aliases1[i];
12379355ec05SMatthew G. Knepley       tmpA2[i] = options->aliases2[i];
12389355ec05SMatthew G. Knepley     }
12399355ec05SMatthew G. Knepley     free(options->aliases1);
12409355ec05SMatthew G. Knepley     free(options->aliases2);
12419355ec05SMatthew G. Knepley     options->aliases1 = tmpA1;
12429355ec05SMatthew G. Knepley     options->aliases2 = tmpA2;
12439355ec05SMatthew G. Knepley   }
12449371c9d4SSatish Balay   newname++;
12459371c9d4SSatish Balay   oldname++;
12469566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
12479355ec05SMatthew G. Knepley   options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1248c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
12499566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
12509355ec05SMatthew G. Knepley   options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1251c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
12529355ec05SMatthew G. Knepley   ++options->Na;
12533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12542d747510SLisandro Dalcin }
12554416b707SBarry Smith 
1256e5c89e4eSSatish Balay /*@C
1257e5c89e4eSSatish Balay    PetscOptionsSetValue - Sets an option name-value pair in the options
1258e5c89e4eSSatish Balay    database, overriding whatever is already present.
1259e5c89e4eSSatish Balay 
12601c9f3c13SBarry Smith    Logically Collective
1261e5c89e4eSSatish Balay 
1262e5c89e4eSSatish Balay    Input Parameters:
126320f4b53cSBarry Smith +  options - options database, use `NULL` for the default global database
1264c5929fdfSBarry Smith .  name - name of option, this SHOULD have the - prepended
126520f4b53cSBarry Smith -  value - the option value (not used for all options, so can be `NULL`)
1266e5c89e4eSSatish Balay 
1267e5c89e4eSSatish Balay    Level: intermediate
1268e5c89e4eSSatish Balay 
1269e5c89e4eSSatish Balay    Note:
1270811af0c4SBarry Smith    This function can be called BEFORE `PetscInitialize()`
1271d49172ceSBarry Smith 
127221532e8aSBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
12731c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
12741c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12751c9f3c13SBarry Smith    on different ranks.
12761c9f3c13SBarry Smith 
127720f4b53cSBarry Smith    Developers Note:
127820f4b53cSBarry Smith    Uses malloc() directly because PETSc may not be initialized yet.
1279b0250c70SBarry Smith 
1280db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1281e5c89e4eSSatish Balay @*/
1282d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1283d71ae5a4SJacob Faibussowitsch {
128439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12859355ec05SMatthew G. Knepley   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
12863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1287c5b5d8d5SVaclav Hapla }
1288c5b5d8d5SVaclav Hapla 
12899355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1290d71ae5a4SJacob Faibussowitsch {
1291e5c89e4eSSatish Balay   size_t    len;
12929355ec05SMatthew G. Knepley   int       n, i;
1293e5c89e4eSSatish Balay   char    **names;
12949355ec05SMatthew G. Knepley   char      fullname[PETSC_MAX_OPTION_NAME] = "";
1295c5b5d8d5SVaclav Hapla   PetscBool flg;
1296e5c89e4eSSatish Balay 
129739a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12987272c0d2SVaclav Hapla   if (!options) {
12999566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
13007272c0d2SVaclav Hapla     options = defaultoptions;
1301c5929fdfSBarry Smith   }
130239a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
13032d747510SLisandro Dalcin 
13049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
13053ba16761SJacob Faibussowitsch   if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1306e5c89e4eSSatish Balay 
13072d747510SLisandro Dalcin   name++; /* skip starting dash */
13082d747510SLisandro Dalcin 
130974e0666dSJed Brown   if (options->prefixind > 0) {
1310d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
13112d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
131289ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
13132d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
131474e0666dSJed Brown     name                           = fullname;
131574e0666dSJed Brown   }
131674e0666dSJed Brown 
131774e0666dSJed Brown   /* check against aliases */
13189355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
13192d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
13209371c9d4SSatish Balay     if (!result) {
13219371c9d4SSatish Balay       name = options->aliases2[i];
13229371c9d4SSatish Balay       break;
13239371c9d4SSatish Balay     }
1324e5c89e4eSSatish Balay   }
1325e5c89e4eSSatish Balay 
13262d747510SLisandro Dalcin   /* slow search */
13279355ec05SMatthew G. Knepley   n     = options->N;
1328e5c89e4eSSatish Balay   names = options->names;
13299355ec05SMatthew G. Knepley   for (i = 0; i < options->N; i++) {
13302d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13312d747510SLisandro Dalcin     if (!result) {
13329371c9d4SSatish Balay       n = i;
13339371c9d4SSatish Balay       goto setvalue;
13342d747510SLisandro Dalcin     } else if (result > 0) {
13359371c9d4SSatish Balay       n = i;
13369371c9d4SSatish Balay       break;
1337e5c89e4eSSatish Balay     }
1338e5c89e4eSSatish Balay   }
13399355ec05SMatthew G. Knepley   if (options->N == options->Nalloc) {
13409355ec05SMatthew G. Knepley     char             **names, **values;
13419355ec05SMatthew G. Knepley     PetscBool         *used;
13429355ec05SMatthew G. Knepley     PetscOptionSource *source;
13439355ec05SMatthew G. Knepley 
13449355ec05SMatthew G. Knepley     options->Nalloc = PetscMax(10, options->Nalloc * 2);
13459355ec05SMatthew G. Knepley     names           = (char **)malloc(options->Nalloc * sizeof(char *));
13469355ec05SMatthew G. Knepley     values          = (char **)malloc(options->Nalloc * sizeof(char *));
13479355ec05SMatthew G. Knepley     used            = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
13489355ec05SMatthew G. Knepley     source          = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
13499355ec05SMatthew G. Knepley     for (int i = 0; i < options->N; ++i) {
13509355ec05SMatthew G. Knepley       names[i]  = options->names[i];
13519355ec05SMatthew G. Knepley       values[i] = options->values[i];
13529355ec05SMatthew G. Knepley       used[i]   = options->used[i];
13539355ec05SMatthew G. Knepley       source[i] = options->source[i];
13549355ec05SMatthew G. Knepley     }
13559355ec05SMatthew G. Knepley     free(options->names);
13569355ec05SMatthew G. Knepley     free(options->values);
13579355ec05SMatthew G. Knepley     free(options->used);
13589355ec05SMatthew G. Knepley     free(options->source);
13599355ec05SMatthew G. Knepley     options->names  = names;
13609355ec05SMatthew G. Knepley     options->values = values;
13619355ec05SMatthew G. Knepley     options->used   = used;
13629355ec05SMatthew G. Knepley     options->source = source;
13639355ec05SMatthew G. Knepley   }
136439a651e2SJacob Faibussowitsch 
13652d747510SLisandro Dalcin   /* shift remaining values up 1 */
13669355ec05SMatthew G. Knepley   for (i = options->N; i > n; i--) {
13675e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1368e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1369e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
13709355ec05SMatthew G. Knepley     options->source[i] = options->source[i - 1];
1371e5c89e4eSSatish Balay   }
13722d747510SLisandro Dalcin   options->names[n]  = NULL;
13732d747510SLisandro Dalcin   options->values[n] = NULL;
13742d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
13759355ec05SMatthew G. Knepley   options->source[n] = PETSC_OPT_CODE;
13762d747510SLisandro Dalcin   options->N++;
13772d747510SLisandro Dalcin 
13782d747510SLisandro Dalcin   /* destroy hash table */
13792d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13802d747510SLisandro Dalcin   options->ht = NULL;
13812d747510SLisandro Dalcin 
13822d747510SLisandro Dalcin   /* set new name */
138370d8d27cSBarry Smith   len               = strlen(name);
13845e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
138539a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1386d49172ceSBarry Smith   strcpy(options->names[n], name);
13872d747510SLisandro Dalcin 
13882d747510SLisandro Dalcin setvalue:
13892d747510SLisandro Dalcin   /* set new value */
13902d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1391d49172ceSBarry Smith   len = value ? strlen(value) : 0;
13925e8c5e88SLisandro Dalcin   if (len) {
1393e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1394d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1395d49172ceSBarry Smith     strcpy(options->values[n], value);
13962d747510SLisandro Dalcin   } else {
13972d747510SLisandro Dalcin     options->values[n] = NULL;
13982d747510SLisandro Dalcin   }
13999355ec05SMatthew G. Knepley   options->source[n] = source;
14002d747510SLisandro Dalcin 
140191ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
140291ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
140391ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1404d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
140591ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
140691ad3481SVaclav Hapla   }
140791ad3481SVaclav Hapla 
14089355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, value, source));
1409c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
14103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1411e5c89e4eSSatish Balay }
1412e5c89e4eSSatish Balay 
1413e5c89e4eSSatish Balay /*@C
1414e5c89e4eSSatish Balay    PetscOptionsClearValue - Clears an option name-value pair in the options
1415e5c89e4eSSatish Balay    database, overriding whatever is already present.
1416e5c89e4eSSatish Balay 
14171c9f3c13SBarry Smith    Logically Collective
1418e5c89e4eSSatish Balay 
1419d8d19677SJose E. Roman    Input Parameters:
142020f4b53cSBarry Smith +  options - options database, use `NULL` for the default global database
1421a2b725a8SWilliam Gropp -  name - name of option, this SHOULD have the - prepended
1422e5c89e4eSSatish Balay 
1423e5c89e4eSSatish Balay    Level: intermediate
1424e5c89e4eSSatish Balay 
1425811af0c4SBarry Smith    Note:
142621532e8aSBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
14271c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
14281c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
14291c9f3c13SBarry Smith    on different ranks.
14301c9f3c13SBarry Smith 
1431db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1432e5c89e4eSSatish Balay @*/
1433d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1434d71ae5a4SJacob Faibussowitsch {
14352d747510SLisandro Dalcin   int    N, n, i;
14362d747510SLisandro Dalcin   char **names;
1437e5c89e4eSSatish Balay 
1438e5c89e4eSSatish Balay   PetscFunctionBegin;
1439c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1440cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1441c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
14422d747510SLisandro Dalcin 
14432d747510SLisandro Dalcin   name++; /* skip starting dash */
14442d747510SLisandro Dalcin 
14452d747510SLisandro Dalcin   /* slow search */
14462d747510SLisandro Dalcin   N = n = options->N;
1447e5c89e4eSSatish Balay   names = options->names;
1448e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
14492d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
14502d747510SLisandro Dalcin     if (!result) {
14519371c9d4SSatish Balay       n = i;
14529371c9d4SSatish Balay       break;
14532d747510SLisandro Dalcin     } else if (result > 0) {
14549371c9d4SSatish Balay       n = N;
14559371c9d4SSatish Balay       break;
1456e5c89e4eSSatish Balay     }
14572d747510SLisandro Dalcin   }
14583ba16761SJacob Faibussowitsch   if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1459e5c89e4eSSatish Balay 
14602d747510SLisandro Dalcin   /* remove name and value */
14612d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
14622d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1463e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1464e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
14655e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1466e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1467e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
14689355ec05SMatthew G. Knepley     options->source[i] = options->source[i + 1];
1469e5c89e4eSSatish Balay   }
1470e5c89e4eSSatish Balay   options->N--;
14712d747510SLisandro Dalcin 
14722d747510SLisandro Dalcin   /* destroy hash table */
14732d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
14742d747510SLisandro Dalcin   options->ht = NULL;
14752d747510SLisandro Dalcin 
14769355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
14773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1478e5c89e4eSSatish Balay }
1479e5c89e4eSSatish Balay 
1480e5c89e4eSSatish Balay /*@C
14812d747510SLisandro Dalcin    PetscOptionsFindPair - Gets an option name-value pair from the options database.
1482e5c89e4eSSatish Balay 
14832d747510SLisandro Dalcin    Not Collective
1484e5c89e4eSSatish Balay 
1485e5c89e4eSSatish Balay    Input Parameters:
148620f4b53cSBarry Smith +  options - options database, use `NULL` for the default global database
148720f4b53cSBarry Smith .  pre - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
14882d747510SLisandro Dalcin -  name - name of option, this SHOULD have the "-" prepended
1489e5c89e4eSSatish Balay 
14902d747510SLisandro Dalcin    Output Parameters:
14912d747510SLisandro Dalcin +  value - the option value (optional, not used for all options)
14922d747510SLisandro Dalcin -  set - whether the option is set (optional)
1493e5c89e4eSSatish Balay 
149420f4b53cSBarry Smith    Level: developer
149520f4b53cSBarry Smith 
1496811af0c4SBarry Smith    Note:
14979666a313SBarry Smith    Each process may find different values or no value depending on how options were inserted into the database
14981c9f3c13SBarry Smith 
1499db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1500e5c89e4eSSatish Balay @*/
1501d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1502d71ae5a4SJacob Faibussowitsch {
15039355ec05SMatthew G. Knepley   char      buf[PETSC_MAX_OPTION_NAME];
1504daabea38SBarry Smith   PetscBool usehashtable = PETSC_TRUE;
15052d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1506e5c89e4eSSatish Balay 
1507e5c89e4eSSatish Balay   PetscFunctionBegin;
1508c5929fdfSBarry Smith   options = options ? options : defaultoptions;
150908401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1510cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1511e5c89e4eSSatish Balay 
15122d747510SLisandro Dalcin   name++; /* skip starting dash */
1513e5c89e4eSSatish Balay 
15147cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
15152d747510SLisandro Dalcin   if (pre && pre[0]) {
15162d747510SLisandro Dalcin     char *ptr = buf;
15179371c9d4SSatish Balay     if (name[0] == '-') {
15189371c9d4SSatish Balay       *ptr++ = '-';
15199371c9d4SSatish Balay       name++;
15209371c9d4SSatish Balay     }
15219566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
15229566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
15232d747510SLisandro Dalcin     name = buf;
15247cd08cecSJed Brown   }
15252d747510SLisandro Dalcin 
152676bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
15272f828895SJed Brown     PetscBool valid;
15289355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
15299566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
15309566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
153128b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
15322f828895SJed Brown   }
1533e5c89e4eSSatish Balay 
15342d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
15352d747510SLisandro Dalcin     int          i, ret;
15362d747510SLisandro Dalcin     khiter_t     it;
15372d747510SLisandro Dalcin     khash_t(HO) *ht;
15382d747510SLisandro Dalcin     ht = kh_init(HO);
153928b400f6SJacob Faibussowitsch     PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15402d747510SLisandro Dalcin     ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
154128b400f6SJacob Faibussowitsch     PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15422d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
15432d747510SLisandro Dalcin       it = kh_put(HO, ht, options->names[i], &ret);
154408401ef6SPierre Jolivet       PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15452d747510SLisandro Dalcin       kh_val(ht, it) = i;
15462d747510SLisandro Dalcin     }
15472d747510SLisandro Dalcin     options->ht = ht;
15482d747510SLisandro Dalcin   }
15492d747510SLisandro Dalcin 
15509371c9d4SSatish Balay   if (usehashtable) { /* fast search */
15512d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
15522d747510SLisandro Dalcin     khiter_t     it = kh_get(HO, ht, name);
15532d747510SLisandro Dalcin     if (it != kh_end(ht)) {
15542d747510SLisandro Dalcin       int i            = kh_val(ht, it);
1555e5c89e4eSSatish Balay       options->used[i] = PETSC_TRUE;
15562d747510SLisandro Dalcin       if (value) *value = options->values[i];
15572d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
15583ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
15592d747510SLisandro Dalcin     }
15609371c9d4SSatish Balay   } else { /* slow search */
15612d747510SLisandro Dalcin     int i, N = options->N;
15622d747510SLisandro Dalcin     for (i = 0; i < N; i++) {
1563daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i], name);
15642d747510SLisandro Dalcin       if (!result) {
15652d747510SLisandro Dalcin         options->used[i] = PETSC_TRUE;
15662d747510SLisandro Dalcin         if (value) *value = options->values[i];
15672d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
15683ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15692d747510SLisandro Dalcin       } else if (result > 0) {
1570e5c89e4eSSatish Balay         break;
1571e5c89e4eSSatish Balay       }
1572e5c89e4eSSatish Balay     }
15732d747510SLisandro Dalcin   }
15742d747510SLisandro Dalcin 
15752d747510SLisandro Dalcin   /*
15762d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
15772d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
15782d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
15792d747510SLisandro Dalcin    */
15802d747510SLisandro Dalcin   if (matchnumbers) {
15812d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1582e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
15832d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
15842d747510SLisandro Dalcin       if (name[i] == '_') {
15852d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
15862d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
15872d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1588e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1589e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1590e5c89e4eSSatish Balay           }
15912d747510SLisandro Dalcin           i = j - 1;
1592e5c89e4eSSatish Balay           break;
1593e5c89e4eSSatish Balay         }
1594e5c89e4eSSatish Balay       }
1595e5c89e4eSSatish Balay     }
1596e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
15972d747510SLisandro Dalcin       PetscBool found;
15989355ec05SMatthew G. Knepley       char      opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
15999566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
16009566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
16019566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
16029566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
16039371c9d4SSatish Balay       if (found) {
16049371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
16053ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
16069371c9d4SSatish Balay       }
1607e5c89e4eSSatish Balay     }
1608e5c89e4eSSatish Balay   }
16092d747510SLisandro Dalcin 
16102d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1612e5c89e4eSSatish Balay }
1613e5c89e4eSSatish Balay 
1614d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
1615d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1616d71ae5a4SJacob Faibussowitsch {
16179355ec05SMatthew G. Knepley   char buf[PETSC_MAX_OPTION_NAME];
1618d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1619514bf10dSMatthew G Knepley 
1620514bf10dSMatthew G Knepley   PetscFunctionBegin;
1621c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1622cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1623cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1624514bf10dSMatthew G Knepley 
16252d747510SLisandro Dalcin   name++; /* skip starting dash */
1626514bf10dSMatthew G Knepley 
1627514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
16282d747510SLisandro Dalcin   if (pre && pre[0]) {
16292d747510SLisandro Dalcin     char *ptr = buf;
16309371c9d4SSatish Balay     if (name[0] == '-') {
16319371c9d4SSatish Balay       *ptr++ = '-';
16329371c9d4SSatish Balay       name++;
16339371c9d4SSatish Balay     }
16349b15cf9aSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
16359566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
16362d747510SLisandro Dalcin     name = buf;
1637514bf10dSMatthew G Knepley   }
16382d747510SLisandro Dalcin 
163976bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1640514bf10dSMatthew G Knepley     PetscBool valid;
16419355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
16429566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
16439566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
164428b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1645514bf10dSMatthew G Knepley   }
1646514bf10dSMatthew G Knepley 
1647d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1648d6ced9c0SMatthew G. Knepley   {
1649d6ced9c0SMatthew G. Knepley     int i, j;
1650d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1651d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1652d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1653d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1654d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1655d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1656d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1657d6ced9c0SMatthew G. Knepley           }
1658d6ced9c0SMatthew G. Knepley           i = j - 1;
1659d6ced9c0SMatthew G. Knepley           break;
1660d6ced9c0SMatthew G. Knepley         }
1661d6ced9c0SMatthew G. Knepley       }
1662d6ced9c0SMatthew G. Knepley     }
1663d6ced9c0SMatthew G. Knepley   }
1664d6ced9c0SMatthew G. Knepley 
1665363da2dcSJacob Faibussowitsch   /* slow search */
1666363da2dcSJacob Faibussowitsch   for (int c = -1; c < numCnt; ++c) {
1667363da2dcSJacob Faibussowitsch     char   opt[PETSC_MAX_OPTION_NAME + 2] = "";
16682d747510SLisandro Dalcin     size_t len;
1669d6ced9c0SMatthew G. Knepley 
1670d6ced9c0SMatthew G. Knepley     if (c < 0) {
1671c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1672d6ced9c0SMatthew G. Knepley     } else {
1673363da2dcSJacob Faibussowitsch       PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1674363da2dcSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1675d6ced9c0SMatthew G. Knepley     }
16769566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(opt, &len));
1677363da2dcSJacob Faibussowitsch     for (int i = 0; i < options->N; i++) {
1678363da2dcSJacob Faibussowitsch       PetscBool match;
1679363da2dcSJacob Faibussowitsch 
16809566063dSJacob Faibussowitsch       PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1681514bf10dSMatthew G Knepley       if (match) {
1682514bf10dSMatthew G Knepley         options->used[i] = PETSC_TRUE;
16832d747510SLisandro Dalcin         if (value) *value = options->values[i];
16842d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
16853ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
1686514bf10dSMatthew G Knepley       }
1687514bf10dSMatthew G Knepley     }
16882d747510SLisandro Dalcin   }
16892d747510SLisandro Dalcin 
16902d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1692514bf10dSMatthew G Knepley }
1693514bf10dSMatthew G Knepley 
1694e5c89e4eSSatish Balay /*@C
1695e5c89e4eSSatish Balay    PetscOptionsReject - Generates an error if a certain option is given.
1696e5c89e4eSSatish Balay 
16971c9f3c13SBarry Smith    Not Collective
1698e5c89e4eSSatish Balay 
1699e5c89e4eSSatish Balay    Input Parameters:
170020f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
170120f4b53cSBarry Smith .  pre - the option prefix (may be `NULL`)
17022d747510SLisandro Dalcin .  name - the option name one is seeking
170320f4b53cSBarry Smith -  mess - error message (may be `NULL`)
1704e5c89e4eSSatish Balay 
1705e5c89e4eSSatish Balay    Level: advanced
1706e5c89e4eSSatish Balay 
1707c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1708db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1709db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1710c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1711db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1712db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1713e5c89e4eSSatish Balay @*/
1714d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1715d71ae5a4SJacob Faibussowitsch {
1716ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1717e5c89e4eSSatish Balay 
1718e5c89e4eSSatish Balay   PetscFunctionBegin;
17199566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1720e5c89e4eSSatish Balay   if (flag) {
172108401ef6SPierre 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);
1722f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1723e5c89e4eSSatish Balay   }
17243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1725e5c89e4eSSatish Balay }
1726e5c89e4eSSatish Balay 
1727e5c89e4eSSatish Balay /*@C
17282d747510SLisandro Dalcin    PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
17292d747510SLisandro Dalcin 
17302d747510SLisandro Dalcin    Not Collective
17312d747510SLisandro Dalcin 
1732811af0c4SBarry Smith    Input Parameter:
173320f4b53cSBarry Smith .  options - options database, use `NULL` for default global database
17342d747510SLisandro Dalcin 
1735811af0c4SBarry Smith    Output Parameter:
1736811af0c4SBarry Smith .  set - `PETSC_TRUE` if found else `PETSC_FALSE`.
17372d747510SLisandro Dalcin 
17382d747510SLisandro Dalcin    Level: advanced
17392d747510SLisandro Dalcin 
1740db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
17412d747510SLisandro Dalcin @*/
1742d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1743d71ae5a4SJacob Faibussowitsch {
17442d747510SLisandro Dalcin   PetscFunctionBegin;
1745dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
17462d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17472d747510SLisandro Dalcin   *set    = options->help;
17483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17492d747510SLisandro Dalcin }
17502d747510SLisandro Dalcin 
1751d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1752d71ae5a4SJacob Faibussowitsch {
1753d314f959SVaclav Hapla   PetscFunctionBegin;
1754dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
1755d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1756d314f959SVaclav Hapla   *set    = options->help_intro;
17573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1758d314f959SVaclav Hapla }
1759d314f959SVaclav Hapla 
17602d747510SLisandro Dalcin /*@C
1761e24fcbf7SPierre 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
1762e24fcbf7SPierre Jolivet                       if its value is set to false.
1763e5c89e4eSSatish Balay 
1764e5c89e4eSSatish Balay    Not Collective
1765e5c89e4eSSatish Balay 
1766e5c89e4eSSatish Balay    Input Parameters:
176720f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
176820f4b53cSBarry Smith .  pre - string to prepend to the name or `NULL`
17693de71b31SHong Zhang -  name - the option one is seeking
1770e5c89e4eSSatish Balay 
1771811af0c4SBarry Smith    Output Parameter:
1772811af0c4SBarry Smith .  set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1773e5c89e4eSSatish Balay 
1774e5c89e4eSSatish Balay    Level: beginner
1775e5c89e4eSSatish Balay 
1776811af0c4SBarry Smith    Note:
1777811af0c4SBarry Smith    In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
177890d69ab7SBarry Smith 
1779db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1780db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1781db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1782c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1783db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1784db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1785e5c89e4eSSatish Balay @*/
1786d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1787d71ae5a4SJacob Faibussowitsch {
17882d747510SLisandro Dalcin   const char *value;
1789ace3abfcSBarry Smith   PetscBool   flag;
1790e5c89e4eSSatish Balay 
1791e5c89e4eSSatish Balay   PetscFunctionBegin;
17929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
179396ef3cdfSSatish Balay   if (set) *set = flag;
17943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1795e5c89e4eSSatish Balay }
1796e5c89e4eSSatish Balay 
1797e5c89e4eSSatish Balay /*@C
17982d747510SLisandro Dalcin    PetscOptionsGetAll - Lists all the options the program was run with in a single string.
17992d747510SLisandro Dalcin 
18002d747510SLisandro Dalcin    Not Collective
18012d747510SLisandro Dalcin 
1802fd292e60Sprj-    Input Parameter:
180320f4b53cSBarry Smith .  options - the options database, use `NULL` for the default global database
18042d747510SLisandro Dalcin 
18052d747510SLisandro Dalcin    Output Parameter:
18062d747510SLisandro Dalcin .  copts - pointer where string pointer is stored
18072d747510SLisandro Dalcin 
180820f4b53cSBarry Smith    Level: advanced
180920f4b53cSBarry Smith 
18102d747510SLisandro Dalcin    Notes:
1811811af0c4SBarry Smith     The array and each entry in the array should be freed with `PetscFree()`
1812811af0c4SBarry Smith 
18131c9f3c13SBarry Smith     Each process may have different values depending on how the options were inserted into the database
18142d747510SLisandro Dalcin 
1815db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
18162d747510SLisandro Dalcin @*/
1817d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[])
1818d71ae5a4SJacob Faibussowitsch {
18192d747510SLisandro Dalcin   PetscInt i;
18202d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
18212d747510SLisandro Dalcin   char    *coptions = NULL;
18222d747510SLisandro Dalcin 
18232d747510SLisandro Dalcin   PetscFunctionBegin;
18242d747510SLisandro Dalcin   PetscValidPointer(copts, 2);
18252d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18262d747510SLisandro Dalcin   /* count the length of the required string */
18272d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18289566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
18292d747510SLisandro Dalcin     len += 2 + lent;
18302d747510SLisandro Dalcin     if (options->values[i]) {
18319566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
18322d747510SLisandro Dalcin       len += 1 + lent;
18332d747510SLisandro Dalcin     }
18342d747510SLisandro Dalcin   }
18359566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
18362d747510SLisandro Dalcin   coptions[0] = 0;
18372d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1838c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, "-", len));
1839c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, options->names[i], len));
1840c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, " ", len));
18412d747510SLisandro Dalcin     if (options->values[i]) {
1842c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, options->values[i], len));
1843c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, " ", len));
18442d747510SLisandro Dalcin     }
18452d747510SLisandro Dalcin   }
18462d747510SLisandro Dalcin   *copts = coptions;
18473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18482d747510SLisandro Dalcin }
18492d747510SLisandro Dalcin 
18502d747510SLisandro Dalcin /*@C
18512d747510SLisandro Dalcin    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
18522d747510SLisandro Dalcin 
18532d747510SLisandro Dalcin    Not Collective
18542d747510SLisandro Dalcin 
1855d8d19677SJose E. Roman    Input Parameters:
185620f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
18572d747510SLisandro Dalcin -  name - string name of option
18582d747510SLisandro Dalcin 
18592d747510SLisandro Dalcin    Output Parameter:
1860811af0c4SBarry Smith .  used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
18612d747510SLisandro Dalcin 
18622d747510SLisandro Dalcin    Level: advanced
18632d747510SLisandro Dalcin 
1864811af0c4SBarry Smith    Note:
18659666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
18661c9f3c13SBarry Smith    on the given process
18671c9f3c13SBarry Smith 
1868db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
18692d747510SLisandro Dalcin @*/
1870d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1871d71ae5a4SJacob Faibussowitsch {
18722d747510SLisandro Dalcin   PetscInt i;
18732d747510SLisandro Dalcin 
18742d747510SLisandro Dalcin   PetscFunctionBegin;
18752d747510SLisandro Dalcin   PetscValidCharPointer(name, 2);
1876dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(used, 3);
18772d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18782d747510SLisandro Dalcin   *used   = PETSC_FALSE;
18792d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18809566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
18812d747510SLisandro Dalcin     if (*used) {
18822d747510SLisandro Dalcin       *used = options->used[i];
18832d747510SLisandro Dalcin       break;
18842d747510SLisandro Dalcin     }
18852d747510SLisandro Dalcin   }
18863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18872d747510SLisandro Dalcin }
18882d747510SLisandro Dalcin 
1889487a658cSBarry Smith /*@
18902d747510SLisandro Dalcin    PetscOptionsAllUsed - Returns a count of the number of options in the
18912d747510SLisandro Dalcin    database that have never been selected.
18922d747510SLisandro Dalcin 
18932d747510SLisandro Dalcin    Not Collective
18942d747510SLisandro Dalcin 
18952d747510SLisandro Dalcin    Input Parameter:
189620f4b53cSBarry Smith .  options - options database, use `NULL` for default global database
18972d747510SLisandro Dalcin 
18982d747510SLisandro Dalcin    Output Parameter:
18992d747510SLisandro Dalcin .  N - count of options not used
19002d747510SLisandro Dalcin 
19012d747510SLisandro Dalcin    Level: advanced
19022d747510SLisandro Dalcin 
1903811af0c4SBarry Smith    Note:
19049666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
19051c9f3c13SBarry Smith    on the given process
19061c9f3c13SBarry Smith 
1907db781477SPatrick Sanan .seealso: `PetscOptionsView()`
19082d747510SLisandro Dalcin @*/
1909d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1910d71ae5a4SJacob Faibussowitsch {
19112d747510SLisandro Dalcin   PetscInt i, n = 0;
19122d747510SLisandro Dalcin 
19132d747510SLisandro Dalcin   PetscFunctionBegin;
19142d747510SLisandro Dalcin   PetscValidIntPointer(N, 2);
19152d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19162d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
19172d747510SLisandro Dalcin     if (!options->used[i]) n++;
19182d747510SLisandro Dalcin   }
19192d747510SLisandro Dalcin   *N = n;
19203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19212d747510SLisandro Dalcin }
19222d747510SLisandro Dalcin 
1923487a658cSBarry Smith /*@
19242d747510SLisandro Dalcin    PetscOptionsLeft - Prints to screen any options that were set and never used.
19252d747510SLisandro Dalcin 
19262d747510SLisandro Dalcin    Not Collective
19272d747510SLisandro Dalcin 
19282d747510SLisandro Dalcin    Input Parameter:
192920f4b53cSBarry Smith .  options - options database; use `NULL` for default global database
19302d747510SLisandro Dalcin 
19312d747510SLisandro Dalcin    Options Database Key:
1932811af0c4SBarry Smith .  -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
19332d747510SLisandro Dalcin 
193420f4b53cSBarry Smith    Level: advanced
193520f4b53cSBarry Smith 
19363de2bfdfSBarry Smith    Notes:
1937811af0c4SBarry Smith       This is rarely used directly, it is called by `PetscFinalize()` in debug more or if -options_left
19381c9f3c13SBarry Smith       is passed otherwise to help users determine possible mistakes in their usage of options. This
1939811af0c4SBarry Smith       only prints values on process zero of `PETSC_COMM_WORLD`.
1940811af0c4SBarry Smith 
1941811af0c4SBarry Smith       Other processes depending the objects
19421c9f3c13SBarry Smith       used may have different options that are left unused.
19433de2bfdfSBarry Smith 
1944db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
19452d747510SLisandro Dalcin @*/
1946d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeft(PetscOptions options)
1947d71ae5a4SJacob Faibussowitsch {
19482d747510SLisandro Dalcin   PetscInt     i;
19493de2bfdfSBarry Smith   PetscInt     cnt = 0;
19503de2bfdfSBarry Smith   PetscOptions toptions;
19512d747510SLisandro Dalcin 
19522d747510SLisandro Dalcin   PetscFunctionBegin;
19533de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
19543de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
19553de2bfdfSBarry Smith     if (!toptions->used[i]) {
1956660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
19573de2bfdfSBarry Smith       if (toptions->values[i]) {
19589355ec05SMatthew G. Knepley         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s value: %s source: %s\n", toptions->names[i], toptions->values[i], PetscOptionSources[toptions->source[i]]));
19592d747510SLisandro Dalcin       } else {
19609355ec05SMatthew G. Knepley         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
19612d747510SLisandro Dalcin       }
19622d747510SLisandro Dalcin     }
19632d747510SLisandro Dalcin   }
19643de2bfdfSBarry Smith   if (!options) {
19653de2bfdfSBarry Smith     toptions = defaultoptions;
19663de2bfdfSBarry Smith     while (toptions->previous) {
19673de2bfdfSBarry Smith       cnt++;
19683de2bfdfSBarry Smith       toptions = toptions->previous;
19693de2bfdfSBarry Smith     }
197048a46eb9SPierre 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));
19713de2bfdfSBarry Smith   }
19723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19732d747510SLisandro Dalcin }
19742d747510SLisandro Dalcin 
19752d747510SLisandro Dalcin /*@C
19762d747510SLisandro Dalcin    PetscOptionsLeftGet - Returns all options that were set and never used.
19772d747510SLisandro Dalcin 
19782d747510SLisandro Dalcin    Not Collective
19792d747510SLisandro Dalcin 
19802d747510SLisandro Dalcin    Input Parameter:
198120f4b53cSBarry Smith .  options - options database, use `NULL` for default global database
19822d747510SLisandro Dalcin 
1983d8d19677SJose E. Roman    Output Parameters:
1984a2b725a8SWilliam Gropp +  N - count of options not used
19852d747510SLisandro Dalcin .  names - names of options not used
1986a2b725a8SWilliam Gropp -  values - values of options not used
19872d747510SLisandro Dalcin 
19882d747510SLisandro Dalcin    Level: advanced
19892d747510SLisandro Dalcin 
19902d747510SLisandro Dalcin    Notes:
1991811af0c4SBarry Smith    Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1992811af0c4SBarry Smith 
1993811af0c4SBarry Smith    The value returned may be different on each process and depends on which options have been processed
19941c9f3c13SBarry Smith    on the given process
19952d747510SLisandro Dalcin 
1996db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
19972d747510SLisandro Dalcin @*/
1998d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
1999d71ae5a4SJacob Faibussowitsch {
20002d747510SLisandro Dalcin   PetscInt i, n;
20012d747510SLisandro Dalcin 
20022d747510SLisandro Dalcin   PetscFunctionBegin;
20032d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
20042d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
20052d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
20062d747510SLisandro Dalcin   options = options ? options : defaultoptions;
20072d747510SLisandro Dalcin 
20082d747510SLisandro Dalcin   /* The number of unused PETSc options */
20092d747510SLisandro Dalcin   n = 0;
20102d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
2011660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
20122d747510SLisandro Dalcin     if (!options->used[i]) n++;
20132d747510SLisandro Dalcin   }
2014ad540459SPierre Jolivet   if (N) *N = n;
20159566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
20169566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
20172d747510SLisandro Dalcin 
20182d747510SLisandro Dalcin   n = 0;
20192d747510SLisandro Dalcin   if (names || values) {
20202d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
20212d747510SLisandro Dalcin       if (!options->used[i]) {
2022660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
20232d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
20242d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
20252d747510SLisandro Dalcin         n++;
20262d747510SLisandro Dalcin       }
20272d747510SLisandro Dalcin     }
20282d747510SLisandro Dalcin   }
20293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20302d747510SLisandro Dalcin }
20312d747510SLisandro Dalcin 
20322d747510SLisandro Dalcin /*@C
2033811af0c4SBarry Smith    PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
20342d747510SLisandro Dalcin 
20352d747510SLisandro Dalcin    Not Collective
20362d747510SLisandro Dalcin 
2037d8d19677SJose E. Roman    Input Parameters:
203820f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
20392d747510SLisandro Dalcin .  names - names of options not used
2040a2b725a8SWilliam Gropp -  values - values of options not used
20412d747510SLisandro Dalcin 
20422d747510SLisandro Dalcin    Level: advanced
20432d747510SLisandro Dalcin 
2044db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
20452d747510SLisandro Dalcin @*/
2046d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2047d71ae5a4SJacob Faibussowitsch {
20482d747510SLisandro Dalcin   PetscFunctionBegin;
20492d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
20502d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
20512d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
2052ad540459SPierre Jolivet   if (N) *N = 0;
20539566063dSJacob Faibussowitsch   if (names) PetscCall(PetscFree(*names));
20549566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
20553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20562d747510SLisandro Dalcin }
20572d747510SLisandro Dalcin 
20582d747510SLisandro Dalcin /*@C
2059811af0c4SBarry Smith    PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
20602d747510SLisandro Dalcin 
2061c3339decSBarry Smith    Logically Collective
20622d747510SLisandro Dalcin 
20632d747510SLisandro Dalcin    Input Parameters:
20642d747510SLisandro Dalcin +  name  - option name string
20652d747510SLisandro Dalcin .  value - option value string
20669355ec05SMatthew G. Knepley .  source - The source for the option
206720f4b53cSBarry Smith -  ctx - a `PETSCVIEWERASCII` or `NULL`
20682d747510SLisandro Dalcin 
20692d747510SLisandro Dalcin    Level: intermediate
20702d747510SLisandro Dalcin 
20719666a313SBarry Smith    Notes:
207220f4b53cSBarry Smith      If ctx is `NULL`, `PetscPrintf()` is used.
2073811af0c4SBarry Smith      The first MPI rank in the `PetscViewer` viewer actually prints the values, other
20741c9f3c13SBarry Smith      processes may have different values set
20751c9f3c13SBarry Smith 
2076811af0c4SBarry Smith      If `PetscCIEnabled` then do not print the test harness options
2077660278c0SBarry Smith 
2078db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
20792d747510SLisandro Dalcin @*/
20809355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], PetscOptionSource source, void *ctx)
2081d71ae5a4SJacob Faibussowitsch {
20822d747510SLisandro Dalcin   PetscFunctionBegin;
20833ba16761SJacob Faibussowitsch   if (PetscCIOption(name)) PetscFunctionReturn(PETSC_SUCCESS);
2084660278c0SBarry Smith 
20859060e2f9SVaclav Hapla   if (ctx) {
20869060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
20872d747510SLisandro Dalcin     if (!value) {
20889566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
20892d747510SLisandro Dalcin     } else if (!value[0]) {
20909355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20912d747510SLisandro Dalcin     } else {
20929355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20932d747510SLisandro Dalcin     }
20949060e2f9SVaclav Hapla   } else {
20959060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
20969060e2f9SVaclav Hapla     if (!value) {
20979566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
20989060e2f9SVaclav Hapla     } else if (!value[0]) {
20999355ec05SMatthew G. Knepley       PetscCall(PetscPrintf(comm, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
21009060e2f9SVaclav Hapla     } else {
2101aaa8cc7dSPierre Jolivet       PetscCall(PetscPrintf(comm, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
21029060e2f9SVaclav Hapla     }
21039060e2f9SVaclav Hapla   }
21043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21052d747510SLisandro Dalcin }
21062d747510SLisandro Dalcin 
21072d747510SLisandro Dalcin /*@C
21082d747510SLisandro Dalcin    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
21092d747510SLisandro Dalcin    modified the PETSc options database.
21102d747510SLisandro Dalcin 
21112d747510SLisandro Dalcin    Not Collective
21122d747510SLisandro Dalcin 
21132d747510SLisandro Dalcin    Input Parameters:
211420f4b53cSBarry Smith +  monitor - pointer to function (if this is `NULL`, it turns off monitoring
21152d747510SLisandro Dalcin .  mctx    - [optional] context for private data for the
211620f4b53cSBarry Smith              monitor routine (use `NULL` if no context is desired)
21172d747510SLisandro Dalcin -  monitordestroy - [optional] routine that frees monitor context
211820f4b53cSBarry Smith           (may be `NULL`)
21192d747510SLisandro Dalcin 
212020f4b53cSBarry Smith    Calling Sequence of `monitor`:
212120f4b53cSBarry Smith $   PetscErrorCode monitor(const char name[], const char value[], void *mctx)
21222d747510SLisandro Dalcin +  name - option name string
21232d747510SLisandro Dalcin .  value - option value string
21249355ec05SMatthew G. Knepley . source - option source
2125811af0c4SBarry Smith -  mctx  - optional monitoring context, as set by `PetscOptionsMonitorSet()`
21262d747510SLisandro Dalcin 
212720f4b53cSBarry Smith    Calling Sequence of `monitordestroy`:
212820f4b53cSBarry Smith $  PetscErrorCode monitordestroy(void *cctx)
212920f4b53cSBarry Smith 
213020f4b53cSBarry Smith    Options Database Key:
2131811af0c4SBarry Smith    See `PetscInitialize()` for options related to option database monitoring.
21322d747510SLisandro Dalcin 
213320f4b53cSBarry Smith    Level: intermediate
213420f4b53cSBarry Smith 
21352d747510SLisandro Dalcin    Notes:
21362d747510SLisandro Dalcin    The default is to do nothing.  To print the name and value of options
2137811af0c4SBarry Smith    being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
21382d747510SLisandro Dalcin    with a null monitoring context.
21392d747510SLisandro Dalcin 
21402d747510SLisandro Dalcin    Several different monitoring routines may be set by calling
2141811af0c4SBarry Smith    `PetscOptionsMonitorSet()` multiple times; all will be called in the
21422d747510SLisandro Dalcin    order in which they were set.
21432d747510SLisandro Dalcin 
2144db781477SPatrick Sanan .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
21452d747510SLisandro Dalcin @*/
21469355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **))
2147d71ae5a4SJacob Faibussowitsch {
21482d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
21492d747510SLisandro Dalcin 
21502d747510SLisandro Dalcin   PetscFunctionBegin;
21513ba16761SJacob Faibussowitsch   if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
215208401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
21532d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
21542d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
21552d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void *)mctx;
21563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21572d747510SLisandro Dalcin }
21582d747510SLisandro Dalcin 
21592d747510SLisandro Dalcin /*
21602d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
216163fe8743SVaclav Hapla      Empty string is considered as true.
21622d747510SLisandro Dalcin */
2163d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2164d71ae5a4SJacob Faibussowitsch {
21652d747510SLisandro Dalcin   PetscBool istrue, isfalse;
21662d747510SLisandro Dalcin   size_t    len;
21672d747510SLisandro Dalcin 
21682d747510SLisandro Dalcin   PetscFunctionBegin;
216963fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
21709566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
21719371c9d4SSatish Balay   if (!len) {
21729371c9d4SSatish Balay     *a = PETSC_TRUE;
21733ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21749371c9d4SSatish Balay   }
21759566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
21769371c9d4SSatish Balay   if (istrue) {
21779371c9d4SSatish Balay     *a = PETSC_TRUE;
21783ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21799371c9d4SSatish Balay   }
21809566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
21819371c9d4SSatish Balay   if (istrue) {
21829371c9d4SSatish Balay     *a = PETSC_TRUE;
21833ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21849371c9d4SSatish Balay   }
21859566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
21869371c9d4SSatish Balay   if (istrue) {
21879371c9d4SSatish Balay     *a = PETSC_TRUE;
21883ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21899371c9d4SSatish Balay   }
21909566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
21919371c9d4SSatish Balay   if (istrue) {
21929371c9d4SSatish Balay     *a = PETSC_TRUE;
21933ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21949371c9d4SSatish Balay   }
21959566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
21969371c9d4SSatish Balay   if (isfalse) {
21979371c9d4SSatish Balay     *a = PETSC_FALSE;
21983ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21999371c9d4SSatish Balay   }
22009566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
22019371c9d4SSatish Balay   if (isfalse) {
22029371c9d4SSatish Balay     *a = PETSC_FALSE;
22033ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22049371c9d4SSatish Balay   }
22059566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
22069371c9d4SSatish Balay   if (isfalse) {
22079371c9d4SSatish Balay     *a = PETSC_FALSE;
22083ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22099371c9d4SSatish Balay   }
22109566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
22119371c9d4SSatish Balay   if (isfalse) {
22129371c9d4SSatish Balay     *a = PETSC_FALSE;
22133ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22149371c9d4SSatish Balay   }
221598921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
22162d747510SLisandro Dalcin }
22172d747510SLisandro Dalcin 
22182d747510SLisandro Dalcin /*
22192d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
22202d747510SLisandro Dalcin */
2221d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2222d71ae5a4SJacob Faibussowitsch {
22232d747510SLisandro Dalcin   size_t    len;
22242d747510SLisandro Dalcin   PetscBool decide, tdefault, mouse;
22252d747510SLisandro Dalcin 
22262d747510SLisandro Dalcin   PetscFunctionBegin;
22279566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
22285f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22292d747510SLisandro Dalcin 
22309566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
223148a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
22329566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
223348a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
22349566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
22352d747510SLisandro Dalcin 
22362d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
22372d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
22382d747510SLisandro Dalcin   else if (mouse) *a = -1;
22392d747510SLisandro Dalcin   else {
22402d747510SLisandro Dalcin     char *endptr;
22412d747510SLisandro Dalcin     long  strtolval;
22422d747510SLisandro Dalcin 
22432d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2244cc73adaaSBarry 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);
22452d747510SLisandro Dalcin 
22462d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
22472d747510SLisandro Dalcin     (void)strtolval;
22482d747510SLisandro Dalcin     *a = atoll(name);
22492d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
22502d747510SLisandro Dalcin     (void)strtolval;
22512d747510SLisandro Dalcin     *a = _atoi64(name);
22522d747510SLisandro Dalcin #else
22532d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
22542d747510SLisandro Dalcin #endif
22552d747510SLisandro Dalcin   }
22563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22572d747510SLisandro Dalcin }
22582d747510SLisandro Dalcin 
22592d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22602d747510SLisandro Dalcin   #include <quadmath.h>
22612d747510SLisandro Dalcin #endif
22622d747510SLisandro Dalcin 
2263d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2264d71ae5a4SJacob Faibussowitsch {
22652d747510SLisandro Dalcin   PetscFunctionBegin;
22662d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22672d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
22682d747510SLisandro Dalcin #else
22692d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
22702d747510SLisandro Dalcin #endif
22713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22722d747510SLisandro Dalcin }
22732d747510SLisandro Dalcin 
2274d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2275d71ae5a4SJacob Faibussowitsch {
22762d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
22772d747510SLisandro Dalcin   char     *ptr;
22782d747510SLisandro Dalcin   PetscReal strtoval;
22792d747510SLisandro Dalcin 
22802d747510SLisandro Dalcin   PetscFunctionBegin;
22819566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
22822d747510SLisandro Dalcin   if (ptr == name) {
22832d747510SLisandro Dalcin     strtoval = 1.;
22842d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
22852d747510SLisandro Dalcin     if (name[0] == 'i') {
22862d747510SLisandro Dalcin       ptr++;
22872d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
22882d747510SLisandro Dalcin       ptr += 2;
22892d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
22902d747510SLisandro Dalcin       strtoval = -1.;
22912d747510SLisandro Dalcin       ptr += 2;
22922d747510SLisandro Dalcin     }
22932d747510SLisandro Dalcin   } else if (*ptr == 'i') {
22942d747510SLisandro Dalcin     hasi = PETSC_TRUE;
22952d747510SLisandro Dalcin     ptr++;
22962d747510SLisandro Dalcin   }
22972d747510SLisandro Dalcin   *endptr      = ptr;
22982d747510SLisandro Dalcin   *isImaginary = hasi;
22992d747510SLisandro Dalcin   if (hasi) {
23002d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
230198921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
23022d747510SLisandro Dalcin #else
23032d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
23042d747510SLisandro Dalcin #endif
23052d747510SLisandro Dalcin   } else {
23062d747510SLisandro Dalcin     *a = strtoval;
23072d747510SLisandro Dalcin   }
23083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23092d747510SLisandro Dalcin }
23102d747510SLisandro Dalcin 
23112d747510SLisandro Dalcin /*
23122d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
23132d747510SLisandro Dalcin */
2314d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2315d71ae5a4SJacob Faibussowitsch {
23162d747510SLisandro Dalcin   size_t    len;
23172d747510SLisandro Dalcin   PetscBool match;
23182d747510SLisandro Dalcin   char     *endptr;
23192d747510SLisandro Dalcin 
23202d747510SLisandro Dalcin   PetscFunctionBegin;
23219566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
232228b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
23232d747510SLisandro Dalcin 
23249566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
23259566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
23269371c9d4SSatish Balay   if (match) {
23279371c9d4SSatish Balay     *a = PETSC_DEFAULT;
23283ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23299371c9d4SSatish Balay   }
23302d747510SLisandro Dalcin 
23319566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
23329566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
23339371c9d4SSatish Balay   if (match) {
23349371c9d4SSatish Balay     *a = PETSC_DECIDE;
23353ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23369371c9d4SSatish Balay   }
23372d747510SLisandro Dalcin 
23389566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
233939a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
23403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23412d747510SLisandro Dalcin }
23422d747510SLisandro Dalcin 
2343d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2344d71ae5a4SJacob Faibussowitsch {
23452d747510SLisandro Dalcin   PetscBool   imag1;
23462d747510SLisandro Dalcin   size_t      len;
23472d747510SLisandro Dalcin   PetscScalar val = 0.;
23482d747510SLisandro Dalcin   char       *ptr = NULL;
23492d747510SLisandro Dalcin 
23502d747510SLisandro Dalcin   PetscFunctionBegin;
23519566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
235228b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
23539566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
23542d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
23552d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
23562d747510SLisandro Dalcin     PetscBool   imag2;
23572d747510SLisandro Dalcin     PetscScalar val2;
23582d747510SLisandro Dalcin 
23599566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
236039a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
23612d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
23622d747510SLisandro Dalcin   }
23632d747510SLisandro Dalcin #endif
236439a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
23652d747510SLisandro Dalcin   *a = val;
23663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23672d747510SLisandro Dalcin }
23682d747510SLisandro Dalcin 
23692d747510SLisandro Dalcin /*@C
23702d747510SLisandro Dalcin    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
23712d747510SLisandro Dalcin             option in the database.
2372e5c89e4eSSatish Balay 
2373e5c89e4eSSatish Balay    Not Collective
2374e5c89e4eSSatish Balay 
2375e5c89e4eSSatish Balay    Input Parameters:
237620f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
237720f4b53cSBarry Smith .  pre - the string to prepend to the name or `NULL`
2378e5c89e4eSSatish Balay -  name - the option one is seeking
2379e5c89e4eSSatish Balay 
2380d8d19677SJose E. Roman    Output Parameters:
23812d747510SLisandro Dalcin +  ivalue - the logical value to return
2382811af0c4SBarry Smith -  set - `PETSC_TRUE`  if found, else `PETSC_FALSE`
2383e5c89e4eSSatish Balay 
2384e5c89e4eSSatish Balay    Level: beginner
2385e5c89e4eSSatish Balay 
238695452b02SPatrick Sanan    Notes:
2387811af0c4SBarry Smith        TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`
2388811af0c4SBarry Smith        FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
23892d747510SLisandro Dalcin 
2390811af0c4SBarry 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
23912d747510SLisandro Dalcin      is equivalent to -requested_bool true
23922d747510SLisandro Dalcin 
23932d747510SLisandro Dalcin        If the user does not supply the option at all ivalue is NOT changed. Thus
23942efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
23952efd9cb1SBarry Smith 
2396db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2397db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2398db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2399c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2400db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2401db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2402e5c89e4eSSatish Balay @*/
2403d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2404d71ae5a4SJacob Faibussowitsch {
24052d747510SLisandro Dalcin   const char *value;
2406ace3abfcSBarry Smith   PetscBool   flag;
2407e5c89e4eSSatish Balay 
2408e5c89e4eSSatish Balay   PetscFunctionBegin;
24092d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2410064a246eSJacob Faibussowitsch   if (ivalue) PetscValidBoolPointer(ivalue, 4);
24119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2412e5c89e4eSSatish Balay   if (flag) {
241396ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
24149566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
24152d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2416e5c89e4eSSatish Balay   } else {
241796ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2418e5c89e4eSSatish Balay   }
24193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2420e5c89e4eSSatish Balay }
2421e5c89e4eSSatish Balay 
2422e5c89e4eSSatish Balay /*@C
2423e5c89e4eSSatish Balay    PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2424e5c89e4eSSatish Balay 
2425e5c89e4eSSatish Balay    Not Collective
2426e5c89e4eSSatish Balay 
2427e5c89e4eSSatish Balay    Input Parameters:
242820f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
242920f4b53cSBarry Smith .  pre - the string to prepend to the name or `NULL`
2430e5c89e4eSSatish Balay .  opt - option name
2431a264d7a6SBarry Smith .  list - the possible choices (one of these must be selected, anything else is invalid)
2432a2b725a8SWilliam Gropp -  ntext - number of choices
2433e5c89e4eSSatish Balay 
2434d8d19677SJose E. Roman    Output Parameters:
24352efd9cb1SBarry Smith +  value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2436811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2437e5c89e4eSSatish Balay 
2438e5c89e4eSSatish Balay    Level: intermediate
2439e5c89e4eSSatish Balay 
244095452b02SPatrick Sanan    Notes:
244195452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
24422efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
24432efd9cb1SBarry Smith 
2444811af0c4SBarry Smith    See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2445e5c89e4eSSatish Balay 
2446db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2447db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2448db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2449c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2450db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2451db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2452e5c89e4eSSatish Balay @*/
2453d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscInt ntext, PetscInt *value, PetscBool *set)
2454d71ae5a4SJacob Faibussowitsch {
245558b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2456e5c89e4eSSatish Balay   char     *svalue;
2457ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2458e5c89e4eSSatish Balay   PetscInt  i;
2459e5c89e4eSSatish Balay 
2460e5c89e4eSSatish Balay   PetscFunctionBegin;
24612d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
2462e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
24639566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2464e5c89e4eSSatish Balay     if (alen > len) len = alen;
246558b0ac4eSStefano Zampini     tlen += len + 1;
2466e5c89e4eSSatish Balay   }
2467e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
24689566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
24699566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2470e5c89e4eSSatish Balay   if (aset) {
24719566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
247258b0ac4eSStefano Zampini     if (!flg) {
2473c6a7a370SJeremy L Thompson       char *avail;
247458b0ac4eSStefano Zampini 
24759566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
2476c6a7a370SJeremy L Thompson       avail[0] = '\0';
247758b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
2478c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, list[i], tlen));
2479c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, " ", tlen));
248058b0ac4eSStefano Zampini       }
24819566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
248298921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
248358b0ac4eSStefano Zampini     }
2484fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2485a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
24869566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
24873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2488e5c89e4eSSatish Balay }
2489e5c89e4eSSatish Balay 
2490e5c89e4eSSatish Balay /*@C
2491e5c89e4eSSatish Balay    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2492e5c89e4eSSatish Balay 
2493e5c89e4eSSatish Balay    Not Collective
2494e5c89e4eSSatish Balay 
2495e5c89e4eSSatish Balay    Input Parameters:
249620f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
249720f4b53cSBarry Smith .  pre - option prefix or `NULL`
2498e5c89e4eSSatish Balay .  opt - option name
24996b867d5aSJose E. Roman -  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2500e5c89e4eSSatish Balay 
2501d8d19677SJose E. Roman    Output Parameters:
2502e5c89e4eSSatish Balay +  value - the  value to return
2503811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2504e5c89e4eSSatish Balay 
2505e5c89e4eSSatish Balay    Level: beginner
2506e5c89e4eSSatish Balay 
250795452b02SPatrick Sanan    Notes:
250895452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
25092efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2510e5c89e4eSSatish Balay 
2511811af0c4SBarry Smith           List is usually something like `PCASMTypes` or some other predefined list of enum names
2512e5c89e4eSSatish Balay 
2513db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2514db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2515db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2516db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2517c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2518db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2519db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2520e5c89e4eSSatish Balay @*/
2521d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscEnum *value, PetscBool *set)
2522d71ae5a4SJacob Faibussowitsch {
252369a24498SJed Brown   PetscInt  ntext = 0, tval;
2524ace3abfcSBarry Smith   PetscBool fset;
2525e5c89e4eSSatish Balay 
2526e5c89e4eSSatish Balay   PetscFunctionBegin;
25272d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
2528ad540459SPierre 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");
252908401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2530e5c89e4eSSatish Balay   ntext -= 3;
25319566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
253269a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2533809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2534809ceb46SBarry Smith   if (set) *set = fset;
25353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2536e5c89e4eSSatish Balay }
2537e5c89e4eSSatish Balay 
2538e5c89e4eSSatish Balay /*@C
25392d747510SLisandro Dalcin    PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2540e5c89e4eSSatish Balay 
2541e5c89e4eSSatish Balay    Not Collective
2542e5c89e4eSSatish Balay 
2543e5c89e4eSSatish Balay    Input Parameters:
254420f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
254520f4b53cSBarry Smith .  pre - the string to prepend to the name or `NULL`
2546e5c89e4eSSatish Balay -  name - the option one is seeking
2547e5c89e4eSSatish Balay 
2548d8d19677SJose E. Roman    Output Parameters:
25492d747510SLisandro Dalcin +  ivalue - the integer value to return
2550811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2551e5c89e4eSSatish Balay 
2552e5c89e4eSSatish Balay    Level: beginner
2553e5c89e4eSSatish Balay 
2554e5c89e4eSSatish Balay    Notes:
25552d747510SLisandro Dalcin    If the user does not supply the option ivalue is NOT changed. Thus
25562efd9cb1SBarry Smith    you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
25575c07ccb8SBarry Smith 
2558db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2559db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2560db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2561db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2562c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2563db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2564db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2565e5c89e4eSSatish Balay @*/
2566d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2567d71ae5a4SJacob Faibussowitsch {
25682d747510SLisandro Dalcin   const char *value;
25692d747510SLisandro Dalcin   PetscBool   flag;
2570e5c89e4eSSatish Balay 
2571e5c89e4eSSatish Balay   PetscFunctionBegin;
25722d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
25732d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
25749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2575e5c89e4eSSatish Balay   if (flag) {
257634a9cc2cSBarry Smith     if (!value) {
25772d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
257834a9cc2cSBarry Smith     } else {
25792d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
25809566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2581e5c89e4eSSatish Balay     }
2582e5c89e4eSSatish Balay   } else {
258396ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2584e5c89e4eSSatish Balay   }
25853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2586e5c89e4eSSatish Balay }
2587e5c89e4eSSatish Balay 
2588e2446a98SMatthew Knepley /*@C
2589e5c89e4eSSatish Balay    PetscOptionsGetReal - Gets the double precision value for a particular
2590e5c89e4eSSatish Balay    option in the database.
2591e5c89e4eSSatish Balay 
2592e5c89e4eSSatish Balay    Not Collective
2593e5c89e4eSSatish Balay 
2594e5c89e4eSSatish Balay    Input Parameters:
259520f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
259620f4b53cSBarry Smith .  pre - string to prepend to each name or `NULL`
2597e5c89e4eSSatish Balay -  name - the option one is seeking
2598e5c89e4eSSatish Balay 
2599d8d19677SJose E. Roman    Output Parameters:
2600e5c89e4eSSatish Balay +  dvalue - the double value to return
2601811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2602e5c89e4eSSatish Balay 
260320f4b53cSBarry Smith    Level: beginner
260420f4b53cSBarry Smith 
2605811af0c4SBarry Smith    Note:
260695452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
26072efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2608e4974155SBarry Smith 
2609db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2610c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2611db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2612c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2613db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2614db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2615e5c89e4eSSatish Balay @*/
2616d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2617d71ae5a4SJacob Faibussowitsch {
26182d747510SLisandro Dalcin   const char *value;
2619ace3abfcSBarry Smith   PetscBool   flag;
2620e5c89e4eSSatish Balay 
2621e5c89e4eSSatish Balay   PetscFunctionBegin;
26222d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
26232d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
26249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2625e5c89e4eSSatish Balay   if (flag) {
2626a297a907SKarl Rupp     if (!value) {
2627a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2628a297a907SKarl Rupp     } else {
2629a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
26309566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2631a297a907SKarl Rupp     }
2632e5c89e4eSSatish Balay   } else {
263396ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2634e5c89e4eSSatish Balay   }
26353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2636e5c89e4eSSatish Balay }
2637e5c89e4eSSatish Balay 
2638e5c89e4eSSatish Balay /*@C
2639e5c89e4eSSatish Balay    PetscOptionsGetScalar - Gets the scalar value for a particular
2640e5c89e4eSSatish Balay    option in the database.
2641e5c89e4eSSatish Balay 
2642e5c89e4eSSatish Balay    Not Collective
2643e5c89e4eSSatish Balay 
2644e5c89e4eSSatish Balay    Input Parameters:
264520f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
264620f4b53cSBarry Smith .  pre - string to prepend to each name or `NULL`
2647e5c89e4eSSatish Balay -  name - the option one is seeking
2648e5c89e4eSSatish Balay 
2649d8d19677SJose E. Roman    Output Parameters:
2650e5c89e4eSSatish Balay +  dvalue - the double value to return
2651811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2652e5c89e4eSSatish Balay 
2653e5c89e4eSSatish Balay    Level: beginner
2654e5c89e4eSSatish Balay 
2655e5c89e4eSSatish Balay    Usage:
2656eb4ae41dSBarry Smith    A complex number 2+3i must be specified with NO spaces
2657e5c89e4eSSatish Balay 
2658811af0c4SBarry Smith    Note:
265995452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
26602efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2661e4974155SBarry Smith 
2662db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2663db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2664db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2665c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2666db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2667db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2668e5c89e4eSSatish Balay @*/
2669d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2670d71ae5a4SJacob Faibussowitsch {
26712d747510SLisandro Dalcin   const char *value;
2672ace3abfcSBarry Smith   PetscBool   flag;
2673e5c89e4eSSatish Balay 
2674e5c89e4eSSatish Balay   PetscFunctionBegin;
26752d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
26762d747510SLisandro Dalcin   PetscValidScalarPointer(dvalue, 4);
26779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2678e5c89e4eSSatish Balay   if (flag) {
2679e5c89e4eSSatish Balay     if (!value) {
268096ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2681e5c89e4eSSatish Balay     } else {
2682e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
26839566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2684e5c89e4eSSatish Balay #else
26859566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2686e5c89e4eSSatish Balay #endif
268796ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2688e5c89e4eSSatish Balay     }
2689e5c89e4eSSatish Balay   } else { /* flag */
269096ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2691e5c89e4eSSatish Balay   }
26923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2693e5c89e4eSSatish Balay }
2694e5c89e4eSSatish Balay 
2695e5c89e4eSSatish Balay /*@C
2696e5c89e4eSSatish Balay    PetscOptionsGetString - Gets the string value for a particular option in
2697e5c89e4eSSatish Balay    the database.
2698e5c89e4eSSatish Balay 
2699e5c89e4eSSatish Balay    Not Collective
2700e5c89e4eSSatish Balay 
2701e5c89e4eSSatish Balay    Input Parameters:
270220f4b53cSBarry Smith +  options - options database, use `NULL` for default global database
270320f4b53cSBarry Smith .  pre - string to prepend to name or `NULL`
2704e5c89e4eSSatish Balay .  name - the option one is seeking
2705bcbf2dc5SJed Brown -  len - maximum length of the string including null termination
2706e5c89e4eSSatish Balay 
2707e5c89e4eSSatish Balay    Output Parameters:
2708e5c89e4eSSatish Balay +  string - location to copy string
2709811af0c4SBarry Smith -  set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2710e5c89e4eSSatish Balay 
2711e5c89e4eSSatish Balay    Level: beginner
2712e5c89e4eSSatish Balay 
271320f4b53cSBarry Smith    Note:
271420f4b53cSBarry 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`
271520f4b53cSBarry Smith 
271620f4b53cSBarry Smith            If the user does not use the option then the string is not changed. Thus
271720f4b53cSBarry Smith            you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
271820f4b53cSBarry Smith 
271920f4b53cSBarry 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).
272020f4b53cSBarry Smith 
2721e5c89e4eSSatish Balay    Fortran Note:
2722e5c89e4eSSatish Balay    The Fortran interface is slightly different from the C/C++
2723e5c89e4eSSatish Balay    interface (len is not used).  Sample usage in Fortran follows
2724e5c89e4eSSatish Balay .vb
2725e5c89e4eSSatish Balay       character *20    string
272693e6ba5cSBarry Smith       PetscErrorCode   ierr
272793e6ba5cSBarry Smith       PetscBool        set
27281b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2729e5c89e4eSSatish Balay .ve
2730e5c89e4eSSatish Balay 
2731db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2732db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2733db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2734c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2735db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2736db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2737e5c89e4eSSatish Balay @*/
2738d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set)
2739d71ae5a4SJacob Faibussowitsch {
27402d747510SLisandro Dalcin   const char *value;
2741ace3abfcSBarry Smith   PetscBool   flag;
2742e5c89e4eSSatish Balay 
2743e5c89e4eSSatish Balay   PetscFunctionBegin;
27442d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
27452d747510SLisandro Dalcin   PetscValidCharPointer(string, 4);
27469566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2747e5c89e4eSSatish Balay   if (!flag) {
274896ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2749e5c89e4eSSatish Balay   } else {
275096ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
27519566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
27529566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2753e5c89e4eSSatish Balay   }
27543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2755e5c89e4eSSatish Balay }
2756e5c89e4eSSatish Balay 
2757d71ae5a4SJacob Faibussowitsch char *PetscOptionsGetStringMatlab(PetscOptions options, const char pre[], const char name[])
2758d71ae5a4SJacob Faibussowitsch {
27592d747510SLisandro Dalcin   const char *value;
276014ce751eSBarry Smith   PetscBool   flag;
276114ce751eSBarry Smith 
276214ce751eSBarry Smith   PetscFunctionBegin;
276339a651e2SJacob Faibussowitsch   if (PetscOptionsFindPair(options, pre, name, &value, &flag)) PetscFunctionReturn(NULL);
27642d747510SLisandro Dalcin   if (flag) PetscFunctionReturn((char *)value);
276539a651e2SJacob Faibussowitsch   PetscFunctionReturn(NULL);
276614ce751eSBarry Smith }
276714ce751eSBarry Smith 
27682d747510SLisandro Dalcin /*@C
27692d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2770f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
27712d747510SLisandro Dalcin 
27722d747510SLisandro Dalcin   Not Collective
27732d747510SLisandro Dalcin 
27742d747510SLisandro Dalcin   Input Parameters:
277520f4b53cSBarry Smith + options - options database, use `NULL` for default global database
277620f4b53cSBarry Smith . pre - string to prepend to each name or `NULL`
27776b867d5aSJose E. Roman - name - the option one is seeking
27786b867d5aSJose E. Roman 
2779d8d19677SJose E. Roman   Output Parameters:
27802d747510SLisandro Dalcin + dvalue - the integer values to return
2781f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2782811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
27832d747510SLisandro Dalcin 
27842d747510SLisandro Dalcin   Level: beginner
27852d747510SLisandro Dalcin 
2786811af0c4SBarry Smith   Note:
278720f4b53cSBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`. FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
27882d747510SLisandro Dalcin 
2789db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2790db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2791db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2792c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2793db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2794db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
27952d747510SLisandro Dalcin @*/
2796d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2797d71ae5a4SJacob Faibussowitsch {
27982d747510SLisandro Dalcin   const char *svalue;
27992d747510SLisandro Dalcin   char       *value;
28002d747510SLisandro Dalcin   PetscInt    n = 0;
28012d747510SLisandro Dalcin   PetscBool   flag;
28022d747510SLisandro Dalcin   PetscToken  token;
28032d747510SLisandro Dalcin 
28042d747510SLisandro Dalcin   PetscFunctionBegin;
28052d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2806064a246eSJacob Faibussowitsch   PetscValidBoolPointer(dvalue, 4);
28072d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
28082d747510SLisandro Dalcin 
28099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28109371c9d4SSatish Balay   if (!flag || !svalue) {
28119371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28129371c9d4SSatish Balay     *nmax = 0;
28133ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
28149371c9d4SSatish Balay   }
28152d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28169566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28179566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28182d747510SLisandro Dalcin   while (value && n < *nmax) {
28199566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
28209566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
28212d747510SLisandro Dalcin     dvalue++;
28222d747510SLisandro Dalcin     n++;
28232d747510SLisandro Dalcin   }
28249566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28252d747510SLisandro Dalcin   *nmax = n;
28263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28272d747510SLisandro Dalcin }
28282d747510SLisandro Dalcin 
28292d747510SLisandro Dalcin /*@C
28302d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
28312d747510SLisandro Dalcin 
28322d747510SLisandro Dalcin   Not Collective
28332d747510SLisandro Dalcin 
28342d747510SLisandro Dalcin   Input Parameters:
283520f4b53cSBarry Smith + options - options database, use `NULL` for default global database
283620f4b53cSBarry Smith . pre - option prefix or `NULL`
28372d747510SLisandro Dalcin . name - option name
28386b867d5aSJose E. Roman - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
28396b867d5aSJose E. Roman 
28402d747510SLisandro Dalcin   Output Parameters:
28412d747510SLisandro Dalcin + ivalue - the  enum values to return
2842f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2843811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
28442d747510SLisandro Dalcin 
28452d747510SLisandro Dalcin   Level: beginner
28462d747510SLisandro Dalcin 
28472d747510SLisandro Dalcin   Notes:
28482d747510SLisandro Dalcin   The array must be passed as a comma separated list.
28492d747510SLisandro Dalcin 
28502d747510SLisandro Dalcin   There must be no intervening spaces between the values.
28512d747510SLisandro Dalcin 
2852811af0c4SBarry Smith   list is usually something like `PCASMTypes` or some other predefined list of enum names.
28532d747510SLisandro Dalcin 
2854db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2855db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2856db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, `PetscOptionsName()`,
2857c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2858db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2859db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
28602d747510SLisandro Dalcin @*/
2861d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const *list, PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
2862d71ae5a4SJacob Faibussowitsch {
28632d747510SLisandro Dalcin   const char *svalue;
28642d747510SLisandro Dalcin   char       *value;
28652d747510SLisandro Dalcin   PetscInt    n = 0;
28662d747510SLisandro Dalcin   PetscEnum   evalue;
28672d747510SLisandro Dalcin   PetscBool   flag;
28682d747510SLisandro Dalcin   PetscToken  token;
28692d747510SLisandro Dalcin 
28702d747510SLisandro Dalcin   PetscFunctionBegin;
28712d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
28722d747510SLisandro Dalcin   PetscValidPointer(list, 4);
28732d747510SLisandro Dalcin   PetscValidPointer(ivalue, 5);
28742d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 6);
28752d747510SLisandro Dalcin 
28769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28779371c9d4SSatish Balay   if (!flag || !svalue) {
28789371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28799371c9d4SSatish Balay     *nmax = 0;
28803ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
28819371c9d4SSatish Balay   }
28822d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28839566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28849566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28852d747510SLisandro Dalcin   while (value && n < *nmax) {
28869566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
288728b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
28882d747510SLisandro Dalcin     ivalue[n++] = evalue;
28899566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
28902d747510SLisandro Dalcin   }
28919566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28922d747510SLisandro Dalcin   *nmax = n;
28933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28942d747510SLisandro Dalcin }
28952d747510SLisandro Dalcin 
28962d747510SLisandro Dalcin /*@C
2897f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
28982d747510SLisandro Dalcin 
28992d747510SLisandro Dalcin   Not Collective
29002d747510SLisandro Dalcin 
29012d747510SLisandro Dalcin   Input Parameters:
290220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
290320f4b53cSBarry Smith . pre - string to prepend to each name or `NULL`
29046b867d5aSJose E. Roman - name - the option one is seeking
29056b867d5aSJose E. Roman 
2906d8d19677SJose E. Roman   Output Parameters:
29072d747510SLisandro Dalcin + ivalue - the integer values to return
2908f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2909811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
29102d747510SLisandro Dalcin 
29112d747510SLisandro Dalcin   Level: beginner
29122d747510SLisandro Dalcin 
29132d747510SLisandro Dalcin   Notes:
29142d747510SLisandro Dalcin   The array can be passed as
2915811af0c4SBarry Smith +  a comma separated list -                                 0,1,2,3,4,5,6,7
2916811af0c4SBarry Smith .  a range (start\-end+1) -                                 0-8
2917811af0c4SBarry Smith .  a range with given increment (start\-end+1:inc) -        0-7:2
2918811af0c4SBarry Smith -  a combination of values and ranges separated by commas - 0,1-8,8-15:2
29192d747510SLisandro Dalcin 
29202d747510SLisandro Dalcin   There must be no intervening spaces between the values.
29212d747510SLisandro Dalcin 
2922db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2923db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2924db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2925c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2926db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2927db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29282d747510SLisandro Dalcin @*/
2929d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
2930d71ae5a4SJacob Faibussowitsch {
29312d747510SLisandro Dalcin   const char *svalue;
29322d747510SLisandro Dalcin   char       *value;
29332d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
29342d747510SLisandro Dalcin   size_t      len;
29352d747510SLisandro Dalcin   PetscBool   flag, foundrange;
29362d747510SLisandro Dalcin   PetscToken  token;
29372d747510SLisandro Dalcin 
29382d747510SLisandro Dalcin   PetscFunctionBegin;
29392d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
29402d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
29412d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
29422d747510SLisandro Dalcin 
29439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29449371c9d4SSatish Balay   if (!flag || !svalue) {
29459371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29469371c9d4SSatish Balay     *nmax = 0;
29473ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29489371c9d4SSatish Balay   }
29492d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29509566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29519566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29522d747510SLisandro Dalcin   while (value && n < *nmax) {
29532d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
29542d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
29559566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value, &len));
29562d747510SLisandro Dalcin     if (value[0] == '-') i = 2;
29572d747510SLisandro Dalcin     else i = 1;
29582d747510SLisandro Dalcin     for (; i < (int)len; i++) {
29592d747510SLisandro Dalcin       if (value[i] == '-') {
2960cc73adaaSBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
29612d747510SLisandro Dalcin         value[i] = 0;
29622d747510SLisandro Dalcin 
29639566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value, &start));
29642d747510SLisandro Dalcin         inc = 1;
29652d747510SLisandro Dalcin         j   = i + 1;
29662d747510SLisandro Dalcin         for (; j < (int)len; j++) {
29672d747510SLisandro Dalcin           if (value[j] == ':') {
29682d747510SLisandro Dalcin             value[j] = 0;
29692d747510SLisandro Dalcin 
29709566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value + j + 1, &inc));
297108401ef6SPierre 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);
29722d747510SLisandro Dalcin             break;
29732d747510SLisandro Dalcin           }
29742d747510SLisandro Dalcin         }
29759566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
297608401ef6SPierre 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);
29772d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
2978cc73adaaSBarry 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);
29792d747510SLisandro Dalcin         for (; start < end; start += inc) {
29809371c9d4SSatish Balay           *ivalue = start;
29819371c9d4SSatish Balay           ivalue++;
29829371c9d4SSatish Balay           n++;
29832d747510SLisandro Dalcin         }
29842d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
29852d747510SLisandro Dalcin         break;
29862d747510SLisandro Dalcin       }
29872d747510SLisandro Dalcin     }
29882d747510SLisandro Dalcin     if (!foundrange) {
29899566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
29902d747510SLisandro Dalcin       ivalue++;
29912d747510SLisandro Dalcin       n++;
29922d747510SLisandro Dalcin     }
29939566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29942d747510SLisandro Dalcin   }
29959566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29962d747510SLisandro Dalcin   *nmax = n;
29973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29982d747510SLisandro Dalcin }
29992d747510SLisandro Dalcin 
30002d747510SLisandro Dalcin /*@C
30012d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
3002f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
30032d747510SLisandro Dalcin 
30042d747510SLisandro Dalcin   Not Collective
30052d747510SLisandro Dalcin 
30062d747510SLisandro Dalcin   Input Parameters:
300720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
300820f4b53cSBarry Smith . pre - string to prepend to each name or `NULL`
30096b867d5aSJose E. Roman - name - the option one is seeking
30106b867d5aSJose E. Roman 
30112d747510SLisandro Dalcin   Output Parameters:
30122d747510SLisandro Dalcin + dvalue - the double values to return
3013f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3014811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
30152d747510SLisandro Dalcin 
30162d747510SLisandro Dalcin   Level: beginner
30172d747510SLisandro Dalcin 
3018db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3019db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3020db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3021c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3022db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3023db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30242d747510SLisandro Dalcin @*/
3025d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
3026d71ae5a4SJacob Faibussowitsch {
30272d747510SLisandro Dalcin   const char *svalue;
30282d747510SLisandro Dalcin   char       *value;
30292d747510SLisandro Dalcin   PetscInt    n = 0;
30302d747510SLisandro Dalcin   PetscBool   flag;
30312d747510SLisandro Dalcin   PetscToken  token;
30322d747510SLisandro Dalcin 
30332d747510SLisandro Dalcin   PetscFunctionBegin;
30342d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
30352d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
30362d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
30372d747510SLisandro Dalcin 
30389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30399371c9d4SSatish Balay   if (!flag || !svalue) {
30409371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30419371c9d4SSatish Balay     *nmax = 0;
30423ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
30439371c9d4SSatish Balay   }
30442d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30459566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30469566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30472d747510SLisandro Dalcin   while (value && n < *nmax) {
30489566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
30499566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30502d747510SLisandro Dalcin     n++;
30512d747510SLisandro Dalcin   }
30529566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30532d747510SLisandro Dalcin   *nmax = n;
30543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30552d747510SLisandro Dalcin }
30562d747510SLisandro Dalcin 
30572d747510SLisandro Dalcin /*@C
30582d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
3059f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
30602d747510SLisandro Dalcin 
30612d747510SLisandro Dalcin   Not Collective
30622d747510SLisandro Dalcin 
30632d747510SLisandro Dalcin   Input Parameters:
306420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
306520f4b53cSBarry Smith . pre - string to prepend to each name or `NULL`
30666b867d5aSJose E. Roman - name - the option one is seeking
30676b867d5aSJose E. Roman 
30682d747510SLisandro Dalcin   Output Parameters:
30692d747510SLisandro Dalcin + dvalue - the scalar values to return
3070f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3071811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
30722d747510SLisandro Dalcin 
30732d747510SLisandro Dalcin   Level: beginner
30742d747510SLisandro Dalcin 
3075db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3076db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3077db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3078c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3079db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3080db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30812d747510SLisandro Dalcin @*/
3082d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3083d71ae5a4SJacob Faibussowitsch {
30842d747510SLisandro Dalcin   const char *svalue;
30852d747510SLisandro Dalcin   char       *value;
30862d747510SLisandro Dalcin   PetscInt    n = 0;
30872d747510SLisandro Dalcin   PetscBool   flag;
30882d747510SLisandro Dalcin   PetscToken  token;
30892d747510SLisandro Dalcin 
30902d747510SLisandro Dalcin   PetscFunctionBegin;
30912d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
3092064a246eSJacob Faibussowitsch   PetscValidScalarPointer(dvalue, 4);
30932d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
30942d747510SLisandro Dalcin 
30959566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30969371c9d4SSatish Balay   if (!flag || !svalue) {
30979371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30989371c9d4SSatish Balay     *nmax = 0;
30993ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
31009371c9d4SSatish Balay   }
31012d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31029566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31039566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31042d747510SLisandro Dalcin   while (value && n < *nmax) {
31059566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value, dvalue++));
31069566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
31072d747510SLisandro Dalcin     n++;
31082d747510SLisandro Dalcin   }
31099566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
31102d747510SLisandro Dalcin   *nmax = n;
31113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31122d747510SLisandro Dalcin }
311314ce751eSBarry Smith 
3114e5c89e4eSSatish Balay /*@C
3115e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
3116f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
3117e5c89e4eSSatish Balay 
3118cf53795eSBarry Smith   Not Collective; No Fortran Support
3119e5c89e4eSSatish Balay 
3120e5c89e4eSSatish Balay   Input Parameters:
312120f4b53cSBarry Smith + options - options database, use `NULL` for default global database
312220f4b53cSBarry Smith . pre - string to prepend to name or `NULL`
31236b867d5aSJose E. Roman - name - the option one is seeking
31246b867d5aSJose E. Roman 
3125e7b76fa7SPatrick Sanan   Output Parameters:
3126e5c89e4eSSatish Balay + strings - location to copy strings
3127f1a722f8SMatthew G. Knepley . nmax - On input maximum number of strings, on output the actual number of strings found
3128811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3129e5c89e4eSSatish Balay 
3130e5c89e4eSSatish Balay   Level: beginner
3131e5c89e4eSSatish Balay 
3132e5c89e4eSSatish Balay   Notes:
3133e7b76fa7SPatrick Sanan   The nmax parameter is used for both input and output.
3134e7b76fa7SPatrick Sanan 
3135e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
3136e5c89e4eSSatish Balay   strings returned by this function.
3137e5c89e4eSSatish Balay 
3138e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3139cf53795eSBarry Smith   returned.
3140e5c89e4eSSatish Balay 
3141db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3142db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3143db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3144c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3145db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3146db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3147e5c89e4eSSatish Balay @*/
3148d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set)
3149d71ae5a4SJacob Faibussowitsch {
31502d747510SLisandro Dalcin   const char *svalue;
3151e5c89e4eSSatish Balay   char       *value;
31522d747510SLisandro Dalcin   PetscInt    n = 0;
3153ace3abfcSBarry Smith   PetscBool   flag;
31549c9d3cfdSBarry Smith   PetscToken  token;
3155e5c89e4eSSatish Balay 
3156e5c89e4eSSatish Balay   PetscFunctionBegin;
31572d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
31582d747510SLisandro Dalcin   PetscValidPointer(strings, 4);
31592d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
3160e5c89e4eSSatish Balay 
31619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
31629371c9d4SSatish Balay   if (!flag || !svalue) {
31639371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
31649371c9d4SSatish Balay     *nmax = 0;
31653ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
31669371c9d4SSatish Balay   }
31672d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31689566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31699566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31702d747510SLisandro Dalcin   while (value && n < *nmax) {
31719566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
31729566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3173e5c89e4eSSatish Balay     n++;
3174e5c89e4eSSatish Balay   }
31759566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3176e5c89e4eSSatish Balay   *nmax = n;
31773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3178e5c89e4eSSatish Balay }
317906824ed3SPatrick Sanan 
318006824ed3SPatrick Sanan /*@C
31814ead3382SBarry Smith    PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with `newname`
318206824ed3SPatrick Sanan 
318306824ed3SPatrick Sanan    Prints a deprecation warning, unless an option is supplied to suppress.
318406824ed3SPatrick Sanan 
31851c9f3c13SBarry Smith    Logically Collective
318606824ed3SPatrick Sanan 
318706824ed3SPatrick Sanan    Input Parameters:
318820f4b53cSBarry Smith +  pre - string to prepend to name or `NULL`
318906824ed3SPatrick Sanan .  oldname - the old, deprecated option
319020f4b53cSBarry Smith .  newname - the new option, or `NULL` if option is purely removed
31919f3a6782SPatrick Sanan .  version - a string describing the version of first deprecation, e.g. "3.9"
319220f4b53cSBarry Smith -  info - additional information string, or `NULL`.
319306824ed3SPatrick Sanan 
3194811af0c4SBarry Smith    Options Database Key:
319506824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
319606824ed3SPatrick Sanan 
319720f4b53cSBarry Smith    Level: developer
319820f4b53cSBarry Smith 
319906824ed3SPatrick Sanan    Notes:
32004ead3382SBarry Smith    If `newname` is provided then the options database will automatically check the database for `oldname`.
32014ead3382SBarry Smith 
32024ead3382SBarry Smith    The old call `PetscOptionsXXX`(`oldname`) should be removed from the source code when both (1) the call to `PetscOptionsDeprecated()` occurs before the
32034ead3382SBarry Smith    new call to `PetscOptionsXXX`(`newname`) and (2) the argument handling of the new call to `PetscOptionsXXX`(`newname`) is identical to the previous call.
32044ead3382SBarry Smith    See `PTScotch_PartGraph_Seq()` for an example of when (1) fails and `SNESTestJacobian()` where an example of (2) fails.
32054ead3382SBarry Smith 
3206811af0c4SBarry Smith    Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
320735cb6cd3SPierre Jolivet    Only the process of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3208811af0c4SBarry Smith    `PetscObjectOptionsBegin()` prints the information
3209b40114eaSPatrick Sanan    If newname is provided, the old option is replaced. Otherwise, it remains
3210b40114eaSPatrick Sanan    in the options database.
32119f3a6782SPatrick Sanan    If an option is not replaced, the info argument should be used to advise the user
32129f3a6782SPatrick Sanan    on how to proceed.
32139f3a6782SPatrick Sanan    There is a limit on the length of the warning printed, so very long strings
32149f3a6782SPatrick Sanan    provided as info may be truncated.
321506824ed3SPatrick Sanan 
3216db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
321706824ed3SPatrick Sanan @*/
3218d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3219d71ae5a4SJacob Faibussowitsch {
322006824ed3SPatrick Sanan   PetscBool         found, quiet;
322106824ed3SPatrick Sanan   const char       *value;
322206824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
32239f3a6782SPatrick Sanan   char              msg[4096];
3224b0bdc838SStefano Zampini   char             *prefix  = NULL;
3225b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3226b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
322706824ed3SPatrick Sanan 
322806824ed3SPatrick Sanan   PetscFunctionBegin;
322906824ed3SPatrick Sanan   PetscValidCharPointer(oldname, 2);
323006824ed3SPatrick Sanan   PetscValidCharPointer(version, 4);
3231b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3232b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3233b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3234b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3235b0bdc838SStefano Zampini   }
32369566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
323706824ed3SPatrick Sanan   if (found) {
323806824ed3SPatrick Sanan     if (newname) {
32391baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
32409566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options, newname, value));
32411baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
32429566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3243b40114eaSPatrick Sanan     }
324406824ed3SPatrick Sanan     quiet = PETSC_FALSE;
32459566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
324606824ed3SPatrick Sanan     if (!quiet) {
3247c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option ", sizeof(msg)));
3248c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, oldname, sizeof(msg)));
3249c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3250c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
32514bd3d7f8SBarry Smith       PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
325206824ed3SPatrick Sanan       if (newname) {
32534bd3d7f8SBarry Smith         PetscCall(PetscStrlcat(msg, "   Use the option ", sizeof(msg)));
3254c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, newname, sizeof(msg)));
3255c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
325606824ed3SPatrick Sanan       }
32579f3a6782SPatrick Sanan       if (info) {
3258c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3259c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
32609f3a6782SPatrick Sanan       }
3261c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3262c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3263c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
32649566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
326506824ed3SPatrick Sanan     }
326606824ed3SPatrick Sanan   }
32673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
326806824ed3SPatrick Sanan }
3269