xref: /petsc/src/sys/objects/options.c (revision b3480c8141127d67566193c1958929f926c40d1c)
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;
1279355ec05SMatthew G. Knepley   if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name, value, source, NULL));
1289355ec05SMatthew G. Knepley   for (PetscInt i = 0; i < options->numbermonitors; i++) PetscCall((*options->monitor[i])(name, value, source, options->monitorcontext[i]));
1293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
130e5c89e4eSSatish Balay }
131e5c89e4eSSatish Balay 
1322d747510SLisandro Dalcin /*@
1332d747510SLisandro Dalcin   PetscOptionsCreate - Creates an empty options database.
134e5c89e4eSSatish Balay 
13520f4b53cSBarry Smith   Logically Collective
1361c9f3c13SBarry Smith 
137e5c89e4eSSatish Balay   Output Parameter:
1382d747510SLisandro Dalcin . options - Options database object
139e5c89e4eSSatish Balay 
140e5c89e4eSSatish Balay   Level: advanced
141e5c89e4eSSatish Balay 
142811af0c4SBarry Smith   Note:
143811af0c4SBarry Smith   Though PETSc has a concept of multiple options database the current code uses a single default `PetscOptions` object
144811af0c4SBarry Smith 
145811af0c4SBarry Smith   Developer Notes:
146811af0c4SBarry Smith   We may want eventually to pass a `MPI_Comm` to determine the ownership of the object
147811af0c4SBarry Smith 
148811af0c4SBarry Smith   This object never got developed after being introduced, it is not clear that supporting multiple `PetscOptions` objects is useful
1491c9f3c13SBarry Smith 
150db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
151e5c89e4eSSatish Balay @*/
152d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreate(PetscOptions *options)
153d71ae5a4SJacob Faibussowitsch {
15439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1554f572ea9SToby Isaac   PetscAssertPointer(options, 1);
1562d747510SLisandro Dalcin   *options = (PetscOptions)calloc(1, sizeof(**options));
15739a651e2SJacob Faibussowitsch   PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
1583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1592d747510SLisandro Dalcin }
1602d747510SLisandro Dalcin 
1612d747510SLisandro Dalcin /*@
1622d747510SLisandro Dalcin   PetscOptionsDestroy - Destroys an option database.
1632d747510SLisandro Dalcin 
16420f4b53cSBarry Smith   Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
1651c9f3c13SBarry Smith 
1662d747510SLisandro Dalcin   Input Parameter:
167811af0c4SBarry Smith . options - the `PetscOptions` object
1682d747510SLisandro Dalcin 
1693de2bfdfSBarry Smith   Level: advanced
1702d747510SLisandro Dalcin 
171aec76313SJacob Faibussowitsch .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsSetValue()`
1722d747510SLisandro Dalcin @*/
173d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
174d71ae5a4SJacob Faibussowitsch {
175362febeeSStefano Zampini   PetscFunctionBegin;
1764f572ea9SToby Isaac   PetscAssertPointer(options, 1);
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 
215aec76313SJacob Faibussowitsch   Developer Notes:
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 
23642747ad1SJacob Faibussowitsch .seealso: `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 
268cc4c1da9SBarry Smith /*@
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
28010450e9eSJacob Faibussowitsch 
28110450e9eSJacob Faibussowitsch .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`
2823fc1eb6aSBarry Smith @*/
283d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid)
284d71ae5a4SJacob Faibussowitsch {
285f603b5e9SToby Isaac   char               *ptr;
28627304958SStefano Zampini   PETSC_UNUSED double d;
2877c5db45bSBarry Smith 
28896fc60bcSBarry Smith   PetscFunctionBegin;
2894f572ea9SToby Isaac   if (key) PetscAssertPointer(key, 1);
2904f572ea9SToby Isaac   PetscAssertPointer(valid, 2);
2912d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2923ba16761SJacob Faibussowitsch   if (!key) PetscFunctionReturn(PETSC_SUCCESS);
2933ba16761SJacob Faibussowitsch   if (key[0] != '-') PetscFunctionReturn(PETSC_SUCCESS);
2942d747510SLisandro Dalcin   if (key[1] == '-') key++;
2953ba16761SJacob Faibussowitsch   if (!isalpha((int)key[1])) PetscFunctionReturn(PETSC_SUCCESS);
29627304958SStefano Zampini   d = strtod(key, &ptr);
2973ba16761SJacob Faibussowitsch   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(PETSC_SUCCESS);
2982d747510SLisandro Dalcin   *valid = PETSC_TRUE;
2993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30096fc60bcSBarry Smith }
30196fc60bcSBarry Smith 
30210c654e6SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertString_Private(PetscOptions options, const char in_str[], PetscOptionSource source)
303d71ae5a4SJacob Faibussowitsch {
304d06005cbSLisandro Dalcin   char      *first, *second;
3059c9d3cfdSBarry Smith   PetscToken token;
306e5c89e4eSSatish Balay 
307e5c89e4eSSatish Balay   PetscFunctionBegin;
3089566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(in_str, ' ', &token));
3099566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &first));
31096fc60bcSBarry Smith   while (first) {
311d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
31210c654e6SJacob Faibussowitsch 
3139566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
3149566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
3159566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
3169566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
3179566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
3189566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(first, &key));
319d06005cbSLisandro Dalcin     if (!key) {
3209566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
321d06005cbSLisandro Dalcin     } else if (isfile) {
3229566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
32310c654e6SJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(PETSC_COMM_SELF, options, second, PETSC_TRUE));
3249566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
325d06005cbSLisandro Dalcin     } else if (isfileyaml) {
3269566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
32710c654e6SJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(PETSC_COMM_SELF, options, second, PETSC_TRUE));
3289566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
329d06005cbSLisandro Dalcin     } else if (isstringyaml) {
3309566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3319355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, second, source));
3329566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
333d06005cbSLisandro Dalcin     } else if (ispush) {
3349566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3359566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, second));
3369566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
3379db968c8SJed Brown     } else if (ispop) {
3389566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
3399566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
340d06005cbSLisandro Dalcin     } else {
3419566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3429566063dSJacob Faibussowitsch       PetscCall(PetscOptionsValidKey(second, &key));
34396fc60bcSBarry Smith       if (!key) {
3449355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, second, NULL, source));
3459566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &first));
34696fc60bcSBarry Smith       } else {
3479355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, NULL, NULL, source));
34896fc60bcSBarry Smith         first = second;
34996fc60bcSBarry Smith       }
350e5c89e4eSSatish Balay     }
351e5c89e4eSSatish Balay   }
3529566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
354e5c89e4eSSatish Balay }
355e5c89e4eSSatish Balay 
3565d83a8b1SBarry Smith /*@
3579355ec05SMatthew G. Knepley   PetscOptionsInsertString - Inserts options into the database from a string
3589355ec05SMatthew G. Knepley 
3599355ec05SMatthew G. Knepley   Logically Collective
3609355ec05SMatthew G. Knepley 
3619355ec05SMatthew G. Knepley   Input Parameters:
3629355ec05SMatthew G. Knepley + options - options object
3639355ec05SMatthew G. Knepley - in_str  - string that contains options separated by blanks
3649355ec05SMatthew G. Knepley 
3659355ec05SMatthew G. Knepley   Level: intermediate
3669355ec05SMatthew G. Knepley 
36720f4b53cSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
3689355ec05SMatthew G. Knepley   have the affect of these options. If some processes that create objects call this routine and others do
3699355ec05SMatthew G. Knepley   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
3709355ec05SMatthew G. Knepley   on different ranks.
3719355ec05SMatthew G. Knepley 
3729355ec05SMatthew G. Knepley    Contributed by Boyana Norris
3739355ec05SMatthew G. Knepley 
3749355ec05SMatthew G. Knepley .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
3759355ec05SMatthew G. Knepley           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3769355ec05SMatthew G. Knepley           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3779355ec05SMatthew G. Knepley           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3789355ec05SMatthew G. Knepley           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3799355ec05SMatthew G. Knepley           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
3809355ec05SMatthew G. Knepley @*/
3819355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[])
3829355ec05SMatthew G. Knepley {
3839355ec05SMatthew G. Knepley   PetscFunctionBegin;
3849355ec05SMatthew G. Knepley   PetscCall(PetscOptionsInsertString_Private(options, in_str, PETSC_OPT_CODE));
3853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3869355ec05SMatthew G. Knepley }
3879355ec05SMatthew G. Knepley 
3883fc1eb6aSBarry Smith /*
3893fc1eb6aSBarry Smith     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
3903fc1eb6aSBarry Smith */
391d71ae5a4SJacob Faibussowitsch static char *Petscgetline(FILE *f)
392d71ae5a4SJacob Faibussowitsch {
3935fa91da5SBarry Smith   size_t size = 0;
3945fa91da5SBarry Smith   size_t len  = 0;
3955fa91da5SBarry Smith   size_t last = 0;
3960298fd71SBarry Smith   char  *buf  = NULL;
3975fa91da5SBarry Smith 
39802c9f0b5SLisandro Dalcin   if (feof(f)) return NULL;
3995fa91da5SBarry Smith   do {
4005fa91da5SBarry Smith     size += 1024;                             /* BUFSIZ is defined as "the optimal read size for this platform" */
4016e0c8459SSatish Balay     buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
4025fa91da5SBarry Smith     /* Actually do the read. Note that fgets puts a terminal '\0' on the
4035fa91da5SBarry Smith     end of the string, so we make sure we overwrite this */
404e86f3e45SDave May     if (!fgets(buf + len, 1024, f)) buf[len] = 0;
4053ba16761SJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, PetscStrlen(buf, &len));
4065fa91da5SBarry Smith     last = len - 1;
4075fa91da5SBarry Smith   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
40808ac41f7SSatish Balay   if (len) return buf;
4095fa91da5SBarry Smith   free(buf);
41002c9f0b5SLisandro Dalcin   return NULL;
4115fa91da5SBarry Smith }
4125fa91da5SBarry Smith 
413d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml)
414d71ae5a4SJacob Faibussowitsch {
415be10d61cSLisandro Dalcin   char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
416e5c89e4eSSatish Balay 
417be10d61cSLisandro Dalcin   PetscFunctionBegin;
418362febeeSStefano Zampini   *yaml = PETSC_FALSE;
4199566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
4209566063dSJacob Faibussowitsch   PetscCall(PetscFixFilename(fname, path));
4219566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(path, ":yaml", yaml));
422be10d61cSLisandro Dalcin   if (*yaml) {
4239566063dSJacob Faibussowitsch     PetscCall(PetscStrrchr(path, ':', &tail));
424be10d61cSLisandro Dalcin     tail[-1] = 0; /* remove ":yaml" suffix from path */
425be10d61cSLisandro Dalcin   }
4269566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
427a1d2f846SLisandro Dalcin   /* check for standard YAML and JSON filename extensions */
4289566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
4299566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
4309566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
431a1d2f846SLisandro Dalcin   if (!*yaml) { /* check file contents */
432a1d2f846SLisandro Dalcin     PetscMPIInt rank;
4339566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
434dd400576SPatrick Sanan     if (rank == 0) {
435a1d2f846SLisandro Dalcin       FILE *fh = fopen(filename, "r");
436a1d2f846SLisandro Dalcin       if (fh) {
437a1d2f846SLisandro Dalcin         char buf[6] = "";
438a1d2f846SLisandro Dalcin         if (fread(buf, 1, 6, fh) > 0) {
4399566063dSJacob Faibussowitsch           PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml));          /* check for '%YAML' tag */
4409566063dSJacob Faibussowitsch           if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
441a1d2f846SLisandro Dalcin         }
442a1d2f846SLisandro Dalcin         (void)fclose(fh);
443a1d2f846SLisandro Dalcin       }
444a1d2f846SLisandro Dalcin     }
4459566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(yaml, 1, MPIU_BOOL, 0, comm));
446a1d2f846SLisandro Dalcin   }
4473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
448be10d61cSLisandro Dalcin }
449e5c89e4eSSatish Balay 
450d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
451d71ae5a4SJacob Faibussowitsch {
4528c0b561eSLisandro Dalcin   char       *string, *vstring = NULL, *astring = NULL, *packed = NULL;
4537fb43599SVaclav Hapla   char       *tokens[4];
45413e3f751SJed Brown   size_t      i, len, bytes;
455e5c89e4eSSatish Balay   FILE       *fd;
4567fb43599SVaclav Hapla   PetscToken  token = NULL;
457ed9cf6e9SBarry Smith   int         err;
458bbcf679cSJacob Faibussowitsch   char       *cmatch = NULL;
459581bbe83SVaclav Hapla   const char  cmt    = '#';
4609210b8eaSVaclav Hapla   PetscInt    line   = 1;
4613a018368SJed Brown   PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
4629210b8eaSVaclav Hapla   PetscBool   isdir, alias = PETSC_FALSE, valid;
463e5c89e4eSSatish Balay 
464e5c89e4eSSatish Balay   PetscFunctionBegin;
4659566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tokens, sizeof(tokens)));
4669566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
467dd400576SPatrick Sanan   if (rank == 0) {
4688c0b561eSLisandro Dalcin     char fpath[PETSC_MAX_PATH_LEN];
4698c0b561eSLisandro Dalcin     char fname[PETSC_MAX_PATH_LEN];
47005c7dedfSBarry Smith 
4719566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
4729566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
4738c0b561eSLisandro Dalcin 
474e5c89e4eSSatish Balay     fd = fopen(fname, "r");
4759566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname, 'r', &isdir));
47608401ef6SPierre Jolivet     PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
477ad38b122SPatrick Sanan     if (fd && !isdir) {
4783a018368SJed Brown       PetscSegBuffer vseg, aseg;
4799566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4809566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4813a018368SJed Brown 
4829b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4839566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
484e24ecc5dSJed Brown 
4855fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4864704e885SBarry Smith         /* eliminate comments from each line */
4879566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
48890f79514SSatish Balay         if (cmatch) *cmatch = 0;
4899566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4905981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
491e5c89e4eSSatish Balay         for (i = 0; i < len; i++) {
492ad540459SPierre Jolivet           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
493e5c89e4eSSatish Balay         }
4949566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4959566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4967fb43599SVaclav Hapla         if (!tokens[0]) {
49702b0d46eSSatish Balay           goto destroy;
4987fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
4999566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
50090f79514SSatish Balay         }
50148a46eb9SPierre Jolivet         for (i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
5027fb43599SVaclav Hapla         if (!tokens[0]) {
5032662f744SSatish Balay           goto destroy;
5047fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
5059566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
50628b400f6SJacob 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]);
5079566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
5089566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
5099566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
510e24ecc5dSJed Brown           vstring[len] = ' ';
5117fb43599SVaclav Hapla           if (tokens[1]) {
5129566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
51328b400f6SJacob Faibussowitsch             PetscCheck(!valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": cannot specify two options per line (%s %s)", fname, line, tokens[0], tokens[1]);
5149566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5159566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
516e24ecc5dSJed Brown             vstring[0] = '"';
5179566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
518e24ecc5dSJed Brown             vstring[len + 1] = '"';
519e24ecc5dSJed Brown             vstring[len + 2] = ' ';
52009192fe3SBarry Smith           }
52190f79514SSatish Balay         } else {
5229566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
5239210b8eaSVaclav Hapla           if (alias) {
5249566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
52528b400f6SJacob 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]);
52608401ef6SPierre 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]);
5279566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
52828b400f6SJacob 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]);
5299566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5309566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5319566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
532e24ecc5dSJed Brown             astring[len] = ' ';
533e24ecc5dSJed Brown 
5349566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5359566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5369566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
537e24ecc5dSJed Brown             astring[len] = ' ';
53898921bdaSJacob 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]);
5399210b8eaSVaclav Hapla         }
5409210b8eaSVaclav Hapla         {
5419210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
54228b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
543e5c89e4eSSatish Balay         }
54402b0d46eSSatish Balay       destroy:
5454b40f50bSBarry Smith         free(string);
5469566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5479210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5489210b8eaSVaclav Hapla         line++;
549e5c89e4eSSatish Balay       }
550ed9cf6e9SBarry Smith       err = fclose(fd);
55128b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5529566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5539566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5549566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
555e24ecc5dSJed Brown       astring[0] = 0;
5569566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5579566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5589566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
559e24ecc5dSJed Brown       vstring[0] = 0;
5609566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5619566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5629566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5639566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5649566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
56528b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5669b754dc9SBarry Smith   }
56705c7dedfSBarry Smith 
5683a018368SJed Brown   counts[0] = acnt;
5693a018368SJed Brown   counts[1] = cnt;
5704201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
57128b400f6SJacob 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/");
5723a018368SJed Brown   acnt = counts[0];
5733a018368SJed Brown   cnt  = counts[1];
57448a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5753a018368SJed Brown   if (acnt || cnt) {
5769566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5773a018368SJed Brown     astring = packed;
5783a018368SJed Brown     vstring = packed + acnt + 1;
5793a018368SJed Brown   }
5803a018368SJed Brown 
5819b754dc9SBarry Smith   if (acnt) {
5829566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5839566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5847fb43599SVaclav Hapla     while (tokens[0]) {
5859566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5869566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5879566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5889b754dc9SBarry Smith     }
5899566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5909b754dc9SBarry Smith   }
5919b754dc9SBarry Smith 
5929355ec05SMatthew G. Knepley   if (cnt) PetscCall(PetscOptionsInsertString_Private(options, vstring, PETSC_OPT_FILE));
5939566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
5943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
595e5c89e4eSSatish Balay }
596e5c89e4eSSatish Balay 
5975d83a8b1SBarry Smith /*@
598be10d61cSLisandro Dalcin   PetscOptionsInsertFile - Inserts options into the database from a file.
599be10d61cSLisandro Dalcin 
600be10d61cSLisandro Dalcin   Collective
601be10d61cSLisandro Dalcin 
602d8d19677SJose E. Roman   Input Parameters:
603811af0c4SBarry Smith + comm    - the processes that will share the options (usually `PETSC_COMM_WORLD`)
60420f4b53cSBarry Smith . options - options database, use `NULL` for default global database
605be10d61cSLisandro Dalcin . file    - name of file,
606be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
607be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
608811af0c4SBarry Smith - require - if `PETSC_TRUE` will generate an error if the file does not exist
609be10d61cSLisandro Dalcin 
61020f4b53cSBarry Smith   Level: developer
61120f4b53cSBarry Smith 
612be10d61cSLisandro Dalcin   Notes:
613be10d61cSLisandro Dalcin   Use  # for lines that are comments and which should be ignored.
614811af0c4SBarry Smith   Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
61521532e8aSBarry 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
61621532e8aSBarry Smith   calls to `XXXSetFromOptions()`, it should not be used for options listed under PetscInitialize().
61721532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes in comm will
61821532e8aSBarry Smith   have the effect of these options. If some processes that create objects call this routine and others do
619be10d61cSLisandro Dalcin   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
620be10d61cSLisandro Dalcin   on different ranks.
621be10d61cSLisandro Dalcin 
622db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
623db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
624db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
625c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
626db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
627db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
628be10d61cSLisandro Dalcin @*/
629d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
630d71ae5a4SJacob Faibussowitsch {
631be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
632be10d61cSLisandro Dalcin   PetscBool yaml;
633be10d61cSLisandro Dalcin 
634be10d61cSLisandro Dalcin   PetscFunctionBegin;
6359566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
636be10d61cSLisandro Dalcin   if (yaml) {
6379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
638be10d61cSLisandro Dalcin   } else {
6399566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
640be10d61cSLisandro Dalcin   }
6413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
642be10d61cSLisandro Dalcin }
643be10d61cSLisandro Dalcin 
644be10d61cSLisandro Dalcin /*@C
645d06005cbSLisandro Dalcin   PetscOptionsInsertArgs - Inserts options into the database from a array of strings
646d06005cbSLisandro Dalcin 
647d06005cbSLisandro Dalcin   Logically Collective
648d06005cbSLisandro Dalcin 
649d8d19677SJose E. Roman   Input Parameters:
650d06005cbSLisandro Dalcin + options - options object
6516aad120cSJose E. Roman . argc    - the array length
652d06005cbSLisandro Dalcin - args    - the string array
653d06005cbSLisandro Dalcin 
654d06005cbSLisandro Dalcin   Level: intermediate
655d06005cbSLisandro Dalcin 
656db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
657d06005cbSLisandro Dalcin @*/
658d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, char *args[])
659d71ae5a4SJacob Faibussowitsch {
660d06005cbSLisandro Dalcin   MPI_Comm     comm  = PETSC_COMM_WORLD;
661d06005cbSLisandro Dalcin   int          left  = PetscMax(argc, 0);
662d06005cbSLisandro Dalcin   char *const *eargs = args;
66385079163SJed Brown 
66485079163SJed Brown   PetscFunctionBegin;
66585079163SJed Brown   while (left) {
666d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6679566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6689566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6699566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6709566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6719566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6729566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
673093de6efSBarry Smith     if (!key) {
6749371c9d4SSatish Balay       eargs++;
6759371c9d4SSatish Balay       left--;
676d06005cbSLisandro Dalcin     } else if (isfile) {
677cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6789566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6799371c9d4SSatish Balay       eargs += 2;
6809371c9d4SSatish Balay       left -= 2;
681d06005cbSLisandro Dalcin     } else if (isfileyaml) {
682cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6839566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6849371c9d4SSatish Balay       eargs += 2;
6859371c9d4SSatish Balay       left -= 2;
686d06005cbSLisandro Dalcin     } else if (isstringyaml) {
687cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6889355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
6899371c9d4SSatish Balay       eargs += 2;
6909371c9d4SSatish Balay       left -= 2;
691d06005cbSLisandro Dalcin     } else if (ispush) {
69208401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
693cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6949566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6959371c9d4SSatish Balay       eargs += 2;
6969371c9d4SSatish Balay       left -= 2;
697d06005cbSLisandro Dalcin     } else if (ispop) {
6989566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
6999371c9d4SSatish Balay       eargs++;
7009371c9d4SSatish Balay       left--;
7017935c3d8SJed Brown     } else {
7027935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
7039566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
70498b6bf53SJed Brown       if (left < 2 || nextiskey) {
7059355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
7069371c9d4SSatish Balay         eargs++;
7079371c9d4SSatish Balay         left--;
70885079163SJed Brown       } else {
7099355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
7109371c9d4SSatish Balay         eargs += 2;
7119371c9d4SSatish Balay         left -= 2;
71285079163SJed Brown       }
71385079163SJed Brown     }
7147935c3d8SJed Brown   }
7153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71685079163SJed Brown }
71785079163SJed Brown 
71810c654e6SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], const PetscBool set[], PetscBool *flg)
719d71ae5a4SJacob Faibussowitsch {
720c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
721c5b5d8d5SVaclav Hapla   if (set[opt]) {
7229566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
723c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
7243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
725c5b5d8d5SVaclav Hapla }
726c5b5d8d5SVaclav Hapla 
727660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
728d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
729d71ae5a4SJacob Faibussowitsch {
730c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
731c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
732c5b5d8d5SVaclav Hapla   size_t             o;
733c5b5d8d5SVaclav Hapla   int                a;
734c5b5d8d5SVaclav Hapla   const char       **val;
7350c99d500SBarry Smith   char             **cval;
736660278c0SBarry Smith   PetscBool         *set, unneeded;
737c5b5d8d5SVaclav Hapla 
738c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7390c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7400c99d500SBarry Smith   val = (const char **)cval;
741c5b5d8d5SVaclav Hapla 
742c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
74348a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
744c5b5d8d5SVaclav Hapla 
745a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
746c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
747c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
748c5b5d8d5SVaclav Hapla 
7499566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
750c5b5d8d5SVaclav Hapla     if (!valid) continue;
751c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7529566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
753c5b5d8d5SVaclav Hapla       if (eq) {
754c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
755c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
756c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
757c5b5d8d5SVaclav Hapla         break;
758c5b5d8d5SVaclav Hapla       }
759c5b5d8d5SVaclav Hapla     }
760c5b5d8d5SVaclav Hapla   }
761c5b5d8d5SVaclav Hapla 
762c5b5d8d5SVaclav Hapla   /* Process flags */
7639566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
764d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7659566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
766660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
767660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
7689355ec05SMatthew G. Knepley   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
7699566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
772c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
773c5b5d8d5SVaclav Hapla 
774c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
775660278c0SBarry Smith   for (o = 1; o < n; o++) {
776c5b5d8d5SVaclav Hapla     if (set[o]) {
7779355ec05SMatthew G. Knepley       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
778d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
779c5b5d8d5SVaclav Hapla     }
780c5b5d8d5SVaclav Hapla   }
7810c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
782c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
7833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
784c5b5d8d5SVaclav Hapla }
785c5b5d8d5SVaclav Hapla 
786d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
787d71ae5a4SJacob Faibussowitsch {
78839a651e2SJacob Faibussowitsch   PetscFunctionBegin;
7894f572ea9SToby Isaac   PetscAssertPointer(flg, 3);
790c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
791c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
79239a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
793c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
794c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7959566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
796c5b5d8d5SVaclav Hapla         if (*flg) break;
797c5b5d8d5SVaclav Hapla       }
798c5b5d8d5SVaclav Hapla     }
799c5b5d8d5SVaclav Hapla   }
8003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
801c5b5d8d5SVaclav Hapla }
80285079163SJed Brown 
803e5c89e4eSSatish Balay /*@C
804e5c89e4eSSatish Balay   PetscOptionsInsert - Inserts into the options database from the command line,
805e5c89e4eSSatish Balay   the environmental variable and a file.
806e5c89e4eSSatish Balay 
807811af0c4SBarry Smith   Collective on `PETSC_COMM_WORLD`
8081c9f3c13SBarry Smith 
809e5c89e4eSSatish Balay   Input Parameters:
81020f4b53cSBarry Smith + options - options database or `NULL` for the default global database
811c5929fdfSBarry Smith . argc    - count of number of command line arguments
812e5c89e4eSSatish Balay . args    - the command line arguments
813be10d61cSLisandro Dalcin - file    - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
81420f4b53cSBarry Smith           Use `NULL` or empty string to not check for code specific file.
815be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
816c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
817e5c89e4eSSatish Balay 
818081c24baSBoyana Norris   Options Database Keys:
819d06005cbSLisandro Dalcin + -options_file <filename>      - read options from a file
820d06005cbSLisandro Dalcin - -options_file_yaml <filename> - read options from a YAML file
821c5b5d8d5SVaclav Hapla 
82220f4b53cSBarry Smith   Level: advanced
82320f4b53cSBarry Smith 
824811af0c4SBarry Smith   Notes:
82520f4b53cSBarry Smith   Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
826811af0c4SBarry Smith   the user does not typically need to call this routine. `PetscOptionsInsert()`
827811af0c4SBarry Smith   can be called several times, adding additional entries into the database.
828811af0c4SBarry Smith 
829811af0c4SBarry Smith   See `PetscInitialize()` for options related to option database monitoring.
830081c24baSBoyana Norris 
831db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
832db781477SPatrick Sanan           `PetscInitialize()`
833e5c89e4eSSatish Balay @*/
834d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[])
835d71ae5a4SJacob Faibussowitsch {
836d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
837e5c89e4eSSatish Balay   PetscMPIInt rank;
838c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
839c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
840e5c89e4eSSatish Balay 
841e5c89e4eSSatish Balay   PetscFunctionBegin;
84208401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8439566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
844e5c89e4eSSatish Balay 
845c5b5d8d5SVaclav Hapla   if (!options) {
8469566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
847c5b5d8d5SVaclav Hapla     options = defaultoptions;
848c5b5d8d5SVaclav Hapla   }
849c5b5d8d5SVaclav Hapla   if (hasArgs) {
850c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8519566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
852660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
853c5b5d8d5SVaclav Hapla   }
8544b09e917SBarry Smith   if (file && file[0]) {
8559566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
856c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8579566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
858321366bcSBarry Smith   }
859c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
860be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8619566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8629566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
863c6a7a370SJeremy L Thompson     if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
8649566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8659566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8669566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
867e5c89e4eSSatish Balay   }
868e5c89e4eSSatish Balay 
8692d747510SLisandro Dalcin   /* insert environment options */
870e5c89e4eSSatish Balay   {
8712d747510SLisandro Dalcin     char  *eoptions = NULL;
872e5c89e4eSSatish Balay     size_t len      = 0;
873dd400576SPatrick Sanan     if (rank == 0) {
874e5c89e4eSSatish Balay       eoptions = (char *)getenv("PETSC_OPTIONS");
8759566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
876e5c89e4eSSatish Balay     }
8779566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
878e5c89e4eSSatish Balay     if (len) {
8799566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8809566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
88196fc60bcSBarry Smith       if (rank) eoptions[len] = 0;
8829355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8839566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
884e5c89e4eSSatish Balay     }
885e5c89e4eSSatish Balay   }
886e5c89e4eSSatish Balay 
887d06005cbSLisandro Dalcin   /* insert YAML environment options */
88856a31166SBarry Smith   {
8899fc438c3SToby Isaac     char  *eoptions = NULL;
8909fc438c3SToby Isaac     size_t len      = 0;
891dd400576SPatrick Sanan     if (rank == 0) {
8929fc438c3SToby Isaac       eoptions = (char *)getenv("PETSC_OPTIONS_YAML");
8939566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
8949fc438c3SToby Isaac     }
8959566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8969fc438c3SToby Isaac     if (len) {
8979566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8989566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
8999fc438c3SToby Isaac       if (rank) eoptions[len] = 0;
9009355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
9019566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
9029fc438c3SToby Isaac     }
9039fc438c3SToby Isaac   }
9043bcbd388SSean Farley 
905c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
9069566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, *args + 1));
907660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
9083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
909e5c89e4eSSatish Balay }
910e5c89e4eSSatish Balay 
911660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
912660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
913e9a33e21SBarry Smith static const char *PetscCIOptions[] = {"malloc_debug", "malloc_dump", "malloc_test", "malloc", "nox", "nox_warning", "display", "saws_port_auto_select", "saws_port_auto_select_silent", "vecscatter_mpi1", "check_pointer_intensity", "cuda_initialize", "error_output_stdout", "use_gpu_aware_mpi", "checkfunctionlist", "fp_trap", "petsc_ci", "petsc_ci_portable_error_output", "options_left"};
914660278c0SBarry Smith 
915d71ae5a4SJacob Faibussowitsch static PetscBool PetscCIOption(const char *name)
916d71ae5a4SJacob Faibussowitsch {
917660278c0SBarry Smith   PetscInt  idx;
918660278c0SBarry Smith   PetscBool found;
919660278c0SBarry Smith 
920660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
9213ba16761SJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
922660278c0SBarry Smith   return found;
923660278c0SBarry Smith }
924660278c0SBarry Smith 
9255d83a8b1SBarry Smith /*@
92688c29154SBarry Smith   PetscOptionsView - Prints the options that have been loaded. This is
927e5c89e4eSSatish Balay   useful for debugging purposes.
928e5c89e4eSSatish Balay 
929ffeef943SBarry Smith   Logically Collective, No Fortran Support
930e5c89e4eSSatish Balay 
931d8d19677SJose E. Roman   Input Parameters:
93220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
933811af0c4SBarry Smith - viewer  - must be an `PETSCVIEWERASCII` viewer
934e5c89e4eSSatish Balay 
935e5c89e4eSSatish Balay   Options Database Key:
936811af0c4SBarry Smith . -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
937e5c89e4eSSatish Balay 
93820f4b53cSBarry Smith   Level: advanced
93920f4b53cSBarry Smith 
940811af0c4SBarry Smith   Note:
94121532e8aSBarry Smith   Only the MPI rank 0 of the `MPI_Comm` used to create view prints the option values. Other processes
9421c9f3c13SBarry Smith   may have different values but they are not printed.
9431c9f3c13SBarry Smith 
944db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
945e5c89e4eSSatish Balay @*/
946d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
947d71ae5a4SJacob Faibussowitsch {
948660278c0SBarry Smith   PetscInt  i, N = 0;
94988c29154SBarry Smith   PetscBool isascii;
950e5c89e4eSSatish Balay 
951e5c89e4eSSatish Balay   PetscFunctionBegin;
9522d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
953c5929fdfSBarry Smith   options = options ? options : defaultoptions;
95488c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9559566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
95628b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
95788c29154SBarry Smith 
958660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
959660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
960660278c0SBarry Smith     N++;
961660278c0SBarry Smith   }
962660278c0SBarry Smith 
963660278c0SBarry Smith   if (!N) {
9649566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9653ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
96630694fe9SBarry Smith   }
9672d747510SLisandro Dalcin 
9689566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
969e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
970660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
971e5c89e4eSSatish Balay     if (options->values[i]) {
9729355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
973e5c89e4eSSatish Balay     } else {
9749355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
975e5c89e4eSSatish Balay     }
9769355ec05SMatthew G. Knepley     PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
977e5c89e4eSSatish Balay   }
9789566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
9793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
980e5c89e4eSSatish Balay }
981e5c89e4eSSatish Balay 
982e11779c2SBarry Smith /*
983e11779c2SBarry Smith    Called by error handlers to print options used in run
984e11779c2SBarry Smith */
985d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftError(void)
986d71ae5a4SJacob Faibussowitsch {
987f4bc716fSBarry Smith   PetscInt i, nopt = 0;
988f4bc716fSBarry Smith 
989f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
990f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
991f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
992f4bc716fSBarry Smith       nopt++;
993f4bc716fSBarry Smith     }
994f4bc716fSBarry Smith   }
995f4bc716fSBarry Smith   if (nopt) {
9967d44c3adSBarry Smith     PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
997f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
998f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
999f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
10003ba16761SJacob 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]]));
10013ba16761SJacob Faibussowitsch         else PetscCall((*PetscErrorPrintf)("  Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
1002f4bc716fSBarry Smith       }
1003f4bc716fSBarry Smith     }
1004f4bc716fSBarry Smith   }
10053ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1006f4bc716fSBarry Smith }
1007f4bc716fSBarry Smith 
1008d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1009d71ae5a4SJacob Faibussowitsch {
1010660278c0SBarry Smith   PetscInt     i, N = 0;
10114416b707SBarry Smith   PetscOptions options = defaultoptions;
1012e11779c2SBarry Smith 
1013660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
1014660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1015660278c0SBarry Smith     N++;
1016660278c0SBarry Smith   }
1017660278c0SBarry Smith 
1018660278c0SBarry Smith   if (N) {
10193ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1020e11779c2SBarry Smith   } else {
10213ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1022e11779c2SBarry Smith   }
1023e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1024660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1025e11779c2SBarry Smith     if (options->values[i]) {
10263ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1027e11779c2SBarry Smith     } else {
10283ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1029e11779c2SBarry Smith     }
1030e11779c2SBarry Smith   }
10313ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1032e11779c2SBarry Smith }
1033e11779c2SBarry Smith 
10345d83a8b1SBarry Smith /*@
103574e0666dSJed Brown   PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
103674e0666dSJed Brown 
10371c9f3c13SBarry Smith   Logically Collective
103874e0666dSJed Brown 
1039d8d19677SJose E. Roman   Input Parameters:
104020f4b53cSBarry Smith + options - options database, or `NULL` for the default global database
1041c5929fdfSBarry Smith - prefix  - The string to append to the existing prefix
10429db968c8SJed Brown 
10439db968c8SJed Brown   Options Database Keys:
10449db968c8SJed Brown + -prefix_push <some_prefix_> - push the given prefix
10459db968c8SJed Brown - -prefix_pop                 - pop the last prefix
10469db968c8SJed Brown 
104720f4b53cSBarry Smith   Level: advanced
104820f4b53cSBarry Smith 
10499db968c8SJed Brown   Notes:
105021532e8aSBarry Smith   It is common to use this in conjunction with `-options_file` as in
10519314d9b7SBarry Smith .vb
10529314d9b7SBarry Smith  -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10539314d9b7SBarry Smith .ve
105421532e8aSBarry Smith   where the files no longer require all options to be prefixed with `-system2_`.
105574e0666dSJed Brown 
105621532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
10571c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
10581c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10591c9f3c13SBarry Smith   on different ranks.
10601c9f3c13SBarry Smith 
1061db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
106274e0666dSJed Brown @*/
1063d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1064d71ae5a4SJacob Faibussowitsch {
106574e0666dSJed Brown   size_t    n;
106674e0666dSJed Brown   PetscInt  start;
10679355ec05SMatthew G. Knepley   char      key[PETSC_MAX_OPTION_NAME + 1];
10682d747510SLisandro Dalcin   PetscBool valid;
106974e0666dSJed Brown 
107074e0666dSJed Brown   PetscFunctionBegin;
10714f572ea9SToby Isaac   PetscAssertPointer(prefix, 2);
1072c5929fdfSBarry Smith   options = options ? options : defaultoptions;
107300045ab3SPierre Jolivet   PetscCheck(options->prefixind < MAXPREFIXES, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum depth of prefix stack %d exceeded, recompile src/sys/objects/options.c with larger value for MAXPREFIXES", MAXPREFIXES);
10742d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10759566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10778bf569ecSLisandro 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 */
107828b400f6SJacob 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" : "");
107974e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10809566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
108108401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10829566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
108374e0666dSJed Brown   options->prefixstack[options->prefixind++] = start + n;
10843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108574e0666dSJed Brown }
108674e0666dSJed Brown 
10875d83a8b1SBarry Smith /*@
1088811af0c4SBarry Smith   PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
108974e0666dSJed Brown 
1090811af0c4SBarry Smith   Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
109174e0666dSJed Brown 
1092811af0c4SBarry Smith   Input Parameter:
109320f4b53cSBarry Smith . options - options database, or `NULL` for the default global database
1094c5929fdfSBarry Smith 
109574e0666dSJed Brown   Level: advanced
109674e0666dSJed Brown 
1097db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
109874e0666dSJed Brown @*/
1099d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1100d71ae5a4SJacob Faibussowitsch {
110174e0666dSJed Brown   PetscInt offset;
110274e0666dSJed Brown 
110374e0666dSJed Brown   PetscFunctionBegin;
1104c5929fdfSBarry Smith   options = options ? options : defaultoptions;
110508401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
110674e0666dSJed Brown   options->prefixind--;
110774e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
110874e0666dSJed Brown   options->prefix[offset] = 0;
11093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
111074e0666dSJed Brown }
111174e0666dSJed Brown 
11125d83a8b1SBarry Smith /*@
1113a542b6e8SBarry Smith   PetscOptionsClear - Removes all options form the database leaving it empty.
1114a542b6e8SBarry Smith 
11151c9f3c13SBarry Smith   Logically Collective
11161c9f3c13SBarry Smith 
1117811af0c4SBarry Smith   Input Parameter:
111820f4b53cSBarry Smith . options - options database, use `NULL` for the default global database
1119c5929fdfSBarry Smith 
112020f4b53cSBarry Smith   Level: developer
112120f4b53cSBarry Smith 
112220f4b53cSBarry Smith   Note:
112321532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11241c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11251c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11261c9f3c13SBarry Smith   on different ranks.
11271c9f3c13SBarry Smith 
11287e6f8dd6SBarry Smith   Developer Note:
11297e6f8dd6SBarry Smith   Uses `free()` directly because the current option values were set with `malloc()`
11307e6f8dd6SBarry Smith 
1131db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1132a542b6e8SBarry Smith @*/
1133d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClear(PetscOptions options)
1134d71ae5a4SJacob Faibussowitsch {
1135a542b6e8SBarry Smith   PetscInt i;
1136a542b6e8SBarry Smith 
113739a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1138c5929fdfSBarry Smith   options = options ? options : defaultoptions;
11393ba16761SJacob Faibussowitsch   if (!options) PetscFunctionReturn(PETSC_SUCCESS);
11402d747510SLisandro Dalcin 
1141a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1142a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1143a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1144a542b6e8SBarry Smith   }
11452d747510SLisandro Dalcin   options->N = 0;
11469355ec05SMatthew G. Knepley   free(options->names);
11479355ec05SMatthew G. Knepley   free(options->values);
11489355ec05SMatthew G. Knepley   free(options->used);
11499355ec05SMatthew G. Knepley   free(options->source);
11509355ec05SMatthew G. Knepley   options->names  = NULL;
11519355ec05SMatthew G. Knepley   options->values = NULL;
11529355ec05SMatthew G. Knepley   options->used   = NULL;
11539355ec05SMatthew G. Knepley   options->source = NULL;
11549355ec05SMatthew G. Knepley   options->Nalloc = 0;
11552d747510SLisandro Dalcin 
11569355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
1157a542b6e8SBarry Smith     free(options->aliases1[i]);
1158a542b6e8SBarry Smith     free(options->aliases2[i]);
1159a542b6e8SBarry Smith   }
11609355ec05SMatthew G. Knepley   options->Na = 0;
11619355ec05SMatthew G. Knepley   free(options->aliases1);
11629355ec05SMatthew G. Knepley   free(options->aliases2);
11639355ec05SMatthew G. Knepley   options->aliases1 = options->aliases2 = NULL;
11649355ec05SMatthew G. Knepley   options->Naalloc                      = 0;
1165a542b6e8SBarry Smith 
11662d747510SLisandro Dalcin   /* destroy hash table */
11672d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11682d747510SLisandro Dalcin   options->ht = NULL;
11690eb63584SBarry Smith 
11702d747510SLisandro Dalcin   options->prefixind  = 0;
11712d747510SLisandro Dalcin   options->prefix[0]  = 0;
11722d747510SLisandro Dalcin   options->help       = PETSC_FALSE;
11739355ec05SMatthew G. Knepley   options->help_intro = PETSC_FALSE;
11743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11754416b707SBarry Smith }
11764416b707SBarry Smith 
11775d83a8b1SBarry Smith /*@
11782d747510SLisandro Dalcin   PetscOptionsSetAlias - Makes a key and alias for another key
11792d747510SLisandro Dalcin 
11801c9f3c13SBarry Smith   Logically Collective
11812d747510SLisandro Dalcin 
11822d747510SLisandro Dalcin   Input Parameters:
118320f4b53cSBarry Smith + options - options database, or `NULL` for default global database
11842d747510SLisandro Dalcin . newname - the alias
11852d747510SLisandro Dalcin - oldname - the name that alias will refer to
11862d747510SLisandro Dalcin 
11872d747510SLisandro Dalcin   Level: advanced
11882d747510SLisandro Dalcin 
118920f4b53cSBarry Smith   Note:
119021532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11911c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11921c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11931c9f3c13SBarry Smith   on different ranks.
11941c9f3c13SBarry Smith 
11957e6f8dd6SBarry Smith   Developer Note:
11967e6f8dd6SBarry Smith   Uses `malloc()` directly because PETSc may not be initialized yet.
11977e6f8dd6SBarry Smith 
11980241b274SPierre Jolivet .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1199c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1200db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1201c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1202db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1203db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
12042d747510SLisandro Dalcin @*/
1205d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1206d71ae5a4SJacob Faibussowitsch {
12072d747510SLisandro Dalcin   size_t    len;
12089210b8eaSVaclav Hapla   PetscBool valid;
12092d747510SLisandro Dalcin 
12102d747510SLisandro Dalcin   PetscFunctionBegin;
12114f572ea9SToby Isaac   PetscAssertPointer(newname, 2);
12124f572ea9SToby Isaac   PetscAssertPointer(oldname, 3);
12132d747510SLisandro Dalcin   options = options ? options : defaultoptions;
12149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
121528b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
12169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
121728b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
12182d747510SLisandro Dalcin 
12199355ec05SMatthew G. Knepley   if (options->Na == options->Naalloc) {
12209355ec05SMatthew G. Knepley     char **tmpA1, **tmpA2;
12212d747510SLisandro Dalcin 
12229355ec05SMatthew G. Knepley     options->Naalloc = PetscMax(4, options->Naalloc * 2);
12239355ec05SMatthew G. Knepley     tmpA1            = (char **)malloc(options->Naalloc * sizeof(char *));
12249355ec05SMatthew G. Knepley     tmpA2            = (char **)malloc(options->Naalloc * sizeof(char *));
12259355ec05SMatthew G. Knepley     for (int i = 0; i < options->Na; ++i) {
12269355ec05SMatthew G. Knepley       tmpA1[i] = options->aliases1[i];
12279355ec05SMatthew G. Knepley       tmpA2[i] = options->aliases2[i];
12289355ec05SMatthew G. Knepley     }
12299355ec05SMatthew G. Knepley     free(options->aliases1);
12309355ec05SMatthew G. Knepley     free(options->aliases2);
12319355ec05SMatthew G. Knepley     options->aliases1 = tmpA1;
12329355ec05SMatthew G. Knepley     options->aliases2 = tmpA2;
12339355ec05SMatthew G. Knepley   }
12349371c9d4SSatish Balay   newname++;
12359371c9d4SSatish Balay   oldname++;
12369566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
12379355ec05SMatthew G. Knepley   options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1238c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
12399566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
12409355ec05SMatthew G. Knepley   options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1241c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
12429355ec05SMatthew G. Knepley   ++options->Na;
12433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12442d747510SLisandro Dalcin }
12454416b707SBarry Smith 
12465d83a8b1SBarry Smith /*@
1247e5c89e4eSSatish Balay   PetscOptionsSetValue - Sets an option name-value pair in the options
1248e5c89e4eSSatish Balay   database, overriding whatever is already present.
1249e5c89e4eSSatish Balay 
12501c9f3c13SBarry Smith   Logically Collective
1251e5c89e4eSSatish Balay 
1252e5c89e4eSSatish Balay   Input Parameters:
125320f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1254c5929fdfSBarry Smith . name    - name of option, this SHOULD have the - prepended
125520f4b53cSBarry Smith - value   - the option value (not used for all options, so can be `NULL`)
1256e5c89e4eSSatish Balay 
1257e5c89e4eSSatish Balay   Level: intermediate
1258e5c89e4eSSatish Balay 
1259e5c89e4eSSatish Balay   Note:
1260811af0c4SBarry Smith   This function can be called BEFORE `PetscInitialize()`
1261d49172ceSBarry Smith 
126221532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
12631c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
12641c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12651c9f3c13SBarry Smith   on different ranks.
12661c9f3c13SBarry Smith 
12677e6f8dd6SBarry Smith   Developer Note:
12687e6f8dd6SBarry Smith   Uses `malloc()` directly because PETSc may not be initialized yet.
1269b0250c70SBarry Smith 
1270db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1271e5c89e4eSSatish Balay @*/
1272d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1273d71ae5a4SJacob Faibussowitsch {
127439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12759355ec05SMatthew G. Knepley   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
12763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1277c5b5d8d5SVaclav Hapla }
1278c5b5d8d5SVaclav Hapla 
12799355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1280d71ae5a4SJacob Faibussowitsch {
1281e5c89e4eSSatish Balay   size_t    len;
12829355ec05SMatthew G. Knepley   int       n, i;
1283e5c89e4eSSatish Balay   char    **names;
12849355ec05SMatthew G. Knepley   char      fullname[PETSC_MAX_OPTION_NAME] = "";
1285c5b5d8d5SVaclav Hapla   PetscBool flg;
1286e5c89e4eSSatish Balay 
128739a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12887272c0d2SVaclav Hapla   if (!options) {
12899566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12907272c0d2SVaclav Hapla     options = defaultoptions;
1291c5929fdfSBarry Smith   }
129239a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
12932d747510SLisandro Dalcin 
12949566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
12953ba16761SJacob Faibussowitsch   if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1296e5c89e4eSSatish Balay 
12972d747510SLisandro Dalcin   name++; /* skip starting dash */
12982d747510SLisandro Dalcin 
129974e0666dSJed Brown   if (options->prefixind > 0) {
1300d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
13012d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
130289ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
13032d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
130474e0666dSJed Brown     name                           = fullname;
130574e0666dSJed Brown   }
130674e0666dSJed Brown 
130774e0666dSJed Brown   /* check against aliases */
13089355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
13092d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
13109371c9d4SSatish Balay     if (!result) {
13119371c9d4SSatish Balay       name = options->aliases2[i];
13129371c9d4SSatish Balay       break;
13139371c9d4SSatish Balay     }
1314e5c89e4eSSatish Balay   }
1315e5c89e4eSSatish Balay 
13162d747510SLisandro Dalcin   /* slow search */
13179355ec05SMatthew G. Knepley   n     = options->N;
1318e5c89e4eSSatish Balay   names = options->names;
13199355ec05SMatthew G. Knepley   for (i = 0; i < options->N; i++) {
13202d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13212d747510SLisandro Dalcin     if (!result) {
13229371c9d4SSatish Balay       n = i;
13239371c9d4SSatish Balay       goto setvalue;
13242d747510SLisandro Dalcin     } else if (result > 0) {
13259371c9d4SSatish Balay       n = i;
13269371c9d4SSatish Balay       break;
1327e5c89e4eSSatish Balay     }
1328e5c89e4eSSatish Balay   }
13299355ec05SMatthew G. Knepley   if (options->N == options->Nalloc) {
13309355ec05SMatthew G. Knepley     char             **names, **values;
13319355ec05SMatthew G. Knepley     PetscBool         *used;
13329355ec05SMatthew G. Knepley     PetscOptionSource *source;
13339355ec05SMatthew G. Knepley 
13349355ec05SMatthew G. Knepley     options->Nalloc = PetscMax(10, options->Nalloc * 2);
13359355ec05SMatthew G. Knepley     names           = (char **)malloc(options->Nalloc * sizeof(char *));
13369355ec05SMatthew G. Knepley     values          = (char **)malloc(options->Nalloc * sizeof(char *));
13379355ec05SMatthew G. Knepley     used            = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
13389355ec05SMatthew G. Knepley     source          = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
13399355ec05SMatthew G. Knepley     for (int i = 0; i < options->N; ++i) {
13409355ec05SMatthew G. Knepley       names[i]  = options->names[i];
13419355ec05SMatthew G. Knepley       values[i] = options->values[i];
13429355ec05SMatthew G. Knepley       used[i]   = options->used[i];
13439355ec05SMatthew G. Knepley       source[i] = options->source[i];
13449355ec05SMatthew G. Knepley     }
13459355ec05SMatthew G. Knepley     free(options->names);
13469355ec05SMatthew G. Knepley     free(options->values);
13479355ec05SMatthew G. Knepley     free(options->used);
13489355ec05SMatthew G. Knepley     free(options->source);
13499355ec05SMatthew G. Knepley     options->names  = names;
13509355ec05SMatthew G. Knepley     options->values = values;
13519355ec05SMatthew G. Knepley     options->used   = used;
13529355ec05SMatthew G. Knepley     options->source = source;
13539355ec05SMatthew G. Knepley   }
135439a651e2SJacob Faibussowitsch 
13552d747510SLisandro Dalcin   /* shift remaining values up 1 */
13569355ec05SMatthew G. Knepley   for (i = options->N; i > n; i--) {
13575e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1358e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1359e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
13609355ec05SMatthew G. Knepley     options->source[i] = options->source[i - 1];
1361e5c89e4eSSatish Balay   }
13622d747510SLisandro Dalcin   options->names[n]  = NULL;
13632d747510SLisandro Dalcin   options->values[n] = NULL;
13642d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
13659355ec05SMatthew G. Knepley   options->source[n] = PETSC_OPT_CODE;
13662d747510SLisandro Dalcin   options->N++;
13672d747510SLisandro Dalcin 
13682d747510SLisandro Dalcin   /* destroy hash table */
13692d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13702d747510SLisandro Dalcin   options->ht = NULL;
13712d747510SLisandro Dalcin 
13722d747510SLisandro Dalcin   /* set new name */
137370d8d27cSBarry Smith   len               = strlen(name);
13745e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
137539a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1376d49172ceSBarry Smith   strcpy(options->names[n], name);
13772d747510SLisandro Dalcin 
13782d747510SLisandro Dalcin setvalue:
13792d747510SLisandro Dalcin   /* set new value */
13802d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1381d49172ceSBarry Smith   len = value ? strlen(value) : 0;
13825e8c5e88SLisandro Dalcin   if (len) {
1383e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1384d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1385d49172ceSBarry Smith     strcpy(options->values[n], value);
1386432b765aSRené Chenard     options->values[n][len] = '\0';
13872d747510SLisandro Dalcin   } else {
13882d747510SLisandro Dalcin     options->values[n] = NULL;
13892d747510SLisandro Dalcin   }
13909355ec05SMatthew G. Knepley   options->source[n] = source;
13912d747510SLisandro Dalcin 
139291ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
139391ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
139491ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1395d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
139691ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
139791ad3481SVaclav Hapla   }
139891ad3481SVaclav Hapla 
1399432b765aSRené Chenard   PetscCall(PetscOptionsMonitor(options, name, value ? value : "", source));
1400c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
14013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1402e5c89e4eSSatish Balay }
1403e5c89e4eSSatish Balay 
14045d83a8b1SBarry Smith /*@
1405e5c89e4eSSatish Balay   PetscOptionsClearValue - Clears an option name-value pair in the options
1406e5c89e4eSSatish Balay   database, overriding whatever is already present.
1407e5c89e4eSSatish Balay 
14081c9f3c13SBarry Smith   Logically Collective
1409e5c89e4eSSatish Balay 
1410d8d19677SJose E. Roman   Input Parameters:
141120f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1412a2b725a8SWilliam Gropp - name    - name of option, this SHOULD have the - prepended
1413e5c89e4eSSatish Balay 
1414e5c89e4eSSatish Balay   Level: intermediate
1415e5c89e4eSSatish Balay 
1416811af0c4SBarry Smith   Note:
141721532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
14181c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
14191c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
14201c9f3c13SBarry Smith   on different ranks.
14211c9f3c13SBarry Smith 
14227e6f8dd6SBarry Smith   Developer Note:
14237e6f8dd6SBarry Smith   Uses `free()` directly because the options have been set with `malloc()`
14247e6f8dd6SBarry Smith 
1425db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1426e5c89e4eSSatish Balay @*/
1427d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1428d71ae5a4SJacob Faibussowitsch {
14292d747510SLisandro Dalcin   int    N, n, i;
14302d747510SLisandro Dalcin   char **names;
1431e5c89e4eSSatish Balay 
1432e5c89e4eSSatish Balay   PetscFunctionBegin;
1433c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1434cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1435c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
14362d747510SLisandro Dalcin 
14372d747510SLisandro Dalcin   name++; /* skip starting dash */
14382d747510SLisandro Dalcin 
14392d747510SLisandro Dalcin   /* slow search */
14402d747510SLisandro Dalcin   N = n = options->N;
1441e5c89e4eSSatish Balay   names = options->names;
1442e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
14432d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
14442d747510SLisandro Dalcin     if (!result) {
14459371c9d4SSatish Balay       n = i;
14469371c9d4SSatish Balay       break;
14472d747510SLisandro Dalcin     } else if (result > 0) {
14489371c9d4SSatish Balay       n = N;
14499371c9d4SSatish Balay       break;
1450e5c89e4eSSatish Balay     }
14512d747510SLisandro Dalcin   }
14523ba16761SJacob Faibussowitsch   if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1453e5c89e4eSSatish Balay 
14542d747510SLisandro Dalcin   /* remove name and value */
14552d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
14562d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1457e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1458e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
14595e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1460e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1461e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
14629355ec05SMatthew G. Knepley     options->source[i] = options->source[i + 1];
1463e5c89e4eSSatish Balay   }
1464e5c89e4eSSatish Balay   options->N--;
14652d747510SLisandro Dalcin 
14662d747510SLisandro Dalcin   /* destroy hash table */
14672d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
14682d747510SLisandro Dalcin   options->ht = NULL;
14692d747510SLisandro Dalcin 
14709355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
14713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1472e5c89e4eSSatish Balay }
1473e5c89e4eSSatish Balay 
1474e5c89e4eSSatish Balay /*@C
14752d747510SLisandro Dalcin   PetscOptionsFindPair - Gets an option name-value pair from the options database.
1476e5c89e4eSSatish Balay 
14772d747510SLisandro Dalcin   Not Collective
1478e5c89e4eSSatish Balay 
1479e5c89e4eSSatish Balay   Input Parameters:
148020f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
148120f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
14822d747510SLisandro Dalcin - name    - name of option, this SHOULD have the "-" prepended
1483e5c89e4eSSatish Balay 
14842d747510SLisandro Dalcin   Output Parameters:
14852d747510SLisandro Dalcin + value - the option value (optional, not used for all options)
14862d747510SLisandro Dalcin - set   - whether the option is set (optional)
1487e5c89e4eSSatish Balay 
148820f4b53cSBarry Smith   Level: developer
148920f4b53cSBarry Smith 
1490811af0c4SBarry Smith   Note:
14919666a313SBarry Smith   Each process may find different values or no value depending on how options were inserted into the database
14921c9f3c13SBarry Smith 
1493db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1494e5c89e4eSSatish Balay @*/
1495d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1496d71ae5a4SJacob Faibussowitsch {
14979355ec05SMatthew G. Knepley   char      buf[PETSC_MAX_OPTION_NAME];
1498daabea38SBarry Smith   PetscBool usehashtable = PETSC_TRUE;
14992d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1500e5c89e4eSSatish Balay 
1501e5c89e4eSSatish Balay   PetscFunctionBegin;
1502c5929fdfSBarry Smith   options = options ? options : defaultoptions;
150308401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1504cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1505e5c89e4eSSatish Balay 
15062d747510SLisandro Dalcin   name++; /* skip starting dash */
1507e5c89e4eSSatish Balay 
15087cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
15092d747510SLisandro Dalcin   if (pre && pre[0]) {
15102d747510SLisandro Dalcin     char *ptr = buf;
15119371c9d4SSatish Balay     if (name[0] == '-') {
15129371c9d4SSatish Balay       *ptr++ = '-';
15139371c9d4SSatish Balay       name++;
15149371c9d4SSatish Balay     }
15159566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
15169566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
15172d747510SLisandro Dalcin     name = buf;
15187cd08cecSJed Brown   }
15192d747510SLisandro Dalcin 
152076bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
15212f828895SJed Brown     PetscBool valid;
15229355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
15239566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
15249566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
152528b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
15262f828895SJed Brown   }
1527e5c89e4eSSatish Balay 
15282d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
15292d747510SLisandro Dalcin     int          i, ret;
15302d747510SLisandro Dalcin     khiter_t     it;
15312d747510SLisandro Dalcin     khash_t(HO) *ht;
15322d747510SLisandro Dalcin     ht = kh_init(HO);
153328b400f6SJacob Faibussowitsch     PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15342d747510SLisandro Dalcin     ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
153528b400f6SJacob Faibussowitsch     PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15362d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
15372d747510SLisandro Dalcin       it = kh_put(HO, ht, options->names[i], &ret);
153808401ef6SPierre Jolivet       PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15392d747510SLisandro Dalcin       kh_val(ht, it) = i;
15402d747510SLisandro Dalcin     }
15412d747510SLisandro Dalcin     options->ht = ht;
15422d747510SLisandro Dalcin   }
15432d747510SLisandro Dalcin 
15449371c9d4SSatish Balay   if (usehashtable) { /* fast search */
15452d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
15462d747510SLisandro Dalcin     khiter_t     it = kh_get(HO, ht, name);
15472d747510SLisandro Dalcin     if (it != kh_end(ht)) {
15482d747510SLisandro Dalcin       int i            = kh_val(ht, it);
1549e5c89e4eSSatish Balay       options->used[i] = PETSC_TRUE;
15502d747510SLisandro Dalcin       if (value) *value = options->values[i];
15512d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
15523ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
15532d747510SLisandro Dalcin     }
15549371c9d4SSatish Balay   } else { /* slow search */
15552d747510SLisandro Dalcin     int i, N = options->N;
15562d747510SLisandro Dalcin     for (i = 0; i < N; i++) {
1557daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i], name);
15582d747510SLisandro Dalcin       if (!result) {
15592d747510SLisandro Dalcin         options->used[i] = PETSC_TRUE;
15602d747510SLisandro Dalcin         if (value) *value = options->values[i];
15612d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
15623ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15632d747510SLisandro Dalcin       } else if (result > 0) {
1564e5c89e4eSSatish Balay         break;
1565e5c89e4eSSatish Balay       }
1566e5c89e4eSSatish Balay     }
15672d747510SLisandro Dalcin   }
15682d747510SLisandro Dalcin 
15692d747510SLisandro Dalcin   /*
15702d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
15712d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
15722d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
15732d747510SLisandro Dalcin    */
15742d747510SLisandro Dalcin   if (matchnumbers) {
15752d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1576e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
15772d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
15782d747510SLisandro Dalcin       if (name[i] == '_') {
15792d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
15802d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
15812d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1582e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1583e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1584e5c89e4eSSatish Balay           }
15852d747510SLisandro Dalcin           i = j - 1;
1586e5c89e4eSSatish Balay           break;
1587e5c89e4eSSatish Balay         }
1588e5c89e4eSSatish Balay       }
1589e5c89e4eSSatish Balay     }
1590e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
15912d747510SLisandro Dalcin       PetscBool found;
15929355ec05SMatthew G. Knepley       char      opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
15939566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
15949566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15959566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
15969566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
15979371c9d4SSatish Balay       if (found) {
15989371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
15993ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
16009371c9d4SSatish Balay       }
1601e5c89e4eSSatish Balay     }
1602e5c89e4eSSatish Balay   }
16032d747510SLisandro Dalcin 
16042d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1606e5c89e4eSSatish Balay }
1607e5c89e4eSSatish Balay 
1608d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
160954a546c1SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *option[], const char *value[], PetscBool *set)
1610d71ae5a4SJacob Faibussowitsch {
16119355ec05SMatthew G. Knepley   char buf[PETSC_MAX_OPTION_NAME];
1612d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1613514bf10dSMatthew G Knepley 
1614514bf10dSMatthew G Knepley   PetscFunctionBegin;
1615c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1616cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1617cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1618514bf10dSMatthew G Knepley 
16192d747510SLisandro Dalcin   name++; /* skip starting dash */
1620514bf10dSMatthew G Knepley 
1621514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
16222d747510SLisandro Dalcin   if (pre && pre[0]) {
16232d747510SLisandro Dalcin     char *ptr = buf;
16249371c9d4SSatish Balay     if (name[0] == '-') {
16259371c9d4SSatish Balay       *ptr++ = '-';
16269371c9d4SSatish Balay       name++;
16279371c9d4SSatish Balay     }
16289b15cf9aSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
16299566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
16302d747510SLisandro Dalcin     name = buf;
1631514bf10dSMatthew G Knepley   }
16322d747510SLisandro Dalcin 
163376bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1634514bf10dSMatthew G Knepley     PetscBool valid;
16359355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
16369566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
16379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
163828b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1639514bf10dSMatthew G Knepley   }
1640514bf10dSMatthew G Knepley 
1641d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1642d6ced9c0SMatthew G. Knepley   {
1643d6ced9c0SMatthew G. Knepley     int i, j;
1644d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1645d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1646d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1647d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1648d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1649d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1650d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1651d6ced9c0SMatthew G. Knepley           }
1652d6ced9c0SMatthew G. Knepley           i = j - 1;
1653d6ced9c0SMatthew G. Knepley           break;
1654d6ced9c0SMatthew G. Knepley         }
1655d6ced9c0SMatthew G. Knepley       }
1656d6ced9c0SMatthew G. Knepley     }
1657d6ced9c0SMatthew G. Knepley   }
1658d6ced9c0SMatthew G. Knepley 
1659363da2dcSJacob Faibussowitsch   /* slow search */
1660363da2dcSJacob Faibussowitsch   for (int c = -1; c < numCnt; ++c) {
1661363da2dcSJacob Faibussowitsch     char   opt[PETSC_MAX_OPTION_NAME + 2] = "";
16622d747510SLisandro Dalcin     size_t len;
1663d6ced9c0SMatthew G. Knepley 
1664d6ced9c0SMatthew G. Knepley     if (c < 0) {
1665c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1666d6ced9c0SMatthew G. Knepley     } else {
1667363da2dcSJacob Faibussowitsch       PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1668363da2dcSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1669d6ced9c0SMatthew G. Knepley     }
16709566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(opt, &len));
1671363da2dcSJacob Faibussowitsch     for (int i = 0; i < options->N; i++) {
1672363da2dcSJacob Faibussowitsch       PetscBool match;
1673363da2dcSJacob Faibussowitsch 
16749566063dSJacob Faibussowitsch       PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1675514bf10dSMatthew G Knepley       if (match) {
1676514bf10dSMatthew G Knepley         options->used[i] = PETSC_TRUE;
167754a546c1SMatthew G. Knepley         if (option) *option = options->names[i];
16782d747510SLisandro Dalcin         if (value) *value = options->values[i];
16792d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
16803ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
1681514bf10dSMatthew G Knepley       }
1682514bf10dSMatthew G Knepley     }
16832d747510SLisandro Dalcin   }
16842d747510SLisandro Dalcin 
16852d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1687514bf10dSMatthew G Knepley }
1688514bf10dSMatthew G Knepley 
16895d83a8b1SBarry Smith /*@
1690e5c89e4eSSatish Balay   PetscOptionsReject - Generates an error if a certain option is given.
1691e5c89e4eSSatish Balay 
16921c9f3c13SBarry Smith   Not Collective
1693e5c89e4eSSatish Balay 
1694e5c89e4eSSatish Balay   Input Parameters:
169520f4b53cSBarry Smith + options - options database, use `NULL` for default global database
169620f4b53cSBarry Smith . pre     - the option prefix (may be `NULL`)
16972d747510SLisandro Dalcin . name    - the option name one is seeking
169820f4b53cSBarry Smith - mess    - error message (may be `NULL`)
1699e5c89e4eSSatish Balay 
1700e5c89e4eSSatish Balay   Level: advanced
1701e5c89e4eSSatish Balay 
17020241b274SPierre Jolivet .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1703db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1704db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1705c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1706db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1707db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1708e5c89e4eSSatish Balay @*/
1709d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1710d71ae5a4SJacob Faibussowitsch {
1711ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1712e5c89e4eSSatish Balay 
1713e5c89e4eSSatish Balay   PetscFunctionBegin;
17149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1715e5c89e4eSSatish Balay   if (flag) {
171608401ef6SPierre 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);
1717f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1718e5c89e4eSSatish Balay   }
17193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1720e5c89e4eSSatish Balay }
1721e5c89e4eSSatish Balay 
17225d83a8b1SBarry Smith /*@
17232d747510SLisandro Dalcin   PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
17242d747510SLisandro Dalcin 
17252d747510SLisandro Dalcin   Not Collective
17262d747510SLisandro Dalcin 
1727811af0c4SBarry Smith   Input Parameter:
172820f4b53cSBarry Smith . options - options database, use `NULL` for default global database
17292d747510SLisandro Dalcin 
1730811af0c4SBarry Smith   Output Parameter:
1731811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
17322d747510SLisandro Dalcin 
17332d747510SLisandro Dalcin   Level: advanced
17342d747510SLisandro Dalcin 
1735db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
17362d747510SLisandro Dalcin @*/
1737d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1738d71ae5a4SJacob Faibussowitsch {
17392d747510SLisandro Dalcin   PetscFunctionBegin;
17404f572ea9SToby Isaac   PetscAssertPointer(set, 2);
17412d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17422d747510SLisandro Dalcin   *set    = options->help;
17433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17442d747510SLisandro Dalcin }
17452d747510SLisandro Dalcin 
1746d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1747d71ae5a4SJacob Faibussowitsch {
1748d314f959SVaclav Hapla   PetscFunctionBegin;
17494f572ea9SToby Isaac   PetscAssertPointer(set, 2);
1750d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1751d314f959SVaclav Hapla   *set    = options->help_intro;
17523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1753d314f959SVaclav Hapla }
1754d314f959SVaclav Hapla 
17555d83a8b1SBarry Smith /*@
1756e24fcbf7SPierre 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
1757e24fcbf7SPierre Jolivet   if its value is set to false.
1758e5c89e4eSSatish Balay 
1759e5c89e4eSSatish Balay   Not Collective
1760e5c89e4eSSatish Balay 
1761e5c89e4eSSatish Balay   Input Parameters:
176220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
176320f4b53cSBarry Smith . pre     - string to prepend to the name or `NULL`
17643de71b31SHong Zhang - name    - the option one is seeking
1765e5c89e4eSSatish Balay 
1766811af0c4SBarry Smith   Output Parameter:
1767811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1768e5c89e4eSSatish Balay 
1769e5c89e4eSSatish Balay   Level: beginner
1770e5c89e4eSSatish Balay 
1771811af0c4SBarry Smith   Note:
1772811af0c4SBarry Smith   In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
177390d69ab7SBarry Smith 
1774db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1775db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1776db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1777c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1778db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1779db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1780e5c89e4eSSatish Balay @*/
1781d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1782d71ae5a4SJacob Faibussowitsch {
17832d747510SLisandro Dalcin   const char *value;
1784ace3abfcSBarry Smith   PetscBool   flag;
1785e5c89e4eSSatish Balay 
1786e5c89e4eSSatish Balay   PetscFunctionBegin;
17879566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
178896ef3cdfSSatish Balay   if (set) *set = flag;
17893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1790e5c89e4eSSatish Balay }
1791e5c89e4eSSatish Balay 
1792e5c89e4eSSatish Balay /*@C
17932d747510SLisandro Dalcin   PetscOptionsGetAll - Lists all the options the program was run with in a single string.
17942d747510SLisandro Dalcin 
17952d747510SLisandro Dalcin   Not Collective
17962d747510SLisandro Dalcin 
1797fd292e60Sprj-   Input Parameter:
179820f4b53cSBarry Smith . options - the options database, use `NULL` for the default global database
17992d747510SLisandro Dalcin 
18002d747510SLisandro Dalcin   Output Parameter:
18012d747510SLisandro Dalcin . copts - pointer where string pointer is stored
18022d747510SLisandro Dalcin 
180320f4b53cSBarry Smith   Level: advanced
180420f4b53cSBarry Smith 
18052d747510SLisandro Dalcin   Notes:
1806811af0c4SBarry Smith   The array and each entry in the array should be freed with `PetscFree()`
1807811af0c4SBarry Smith 
18081c9f3c13SBarry Smith   Each process may have different values depending on how the options were inserted into the database
18092d747510SLisandro Dalcin 
1810db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
18112d747510SLisandro Dalcin @*/
1812d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[])
1813d71ae5a4SJacob Faibussowitsch {
18142d747510SLisandro Dalcin   PetscInt i;
18152d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
18162d747510SLisandro Dalcin   char    *coptions = NULL;
18172d747510SLisandro Dalcin 
18182d747510SLisandro Dalcin   PetscFunctionBegin;
18194f572ea9SToby Isaac   PetscAssertPointer(copts, 2);
18202d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18212d747510SLisandro Dalcin   /* count the length of the required string */
18222d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18239566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
18242d747510SLisandro Dalcin     len += 2 + lent;
18252d747510SLisandro Dalcin     if (options->values[i]) {
18269566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
18272d747510SLisandro Dalcin       len += 1 + lent;
18282d747510SLisandro Dalcin     }
18292d747510SLisandro Dalcin   }
18309566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
18312d747510SLisandro Dalcin   coptions[0] = 0;
18322d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1833c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, "-", len));
1834c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, options->names[i], len));
1835c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, " ", len));
18362d747510SLisandro Dalcin     if (options->values[i]) {
1837c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, options->values[i], len));
1838c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, " ", len));
18392d747510SLisandro Dalcin     }
18402d747510SLisandro Dalcin   }
18412d747510SLisandro Dalcin   *copts = coptions;
18423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18432d747510SLisandro Dalcin }
18442d747510SLisandro Dalcin 
18455d83a8b1SBarry Smith /*@
18462d747510SLisandro Dalcin   PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
18472d747510SLisandro Dalcin 
18482d747510SLisandro Dalcin   Not Collective
18492d747510SLisandro Dalcin 
1850d8d19677SJose E. Roman   Input Parameters:
185120f4b53cSBarry Smith + options - options database, use `NULL` for default global database
18522d747510SLisandro Dalcin - name    - string name of option
18532d747510SLisandro Dalcin 
18542d747510SLisandro Dalcin   Output Parameter:
1855811af0c4SBarry Smith . used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
18562d747510SLisandro Dalcin 
18572d747510SLisandro Dalcin   Level: advanced
18582d747510SLisandro Dalcin 
1859811af0c4SBarry Smith   Note:
18609666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18611c9f3c13SBarry Smith   on the given process
18621c9f3c13SBarry Smith 
1863db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
18642d747510SLisandro Dalcin @*/
1865d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1866d71ae5a4SJacob Faibussowitsch {
18672d747510SLisandro Dalcin   PetscInt i;
18682d747510SLisandro Dalcin 
18692d747510SLisandro Dalcin   PetscFunctionBegin;
18704f572ea9SToby Isaac   PetscAssertPointer(name, 2);
18714f572ea9SToby Isaac   PetscAssertPointer(used, 3);
18722d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18732d747510SLisandro Dalcin   *used   = PETSC_FALSE;
18742d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18759566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
18762d747510SLisandro Dalcin     if (*used) {
18772d747510SLisandro Dalcin       *used = options->used[i];
18782d747510SLisandro Dalcin       break;
18792d747510SLisandro Dalcin     }
18802d747510SLisandro Dalcin   }
18813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18822d747510SLisandro Dalcin }
18832d747510SLisandro Dalcin 
1884487a658cSBarry Smith /*@
18852d747510SLisandro Dalcin   PetscOptionsAllUsed - Returns a count of the number of options in the
18862d747510SLisandro Dalcin   database that have never been selected.
18872d747510SLisandro Dalcin 
18882d747510SLisandro Dalcin   Not Collective
18892d747510SLisandro Dalcin 
18902d747510SLisandro Dalcin   Input Parameter:
189120f4b53cSBarry Smith . options - options database, use `NULL` for default global database
18922d747510SLisandro Dalcin 
18932d747510SLisandro Dalcin   Output Parameter:
18942d747510SLisandro Dalcin . N - count of options not used
18952d747510SLisandro Dalcin 
18962d747510SLisandro Dalcin   Level: advanced
18972d747510SLisandro Dalcin 
1898811af0c4SBarry Smith   Note:
18999666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
19001c9f3c13SBarry Smith   on the given process
19011c9f3c13SBarry Smith 
1902db781477SPatrick Sanan .seealso: `PetscOptionsView()`
19032d747510SLisandro Dalcin @*/
1904d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1905d71ae5a4SJacob Faibussowitsch {
19062d747510SLisandro Dalcin   PetscInt i, n = 0;
19072d747510SLisandro Dalcin 
19082d747510SLisandro Dalcin   PetscFunctionBegin;
19094f572ea9SToby Isaac   PetscAssertPointer(N, 2);
19102d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19112d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
19122d747510SLisandro Dalcin     if (!options->used[i]) n++;
19132d747510SLisandro Dalcin   }
19142d747510SLisandro Dalcin   *N = n;
19153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19162d747510SLisandro Dalcin }
19172d747510SLisandro Dalcin 
1918487a658cSBarry Smith /*@
19192d747510SLisandro Dalcin   PetscOptionsLeft - Prints to screen any options that were set and never used.
19202d747510SLisandro Dalcin 
19212d747510SLisandro Dalcin   Not Collective
19222d747510SLisandro Dalcin 
19232d747510SLisandro Dalcin   Input Parameter:
192420f4b53cSBarry Smith . options - options database; use `NULL` for default global database
19252d747510SLisandro Dalcin 
19262d747510SLisandro Dalcin   Options Database Key:
1927811af0c4SBarry Smith . -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
19282d747510SLisandro Dalcin 
192920f4b53cSBarry Smith   Level: advanced
193020f4b53cSBarry Smith 
19313de2bfdfSBarry Smith   Notes:
1932811af0c4SBarry Smith   This is rarely used directly, it is called by `PetscFinalize()` in debug more or if -options_left
19331c9f3c13SBarry Smith   is passed otherwise to help users determine possible mistakes in their usage of options. This
1934811af0c4SBarry Smith   only prints values on process zero of `PETSC_COMM_WORLD`.
1935811af0c4SBarry Smith 
1936811af0c4SBarry Smith   Other processes depending the objects
19371c9f3c13SBarry Smith   used may have different options that are left unused.
19383de2bfdfSBarry Smith 
1939db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
19402d747510SLisandro Dalcin @*/
1941d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeft(PetscOptions options)
1942d71ae5a4SJacob Faibussowitsch {
19432d747510SLisandro Dalcin   PetscInt     i;
19443de2bfdfSBarry Smith   PetscInt     cnt = 0;
19453de2bfdfSBarry Smith   PetscOptions toptions;
19462d747510SLisandro Dalcin 
19472d747510SLisandro Dalcin   PetscFunctionBegin;
19483de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
19493de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
19503de2bfdfSBarry Smith     if (!toptions->used[i]) {
1951660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
19523de2bfdfSBarry Smith       if (toptions->values[i]) {
19539355ec05SMatthew 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]]));
19542d747510SLisandro Dalcin       } else {
19559355ec05SMatthew G. Knepley         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
19562d747510SLisandro Dalcin       }
19572d747510SLisandro Dalcin     }
19582d747510SLisandro Dalcin   }
19593de2bfdfSBarry Smith   if (!options) {
19603de2bfdfSBarry Smith     toptions = defaultoptions;
19613de2bfdfSBarry Smith     while (toptions->previous) {
19623de2bfdfSBarry Smith       cnt++;
19633de2bfdfSBarry Smith       toptions = toptions->previous;
19643de2bfdfSBarry Smith     }
196548a46eb9SPierre 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));
19663de2bfdfSBarry Smith   }
19673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19682d747510SLisandro Dalcin }
19692d747510SLisandro Dalcin 
19702d747510SLisandro Dalcin /*@C
19712d747510SLisandro Dalcin   PetscOptionsLeftGet - Returns all options that were set and never used.
19722d747510SLisandro Dalcin 
19732d747510SLisandro Dalcin   Not Collective
19742d747510SLisandro Dalcin 
19752d747510SLisandro Dalcin   Input Parameter:
197620f4b53cSBarry Smith . options - options database, use `NULL` for default global database
19772d747510SLisandro Dalcin 
1978d8d19677SJose E. Roman   Output Parameters:
1979a2b725a8SWilliam Gropp + N      - count of options not used
19802d747510SLisandro Dalcin . names  - names of options not used
1981a2b725a8SWilliam Gropp - values - values of options not used
19822d747510SLisandro Dalcin 
19832d747510SLisandro Dalcin   Level: advanced
19842d747510SLisandro Dalcin 
19852d747510SLisandro Dalcin   Notes:
1986811af0c4SBarry Smith   Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1987811af0c4SBarry Smith 
1988811af0c4SBarry Smith   The value returned may be different on each process and depends on which options have been processed
19891c9f3c13SBarry Smith   on the given process
19902d747510SLisandro Dalcin 
1991db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
19922d747510SLisandro Dalcin @*/
1993d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
1994d71ae5a4SJacob Faibussowitsch {
19952d747510SLisandro Dalcin   PetscInt i, n;
19962d747510SLisandro Dalcin 
19972d747510SLisandro Dalcin   PetscFunctionBegin;
19984f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
19994f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
20004f572ea9SToby Isaac   if (values) PetscAssertPointer(values, 4);
20012d747510SLisandro Dalcin   options = options ? options : defaultoptions;
20022d747510SLisandro Dalcin 
20032d747510SLisandro Dalcin   /* The number of unused PETSc options */
20042d747510SLisandro Dalcin   n = 0;
20052d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
2006660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
20072d747510SLisandro Dalcin     if (!options->used[i]) n++;
20082d747510SLisandro Dalcin   }
2009ad540459SPierre Jolivet   if (N) *N = n;
20109566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
20119566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
20122d747510SLisandro Dalcin 
20132d747510SLisandro Dalcin   n = 0;
20142d747510SLisandro Dalcin   if (names || values) {
20152d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
20162d747510SLisandro Dalcin       if (!options->used[i]) {
2017660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
20182d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
20192d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
20202d747510SLisandro Dalcin         n++;
20212d747510SLisandro Dalcin       }
20222d747510SLisandro Dalcin     }
20232d747510SLisandro Dalcin   }
20243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20252d747510SLisandro Dalcin }
20262d747510SLisandro Dalcin 
20272d747510SLisandro Dalcin /*@C
2028811af0c4SBarry Smith   PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
20292d747510SLisandro Dalcin 
20302d747510SLisandro Dalcin   Not Collective
20312d747510SLisandro Dalcin 
2032d8d19677SJose E. Roman   Input Parameters:
203320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
203410450e9eSJacob Faibussowitsch . N       - count of options not used
20352d747510SLisandro Dalcin . names   - names of options not used
2036a2b725a8SWilliam Gropp - values  - values of options not used
20372d747510SLisandro Dalcin 
20382d747510SLisandro Dalcin   Level: advanced
20392d747510SLisandro Dalcin 
204010450e9eSJacob Faibussowitsch   Notes:
204110450e9eSJacob Faibussowitsch   The user should pass the same pointer to `N` as they did when calling `PetscOptionsLeftGet()`
204210450e9eSJacob Faibussowitsch 
2043db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
20442d747510SLisandro Dalcin @*/
2045d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2046d71ae5a4SJacob Faibussowitsch {
20472d747510SLisandro Dalcin   PetscFunctionBegin;
204810450e9eSJacob Faibussowitsch   (void)options;
20494f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
20504f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
20514f572ea9SToby Isaac   if (values) PetscAssertPointer(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.
20739314d9b7SBarry Smith   The first MPI process 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
211510450e9eSJacob Faibussowitsch . mctx           - [optional] context for private data for the monitor routine (use `NULL` if
211610450e9eSJacob Faibussowitsch                    no context is desired)
211710450e9eSJacob Faibussowitsch - monitordestroy - [optional] routine that frees monitor context (may be `NULL`)
21182d747510SLisandro Dalcin 
211910450e9eSJacob Faibussowitsch   Calling sequence of `monitor`:
21202d747510SLisandro Dalcin + name   - option name string
2121432b765aSRené Chenard . value  - option value string, a value of `NULL` indicates the option is being removed from the database. A value
2122432b765aSRené Chenard            of "" indicates the option is in the database but has no value.
21239355ec05SMatthew G. Knepley . source - option source
2124811af0c4SBarry Smith - mctx   - optional monitoring context, as set by `PetscOptionsMonitorSet()`
21252d747510SLisandro Dalcin 
212610450e9eSJacob Faibussowitsch   Calling sequence of `monitordestroy`:
212710450e9eSJacob Faibussowitsch . mctx - [optional] pointer to context to destroy with
21282d747510SLisandro Dalcin 
2129432b765aSRené Chenard   Options Database Keys:
2130432b765aSRené Chenard + -options_monitor <viewer> - turn on default monitoring
2131432b765aSRené Chenard - -options_monitor_cancel   - turn off any option monitors except the default monitor obtained with `-options_monitor`
2132432b765aSRené Chenard 
213320f4b53cSBarry Smith   Level: intermediate
213420f4b53cSBarry Smith 
21352d747510SLisandro Dalcin   Notes:
213610450e9eSJacob Faibussowitsch   See `PetscInitialize()` for options related to option database monitoring.
213710450e9eSJacob Faibussowitsch 
2138432b765aSRené Chenard   The default is to do no monitoring.  To print the name and value of options
2139811af0c4SBarry Smith   being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
2140432b765aSRené Chenard   with a `NULL` monitoring context. Or use the option `-options_monitor` <viewer>.
21412d747510SLisandro Dalcin 
21422d747510SLisandro Dalcin   Several different monitoring routines may be set by calling
2143811af0c4SBarry Smith   `PetscOptionsMonitorSet()` multiple times; all will be called in the
21442d747510SLisandro Dalcin   order in which they were set.
21452d747510SLisandro Dalcin 
2146db781477SPatrick Sanan .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
21472d747510SLisandro Dalcin @*/
214810450e9eSJacob Faibussowitsch PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource source, void *mctx), void *mctx, PetscErrorCode (*monitordestroy)(void **mctx))
2149d71ae5a4SJacob Faibussowitsch {
21502d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
21512d747510SLisandro Dalcin 
21522d747510SLisandro Dalcin   PetscFunctionBegin;
21533ba16761SJacob Faibussowitsch   if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
215408401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
21552d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
21562d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
21572d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void *)mctx;
21583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21592d747510SLisandro Dalcin }
21602d747510SLisandro Dalcin 
21612d747510SLisandro Dalcin /*
21622d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
216363fe8743SVaclav Hapla      Empty string is considered as true.
21642d747510SLisandro Dalcin */
2165d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2166d71ae5a4SJacob Faibussowitsch {
21672d747510SLisandro Dalcin   PetscBool istrue, isfalse;
21682d747510SLisandro Dalcin   size_t    len;
21692d747510SLisandro Dalcin 
21702d747510SLisandro Dalcin   PetscFunctionBegin;
217163fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
21729566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
21739371c9d4SSatish Balay   if (!len) {
21749371c9d4SSatish Balay     *a = PETSC_TRUE;
21753ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21769371c9d4SSatish Balay   }
21779566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
21789371c9d4SSatish Balay   if (istrue) {
21799371c9d4SSatish Balay     *a = PETSC_TRUE;
21803ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21819371c9d4SSatish Balay   }
21829566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
21839371c9d4SSatish Balay   if (istrue) {
21849371c9d4SSatish Balay     *a = PETSC_TRUE;
21853ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21869371c9d4SSatish Balay   }
21879566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
21889371c9d4SSatish Balay   if (istrue) {
21899371c9d4SSatish Balay     *a = PETSC_TRUE;
21903ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21919371c9d4SSatish Balay   }
21929566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
21939371c9d4SSatish Balay   if (istrue) {
21949371c9d4SSatish Balay     *a = PETSC_TRUE;
21953ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21969371c9d4SSatish Balay   }
21979566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
21989371c9d4SSatish Balay   if (isfalse) {
21999371c9d4SSatish Balay     *a = PETSC_FALSE;
22003ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22019371c9d4SSatish Balay   }
22029566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
22039371c9d4SSatish Balay   if (isfalse) {
22049371c9d4SSatish Balay     *a = PETSC_FALSE;
22053ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22069371c9d4SSatish Balay   }
22079566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
22089371c9d4SSatish Balay   if (isfalse) {
22099371c9d4SSatish Balay     *a = PETSC_FALSE;
22103ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22119371c9d4SSatish Balay   }
22129566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
22139371c9d4SSatish Balay   if (isfalse) {
22149371c9d4SSatish Balay     *a = PETSC_FALSE;
22153ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22169371c9d4SSatish Balay   }
221798921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
22182d747510SLisandro Dalcin }
22192d747510SLisandro Dalcin 
22202d747510SLisandro Dalcin /*
22212d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
22222d747510SLisandro Dalcin */
2223d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2224d71ae5a4SJacob Faibussowitsch {
22252d747510SLisandro Dalcin   size_t    len;
2226*b3480c81SBarry Smith   PetscBool decide, tdefault, mouse, unlimited;
22272d747510SLisandro Dalcin 
22282d747510SLisandro Dalcin   PetscFunctionBegin;
22299566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
22305f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22312d747510SLisandro Dalcin 
22329566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
223348a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
22349566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
223548a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
2236*b3480c81SBarry Smith   if (!decide) PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &decide));
2237*b3480c81SBarry Smith   if (!decide) PetscCall(PetscStrcasecmp(name, "DETERMINE", &decide));
2238*b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &unlimited));
2239*b3480c81SBarry Smith   if (!unlimited) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &unlimited));
22409566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
22412d747510SLisandro Dalcin 
22422d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
22432d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
2244*b3480c81SBarry Smith   else if (unlimited) *a = PETSC_UNLIMITED;
22452d747510SLisandro Dalcin   else if (mouse) *a = -1;
22462d747510SLisandro Dalcin   else {
22472d747510SLisandro Dalcin     char *endptr;
22482d747510SLisandro Dalcin     long  strtolval;
22492d747510SLisandro Dalcin 
22502d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2251cc73adaaSBarry 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);
22522d747510SLisandro Dalcin 
22532d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
22542d747510SLisandro Dalcin     (void)strtolval;
22552d747510SLisandro Dalcin     *a = atoll(name);
22562d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
22572d747510SLisandro Dalcin     (void)strtolval;
22582d747510SLisandro Dalcin     *a = _atoi64(name);
22592d747510SLisandro Dalcin #else
22602d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
22612d747510SLisandro Dalcin #endif
22622d747510SLisandro Dalcin   }
22633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22642d747510SLisandro Dalcin }
22652d747510SLisandro Dalcin 
22662d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22672d747510SLisandro Dalcin   #include <quadmath.h>
22682d747510SLisandro Dalcin #endif
22692d747510SLisandro Dalcin 
2270d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2271d71ae5a4SJacob Faibussowitsch {
22722d747510SLisandro Dalcin   PetscFunctionBegin;
22732d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22742d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
22752d747510SLisandro Dalcin #else
22762d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
22772d747510SLisandro Dalcin #endif
22783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22792d747510SLisandro Dalcin }
22802d747510SLisandro Dalcin 
2281d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2282d71ae5a4SJacob Faibussowitsch {
22832d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
22842d747510SLisandro Dalcin   char     *ptr;
22852d747510SLisandro Dalcin   PetscReal strtoval;
22862d747510SLisandro Dalcin 
22872d747510SLisandro Dalcin   PetscFunctionBegin;
22889566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
22892d747510SLisandro Dalcin   if (ptr == name) {
22902d747510SLisandro Dalcin     strtoval = 1.;
22912d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
22922d747510SLisandro Dalcin     if (name[0] == 'i') {
22932d747510SLisandro Dalcin       ptr++;
22942d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
22952d747510SLisandro Dalcin       ptr += 2;
22962d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
22972d747510SLisandro Dalcin       strtoval = -1.;
22982d747510SLisandro Dalcin       ptr += 2;
22992d747510SLisandro Dalcin     }
23002d747510SLisandro Dalcin   } else if (*ptr == 'i') {
23012d747510SLisandro Dalcin     hasi = PETSC_TRUE;
23022d747510SLisandro Dalcin     ptr++;
23032d747510SLisandro Dalcin   }
23042d747510SLisandro Dalcin   *endptr      = ptr;
23052d747510SLisandro Dalcin   *isImaginary = hasi;
23062d747510SLisandro Dalcin   if (hasi) {
23072d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
230898921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
23092d747510SLisandro Dalcin #else
23102d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
23112d747510SLisandro Dalcin #endif
23122d747510SLisandro Dalcin   } else {
23132d747510SLisandro Dalcin     *a = strtoval;
23142d747510SLisandro Dalcin   }
23153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23162d747510SLisandro Dalcin }
23172d747510SLisandro Dalcin 
23182d747510SLisandro Dalcin /*
23192d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
23202d747510SLisandro Dalcin */
2321d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2322d71ae5a4SJacob Faibussowitsch {
23232d747510SLisandro Dalcin   size_t    len;
23242d747510SLisandro Dalcin   PetscBool match;
23252d747510SLisandro Dalcin   char     *endptr;
23262d747510SLisandro Dalcin 
23272d747510SLisandro Dalcin   PetscFunctionBegin;
23289566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
232928b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
23302d747510SLisandro Dalcin 
23319566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
23329566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
23339371c9d4SSatish Balay   if (match) {
23349371c9d4SSatish Balay     *a = PETSC_DEFAULT;
23353ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23369371c9d4SSatish Balay   }
23372d747510SLisandro Dalcin 
23389566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
23399566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
23409371c9d4SSatish Balay   if (match) {
23419371c9d4SSatish Balay     *a = PETSC_DECIDE;
23423ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23439371c9d4SSatish Balay   }
23442d747510SLisandro Dalcin 
2345*b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &match));
2346*b3480c81SBarry Smith   if (!match) PetscCall(PetscStrcasecmp(name, "DETERMINE", &match));
2347*b3480c81SBarry Smith   if (match) {
2348*b3480c81SBarry Smith     *a = PETSC_DETERMINE;
2349*b3480c81SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
2350*b3480c81SBarry Smith   }
2351*b3480c81SBarry Smith 
2352*b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &match));
2353*b3480c81SBarry Smith   if (!match) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &match));
2354*b3480c81SBarry Smith   if (match) {
2355*b3480c81SBarry Smith     *a = PETSC_UNLIMITED;
2356*b3480c81SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
2357*b3480c81SBarry Smith   }
2358*b3480c81SBarry Smith 
23599566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
236039a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
23613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23622d747510SLisandro Dalcin }
23632d747510SLisandro Dalcin 
2364d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2365d71ae5a4SJacob Faibussowitsch {
23662d747510SLisandro Dalcin   PetscBool   imag1;
23672d747510SLisandro Dalcin   size_t      len;
23682d747510SLisandro Dalcin   PetscScalar val = 0.;
23692d747510SLisandro Dalcin   char       *ptr = NULL;
23702d747510SLisandro Dalcin 
23712d747510SLisandro Dalcin   PetscFunctionBegin;
23729566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
237328b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
23749566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
23752d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
23762d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
23772d747510SLisandro Dalcin     PetscBool   imag2;
23782d747510SLisandro Dalcin     PetscScalar val2;
23792d747510SLisandro Dalcin 
23809566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
238139a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
23822d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
23832d747510SLisandro Dalcin   }
23842d747510SLisandro Dalcin #endif
238539a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
23862d747510SLisandro Dalcin   *a = val;
23873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23882d747510SLisandro Dalcin }
23892d747510SLisandro Dalcin 
23902d747510SLisandro Dalcin /*@C
23912d747510SLisandro Dalcin   PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
23922d747510SLisandro Dalcin   option in the database.
2393e5c89e4eSSatish Balay 
2394e5c89e4eSSatish Balay   Not Collective
2395e5c89e4eSSatish Balay 
2396e5c89e4eSSatish Balay   Input Parameters:
239720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
239820f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2399e5c89e4eSSatish Balay - name    - the option one is seeking
2400e5c89e4eSSatish Balay 
2401d8d19677SJose E. Roman   Output Parameters:
24022d747510SLisandro Dalcin + ivalue - the logical value to return
2403811af0c4SBarry Smith - set    - `PETSC_TRUE`  if found, else `PETSC_FALSE`
2404e5c89e4eSSatish Balay 
2405e5c89e4eSSatish Balay   Level: beginner
2406e5c89e4eSSatish Balay 
240795452b02SPatrick Sanan   Notes:
2408811af0c4SBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`
2409811af0c4SBarry Smith   FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
24102d747510SLisandro Dalcin 
24119314d9b7SBarry 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`
24129314d9b7SBarry Smith   is equivalent to `-requested_bool true`
24132d747510SLisandro Dalcin 
24149314d9b7SBarry Smith   If the user does not supply the option at all `ivalue` is NOT changed. Thus
24159314d9b7SBarry Smith   you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
24162efd9cb1SBarry Smith 
2417db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2418db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2419db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2420c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2421db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2422db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2423e5c89e4eSSatish Balay @*/
2424d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2425d71ae5a4SJacob Faibussowitsch {
24262d747510SLisandro Dalcin   const char *value;
2427ace3abfcSBarry Smith   PetscBool   flag;
2428e5c89e4eSSatish Balay 
2429e5c89e4eSSatish Balay   PetscFunctionBegin;
24304f572ea9SToby Isaac   PetscAssertPointer(name, 3);
24314f572ea9SToby Isaac   if (ivalue) PetscAssertPointer(ivalue, 4);
24329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2433e5c89e4eSSatish Balay   if (flag) {
243496ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
24359566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
24362d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2437e5c89e4eSSatish Balay   } else {
243896ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2439e5c89e4eSSatish Balay   }
24403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2441e5c89e4eSSatish Balay }
2442e5c89e4eSSatish Balay 
2443e5c89e4eSSatish Balay /*@C
2444e5c89e4eSSatish Balay   PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2445e5c89e4eSSatish Balay 
2446e5c89e4eSSatish Balay   Not Collective
2447e5c89e4eSSatish Balay 
2448e5c89e4eSSatish Balay   Input Parameters:
244920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
245020f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2451e5c89e4eSSatish Balay . opt     - option name
2452a264d7a6SBarry Smith . list    - the possible choices (one of these must be selected, anything else is invalid)
2453a2b725a8SWilliam Gropp - ntext   - number of choices
2454e5c89e4eSSatish Balay 
2455d8d19677SJose E. Roman   Output Parameters:
24562efd9cb1SBarry Smith + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2457811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2458e5c89e4eSSatish Balay 
2459e5c89e4eSSatish Balay   Level: intermediate
2460e5c89e4eSSatish Balay 
246195452b02SPatrick Sanan   Notes:
24629314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
24639314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
24642efd9cb1SBarry Smith 
2465811af0c4SBarry Smith   See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2466e5c89e4eSSatish Balay 
2467db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2468db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2469db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2470c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2471db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2472db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2473e5c89e4eSSatish Balay @*/
2474d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscInt ntext, PetscInt *value, PetscBool *set)
2475d71ae5a4SJacob Faibussowitsch {
247658b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2477e5c89e4eSSatish Balay   char     *svalue;
2478ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2479e5c89e4eSSatish Balay   PetscInt  i;
2480e5c89e4eSSatish Balay 
2481e5c89e4eSSatish Balay   PetscFunctionBegin;
24824f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2483e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
24849566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2485e5c89e4eSSatish Balay     if (alen > len) len = alen;
248658b0ac4eSStefano Zampini     tlen += len + 1;
2487e5c89e4eSSatish Balay   }
2488e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
24899566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
24909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2491e5c89e4eSSatish Balay   if (aset) {
24929566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
249358b0ac4eSStefano Zampini     if (!flg) {
2494c6a7a370SJeremy L Thompson       char *avail;
249558b0ac4eSStefano Zampini 
24969566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
2497c6a7a370SJeremy L Thompson       avail[0] = '\0';
249858b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
2499c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, list[i], tlen));
2500c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, " ", tlen));
250158b0ac4eSStefano Zampini       }
25029566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
250398921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
250458b0ac4eSStefano Zampini     }
2505fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2506a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
25079566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
25083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2509e5c89e4eSSatish Balay }
2510e5c89e4eSSatish Balay 
2511e5c89e4eSSatish Balay /*@C
2512e5c89e4eSSatish Balay   PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2513e5c89e4eSSatish Balay 
2514e5c89e4eSSatish Balay   Not Collective
2515e5c89e4eSSatish Balay 
2516e5c89e4eSSatish Balay   Input Parameters:
251720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
251820f4b53cSBarry Smith . pre     - option prefix or `NULL`
2519e5c89e4eSSatish Balay . opt     - option name
25206b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2521e5c89e4eSSatish Balay 
2522d8d19677SJose E. Roman   Output Parameters:
2523e5c89e4eSSatish Balay + value - the value to return
2524811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2525e5c89e4eSSatish Balay 
2526e5c89e4eSSatish Balay   Level: beginner
2527e5c89e4eSSatish Balay 
252895452b02SPatrick Sanan   Notes:
25299314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
25309314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2531e5c89e4eSSatish Balay 
25329314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names
2533e5c89e4eSSatish Balay 
2534db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2535db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2536aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2537db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2538c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2539db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2540db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2541e5c89e4eSSatish Balay @*/
2542d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscEnum *value, PetscBool *set)
2543d71ae5a4SJacob Faibussowitsch {
254469a24498SJed Brown   PetscInt  ntext = 0, tval;
2545ace3abfcSBarry Smith   PetscBool fset;
2546e5c89e4eSSatish Balay 
2547e5c89e4eSSatish Balay   PetscFunctionBegin;
25484f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2549ad540459SPierre 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");
255008401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2551e5c89e4eSSatish Balay   ntext -= 3;
25529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
255369a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2554809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2555809ceb46SBarry Smith   if (set) *set = fset;
25563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2557e5c89e4eSSatish Balay }
2558e5c89e4eSSatish Balay 
2559e5c89e4eSSatish Balay /*@C
25602d747510SLisandro Dalcin   PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2561e5c89e4eSSatish Balay 
2562e5c89e4eSSatish Balay   Not Collective
2563e5c89e4eSSatish Balay 
2564e5c89e4eSSatish Balay   Input Parameters:
256520f4b53cSBarry Smith + options - options database, use `NULL` for default global database
256620f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2567e5c89e4eSSatish Balay - name    - the option one is seeking
2568e5c89e4eSSatish Balay 
2569d8d19677SJose E. Roman   Output Parameters:
25702d747510SLisandro Dalcin + ivalue - the integer value to return
2571811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2572e5c89e4eSSatish Balay 
2573e5c89e4eSSatish Balay   Level: beginner
2574e5c89e4eSSatish Balay 
2575e5c89e4eSSatish Balay   Notes:
25769314d9b7SBarry Smith   If the user does not supply the option `ivalue` is NOT changed. Thus
25779314d9b7SBarry Smith   you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
25785c07ccb8SBarry Smith 
2579*b3480c81SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
2580*b3480c81SBarry Smith 
2581*b3480c81SBarry Smith   Accepts the deprecated value `default`.
2582*b3480c81SBarry Smith 
2583db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2584db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2585aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2586db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2587c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2588db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2589db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2590e5c89e4eSSatish Balay @*/
2591d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2592d71ae5a4SJacob Faibussowitsch {
25932d747510SLisandro Dalcin   const char *value;
25942d747510SLisandro Dalcin   PetscBool   flag;
2595e5c89e4eSSatish Balay 
2596e5c89e4eSSatish Balay   PetscFunctionBegin;
25974f572ea9SToby Isaac   PetscAssertPointer(name, 3);
25984f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
25999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2600e5c89e4eSSatish Balay   if (flag) {
260134a9cc2cSBarry Smith     if (!value) {
26022d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
260334a9cc2cSBarry Smith     } else {
26042d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
26059566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2606e5c89e4eSSatish Balay     }
2607e5c89e4eSSatish Balay   } else {
260896ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2609e5c89e4eSSatish Balay   }
26103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2611e5c89e4eSSatish Balay }
2612e5c89e4eSSatish Balay 
2613e2446a98SMatthew Knepley /*@C
2614e5c89e4eSSatish Balay   PetscOptionsGetReal - Gets the double precision value for a particular
2615e5c89e4eSSatish Balay   option in the database.
2616e5c89e4eSSatish Balay 
2617e5c89e4eSSatish Balay   Not Collective
2618e5c89e4eSSatish Balay 
2619e5c89e4eSSatish Balay   Input Parameters:
262020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
262120f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2622e5c89e4eSSatish Balay - name    - the option one is seeking
2623e5c89e4eSSatish Balay 
2624d8d19677SJose E. Roman   Output Parameters:
2625e5c89e4eSSatish Balay + dvalue - the double value to return
2626811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2627e5c89e4eSSatish Balay 
262820f4b53cSBarry Smith   Level: beginner
262920f4b53cSBarry Smith 
2630*b3480c81SBarry Smith   Notes:
2631*b3480c81SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
2632*b3480c81SBarry Smith 
2633*b3480c81SBarry Smith   Accepts the deprecated value `default`
2634*b3480c81SBarry Smith 
26359314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
26369314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking that the `set` flag is true.
2637e4974155SBarry Smith 
2638db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2639c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2640db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2641c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2642db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2643db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2644e5c89e4eSSatish Balay @*/
2645d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2646d71ae5a4SJacob Faibussowitsch {
26472d747510SLisandro Dalcin   const char *value;
2648ace3abfcSBarry Smith   PetscBool   flag;
2649e5c89e4eSSatish Balay 
2650e5c89e4eSSatish Balay   PetscFunctionBegin;
26514f572ea9SToby Isaac   PetscAssertPointer(name, 3);
26524f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
26539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2654e5c89e4eSSatish Balay   if (flag) {
2655a297a907SKarl Rupp     if (!value) {
2656a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2657a297a907SKarl Rupp     } else {
2658a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
26599566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2660a297a907SKarl Rupp     }
2661e5c89e4eSSatish Balay   } else {
266296ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2663e5c89e4eSSatish Balay   }
26643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2665e5c89e4eSSatish Balay }
2666e5c89e4eSSatish Balay 
2667e5c89e4eSSatish Balay /*@C
2668e5c89e4eSSatish Balay   PetscOptionsGetScalar - Gets the scalar value for a particular
2669e5c89e4eSSatish Balay   option in the database.
2670e5c89e4eSSatish Balay 
2671e5c89e4eSSatish Balay   Not Collective
2672e5c89e4eSSatish Balay 
2673e5c89e4eSSatish Balay   Input Parameters:
267420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
267520f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2676e5c89e4eSSatish Balay - name    - the option one is seeking
2677e5c89e4eSSatish Balay 
2678d8d19677SJose E. Roman   Output Parameters:
26799314d9b7SBarry Smith + dvalue - the scalar value to return
2680811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2681e5c89e4eSSatish Balay 
2682e5c89e4eSSatish Balay   Level: beginner
2683e5c89e4eSSatish Balay 
268410450e9eSJacob Faibussowitsch   Example Usage:
2685eb4ae41dSBarry Smith   A complex number 2+3i must be specified with NO spaces
2686e5c89e4eSSatish Balay 
2687811af0c4SBarry Smith   Note:
26889314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
26899314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking if the `set` flag is true.
2690e4974155SBarry Smith 
2691db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2692db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2693db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2694c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2695db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2696db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2697e5c89e4eSSatish Balay @*/
2698d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2699d71ae5a4SJacob Faibussowitsch {
27002d747510SLisandro Dalcin   const char *value;
2701ace3abfcSBarry Smith   PetscBool   flag;
2702e5c89e4eSSatish Balay 
2703e5c89e4eSSatish Balay   PetscFunctionBegin;
27044f572ea9SToby Isaac   PetscAssertPointer(name, 3);
27054f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
27069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2707e5c89e4eSSatish Balay   if (flag) {
2708e5c89e4eSSatish Balay     if (!value) {
270996ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2710e5c89e4eSSatish Balay     } else {
2711e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
27129566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2713e5c89e4eSSatish Balay #else
27149566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2715e5c89e4eSSatish Balay #endif
271696ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2717e5c89e4eSSatish Balay     }
2718e5c89e4eSSatish Balay   } else { /* flag */
271996ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2720e5c89e4eSSatish Balay   }
27213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2722e5c89e4eSSatish Balay }
2723e5c89e4eSSatish Balay 
2724e5c89e4eSSatish Balay /*@C
2725e5c89e4eSSatish Balay   PetscOptionsGetString - Gets the string value for a particular option in
2726e5c89e4eSSatish Balay   the database.
2727e5c89e4eSSatish Balay 
2728e5c89e4eSSatish Balay   Not Collective
2729e5c89e4eSSatish Balay 
2730e5c89e4eSSatish Balay   Input Parameters:
273120f4b53cSBarry Smith + options - options database, use `NULL` for default global database
273220f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
2733e5c89e4eSSatish Balay . name    - the option one is seeking
2734bcbf2dc5SJed Brown - len     - maximum length of the string including null termination
2735e5c89e4eSSatish Balay 
2736e5c89e4eSSatish Balay   Output Parameters:
2737e5c89e4eSSatish Balay + string - location to copy string
2738811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2739e5c89e4eSSatish Balay 
2740e5c89e4eSSatish Balay   Level: beginner
2741e5c89e4eSSatish Balay 
274220f4b53cSBarry Smith   Note:
27439314d9b7SBarry 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`
274420f4b53cSBarry Smith 
27459314d9b7SBarry Smith   If the user does not use the option then `string` is not changed. Thus
27469314d9b7SBarry Smith   you should ALWAYS initialize `string` if you access it without first checking that the `set` flag is true.
274720f4b53cSBarry Smith 
2748aec76313SJacob Faibussowitsch   Fortran Notes:
2749e5c89e4eSSatish Balay   The Fortran interface is slightly different from the C/C++
2750e5c89e4eSSatish Balay   interface (len is not used).  Sample usage in Fortran follows
2751e5c89e4eSSatish Balay .vb
2752e5c89e4eSSatish Balay       character *20    string
275393e6ba5cSBarry Smith       PetscErrorCode   ierr
275493e6ba5cSBarry Smith       PetscBool        set
27551b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2756e5c89e4eSSatish Balay .ve
2757e5c89e4eSSatish Balay 
2758db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2759db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2760db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2761c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2762db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2763db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2764e5c89e4eSSatish Balay @*/
2765d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set)
2766d71ae5a4SJacob Faibussowitsch {
27672d747510SLisandro Dalcin   const char *value;
2768ace3abfcSBarry Smith   PetscBool   flag;
2769e5c89e4eSSatish Balay 
2770e5c89e4eSSatish Balay   PetscFunctionBegin;
27714f572ea9SToby Isaac   PetscAssertPointer(name, 3);
27724f572ea9SToby Isaac   PetscAssertPointer(string, 4);
27739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2774e5c89e4eSSatish Balay   if (!flag) {
277596ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2776e5c89e4eSSatish Balay   } else {
277796ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
27789566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
27799566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2780e5c89e4eSSatish Balay   }
27813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2782e5c89e4eSSatish Balay }
2783e5c89e4eSSatish Balay 
27842d747510SLisandro Dalcin /*@C
27852d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2786f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
27872d747510SLisandro Dalcin 
27882d747510SLisandro Dalcin   Not Collective
27892d747510SLisandro Dalcin 
27902d747510SLisandro Dalcin   Input Parameters:
279120f4b53cSBarry Smith + options - options database, use `NULL` for default global database
279220f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
27936b867d5aSJose E. Roman - name    - the option one is seeking
27946b867d5aSJose E. Roman 
2795d8d19677SJose E. Roman   Output Parameters:
27969314d9b7SBarry Smith + dvalue - the Boolean values to return
2797f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2798811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
27992d747510SLisandro Dalcin 
28002d747510SLisandro Dalcin   Level: beginner
28012d747510SLisandro Dalcin 
2802811af0c4SBarry Smith   Note:
280320f4b53cSBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`. FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
28042d747510SLisandro Dalcin 
2805db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2806db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2807db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2808c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2809db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2810db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
28112d747510SLisandro Dalcin @*/
2812d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2813d71ae5a4SJacob Faibussowitsch {
28142d747510SLisandro Dalcin   const char *svalue;
28152d747510SLisandro Dalcin   char       *value;
28162d747510SLisandro Dalcin   PetscInt    n = 0;
28172d747510SLisandro Dalcin   PetscBool   flag;
28182d747510SLisandro Dalcin   PetscToken  token;
28192d747510SLisandro Dalcin 
28202d747510SLisandro Dalcin   PetscFunctionBegin;
28214f572ea9SToby Isaac   PetscAssertPointer(name, 3);
28224f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
28234f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
28242d747510SLisandro Dalcin 
28259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28269371c9d4SSatish Balay   if (!flag || !svalue) {
28279371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28289371c9d4SSatish Balay     *nmax = 0;
28293ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
28309371c9d4SSatish Balay   }
28312d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28329566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28339566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28342d747510SLisandro Dalcin   while (value && n < *nmax) {
28359566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
28369566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
28372d747510SLisandro Dalcin     dvalue++;
28382d747510SLisandro Dalcin     n++;
28392d747510SLisandro Dalcin   }
28409566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28412d747510SLisandro Dalcin   *nmax = n;
28423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28432d747510SLisandro Dalcin }
28442d747510SLisandro Dalcin 
28452d747510SLisandro Dalcin /*@C
28462d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
28472d747510SLisandro Dalcin 
28482d747510SLisandro Dalcin   Not Collective
28492d747510SLisandro Dalcin 
28502d747510SLisandro Dalcin   Input Parameters:
285120f4b53cSBarry Smith + options - options database, use `NULL` for default global database
285220f4b53cSBarry Smith . pre     - option prefix or `NULL`
28532d747510SLisandro Dalcin . name    - option name
28546b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
28556b867d5aSJose E. Roman 
28562d747510SLisandro Dalcin   Output Parameters:
28572d747510SLisandro Dalcin + ivalue - the  enum values to return
2858f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2859811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
28602d747510SLisandro Dalcin 
28612d747510SLisandro Dalcin   Level: beginner
28622d747510SLisandro Dalcin 
28632d747510SLisandro Dalcin   Notes:
28649314d9b7SBarry Smith   The array must be passed as a comma separated list with no spaces between the items.
28652d747510SLisandro Dalcin 
28669314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names.
28672d747510SLisandro Dalcin 
2868db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2869db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2870aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsName()`,
2871c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2872db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2873db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
28742d747510SLisandro Dalcin @*/
2875d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const *list, PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
2876d71ae5a4SJacob Faibussowitsch {
28772d747510SLisandro Dalcin   const char *svalue;
28782d747510SLisandro Dalcin   char       *value;
28792d747510SLisandro Dalcin   PetscInt    n = 0;
28802d747510SLisandro Dalcin   PetscEnum   evalue;
28812d747510SLisandro Dalcin   PetscBool   flag;
28822d747510SLisandro Dalcin   PetscToken  token;
28832d747510SLisandro Dalcin 
28842d747510SLisandro Dalcin   PetscFunctionBegin;
28854f572ea9SToby Isaac   PetscAssertPointer(name, 3);
28864f572ea9SToby Isaac   PetscAssertPointer(list, 4);
28874f572ea9SToby Isaac   PetscAssertPointer(ivalue, 5);
28884f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
28892d747510SLisandro Dalcin 
28909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28919371c9d4SSatish Balay   if (!flag || !svalue) {
28929371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28939371c9d4SSatish Balay     *nmax = 0;
28943ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
28959371c9d4SSatish Balay   }
28962d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28979566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28989566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28992d747510SLisandro Dalcin   while (value && n < *nmax) {
29009566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
290128b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
29022d747510SLisandro Dalcin     ivalue[n++] = evalue;
29039566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29042d747510SLisandro Dalcin   }
29059566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29062d747510SLisandro Dalcin   *nmax = n;
29073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29082d747510SLisandro Dalcin }
29092d747510SLisandro Dalcin 
29102d747510SLisandro Dalcin /*@C
2911f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
29122d747510SLisandro Dalcin 
29132d747510SLisandro Dalcin   Not Collective
29142d747510SLisandro Dalcin 
29152d747510SLisandro Dalcin   Input Parameters:
291620f4b53cSBarry Smith + options - options database, use `NULL` for default global database
291720f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
29186b867d5aSJose E. Roman - name    - the option one is seeking
29196b867d5aSJose E. Roman 
2920d8d19677SJose E. Roman   Output Parameters:
29212d747510SLisandro Dalcin + ivalue - the integer values to return
2922f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2923811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
29242d747510SLisandro Dalcin 
29252d747510SLisandro Dalcin   Level: beginner
29262d747510SLisandro Dalcin 
29272d747510SLisandro Dalcin   Notes:
29282d747510SLisandro Dalcin   The array can be passed as
2929811af0c4SBarry Smith +  a comma separated list -                                 0,1,2,3,4,5,6,7
2930811af0c4SBarry Smith .  a range (start\-end+1) -                                 0-8
2931811af0c4SBarry Smith .  a range with given increment (start\-end+1:inc) -        0-7:2
2932811af0c4SBarry Smith -  a combination of values and ranges separated by commas - 0,1-8,8-15:2
29332d747510SLisandro Dalcin 
29342d747510SLisandro Dalcin   There must be no intervening spaces between the values.
29352d747510SLisandro Dalcin 
2936db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2937db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2938db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2939c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2940db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2941db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29422d747510SLisandro Dalcin @*/
2943d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
2944d71ae5a4SJacob Faibussowitsch {
29452d747510SLisandro Dalcin   const char *svalue;
29462d747510SLisandro Dalcin   char       *value;
29472d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
29482d747510SLisandro Dalcin   size_t      len;
29492d747510SLisandro Dalcin   PetscBool   flag, foundrange;
29502d747510SLisandro Dalcin   PetscToken  token;
29512d747510SLisandro Dalcin 
29522d747510SLisandro Dalcin   PetscFunctionBegin;
29534f572ea9SToby Isaac   PetscAssertPointer(name, 3);
29544f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
29554f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
29562d747510SLisandro Dalcin 
29579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29589371c9d4SSatish Balay   if (!flag || !svalue) {
29599371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29609371c9d4SSatish Balay     *nmax = 0;
29613ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29629371c9d4SSatish Balay   }
29632d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29649566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29659566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29662d747510SLisandro Dalcin   while (value && n < *nmax) {
29672d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
29682d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
29699566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value, &len));
29702d747510SLisandro Dalcin     if (value[0] == '-') i = 2;
29712d747510SLisandro Dalcin     else i = 1;
29722d747510SLisandro Dalcin     for (; i < (int)len; i++) {
29732d747510SLisandro Dalcin       if (value[i] == '-') {
2974cc73adaaSBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
29752d747510SLisandro Dalcin         value[i] = 0;
29762d747510SLisandro Dalcin 
29779566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value, &start));
29782d747510SLisandro Dalcin         inc = 1;
29792d747510SLisandro Dalcin         j   = i + 1;
29802d747510SLisandro Dalcin         for (; j < (int)len; j++) {
29812d747510SLisandro Dalcin           if (value[j] == ':') {
29822d747510SLisandro Dalcin             value[j] = 0;
29832d747510SLisandro Dalcin 
29849566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value + j + 1, &inc));
298508401ef6SPierre 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);
29862d747510SLisandro Dalcin             break;
29872d747510SLisandro Dalcin           }
29882d747510SLisandro Dalcin         }
29899566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
299008401ef6SPierre 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);
29912d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
2992cc73adaaSBarry 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);
29932d747510SLisandro Dalcin         for (; start < end; start += inc) {
29949371c9d4SSatish Balay           *ivalue = start;
29959371c9d4SSatish Balay           ivalue++;
29969371c9d4SSatish Balay           n++;
29972d747510SLisandro Dalcin         }
29982d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
29992d747510SLisandro Dalcin         break;
30002d747510SLisandro Dalcin       }
30012d747510SLisandro Dalcin     }
30022d747510SLisandro Dalcin     if (!foundrange) {
30039566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
30042d747510SLisandro Dalcin       ivalue++;
30052d747510SLisandro Dalcin       n++;
30062d747510SLisandro Dalcin     }
30079566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30082d747510SLisandro Dalcin   }
30099566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30102d747510SLisandro Dalcin   *nmax = n;
30113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30122d747510SLisandro Dalcin }
30132d747510SLisandro Dalcin 
30142d747510SLisandro Dalcin /*@C
30152d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
3016f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
30172d747510SLisandro Dalcin 
30182d747510SLisandro Dalcin   Not Collective
30192d747510SLisandro Dalcin 
30202d747510SLisandro Dalcin   Input Parameters:
302120f4b53cSBarry Smith + options - options database, use `NULL` for default global database
302220f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
30236b867d5aSJose E. Roman - name    - the option one is seeking
30246b867d5aSJose E. Roman 
30252d747510SLisandro Dalcin   Output Parameters:
30262d747510SLisandro Dalcin + dvalue - the double values to return
3027f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3028811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
30292d747510SLisandro Dalcin 
30302d747510SLisandro Dalcin   Level: beginner
30312d747510SLisandro Dalcin 
3032db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3033db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3034db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3035c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3036db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3037db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30382d747510SLisandro Dalcin @*/
3039d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
3040d71ae5a4SJacob Faibussowitsch {
30412d747510SLisandro Dalcin   const char *svalue;
30422d747510SLisandro Dalcin   char       *value;
30432d747510SLisandro Dalcin   PetscInt    n = 0;
30442d747510SLisandro Dalcin   PetscBool   flag;
30452d747510SLisandro Dalcin   PetscToken  token;
30462d747510SLisandro Dalcin 
30472d747510SLisandro Dalcin   PetscFunctionBegin;
30484f572ea9SToby Isaac   PetscAssertPointer(name, 3);
30494f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
30504f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
30512d747510SLisandro Dalcin 
30529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30539371c9d4SSatish Balay   if (!flag || !svalue) {
30549371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30559371c9d4SSatish Balay     *nmax = 0;
30563ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
30579371c9d4SSatish Balay   }
30582d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30599566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30609566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30612d747510SLisandro Dalcin   while (value && n < *nmax) {
30629566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
30639566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30642d747510SLisandro Dalcin     n++;
30652d747510SLisandro Dalcin   }
30669566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30672d747510SLisandro Dalcin   *nmax = n;
30683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30692d747510SLisandro Dalcin }
30702d747510SLisandro Dalcin 
30712d747510SLisandro Dalcin /*@C
30722d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
3073f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
30742d747510SLisandro Dalcin 
30752d747510SLisandro Dalcin   Not Collective
30762d747510SLisandro Dalcin 
30772d747510SLisandro Dalcin   Input Parameters:
307820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
307920f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
30806b867d5aSJose E. Roman - name    - the option one is seeking
30816b867d5aSJose E. Roman 
30822d747510SLisandro Dalcin   Output Parameters:
30832d747510SLisandro Dalcin + dvalue - the scalar values to return
3084f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3085811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
30862d747510SLisandro Dalcin 
30872d747510SLisandro Dalcin   Level: beginner
30882d747510SLisandro Dalcin 
3089db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3090db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3091db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3092c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3093db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3094db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30952d747510SLisandro Dalcin @*/
3096d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3097d71ae5a4SJacob Faibussowitsch {
30982d747510SLisandro Dalcin   const char *svalue;
30992d747510SLisandro Dalcin   char       *value;
31002d747510SLisandro Dalcin   PetscInt    n = 0;
31012d747510SLisandro Dalcin   PetscBool   flag;
31022d747510SLisandro Dalcin   PetscToken  token;
31032d747510SLisandro Dalcin 
31042d747510SLisandro Dalcin   PetscFunctionBegin;
31054f572ea9SToby Isaac   PetscAssertPointer(name, 3);
31064f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
31074f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
31082d747510SLisandro Dalcin 
31099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
31109371c9d4SSatish Balay   if (!flag || !svalue) {
31119371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
31129371c9d4SSatish Balay     *nmax = 0;
31133ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
31149371c9d4SSatish Balay   }
31152d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31169566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31179566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31182d747510SLisandro Dalcin   while (value && n < *nmax) {
31199566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value, dvalue++));
31209566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
31212d747510SLisandro Dalcin     n++;
31222d747510SLisandro Dalcin   }
31239566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
31242d747510SLisandro Dalcin   *nmax = n;
31253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31262d747510SLisandro Dalcin }
312714ce751eSBarry Smith 
3128e5c89e4eSSatish Balay /*@C
3129e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
3130f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
3131e5c89e4eSSatish Balay 
3132cf53795eSBarry Smith   Not Collective; No Fortran Support
3133e5c89e4eSSatish Balay 
3134e5c89e4eSSatish Balay   Input Parameters:
313520f4b53cSBarry Smith + options - options database, use `NULL` for default global database
313620f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
31376b867d5aSJose E. Roman - name    - the option one is seeking
31386b867d5aSJose E. Roman 
3139e7b76fa7SPatrick Sanan   Output Parameters:
3140e5c89e4eSSatish Balay + strings - location to copy strings
3141f1a722f8SMatthew G. Knepley . nmax    - On input maximum number of strings, on output the actual number of strings found
3142811af0c4SBarry Smith - set     - `PETSC_TRUE` if found, else `PETSC_FALSE`
3143e5c89e4eSSatish Balay 
3144e5c89e4eSSatish Balay   Level: beginner
3145e5c89e4eSSatish Balay 
3146e5c89e4eSSatish Balay   Notes:
31479314d9b7SBarry Smith   The `nmax` parameter is used for both input and output.
3148e7b76fa7SPatrick Sanan 
3149e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
3150e5c89e4eSSatish Balay   strings returned by this function.
3151e5c89e4eSSatish Balay 
3152e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3153cf53795eSBarry Smith   returned.
3154e5c89e4eSSatish Balay 
3155db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3156db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3157db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3158c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3159db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3160db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3161e5c89e4eSSatish Balay @*/
3162d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set)
3163d71ae5a4SJacob Faibussowitsch {
31642d747510SLisandro Dalcin   const char *svalue;
3165e5c89e4eSSatish Balay   char       *value;
31662d747510SLisandro Dalcin   PetscInt    n = 0;
3167ace3abfcSBarry Smith   PetscBool   flag;
31689c9d3cfdSBarry Smith   PetscToken  token;
3169e5c89e4eSSatish Balay 
3170e5c89e4eSSatish Balay   PetscFunctionBegin;
31714f572ea9SToby Isaac   PetscAssertPointer(name, 3);
31724f572ea9SToby Isaac   PetscAssertPointer(strings, 4);
31734f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
3174e5c89e4eSSatish Balay 
31759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
31769371c9d4SSatish Balay   if (!flag || !svalue) {
31779371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
31789371c9d4SSatish Balay     *nmax = 0;
31793ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
31809371c9d4SSatish Balay   }
31812d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31829566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31839566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31842d747510SLisandro Dalcin   while (value && n < *nmax) {
31859566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
31869566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3187e5c89e4eSSatish Balay     n++;
3188e5c89e4eSSatish Balay   }
31899566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3190e5c89e4eSSatish Balay   *nmax = n;
31913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3192e5c89e4eSSatish Balay }
319306824ed3SPatrick Sanan 
319406824ed3SPatrick Sanan /*@C
3195aec76313SJacob Faibussowitsch   PetscOptionsDeprecated_Private - mark an option as deprecated, optionally replacing it with `newname`
319606824ed3SPatrick Sanan 
319706824ed3SPatrick Sanan   Prints a deprecation warning, unless an option is supplied to suppress.
319806824ed3SPatrick Sanan 
31991c9f3c13SBarry Smith   Logically Collective
320006824ed3SPatrick Sanan 
320106824ed3SPatrick Sanan   Input Parameters:
3202aec76313SJacob Faibussowitsch + PetscOptionsObject - string to prepend to name or `NULL`
320306824ed3SPatrick Sanan . oldname            - the old, deprecated option
320420f4b53cSBarry Smith . newname            - the new option, or `NULL` if option is purely removed
32059f3a6782SPatrick Sanan . version            - a string describing the version of first deprecation, e.g. "3.9"
320620f4b53cSBarry Smith - info               - additional information string, or `NULL`.
320706824ed3SPatrick Sanan 
3208811af0c4SBarry Smith   Options Database Key:
320906824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
321006824ed3SPatrick Sanan 
321120f4b53cSBarry Smith   Level: developer
321220f4b53cSBarry Smith 
321306824ed3SPatrick Sanan   Notes:
32144ead3382SBarry Smith   If `newname` is provided then the options database will automatically check the database for `oldname`.
32154ead3382SBarry Smith 
32164ead3382SBarry Smith   The old call `PetscOptionsXXX`(`oldname`) should be removed from the source code when both (1) the call to `PetscOptionsDeprecated()` occurs before the
32174ead3382SBarry Smith   new call to `PetscOptionsXXX`(`newname`) and (2) the argument handling of the new call to `PetscOptionsXXX`(`newname`) is identical to the previous call.
32184ead3382SBarry Smith   See `PTScotch_PartGraph_Seq()` for an example of when (1) fails and `SNESTestJacobian()` where an example of (2) fails.
32194ead3382SBarry Smith 
3220811af0c4SBarry Smith   Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
322135cb6cd3SPierre Jolivet   Only the process of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3222811af0c4SBarry Smith   `PetscObjectOptionsBegin()` prints the information
3223b40114eaSPatrick Sanan   If newname is provided, the old option is replaced. Otherwise, it remains
3224b40114eaSPatrick Sanan   in the options database.
32259f3a6782SPatrick Sanan   If an option is not replaced, the info argument should be used to advise the user
32269f3a6782SPatrick Sanan   on how to proceed.
32279f3a6782SPatrick Sanan   There is a limit on the length of the warning printed, so very long strings
32289f3a6782SPatrick Sanan   provided as info may be truncated.
322906824ed3SPatrick Sanan 
3230db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
323106824ed3SPatrick Sanan @*/
3232d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3233d71ae5a4SJacob Faibussowitsch {
323406824ed3SPatrick Sanan   PetscBool         found, quiet;
323506824ed3SPatrick Sanan   const char       *value;
323606824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
32379f3a6782SPatrick Sanan   char              msg[4096];
3238b0bdc838SStefano Zampini   char             *prefix  = NULL;
3239b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3240b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
324106824ed3SPatrick Sanan 
324206824ed3SPatrick Sanan   PetscFunctionBegin;
32434f572ea9SToby Isaac   PetscAssertPointer(oldname, 2);
32444f572ea9SToby Isaac   PetscAssertPointer(version, 4);
3245b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3246b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3247b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3248b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3249b0bdc838SStefano Zampini   }
32509566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
325106824ed3SPatrick Sanan   if (found) {
325206824ed3SPatrick Sanan     if (newname) {
32531baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
32549566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options, newname, value));
32551baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
32569566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3257b40114eaSPatrick Sanan     }
325806824ed3SPatrick Sanan     quiet = PETSC_FALSE;
32599566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
326006824ed3SPatrick Sanan     if (!quiet) {
3261c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option ", sizeof(msg)));
3262c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, oldname, sizeof(msg)));
3263c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3264c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
32654bd3d7f8SBarry Smith       PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
326606824ed3SPatrick Sanan       if (newname) {
32674bd3d7f8SBarry Smith         PetscCall(PetscStrlcat(msg, "   Use the option ", sizeof(msg)));
3268c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, newname, sizeof(msg)));
3269c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
327006824ed3SPatrick Sanan       }
32719f3a6782SPatrick Sanan       if (info) {
3272c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3273c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
32749f3a6782SPatrick Sanan       }
3275c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3276c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3277c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
32789566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
327906824ed3SPatrick Sanan     }
328006824ed3SPatrick Sanan   }
32813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
328206824ed3SPatrick Sanan }
3283