xref: /petsc/src/sys/objects/options.c (revision 6f8503afd8ad4bbe73ed56cecb56c6e6848a045d)
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 */
9949abdd8aSBarry Smith   PetscCtxDestroyFn *monitordestroy[MAXOPTIONSMONITORS];                                                /* 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 {
304ce78bad3SBarry Smith   const 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;
453ce78bad3SBarry Smith   const char *tokens[4];
4546497c311SBarry Smith   size_t      len;
455ce78bad3SBarry Smith   PetscCount  bytes;
456e5c89e4eSSatish Balay   FILE       *fd;
4577fb43599SVaclav Hapla   PetscToken  token = NULL;
458ed9cf6e9SBarry Smith   int         err;
459bbcf679cSJacob Faibussowitsch   char       *cmatch = NULL;
460581bbe83SVaclav Hapla   const char  cmt    = '#';
4619210b8eaSVaclav Hapla   PetscInt    line   = 1;
4623a018368SJed Brown   PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
4639210b8eaSVaclav Hapla   PetscBool   isdir, alias = PETSC_FALSE, valid;
464e5c89e4eSSatish Balay 
465e5c89e4eSSatish Balay   PetscFunctionBegin;
4669566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tokens, sizeof(tokens)));
4679566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
468dd400576SPatrick Sanan   if (rank == 0) {
4698c0b561eSLisandro Dalcin     char fpath[PETSC_MAX_PATH_LEN];
4708c0b561eSLisandro Dalcin     char fname[PETSC_MAX_PATH_LEN];
47105c7dedfSBarry Smith 
4727255af2bSBarry Smith     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fname, sizeof(fname)));
4737255af2bSBarry Smith     PetscCall(PetscFixFilename(fname, fpath));
4747255af2bSBarry Smith     PetscCall(PetscGetFullPath(fpath, fname, sizeof(fname)));
4758c0b561eSLisandro Dalcin 
476e5c89e4eSSatish Balay     fd = fopen(fname, "r");
4779566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname, 'r', &isdir));
47808401ef6SPierre Jolivet     PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
479ad38b122SPatrick Sanan     if (fd && !isdir) {
4803a018368SJed Brown       PetscSegBuffer vseg, aseg;
481ce78bad3SBarry Smith 
4829566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4839566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4843a018368SJed Brown 
4859b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4869566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
487e24ecc5dSJed Brown 
4885fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4894704e885SBarry Smith         /* eliminate comments from each line */
4909566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
49190f79514SSatish Balay         if (cmatch) *cmatch = 0;
4929566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4935981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
494dd460d27SBarry Smith         for (size_t i = 0; i < len; i++) {
495ad540459SPierre Jolivet           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
496e5c89e4eSSatish Balay         }
4979566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4989566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4997fb43599SVaclav Hapla         if (!tokens[0]) {
50002b0d46eSSatish Balay           goto destroy;
5017fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
5029566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
50390f79514SSatish Balay         }
504dd460d27SBarry Smith         for (PetscInt i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
5057fb43599SVaclav Hapla         if (!tokens[0]) {
5062662f744SSatish Balay           goto destroy;
5077fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
5089566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
50928b400f6SJacob 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]);
5109566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
5119566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
5129566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
513e24ecc5dSJed Brown           vstring[len] = ' ';
5147fb43599SVaclav Hapla           if (tokens[1]) {
5159566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
51628b400f6SJacob 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]);
5179566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5189566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
519e24ecc5dSJed Brown             vstring[0] = '"';
5209566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
521e24ecc5dSJed Brown             vstring[len + 1] = '"';
522e24ecc5dSJed Brown             vstring[len + 2] = ' ';
52309192fe3SBarry Smith           }
52490f79514SSatish Balay         } else {
5259566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
5269210b8eaSVaclav Hapla           if (alias) {
5279566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
52828b400f6SJacob 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]);
52908401ef6SPierre 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]);
5309566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
53128b400f6SJacob 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]);
5329566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5339566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5349566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
535e24ecc5dSJed Brown             astring[len] = ' ';
536e24ecc5dSJed Brown 
5379566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5389566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5399566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
540e24ecc5dSJed Brown             astring[len] = ' ';
54198921bdaSJacob 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]);
5429210b8eaSVaclav Hapla         }
5439210b8eaSVaclav Hapla         {
5449210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
54528b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
546e5c89e4eSSatish Balay         }
54702b0d46eSSatish Balay       destroy:
5484b40f50bSBarry Smith         free(string);
5499566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5509210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5519210b8eaSVaclav Hapla         line++;
552e5c89e4eSSatish Balay       }
553ed9cf6e9SBarry Smith       err = fclose(fd);
55428b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5559566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5569566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5579566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
558e24ecc5dSJed Brown       astring[0] = 0;
5599566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5609566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5619566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
562e24ecc5dSJed Brown       vstring[0] = 0;
5639566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5649566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5659566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5669566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5679566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
56828b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5699b754dc9SBarry Smith   }
57005c7dedfSBarry Smith 
5713a018368SJed Brown   counts[0] = acnt;
5723a018368SJed Brown   counts[1] = cnt;
5734201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
57428b400f6SJacob 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/");
5753a018368SJed Brown   acnt = counts[0];
5763a018368SJed Brown   cnt  = counts[1];
57748a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5783a018368SJed Brown   if (acnt || cnt) {
5799566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5803a018368SJed Brown     astring = packed;
5813a018368SJed Brown     vstring = packed + acnt + 1;
5823a018368SJed Brown   }
5833a018368SJed Brown 
5849b754dc9SBarry Smith   if (acnt) {
5859566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5869566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5877fb43599SVaclav Hapla     while (tokens[0]) {
5889566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5899566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5909566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5919b754dc9SBarry Smith     }
5929566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5939b754dc9SBarry Smith   }
5949b754dc9SBarry Smith 
5959355ec05SMatthew G. Knepley   if (cnt) PetscCall(PetscOptionsInsertString_Private(options, vstring, PETSC_OPT_FILE));
5969566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
5973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
598e5c89e4eSSatish Balay }
599e5c89e4eSSatish Balay 
6005d83a8b1SBarry Smith /*@
601be10d61cSLisandro Dalcin   PetscOptionsInsertFile - Inserts options into the database from a file.
602be10d61cSLisandro Dalcin 
603be10d61cSLisandro Dalcin   Collective
604be10d61cSLisandro Dalcin 
605d8d19677SJose E. Roman   Input Parameters:
606811af0c4SBarry Smith + comm    - the processes that will share the options (usually `PETSC_COMM_WORLD`)
60720f4b53cSBarry Smith . options - options database, use `NULL` for default global database
608be10d61cSLisandro Dalcin . file    - name of file,
609be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
610be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
611811af0c4SBarry Smith - require - if `PETSC_TRUE` will generate an error if the file does not exist
612be10d61cSLisandro Dalcin 
61320f4b53cSBarry Smith   Level: developer
61420f4b53cSBarry Smith 
615be10d61cSLisandro Dalcin   Notes:
616be10d61cSLisandro Dalcin   Use  # for lines that are comments and which should be ignored.
617811af0c4SBarry Smith   Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
61821532e8aSBarry 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
61921532e8aSBarry Smith   calls to `XXXSetFromOptions()`, it should not be used for options listed under PetscInitialize().
62021532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes in comm will
62121532e8aSBarry Smith   have the effect of these options. If some processes that create objects call this routine and others do
622be10d61cSLisandro Dalcin   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
623be10d61cSLisandro Dalcin   on different ranks.
624be10d61cSLisandro Dalcin 
625db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
626db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
627db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
628c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
629db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
630db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
631be10d61cSLisandro Dalcin @*/
632d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
633d71ae5a4SJacob Faibussowitsch {
634be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
635be10d61cSLisandro Dalcin   PetscBool yaml;
636be10d61cSLisandro Dalcin 
637be10d61cSLisandro Dalcin   PetscFunctionBegin;
6389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
639be10d61cSLisandro Dalcin   if (yaml) {
6409566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
641be10d61cSLisandro Dalcin   } else {
6429566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
643be10d61cSLisandro Dalcin   }
6443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
645be10d61cSLisandro Dalcin }
646be10d61cSLisandro Dalcin 
647be10d61cSLisandro Dalcin /*@C
648d06005cbSLisandro Dalcin   PetscOptionsInsertArgs - Inserts options into the database from a array of strings
649d06005cbSLisandro Dalcin 
650d06005cbSLisandro Dalcin   Logically Collective
651d06005cbSLisandro Dalcin 
652d8d19677SJose E. Roman   Input Parameters:
653d06005cbSLisandro Dalcin + options - options object
6546aad120cSJose E. Roman . argc    - the array length
655d06005cbSLisandro Dalcin - args    - the string array
656d06005cbSLisandro Dalcin 
657d06005cbSLisandro Dalcin   Level: intermediate
658d06005cbSLisandro Dalcin 
659db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
660d06005cbSLisandro Dalcin @*/
661ce78bad3SBarry Smith PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, const char *const args[])
662d71ae5a4SJacob Faibussowitsch {
663d06005cbSLisandro Dalcin   MPI_Comm           comm  = PETSC_COMM_WORLD;
664d06005cbSLisandro Dalcin   int                left  = PetscMax(argc, 0);
665ce78bad3SBarry Smith   const char *const *eargs = args;
66685079163SJed Brown 
66785079163SJed Brown   PetscFunctionBegin;
66885079163SJed Brown   while (left) {
669d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6709566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6719566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6729566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6739566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6749566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6759566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
676093de6efSBarry Smith     if (!key) {
6779371c9d4SSatish Balay       eargs++;
6789371c9d4SSatish Balay       left--;
679d06005cbSLisandro Dalcin     } else if (isfile) {
680cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6819566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6829371c9d4SSatish Balay       eargs += 2;
6839371c9d4SSatish Balay       left -= 2;
684d06005cbSLisandro Dalcin     } else if (isfileyaml) {
685cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6869566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6879371c9d4SSatish Balay       eargs += 2;
6889371c9d4SSatish Balay       left -= 2;
689d06005cbSLisandro Dalcin     } else if (isstringyaml) {
690cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6919355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
6929371c9d4SSatish Balay       eargs += 2;
6939371c9d4SSatish Balay       left -= 2;
694d06005cbSLisandro Dalcin     } else if (ispush) {
69508401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
696cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6979566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6989371c9d4SSatish Balay       eargs += 2;
6999371c9d4SSatish Balay       left -= 2;
700d06005cbSLisandro Dalcin     } else if (ispop) {
7019566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
7029371c9d4SSatish Balay       eargs++;
7039371c9d4SSatish Balay       left--;
7047935c3d8SJed Brown     } else {
7057935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
7069566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
70798b6bf53SJed Brown       if (left < 2 || nextiskey) {
7089355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
7099371c9d4SSatish Balay         eargs++;
7109371c9d4SSatish Balay         left--;
71185079163SJed Brown       } else {
7129355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
7139371c9d4SSatish Balay         eargs += 2;
7149371c9d4SSatish Balay         left -= 2;
71585079163SJed Brown       }
71685079163SJed Brown     }
7177935c3d8SJed Brown   }
7183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71985079163SJed Brown }
72085079163SJed Brown 
72110c654e6SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], const PetscBool set[], PetscBool *flg)
722d71ae5a4SJacob Faibussowitsch {
723c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
724c5b5d8d5SVaclav Hapla   if (set[opt]) {
7259566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
726c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
7273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
728c5b5d8d5SVaclav Hapla }
729c5b5d8d5SVaclav Hapla 
730660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
731d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
732d71ae5a4SJacob Faibussowitsch {
733c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
734c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
735c5b5d8d5SVaclav Hapla   size_t             o;
736c5b5d8d5SVaclav Hapla   int                a;
737c5b5d8d5SVaclav Hapla   const char       **val;
7380c99d500SBarry Smith   char             **cval;
739660278c0SBarry Smith   PetscBool         *set, unneeded;
740c5b5d8d5SVaclav Hapla 
741c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7420c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7430c99d500SBarry Smith   val = (const char **)cval;
744c5b5d8d5SVaclav Hapla 
745c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
74648a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
747c5b5d8d5SVaclav Hapla 
748a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
749c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
750c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
751c5b5d8d5SVaclav Hapla 
7529566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
753c5b5d8d5SVaclav Hapla     if (!valid) continue;
754c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7559566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
756c5b5d8d5SVaclav Hapla       if (eq) {
757c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
758c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
759c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
760c5b5d8d5SVaclav Hapla         break;
761c5b5d8d5SVaclav Hapla       }
762c5b5d8d5SVaclav Hapla     }
763c5b5d8d5SVaclav Hapla   }
764c5b5d8d5SVaclav Hapla 
765c5b5d8d5SVaclav Hapla   /* Process flags */
7669566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
767d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7689566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
769660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
770660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
7719355ec05SMatthew G. Knepley   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
7729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
775c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
776c5b5d8d5SVaclav Hapla 
777c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
778660278c0SBarry Smith   for (o = 1; o < n; o++) {
779c5b5d8d5SVaclav Hapla     if (set[o]) {
7809355ec05SMatthew G. Knepley       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
781d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
782c5b5d8d5SVaclav Hapla     }
783c5b5d8d5SVaclav Hapla   }
7840c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
785c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
7863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
787c5b5d8d5SVaclav Hapla }
788c5b5d8d5SVaclav Hapla 
789d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
790d71ae5a4SJacob Faibussowitsch {
79139a651e2SJacob Faibussowitsch   PetscFunctionBegin;
7924f572ea9SToby Isaac   PetscAssertPointer(flg, 3);
793c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
794c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
79539a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
796c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
797c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7989566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
799c5b5d8d5SVaclav Hapla         if (*flg) break;
800c5b5d8d5SVaclav Hapla       }
801c5b5d8d5SVaclav Hapla     }
802c5b5d8d5SVaclav Hapla   }
8033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
804c5b5d8d5SVaclav Hapla }
80585079163SJed Brown 
806e5c89e4eSSatish Balay /*@C
807e5c89e4eSSatish Balay   PetscOptionsInsert - Inserts into the options database from the command line,
808e5c89e4eSSatish Balay   the environmental variable and a file.
809e5c89e4eSSatish Balay 
810811af0c4SBarry Smith   Collective on `PETSC_COMM_WORLD`
8111c9f3c13SBarry Smith 
812e5c89e4eSSatish Balay   Input Parameters:
81320f4b53cSBarry Smith + options - options database or `NULL` for the default global database
814c5929fdfSBarry Smith . argc    - count of number of command line arguments
815e5c89e4eSSatish Balay . args    - the command line arguments
816be10d61cSLisandro Dalcin - file    - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
81720f4b53cSBarry Smith           Use `NULL` or empty string to not check for code specific file.
818be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
819c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
820e5c89e4eSSatish Balay 
821081c24baSBoyana Norris   Options Database Keys:
822d06005cbSLisandro Dalcin + -options_file <filename>      - read options from a file
823d06005cbSLisandro Dalcin - -options_file_yaml <filename> - read options from a YAML file
824c5b5d8d5SVaclav Hapla 
82520f4b53cSBarry Smith   Level: advanced
82620f4b53cSBarry Smith 
827811af0c4SBarry Smith   Notes:
82820f4b53cSBarry Smith   Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
829811af0c4SBarry Smith   the user does not typically need to call this routine. `PetscOptionsInsert()`
830811af0c4SBarry Smith   can be called several times, adding additional entries into the database.
831811af0c4SBarry Smith 
832811af0c4SBarry Smith   See `PetscInitialize()` for options related to option database monitoring.
833081c24baSBoyana Norris 
834db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
835db781477SPatrick Sanan           `PetscInitialize()`
836e5c89e4eSSatish Balay @*/
837ce78bad3SBarry Smith PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[]) PeNS
838d71ae5a4SJacob Faibussowitsch {
839d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
840e5c89e4eSSatish Balay   PetscMPIInt rank;
841c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
842c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
8436497c311SBarry Smith   char       *eoptions = NULL;
8446497c311SBarry Smith   size_t      len      = 0;
845e5c89e4eSSatish Balay 
846e5c89e4eSSatish Balay   PetscFunctionBegin;
84708401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8489566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
849e5c89e4eSSatish Balay 
850c5b5d8d5SVaclav Hapla   if (!options) {
8519566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
852c5b5d8d5SVaclav Hapla     options = defaultoptions;
853c5b5d8d5SVaclav Hapla   }
854c5b5d8d5SVaclav Hapla   if (hasArgs) {
855c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8569566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
857660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
858c5b5d8d5SVaclav Hapla   }
8594b09e917SBarry Smith   if (file && file[0]) {
8609566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
861c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8629566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
863321366bcSBarry Smith   }
864c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
865be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8666497c311SBarry Smith 
8679566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8689566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
869c6a7a370SJeremy L Thompson     if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
8709566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8719566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8729566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
873e5c89e4eSSatish Balay   }
874e5c89e4eSSatish Balay 
8752d747510SLisandro Dalcin   /* insert environment options */
876dd400576SPatrick Sanan   if (rank == 0) {
877835f2295SStefano Zampini     eoptions = getenv("PETSC_OPTIONS");
8789566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(eoptions, &len));
879e5c89e4eSSatish Balay   }
8809566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
881e5c89e4eSSatish Balay   if (len) {
8829566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8836497c311SBarry Smith     PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, comm));
88496fc60bcSBarry Smith     if (rank) eoptions[len] = 0;
8859355ec05SMatthew G. Knepley     PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8869566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscFree(eoptions));
887e5c89e4eSSatish Balay   }
888e5c89e4eSSatish Balay 
889d06005cbSLisandro Dalcin   /* insert YAML environment options */
890dd400576SPatrick Sanan   if (rank == 0) {
891835f2295SStefano Zampini     eoptions = getenv("PETSC_OPTIONS_YAML");
8929566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(eoptions, &len));
8939fc438c3SToby Isaac   }
8949566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8959fc438c3SToby Isaac   if (len) {
8969566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8976497c311SBarry Smith     PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, comm));
8989fc438c3SToby Isaac     if (rank) eoptions[len] = 0;
8999355ec05SMatthew G. Knepley     PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
9009566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscFree(eoptions));
9019fc438c3SToby Isaac   }
9023bcbd388SSean Farley 
903c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
904ce78bad3SBarry Smith   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, (const char *const *)*args + 1));
905660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
9063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
907e5c89e4eSSatish Balay }
908e5c89e4eSSatish Balay 
909660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
910660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
911e9a33e21SBarry 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"};
912660278c0SBarry Smith 
913d71ae5a4SJacob Faibussowitsch static PetscBool PetscCIOption(const char *name)
914d71ae5a4SJacob Faibussowitsch {
915660278c0SBarry Smith   PetscInt  idx;
916660278c0SBarry Smith   PetscBool found;
917660278c0SBarry Smith 
918660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
9193ba16761SJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
920660278c0SBarry Smith   return found;
921660278c0SBarry Smith }
922660278c0SBarry Smith 
9235d83a8b1SBarry Smith /*@
92488c29154SBarry Smith   PetscOptionsView - Prints the options that have been loaded. This is
925e5c89e4eSSatish Balay   useful for debugging purposes.
926e5c89e4eSSatish Balay 
927ffeef943SBarry Smith   Logically Collective, No Fortran Support
928e5c89e4eSSatish Balay 
929d8d19677SJose E. Roman   Input Parameters:
93020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
931811af0c4SBarry Smith - viewer  - must be an `PETSCVIEWERASCII` viewer
932e5c89e4eSSatish Balay 
933e5c89e4eSSatish Balay   Options Database Key:
934811af0c4SBarry Smith . -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
935e5c89e4eSSatish Balay 
93620f4b53cSBarry Smith   Level: advanced
93720f4b53cSBarry Smith 
938811af0c4SBarry Smith   Note:
93921532e8aSBarry Smith   Only the MPI rank 0 of the `MPI_Comm` used to create view prints the option values. Other processes
9401c9f3c13SBarry Smith   may have different values but they are not printed.
9411c9f3c13SBarry Smith 
942db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
943e5c89e4eSSatish Balay @*/
944d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
945d71ae5a4SJacob Faibussowitsch {
946660278c0SBarry Smith   PetscInt  i, N = 0;
94788c29154SBarry Smith   PetscBool isascii;
948e5c89e4eSSatish Balay 
949e5c89e4eSSatish Balay   PetscFunctionBegin;
9502d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
951c5929fdfSBarry Smith   options = options ? options : defaultoptions;
95288c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9539566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
95428b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
95588c29154SBarry Smith 
956660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
957660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
958660278c0SBarry Smith     N++;
959660278c0SBarry Smith   }
960660278c0SBarry Smith 
961660278c0SBarry Smith   if (!N) {
9629566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9633ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
96430694fe9SBarry Smith   }
9652d747510SLisandro Dalcin 
9669566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
967e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
968660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
969e5c89e4eSSatish Balay     if (options->values[i]) {
9709355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
971e5c89e4eSSatish Balay     } else {
9729355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
973e5c89e4eSSatish Balay     }
9749355ec05SMatthew G. Knepley     PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
975e5c89e4eSSatish Balay   }
9769566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
9773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
978e5c89e4eSSatish Balay }
979e5c89e4eSSatish Balay 
980e11779c2SBarry Smith /*
981e11779c2SBarry Smith    Called by error handlers to print options used in run
982e11779c2SBarry Smith */
983d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftError(void)
984d71ae5a4SJacob Faibussowitsch {
985f4bc716fSBarry Smith   PetscInt i, nopt = 0;
986f4bc716fSBarry Smith 
987f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
988f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
989f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
990f4bc716fSBarry Smith       nopt++;
991f4bc716fSBarry Smith     }
992f4bc716fSBarry Smith   }
993f4bc716fSBarry Smith   if (nopt) {
9947d44c3adSBarry Smith     PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
995f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
996f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
997f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
9983ba16761SJacob 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]]));
9993ba16761SJacob Faibussowitsch         else PetscCall((*PetscErrorPrintf)("  Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
1000f4bc716fSBarry Smith       }
1001f4bc716fSBarry Smith     }
1002f4bc716fSBarry Smith   }
10033ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1004f4bc716fSBarry Smith }
1005f4bc716fSBarry Smith 
1006d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1007d71ae5a4SJacob Faibussowitsch {
1008660278c0SBarry Smith   PetscInt     i, N = 0;
10094416b707SBarry Smith   PetscOptions options = defaultoptions;
1010e11779c2SBarry Smith 
1011660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
1012660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1013660278c0SBarry Smith     N++;
1014660278c0SBarry Smith   }
1015660278c0SBarry Smith 
1016660278c0SBarry Smith   if (N) {
10173ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1018e11779c2SBarry Smith   } else {
10193ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1020e11779c2SBarry Smith   }
1021e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1022660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1023e11779c2SBarry Smith     if (options->values[i]) {
10243ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1025e11779c2SBarry Smith     } else {
10263ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1027e11779c2SBarry Smith     }
1028e11779c2SBarry Smith   }
10293ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1030e11779c2SBarry Smith }
1031e11779c2SBarry Smith 
10325d83a8b1SBarry Smith /*@
103374e0666dSJed Brown   PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
103474e0666dSJed Brown 
10351c9f3c13SBarry Smith   Logically Collective
103674e0666dSJed Brown 
1037d8d19677SJose E. Roman   Input Parameters:
103820f4b53cSBarry Smith + options - options database, or `NULL` for the default global database
1039c5929fdfSBarry Smith - prefix  - The string to append to the existing prefix
10409db968c8SJed Brown 
10419db968c8SJed Brown   Options Database Keys:
10429db968c8SJed Brown + -prefix_push <some_prefix_> - push the given prefix
10439db968c8SJed Brown - -prefix_pop                 - pop the last prefix
10449db968c8SJed Brown 
104520f4b53cSBarry Smith   Level: advanced
104620f4b53cSBarry Smith 
10479db968c8SJed Brown   Notes:
104821532e8aSBarry Smith   It is common to use this in conjunction with `-options_file` as in
10499314d9b7SBarry Smith .vb
10509314d9b7SBarry Smith  -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10519314d9b7SBarry Smith .ve
105221532e8aSBarry Smith   where the files no longer require all options to be prefixed with `-system2_`.
105374e0666dSJed Brown 
105421532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
10551c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
10561c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10571c9f3c13SBarry Smith   on different ranks.
10581c9f3c13SBarry Smith 
1059db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
106074e0666dSJed Brown @*/
1061d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1062d71ae5a4SJacob Faibussowitsch {
106374e0666dSJed Brown   size_t    n;
106474e0666dSJed Brown   PetscInt  start;
10659355ec05SMatthew G. Knepley   char      key[PETSC_MAX_OPTION_NAME + 1];
10662d747510SLisandro Dalcin   PetscBool valid;
106774e0666dSJed Brown 
106874e0666dSJed Brown   PetscFunctionBegin;
10694f572ea9SToby Isaac   PetscAssertPointer(prefix, 2);
1070c5929fdfSBarry Smith   options = options ? options : defaultoptions;
107100045ab3SPierre 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);
10722d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10739566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10758bf569ecSLisandro 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 */
107628b400f6SJacob 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" : "");
107774e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10789566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
107908401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10809566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
10816497c311SBarry Smith   options->prefixstack[options->prefixind++] = (int)(start + n);
10823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108374e0666dSJed Brown }
108474e0666dSJed Brown 
10855d83a8b1SBarry Smith /*@
1086811af0c4SBarry Smith   PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
108774e0666dSJed Brown 
1088811af0c4SBarry Smith   Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
108974e0666dSJed Brown 
1090811af0c4SBarry Smith   Input Parameter:
109120f4b53cSBarry Smith . options - options database, or `NULL` for the default global database
1092c5929fdfSBarry Smith 
109374e0666dSJed Brown   Level: advanced
109474e0666dSJed Brown 
1095db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
109674e0666dSJed Brown @*/
1097d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1098d71ae5a4SJacob Faibussowitsch {
109974e0666dSJed Brown   PetscInt offset;
110074e0666dSJed Brown 
110174e0666dSJed Brown   PetscFunctionBegin;
1102c5929fdfSBarry Smith   options = options ? options : defaultoptions;
110308401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
110474e0666dSJed Brown   options->prefixind--;
110574e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
110674e0666dSJed Brown   options->prefix[offset] = 0;
11073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
110874e0666dSJed Brown }
110974e0666dSJed Brown 
11105d83a8b1SBarry Smith /*@
1111a542b6e8SBarry Smith   PetscOptionsClear - Removes all options form the database leaving it empty.
1112a542b6e8SBarry Smith 
11131c9f3c13SBarry Smith   Logically Collective
11141c9f3c13SBarry Smith 
1115811af0c4SBarry Smith   Input Parameter:
111620f4b53cSBarry Smith . options - options database, use `NULL` for the default global database
1117c5929fdfSBarry Smith 
111820f4b53cSBarry Smith   Level: developer
111920f4b53cSBarry Smith 
112020f4b53cSBarry Smith   Note:
112121532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11221c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11231c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11241c9f3c13SBarry Smith   on different ranks.
11251c9f3c13SBarry Smith 
11267e6f8dd6SBarry Smith   Developer Note:
11277e6f8dd6SBarry Smith   Uses `free()` directly because the current option values were set with `malloc()`
11287e6f8dd6SBarry Smith 
1129db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1130a542b6e8SBarry Smith @*/
1131d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClear(PetscOptions options)
1132d71ae5a4SJacob Faibussowitsch {
1133a542b6e8SBarry Smith   PetscInt i;
1134a542b6e8SBarry Smith 
113539a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1136c5929fdfSBarry Smith   options = options ? options : defaultoptions;
11373ba16761SJacob Faibussowitsch   if (!options) PetscFunctionReturn(PETSC_SUCCESS);
11382d747510SLisandro Dalcin 
1139a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1140a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1141a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1142a542b6e8SBarry Smith   }
11432d747510SLisandro Dalcin   options->N = 0;
11449355ec05SMatthew G. Knepley   free(options->names);
11459355ec05SMatthew G. Knepley   free(options->values);
11469355ec05SMatthew G. Knepley   free(options->used);
11479355ec05SMatthew G. Knepley   free(options->source);
11489355ec05SMatthew G. Knepley   options->names  = NULL;
11499355ec05SMatthew G. Knepley   options->values = NULL;
11509355ec05SMatthew G. Knepley   options->used   = NULL;
11519355ec05SMatthew G. Knepley   options->source = NULL;
11529355ec05SMatthew G. Knepley   options->Nalloc = 0;
11532d747510SLisandro Dalcin 
11549355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
1155a542b6e8SBarry Smith     free(options->aliases1[i]);
1156a542b6e8SBarry Smith     free(options->aliases2[i]);
1157a542b6e8SBarry Smith   }
11589355ec05SMatthew G. Knepley   options->Na = 0;
11599355ec05SMatthew G. Knepley   free(options->aliases1);
11609355ec05SMatthew G. Knepley   free(options->aliases2);
11619355ec05SMatthew G. Knepley   options->aliases1 = options->aliases2 = NULL;
11629355ec05SMatthew G. Knepley   options->Naalloc                      = 0;
1163a542b6e8SBarry Smith 
11642d747510SLisandro Dalcin   /* destroy hash table */
11652d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11662d747510SLisandro Dalcin   options->ht = NULL;
11670eb63584SBarry Smith 
11682d747510SLisandro Dalcin   options->prefixind  = 0;
11692d747510SLisandro Dalcin   options->prefix[0]  = 0;
11702d747510SLisandro Dalcin   options->help       = PETSC_FALSE;
11719355ec05SMatthew G. Knepley   options->help_intro = PETSC_FALSE;
11723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11734416b707SBarry Smith }
11744416b707SBarry Smith 
11755d83a8b1SBarry Smith /*@
11762d747510SLisandro Dalcin   PetscOptionsSetAlias - Makes a key and alias for another key
11772d747510SLisandro Dalcin 
11781c9f3c13SBarry Smith   Logically Collective
11792d747510SLisandro Dalcin 
11802d747510SLisandro Dalcin   Input Parameters:
118120f4b53cSBarry Smith + options - options database, or `NULL` for default global database
11822d747510SLisandro Dalcin . newname - the alias
11832d747510SLisandro Dalcin - oldname - the name that alias will refer to
11842d747510SLisandro Dalcin 
11852d747510SLisandro Dalcin   Level: advanced
11862d747510SLisandro Dalcin 
118720f4b53cSBarry Smith   Note:
118821532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11891c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11901c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11911c9f3c13SBarry Smith   on different ranks.
11921c9f3c13SBarry Smith 
11937e6f8dd6SBarry Smith   Developer Note:
11947e6f8dd6SBarry Smith   Uses `malloc()` directly because PETSc may not be initialized yet.
11957e6f8dd6SBarry Smith 
11960241b274SPierre Jolivet .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1197c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1198db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1199c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1200db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1201db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
12022d747510SLisandro Dalcin @*/
1203d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1204d71ae5a4SJacob Faibussowitsch {
12052d747510SLisandro Dalcin   size_t    len;
12069210b8eaSVaclav Hapla   PetscBool valid;
12072d747510SLisandro Dalcin 
12082d747510SLisandro Dalcin   PetscFunctionBegin;
12094f572ea9SToby Isaac   PetscAssertPointer(newname, 2);
12104f572ea9SToby Isaac   PetscAssertPointer(oldname, 3);
12112d747510SLisandro Dalcin   options = options ? options : defaultoptions;
12129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
121328b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
12149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
121528b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
12162d747510SLisandro Dalcin 
12179355ec05SMatthew G. Knepley   if (options->Na == options->Naalloc) {
12189355ec05SMatthew G. Knepley     char **tmpA1, **tmpA2;
12192d747510SLisandro Dalcin 
12209355ec05SMatthew G. Knepley     options->Naalloc = PetscMax(4, options->Naalloc * 2);
12219355ec05SMatthew G. Knepley     tmpA1            = (char **)malloc(options->Naalloc * sizeof(char *));
12229355ec05SMatthew G. Knepley     tmpA2            = (char **)malloc(options->Naalloc * sizeof(char *));
12239355ec05SMatthew G. Knepley     for (int i = 0; i < options->Na; ++i) {
12249355ec05SMatthew G. Knepley       tmpA1[i] = options->aliases1[i];
12259355ec05SMatthew G. Knepley       tmpA2[i] = options->aliases2[i];
12269355ec05SMatthew G. Knepley     }
12279355ec05SMatthew G. Knepley     free(options->aliases1);
12289355ec05SMatthew G. Knepley     free(options->aliases2);
12299355ec05SMatthew G. Knepley     options->aliases1 = tmpA1;
12309355ec05SMatthew G. Knepley     options->aliases2 = tmpA2;
12319355ec05SMatthew G. Knepley   }
12329371c9d4SSatish Balay   newname++;
12339371c9d4SSatish Balay   oldname++;
12349566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
12359355ec05SMatthew G. Knepley   options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1236c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
12379566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
12389355ec05SMatthew G. Knepley   options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1239c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
12409355ec05SMatthew G. Knepley   ++options->Na;
12413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12422d747510SLisandro Dalcin }
12434416b707SBarry Smith 
12445d83a8b1SBarry Smith /*@
1245e5c89e4eSSatish Balay   PetscOptionsSetValue - Sets an option name-value pair in the options
1246e5c89e4eSSatish Balay   database, overriding whatever is already present.
1247e5c89e4eSSatish Balay 
12481c9f3c13SBarry Smith   Logically Collective
1249e5c89e4eSSatish Balay 
1250e5c89e4eSSatish Balay   Input Parameters:
125120f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1252c5929fdfSBarry Smith . name    - name of option, this SHOULD have the - prepended
125320f4b53cSBarry Smith - value   - the option value (not used for all options, so can be `NULL`)
1254e5c89e4eSSatish Balay 
1255e5c89e4eSSatish Balay   Level: intermediate
1256e5c89e4eSSatish Balay 
1257e5c89e4eSSatish Balay   Note:
1258811af0c4SBarry Smith   This function can be called BEFORE `PetscInitialize()`
1259d49172ceSBarry Smith 
126021532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
12611c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
12621c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12631c9f3c13SBarry Smith   on different ranks.
12641c9f3c13SBarry Smith 
12657e6f8dd6SBarry Smith   Developer Note:
12667e6f8dd6SBarry Smith   Uses `malloc()` directly because PETSc may not be initialized yet.
1267b0250c70SBarry Smith 
1268db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1269e5c89e4eSSatish Balay @*/
1270d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1271d71ae5a4SJacob Faibussowitsch {
127239a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12739355ec05SMatthew G. Knepley   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
12743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1275c5b5d8d5SVaclav Hapla }
1276c5b5d8d5SVaclav Hapla 
12779355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1278d71ae5a4SJacob Faibussowitsch {
1279e5c89e4eSSatish Balay   size_t    len;
12809355ec05SMatthew G. Knepley   int       n, i;
1281e5c89e4eSSatish Balay   char    **names;
12829355ec05SMatthew G. Knepley   char      fullname[PETSC_MAX_OPTION_NAME] = "";
1283c5b5d8d5SVaclav Hapla   PetscBool flg;
1284e5c89e4eSSatish Balay 
128539a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12867272c0d2SVaclav Hapla   if (!options) {
12879566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12887272c0d2SVaclav Hapla     options = defaultoptions;
1289c5929fdfSBarry Smith   }
129039a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
12912d747510SLisandro Dalcin 
12929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
12933ba16761SJacob Faibussowitsch   if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1294e5c89e4eSSatish Balay 
12952d747510SLisandro Dalcin   name++; /* skip starting dash */
12962d747510SLisandro Dalcin 
129774e0666dSJed Brown   if (options->prefixind > 0) {
1298d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
12992d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
130089ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
13012d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
130274e0666dSJed Brown     name                           = fullname;
130374e0666dSJed Brown   }
130474e0666dSJed Brown 
130574e0666dSJed Brown   /* check against aliases */
13069355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
13072d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
13089371c9d4SSatish Balay     if (!result) {
13099371c9d4SSatish Balay       name = options->aliases2[i];
13109371c9d4SSatish Balay       break;
13119371c9d4SSatish Balay     }
1312e5c89e4eSSatish Balay   }
1313e5c89e4eSSatish Balay 
13142d747510SLisandro Dalcin   /* slow search */
13159355ec05SMatthew G. Knepley   n     = options->N;
1316e5c89e4eSSatish Balay   names = options->names;
13179355ec05SMatthew G. Knepley   for (i = 0; i < options->N; i++) {
13182d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13192d747510SLisandro Dalcin     if (!result) {
13209371c9d4SSatish Balay       n = i;
13219371c9d4SSatish Balay       goto setvalue;
13222d747510SLisandro Dalcin     } else if (result > 0) {
13239371c9d4SSatish Balay       n = i;
13249371c9d4SSatish Balay       break;
1325e5c89e4eSSatish Balay     }
1326e5c89e4eSSatish Balay   }
13279355ec05SMatthew G. Knepley   if (options->N == options->Nalloc) {
13289355ec05SMatthew G. Knepley     char             **names, **values;
13299355ec05SMatthew G. Knepley     PetscBool         *used;
13309355ec05SMatthew G. Knepley     PetscOptionSource *source;
13319355ec05SMatthew G. Knepley 
13329355ec05SMatthew G. Knepley     options->Nalloc = PetscMax(10, options->Nalloc * 2);
13339355ec05SMatthew G. Knepley     names           = (char **)malloc(options->Nalloc * sizeof(char *));
13349355ec05SMatthew G. Knepley     values          = (char **)malloc(options->Nalloc * sizeof(char *));
13359355ec05SMatthew G. Knepley     used            = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
13369355ec05SMatthew G. Knepley     source          = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
13379355ec05SMatthew G. Knepley     for (int i = 0; i < options->N; ++i) {
13389355ec05SMatthew G. Knepley       names[i]  = options->names[i];
13399355ec05SMatthew G. Knepley       values[i] = options->values[i];
13409355ec05SMatthew G. Knepley       used[i]   = options->used[i];
13419355ec05SMatthew G. Knepley       source[i] = options->source[i];
13429355ec05SMatthew G. Knepley     }
13439355ec05SMatthew G. Knepley     free(options->names);
13449355ec05SMatthew G. Knepley     free(options->values);
13459355ec05SMatthew G. Knepley     free(options->used);
13469355ec05SMatthew G. Knepley     free(options->source);
13479355ec05SMatthew G. Knepley     options->names  = names;
13489355ec05SMatthew G. Knepley     options->values = values;
13499355ec05SMatthew G. Knepley     options->used   = used;
13509355ec05SMatthew G. Knepley     options->source = source;
13519355ec05SMatthew G. Knepley   }
135239a651e2SJacob Faibussowitsch 
13532d747510SLisandro Dalcin   /* shift remaining values up 1 */
13549355ec05SMatthew G. Knepley   for (i = options->N; i > n; i--) {
13555e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1356e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1357e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
13589355ec05SMatthew G. Knepley     options->source[i] = options->source[i - 1];
1359e5c89e4eSSatish Balay   }
13602d747510SLisandro Dalcin   options->names[n]  = NULL;
13612d747510SLisandro Dalcin   options->values[n] = NULL;
13622d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
13639355ec05SMatthew G. Knepley   options->source[n] = PETSC_OPT_CODE;
13642d747510SLisandro Dalcin   options->N++;
13652d747510SLisandro Dalcin 
13662d747510SLisandro Dalcin   /* destroy hash table */
13672d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13682d747510SLisandro Dalcin   options->ht = NULL;
13692d747510SLisandro Dalcin 
13702d747510SLisandro Dalcin   /* set new name */
137170d8d27cSBarry Smith   len               = strlen(name);
13725e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
137339a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1374d49172ceSBarry Smith   strcpy(options->names[n], name);
13752d747510SLisandro Dalcin 
13762d747510SLisandro Dalcin setvalue:
13772d747510SLisandro Dalcin   /* set new value */
13782d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1379d49172ceSBarry Smith   len = value ? strlen(value) : 0;
13805e8c5e88SLisandro Dalcin   if (len) {
1381e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1382d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1383d49172ceSBarry Smith     strcpy(options->values[n], value);
1384432b765aSRené Chenard     options->values[n][len] = '\0';
13852d747510SLisandro Dalcin   } else {
13862d747510SLisandro Dalcin     options->values[n] = NULL;
13872d747510SLisandro Dalcin   }
13889355ec05SMatthew G. Knepley   options->source[n] = source;
13892d747510SLisandro Dalcin 
139091ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
139191ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
139291ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1393d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
139491ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
139591ad3481SVaclav Hapla   }
139691ad3481SVaclav Hapla 
1397432b765aSRené Chenard   PetscCall(PetscOptionsMonitor(options, name, value ? value : "", source));
1398c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
13993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1400e5c89e4eSSatish Balay }
1401e5c89e4eSSatish Balay 
14025d83a8b1SBarry Smith /*@
1403e5c89e4eSSatish Balay   PetscOptionsClearValue - Clears an option name-value pair in the options
1404e5c89e4eSSatish Balay   database, overriding whatever is already present.
1405e5c89e4eSSatish Balay 
14061c9f3c13SBarry Smith   Logically Collective
1407e5c89e4eSSatish Balay 
1408d8d19677SJose E. Roman   Input Parameters:
140920f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1410a2b725a8SWilliam Gropp - name    - name of option, this SHOULD have the - prepended
1411e5c89e4eSSatish Balay 
1412e5c89e4eSSatish Balay   Level: intermediate
1413e5c89e4eSSatish Balay 
1414811af0c4SBarry Smith   Note:
141521532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
14161c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
14171c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
14181c9f3c13SBarry Smith   on different ranks.
14191c9f3c13SBarry Smith 
14207e6f8dd6SBarry Smith   Developer Note:
14217e6f8dd6SBarry Smith   Uses `free()` directly because the options have been set with `malloc()`
14227e6f8dd6SBarry Smith 
1423db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1424e5c89e4eSSatish Balay @*/
1425d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1426d71ae5a4SJacob Faibussowitsch {
14272d747510SLisandro Dalcin   int    N, n, i;
14282d747510SLisandro Dalcin   char **names;
1429e5c89e4eSSatish Balay 
1430e5c89e4eSSatish Balay   PetscFunctionBegin;
1431c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1432cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1433c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
14342d747510SLisandro Dalcin 
14352d747510SLisandro Dalcin   name++; /* skip starting dash */
14362d747510SLisandro Dalcin 
14372d747510SLisandro Dalcin   /* slow search */
14382d747510SLisandro Dalcin   N = n = options->N;
1439e5c89e4eSSatish Balay   names = options->names;
1440e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
14412d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
14422d747510SLisandro Dalcin     if (!result) {
14439371c9d4SSatish Balay       n = i;
14449371c9d4SSatish Balay       break;
14452d747510SLisandro Dalcin     } else if (result > 0) {
14469371c9d4SSatish Balay       n = N;
14479371c9d4SSatish Balay       break;
1448e5c89e4eSSatish Balay     }
14492d747510SLisandro Dalcin   }
14503ba16761SJacob Faibussowitsch   if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1451e5c89e4eSSatish Balay 
14522d747510SLisandro Dalcin   /* remove name and value */
14532d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
14542d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1455e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1456e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
14575e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1458e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1459e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
14609355ec05SMatthew G. Knepley     options->source[i] = options->source[i + 1];
1461e5c89e4eSSatish Balay   }
1462e5c89e4eSSatish Balay   options->N--;
14632d747510SLisandro Dalcin 
14642d747510SLisandro Dalcin   /* destroy hash table */
14652d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
14662d747510SLisandro Dalcin   options->ht = NULL;
14672d747510SLisandro Dalcin 
14689355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
14693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1470e5c89e4eSSatish Balay }
1471e5c89e4eSSatish Balay 
1472e5c89e4eSSatish Balay /*@C
14732d747510SLisandro Dalcin   PetscOptionsFindPair - Gets an option name-value pair from the options database.
1474e5c89e4eSSatish Balay 
14752d747510SLisandro Dalcin   Not Collective
1476e5c89e4eSSatish Balay 
1477e5c89e4eSSatish Balay   Input Parameters:
147820f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
147920f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
14802d747510SLisandro Dalcin - name    - name of option, this SHOULD have the "-" prepended
1481e5c89e4eSSatish Balay 
14822d747510SLisandro Dalcin   Output Parameters:
14832d747510SLisandro Dalcin + value - the option value (optional, not used for all options)
14842d747510SLisandro Dalcin - set   - whether the option is set (optional)
1485e5c89e4eSSatish Balay 
148620f4b53cSBarry Smith   Level: developer
148720f4b53cSBarry Smith 
1488811af0c4SBarry Smith   Note:
14899666a313SBarry Smith   Each process may find different values or no value depending on how options were inserted into the database
14901c9f3c13SBarry Smith 
1491db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1492e5c89e4eSSatish Balay @*/
1493d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1494d71ae5a4SJacob Faibussowitsch {
14959355ec05SMatthew G. Knepley   char      buf[PETSC_MAX_OPTION_NAME];
14962d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1497e5c89e4eSSatish Balay 
1498e5c89e4eSSatish Balay   PetscFunctionBegin;
1499b33a4df8SMatthew G. Knepley   if (!options) {
1500b33a4df8SMatthew G. Knepley     PetscCall(PetscOptionsCreateDefault());
1501b33a4df8SMatthew G. Knepley     options = defaultoptions;
1502b33a4df8SMatthew G. Knepley   }
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 
152808d7fc57SRené Chenard   if (!options->ht) {
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 
15442d747510SLisandro Dalcin   khash_t(HO) *ht = options->ht;
15452d747510SLisandro Dalcin   khiter_t     it = kh_get(HO, ht, name);
15462d747510SLisandro Dalcin   if (it != kh_end(ht)) {
15472d747510SLisandro Dalcin     int i            = kh_val(ht, it);
1548e5c89e4eSSatish Balay     options->used[i] = PETSC_TRUE;
15492d747510SLisandro Dalcin     if (value) *value = options->values[i];
15502d747510SLisandro Dalcin     if (set) *set = PETSC_TRUE;
15513ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
15522d747510SLisandro Dalcin   }
15532d747510SLisandro Dalcin 
15542d747510SLisandro Dalcin   /*
15552d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
15562d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
15572d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
15582d747510SLisandro Dalcin    */
15592d747510SLisandro Dalcin   if (matchnumbers) {
15602d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1561e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
15622d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
15632d747510SLisandro Dalcin       if (name[i] == '_') {
15642d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
15652d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
15662d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1567e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1568e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1569e5c89e4eSSatish Balay           }
15702d747510SLisandro Dalcin           i = j - 1;
1571e5c89e4eSSatish Balay           break;
1572e5c89e4eSSatish Balay         }
1573e5c89e4eSSatish Balay       }
1574e5c89e4eSSatish Balay     }
1575e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
15762d747510SLisandro Dalcin       PetscBool found;
15779355ec05SMatthew G. Knepley       char      opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
15789566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
15799566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15809566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
15819566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
15829371c9d4SSatish Balay       if (found) {
15839371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
15843ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15859371c9d4SSatish Balay       }
1586e5c89e4eSSatish Balay     }
1587e5c89e4eSSatish Balay   }
15882d747510SLisandro Dalcin 
15892d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
15903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1591e5c89e4eSSatish Balay }
1592e5c89e4eSSatish Balay 
1593d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
159454a546c1SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *option[], const char *value[], PetscBool *set)
1595d71ae5a4SJacob Faibussowitsch {
15969355ec05SMatthew G. Knepley   char buf[PETSC_MAX_OPTION_NAME];
1597d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1598514bf10dSMatthew G Knepley 
1599514bf10dSMatthew G Knepley   PetscFunctionBegin;
1600c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1601cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1602cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1603514bf10dSMatthew G Knepley 
16042d747510SLisandro Dalcin   name++; /* skip starting dash */
1605514bf10dSMatthew G Knepley 
1606514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
16072d747510SLisandro Dalcin   if (pre && pre[0]) {
16082d747510SLisandro Dalcin     char *ptr = buf;
16099371c9d4SSatish Balay     if (name[0] == '-') {
16109371c9d4SSatish Balay       *ptr++ = '-';
16119371c9d4SSatish Balay       name++;
16129371c9d4SSatish Balay     }
16139b15cf9aSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
16149566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
16152d747510SLisandro Dalcin     name = buf;
1616514bf10dSMatthew G Knepley   }
16172d747510SLisandro Dalcin 
161876bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1619514bf10dSMatthew G Knepley     PetscBool valid;
16209355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
16219566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
16229566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
162328b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1624514bf10dSMatthew G Knepley   }
1625514bf10dSMatthew G Knepley 
1626d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1627d6ced9c0SMatthew G. Knepley   {
1628d6ced9c0SMatthew G. Knepley     int i, j;
1629d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1630d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1631d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1632d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1633d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1634d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1635d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1636d6ced9c0SMatthew G. Knepley           }
1637d6ced9c0SMatthew G. Knepley           i = j - 1;
1638d6ced9c0SMatthew G. Knepley           break;
1639d6ced9c0SMatthew G. Knepley         }
1640d6ced9c0SMatthew G. Knepley       }
1641d6ced9c0SMatthew G. Knepley     }
1642d6ced9c0SMatthew G. Knepley   }
1643d6ced9c0SMatthew G. Knepley 
1644363da2dcSJacob Faibussowitsch   /* slow search */
1645363da2dcSJacob Faibussowitsch   for (int c = -1; c < numCnt; ++c) {
1646363da2dcSJacob Faibussowitsch     char   opt[PETSC_MAX_OPTION_NAME + 2] = "";
16472d747510SLisandro Dalcin     size_t len;
1648d6ced9c0SMatthew G. Knepley 
1649d6ced9c0SMatthew G. Knepley     if (c < 0) {
1650c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1651d6ced9c0SMatthew G. Knepley     } else {
1652363da2dcSJacob Faibussowitsch       PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1653363da2dcSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1654d6ced9c0SMatthew G. Knepley     }
16559566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(opt, &len));
1656363da2dcSJacob Faibussowitsch     for (int i = 0; i < options->N; i++) {
1657363da2dcSJacob Faibussowitsch       PetscBool match;
1658363da2dcSJacob Faibussowitsch 
16599566063dSJacob Faibussowitsch       PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1660514bf10dSMatthew G Knepley       if (match) {
1661514bf10dSMatthew G Knepley         options->used[i] = PETSC_TRUE;
166254a546c1SMatthew G. Knepley         if (option) *option = options->names[i];
16632d747510SLisandro Dalcin         if (value) *value = options->values[i];
16642d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
16653ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
1666514bf10dSMatthew G Knepley       }
1667514bf10dSMatthew G Knepley     }
16682d747510SLisandro Dalcin   }
16692d747510SLisandro Dalcin 
16702d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1672514bf10dSMatthew G Knepley }
1673514bf10dSMatthew G Knepley 
16745d83a8b1SBarry Smith /*@
1675e5c89e4eSSatish Balay   PetscOptionsReject - Generates an error if a certain option is given.
1676e5c89e4eSSatish Balay 
16771c9f3c13SBarry Smith   Not Collective
1678e5c89e4eSSatish Balay 
1679e5c89e4eSSatish Balay   Input Parameters:
168020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
168120f4b53cSBarry Smith . pre     - the option prefix (may be `NULL`)
16822d747510SLisandro Dalcin . name    - the option name one is seeking
168320f4b53cSBarry Smith - mess    - error message (may be `NULL`)
1684e5c89e4eSSatish Balay 
1685e5c89e4eSSatish Balay   Level: advanced
1686e5c89e4eSSatish Balay 
16870241b274SPierre Jolivet .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1688db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1689db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1690c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1691db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1692db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1693e5c89e4eSSatish Balay @*/
1694d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1695d71ae5a4SJacob Faibussowitsch {
1696ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1697e5c89e4eSSatish Balay 
1698e5c89e4eSSatish Balay   PetscFunctionBegin;
16999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1700e5c89e4eSSatish Balay   if (flag) {
170108401ef6SPierre 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);
1702f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1703e5c89e4eSSatish Balay   }
17043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1705e5c89e4eSSatish Balay }
1706e5c89e4eSSatish Balay 
17075d83a8b1SBarry Smith /*@
17082d747510SLisandro Dalcin   PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
17092d747510SLisandro Dalcin 
17102d747510SLisandro Dalcin   Not Collective
17112d747510SLisandro Dalcin 
1712811af0c4SBarry Smith   Input Parameter:
171320f4b53cSBarry Smith . options - options database, use `NULL` for default global database
17142d747510SLisandro Dalcin 
1715811af0c4SBarry Smith   Output Parameter:
1716811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
17172d747510SLisandro Dalcin 
17182d747510SLisandro Dalcin   Level: advanced
17192d747510SLisandro Dalcin 
1720db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
17212d747510SLisandro Dalcin @*/
1722d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1723d71ae5a4SJacob Faibussowitsch {
17242d747510SLisandro Dalcin   PetscFunctionBegin;
17254f572ea9SToby Isaac   PetscAssertPointer(set, 2);
17262d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17272d747510SLisandro Dalcin   *set    = options->help;
17283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17292d747510SLisandro Dalcin }
17302d747510SLisandro Dalcin 
1731d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1732d71ae5a4SJacob Faibussowitsch {
1733d314f959SVaclav Hapla   PetscFunctionBegin;
17344f572ea9SToby Isaac   PetscAssertPointer(set, 2);
1735d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1736d314f959SVaclav Hapla   *set    = options->help_intro;
17373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1738d314f959SVaclav Hapla }
1739d314f959SVaclav Hapla 
17405d83a8b1SBarry Smith /*@
1741e24fcbf7SPierre 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
1742e24fcbf7SPierre Jolivet   if its value is set to false.
1743e5c89e4eSSatish Balay 
1744e5c89e4eSSatish Balay   Not Collective
1745e5c89e4eSSatish Balay 
1746e5c89e4eSSatish Balay   Input Parameters:
174720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
174820f4b53cSBarry Smith . pre     - string to prepend to the name or `NULL`
17493de71b31SHong Zhang - name    - the option one is seeking
1750e5c89e4eSSatish Balay 
1751811af0c4SBarry Smith   Output Parameter:
1752811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1753e5c89e4eSSatish Balay 
1754e5c89e4eSSatish Balay   Level: beginner
1755e5c89e4eSSatish Balay 
1756811af0c4SBarry Smith   Note:
1757811af0c4SBarry Smith   In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
175890d69ab7SBarry Smith 
1759db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1760db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1761db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1762c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1763db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1764db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1765e5c89e4eSSatish Balay @*/
1766d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1767d71ae5a4SJacob Faibussowitsch {
17682d747510SLisandro Dalcin   const char *value;
1769ace3abfcSBarry Smith   PetscBool   flag;
1770e5c89e4eSSatish Balay 
1771e5c89e4eSSatish Balay   PetscFunctionBegin;
17729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
177396ef3cdfSSatish Balay   if (set) *set = flag;
17743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1775e5c89e4eSSatish Balay }
1776e5c89e4eSSatish Balay 
1777e5c89e4eSSatish Balay /*@C
17782d747510SLisandro Dalcin   PetscOptionsGetAll - Lists all the options the program was run with in a single string.
17792d747510SLisandro Dalcin 
17802d747510SLisandro Dalcin   Not Collective
17812d747510SLisandro Dalcin 
1782fd292e60Sprj-   Input Parameter:
178320f4b53cSBarry Smith . options - the options database, use `NULL` for the default global database
17842d747510SLisandro Dalcin 
17852d747510SLisandro Dalcin   Output Parameter:
17862d747510SLisandro Dalcin . copts - pointer where string pointer is stored
17872d747510SLisandro Dalcin 
178820f4b53cSBarry Smith   Level: advanced
178920f4b53cSBarry Smith 
17902d747510SLisandro Dalcin   Notes:
1791811af0c4SBarry Smith   The array and each entry in the array should be freed with `PetscFree()`
1792811af0c4SBarry Smith 
17931c9f3c13SBarry Smith   Each process may have different values depending on how the options were inserted into the database
17942d747510SLisandro Dalcin 
1795db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
17962d747510SLisandro Dalcin @*/
1797ce78bad3SBarry Smith PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[]) PeNS
1798d71ae5a4SJacob Faibussowitsch {
17992d747510SLisandro Dalcin   PetscInt i;
18002d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
18012d747510SLisandro Dalcin   char    *coptions = NULL;
18022d747510SLisandro Dalcin 
18032d747510SLisandro Dalcin   PetscFunctionBegin;
18044f572ea9SToby Isaac   PetscAssertPointer(copts, 2);
18052d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18062d747510SLisandro Dalcin   /* count the length of the required string */
18072d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18089566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
18092d747510SLisandro Dalcin     len += 2 + lent;
18102d747510SLisandro Dalcin     if (options->values[i]) {
18119566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
18122d747510SLisandro Dalcin       len += 1 + lent;
18132d747510SLisandro Dalcin     }
18142d747510SLisandro Dalcin   }
18159566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
18162d747510SLisandro Dalcin   coptions[0] = 0;
18172d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1818c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, "-", len));
1819c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, options->names[i], len));
1820c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, " ", len));
18212d747510SLisandro Dalcin     if (options->values[i]) {
1822c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, options->values[i], len));
1823c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, " ", len));
18242d747510SLisandro Dalcin     }
18252d747510SLisandro Dalcin   }
18262d747510SLisandro Dalcin   *copts = coptions;
18273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18282d747510SLisandro Dalcin }
18292d747510SLisandro Dalcin 
18305d83a8b1SBarry Smith /*@
18312d747510SLisandro Dalcin   PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
18322d747510SLisandro Dalcin 
18332d747510SLisandro Dalcin   Not Collective
18342d747510SLisandro Dalcin 
1835d8d19677SJose E. Roman   Input Parameters:
183620f4b53cSBarry Smith + options - options database, use `NULL` for default global database
18372d747510SLisandro Dalcin - name    - string name of option
18382d747510SLisandro Dalcin 
18392d747510SLisandro Dalcin   Output Parameter:
1840811af0c4SBarry Smith . used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
18412d747510SLisandro Dalcin 
18422d747510SLisandro Dalcin   Level: advanced
18432d747510SLisandro Dalcin 
1844811af0c4SBarry Smith   Note:
18459666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18461c9f3c13SBarry Smith   on the given process
18471c9f3c13SBarry Smith 
1848db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
18492d747510SLisandro Dalcin @*/
1850d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1851d71ae5a4SJacob Faibussowitsch {
18522d747510SLisandro Dalcin   PetscInt i;
18532d747510SLisandro Dalcin 
18542d747510SLisandro Dalcin   PetscFunctionBegin;
18554f572ea9SToby Isaac   PetscAssertPointer(name, 2);
18564f572ea9SToby Isaac   PetscAssertPointer(used, 3);
18572d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18582d747510SLisandro Dalcin   *used   = PETSC_FALSE;
18592d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18609566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
18612d747510SLisandro Dalcin     if (*used) {
18622d747510SLisandro Dalcin       *used = options->used[i];
18632d747510SLisandro Dalcin       break;
18642d747510SLisandro Dalcin     }
18652d747510SLisandro Dalcin   }
18663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18672d747510SLisandro Dalcin }
18682d747510SLisandro Dalcin 
1869487a658cSBarry Smith /*@
18702d747510SLisandro Dalcin   PetscOptionsAllUsed - Returns a count of the number of options in the
18712d747510SLisandro Dalcin   database that have never been selected.
18722d747510SLisandro Dalcin 
18732d747510SLisandro Dalcin   Not Collective
18742d747510SLisandro Dalcin 
18752d747510SLisandro Dalcin   Input Parameter:
187620f4b53cSBarry Smith . options - options database, use `NULL` for default global database
18772d747510SLisandro Dalcin 
18782d747510SLisandro Dalcin   Output Parameter:
18792d747510SLisandro Dalcin . N - count of options not used
18802d747510SLisandro Dalcin 
18812d747510SLisandro Dalcin   Level: advanced
18822d747510SLisandro Dalcin 
1883811af0c4SBarry Smith   Note:
18849666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18851c9f3c13SBarry Smith   on the given process
18861c9f3c13SBarry Smith 
1887db781477SPatrick Sanan .seealso: `PetscOptionsView()`
18882d747510SLisandro Dalcin @*/
1889d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1890d71ae5a4SJacob Faibussowitsch {
18912d747510SLisandro Dalcin   PetscInt i, n = 0;
18922d747510SLisandro Dalcin 
18932d747510SLisandro Dalcin   PetscFunctionBegin;
18944f572ea9SToby Isaac   PetscAssertPointer(N, 2);
18952d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18962d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18972d747510SLisandro Dalcin     if (!options->used[i]) n++;
18982d747510SLisandro Dalcin   }
18992d747510SLisandro Dalcin   *N = n;
19003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19012d747510SLisandro Dalcin }
19022d747510SLisandro Dalcin 
1903487a658cSBarry Smith /*@
19042d747510SLisandro Dalcin   PetscOptionsLeft - Prints to screen any options that were set and never used.
19052d747510SLisandro Dalcin 
19062d747510SLisandro Dalcin   Not Collective
19072d747510SLisandro Dalcin 
19082d747510SLisandro Dalcin   Input Parameter:
190920f4b53cSBarry Smith . options - options database; use `NULL` for default global database
19102d747510SLisandro Dalcin 
19112d747510SLisandro Dalcin   Options Database Key:
1912811af0c4SBarry Smith . -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
19132d747510SLisandro Dalcin 
191420f4b53cSBarry Smith   Level: advanced
191520f4b53cSBarry Smith 
19163de2bfdfSBarry Smith   Notes:
1917811af0c4SBarry Smith   This is rarely used directly, it is called by `PetscFinalize()` in debug more or if -options_left
19181c9f3c13SBarry Smith   is passed otherwise to help users determine possible mistakes in their usage of options. This
1919811af0c4SBarry Smith   only prints values on process zero of `PETSC_COMM_WORLD`.
1920811af0c4SBarry Smith 
1921811af0c4SBarry Smith   Other processes depending the objects
19221c9f3c13SBarry Smith   used may have different options that are left unused.
19233de2bfdfSBarry Smith 
1924db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
19252d747510SLisandro Dalcin @*/
1926d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeft(PetscOptions options)
1927d71ae5a4SJacob Faibussowitsch {
19282d747510SLisandro Dalcin   PetscInt     i;
19293de2bfdfSBarry Smith   PetscInt     cnt = 0;
19303de2bfdfSBarry Smith   PetscOptions toptions;
19312d747510SLisandro Dalcin 
19322d747510SLisandro Dalcin   PetscFunctionBegin;
19333de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
19343de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
19353de2bfdfSBarry Smith     if (!toptions->used[i]) {
1936660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
19373de2bfdfSBarry Smith       if (toptions->values[i]) {
19389355ec05SMatthew 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]]));
19392d747510SLisandro Dalcin       } else {
19409355ec05SMatthew G. Knepley         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
19412d747510SLisandro Dalcin       }
19422d747510SLisandro Dalcin     }
19432d747510SLisandro Dalcin   }
19443de2bfdfSBarry Smith   if (!options) {
19453de2bfdfSBarry Smith     toptions = defaultoptions;
19463de2bfdfSBarry Smith     while (toptions->previous) {
19473de2bfdfSBarry Smith       cnt++;
19483de2bfdfSBarry Smith       toptions = toptions->previous;
19493de2bfdfSBarry Smith     }
195048a46eb9SPierre 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));
19513de2bfdfSBarry Smith   }
19523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19532d747510SLisandro Dalcin }
19542d747510SLisandro Dalcin 
19552d747510SLisandro Dalcin /*@C
19562d747510SLisandro Dalcin   PetscOptionsLeftGet - Returns all options that were set and never used.
19572d747510SLisandro Dalcin 
19582d747510SLisandro Dalcin   Not Collective
19592d747510SLisandro Dalcin 
19602d747510SLisandro Dalcin   Input Parameter:
196120f4b53cSBarry Smith . options - options database, use `NULL` for default global database
19622d747510SLisandro Dalcin 
1963d8d19677SJose E. Roman   Output Parameters:
1964a2b725a8SWilliam Gropp + N      - count of options not used
19652d747510SLisandro Dalcin . names  - names of options not used
1966a2b725a8SWilliam Gropp - values - values of options not used
19672d747510SLisandro Dalcin 
19682d747510SLisandro Dalcin   Level: advanced
19692d747510SLisandro Dalcin 
19702d747510SLisandro Dalcin   Notes:
1971811af0c4SBarry Smith   Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1972811af0c4SBarry Smith 
1973811af0c4SBarry Smith   The value returned may be different on each process and depends on which options have been processed
19741c9f3c13SBarry Smith   on the given process
19752d747510SLisandro Dalcin 
1976db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
19772d747510SLisandro Dalcin @*/
1978d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
1979d71ae5a4SJacob Faibussowitsch {
19802d747510SLisandro Dalcin   PetscInt i, n;
19812d747510SLisandro Dalcin 
19822d747510SLisandro Dalcin   PetscFunctionBegin;
19834f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
19844f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
19854f572ea9SToby Isaac   if (values) PetscAssertPointer(values, 4);
19862d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19872d747510SLisandro Dalcin 
19882d747510SLisandro Dalcin   /* The number of unused PETSc options */
19892d747510SLisandro Dalcin   n = 0;
19902d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1991660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
19922d747510SLisandro Dalcin     if (!options->used[i]) n++;
19932d747510SLisandro Dalcin   }
1994ad540459SPierre Jolivet   if (N) *N = n;
19959566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
19969566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
19972d747510SLisandro Dalcin 
19982d747510SLisandro Dalcin   n = 0;
19992d747510SLisandro Dalcin   if (names || values) {
20002d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
20012d747510SLisandro Dalcin       if (!options->used[i]) {
2002660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
20032d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
20042d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
20052d747510SLisandro Dalcin         n++;
20062d747510SLisandro Dalcin       }
20072d747510SLisandro Dalcin     }
20082d747510SLisandro Dalcin   }
20093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20102d747510SLisandro Dalcin }
20112d747510SLisandro Dalcin 
20122d747510SLisandro Dalcin /*@C
2013811af0c4SBarry Smith   PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
20142d747510SLisandro Dalcin 
20152d747510SLisandro Dalcin   Not Collective
20162d747510SLisandro Dalcin 
2017d8d19677SJose E. Roman   Input Parameters:
201820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
201910450e9eSJacob Faibussowitsch . N       - count of options not used
20202d747510SLisandro Dalcin . names   - names of options not used
2021a2b725a8SWilliam Gropp - values  - values of options not used
20222d747510SLisandro Dalcin 
20232d747510SLisandro Dalcin   Level: advanced
20242d747510SLisandro Dalcin 
202510450e9eSJacob Faibussowitsch   Notes:
202610450e9eSJacob Faibussowitsch   The user should pass the same pointer to `N` as they did when calling `PetscOptionsLeftGet()`
202710450e9eSJacob Faibussowitsch 
2028db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
20292d747510SLisandro Dalcin @*/
2030d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2031d71ae5a4SJacob Faibussowitsch {
20322d747510SLisandro Dalcin   PetscFunctionBegin;
203310450e9eSJacob Faibussowitsch   (void)options;
20344f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
20354f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
20364f572ea9SToby Isaac   if (values) PetscAssertPointer(values, 4);
2037ad540459SPierre Jolivet   if (N) *N = 0;
20389566063dSJacob Faibussowitsch   if (names) PetscCall(PetscFree(*names));
20399566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
20403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20412d747510SLisandro Dalcin }
20422d747510SLisandro Dalcin 
20432d747510SLisandro Dalcin /*@C
2044811af0c4SBarry Smith   PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
20452d747510SLisandro Dalcin 
2046c3339decSBarry Smith   Logically Collective
20472d747510SLisandro Dalcin 
20482d747510SLisandro Dalcin   Input Parameters:
20492d747510SLisandro Dalcin + name   - option name string
20502d747510SLisandro Dalcin . value  - option value string
20519355ec05SMatthew G. Knepley . source - The source for the option
205220f4b53cSBarry Smith - ctx    - a `PETSCVIEWERASCII` or `NULL`
20532d747510SLisandro Dalcin 
20542d747510SLisandro Dalcin   Level: intermediate
20552d747510SLisandro Dalcin 
20569666a313SBarry Smith   Notes:
205720f4b53cSBarry Smith   If ctx is `NULL`, `PetscPrintf()` is used.
20589314d9b7SBarry Smith   The first MPI process in the `PetscViewer` viewer actually prints the values, other
20591c9f3c13SBarry Smith   processes may have different values set
20601c9f3c13SBarry Smith 
2061811af0c4SBarry Smith   If `PetscCIEnabled` then do not print the test harness options
2062660278c0SBarry Smith 
2063db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
20642d747510SLisandro Dalcin @*/
20659355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], PetscOptionSource source, void *ctx)
2066d71ae5a4SJacob Faibussowitsch {
20672d747510SLisandro Dalcin   PetscFunctionBegin;
20683ba16761SJacob Faibussowitsch   if (PetscCIOption(name)) PetscFunctionReturn(PETSC_SUCCESS);
2069660278c0SBarry Smith 
20709060e2f9SVaclav Hapla   if (ctx) {
20719060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
20722d747510SLisandro Dalcin     if (!value) {
20739566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
20742d747510SLisandro Dalcin     } else if (!value[0]) {
20759355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20762d747510SLisandro Dalcin     } else {
20779355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20782d747510SLisandro Dalcin     }
20799060e2f9SVaclav Hapla   } else {
20809060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
20819060e2f9SVaclav Hapla     if (!value) {
20829566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
20839060e2f9SVaclav Hapla     } else if (!value[0]) {
20849355ec05SMatthew G. Knepley       PetscCall(PetscPrintf(comm, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20859060e2f9SVaclav Hapla     } else {
2086aaa8cc7dSPierre Jolivet       PetscCall(PetscPrintf(comm, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20879060e2f9SVaclav Hapla     }
20889060e2f9SVaclav Hapla   }
20893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20902d747510SLisandro Dalcin }
20912d747510SLisandro Dalcin 
20922d747510SLisandro Dalcin /*@C
20932d747510SLisandro Dalcin   PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
20942d747510SLisandro Dalcin   modified the PETSc options database.
20952d747510SLisandro Dalcin 
20962d747510SLisandro Dalcin   Not Collective
20972d747510SLisandro Dalcin 
20982d747510SLisandro Dalcin   Input Parameters:
209920f4b53cSBarry Smith + monitor        - pointer to function (if this is `NULL`, it turns off monitoring
210010450e9eSJacob Faibussowitsch . mctx           - [optional] context for private data for the monitor routine (use `NULL` if
210110450e9eSJacob Faibussowitsch                    no context is desired)
210249abdd8aSBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`), see `PetscCtxDestroyFn` for its calling sequence
21032d747510SLisandro Dalcin 
210410450e9eSJacob Faibussowitsch   Calling sequence of `monitor`:
21052d747510SLisandro Dalcin + name   - option name string
2106432b765aSRené Chenard . value  - option value string, a value of `NULL` indicates the option is being removed from the database. A value
2107432b765aSRené Chenard            of "" indicates the option is in the database but has no value.
21089355ec05SMatthew G. Knepley . source - option source
2109811af0c4SBarry Smith - mctx   - optional monitoring context, as set by `PetscOptionsMonitorSet()`
21102d747510SLisandro Dalcin 
2111432b765aSRené Chenard   Options Database Keys:
21128d6650c0SBarry Smith + -options_monitor <viewer> - turn on default monitoring of changes to the options database
2113432b765aSRené Chenard - -options_monitor_cancel   - turn off any option monitors except the default monitor obtained with `-options_monitor`
2114432b765aSRené Chenard 
211520f4b53cSBarry Smith   Level: intermediate
211620f4b53cSBarry Smith 
21172d747510SLisandro Dalcin   Notes:
211810450e9eSJacob Faibussowitsch   See `PetscInitialize()` for options related to option database monitoring.
211910450e9eSJacob Faibussowitsch 
2120432b765aSRené Chenard   The default is to do no monitoring.  To print the name and value of options
2121811af0c4SBarry Smith   being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
2122432b765aSRené Chenard   with a `NULL` monitoring context. Or use the option `-options_monitor` <viewer>.
21232d747510SLisandro Dalcin 
21242d747510SLisandro Dalcin   Several different monitoring routines may be set by calling
2125811af0c4SBarry Smith   `PetscOptionsMonitorSet()` multiple times; all will be called in the
21262d747510SLisandro Dalcin   order in which they were set.
21272d747510SLisandro Dalcin 
212849abdd8aSBarry Smith .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`, `PetscCtxDestroyFn`
21292d747510SLisandro Dalcin @*/
213049abdd8aSBarry Smith PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource source, void *mctx), void *mctx, PetscCtxDestroyFn *monitordestroy)
2131d71ae5a4SJacob Faibussowitsch {
21322d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
21332d747510SLisandro Dalcin 
21342d747510SLisandro Dalcin   PetscFunctionBegin;
21353ba16761SJacob Faibussowitsch   if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
213608401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
21372d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
21382d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
2139835f2295SStefano Zampini   options->monitorcontext[options->numbermonitors++] = mctx;
21403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21412d747510SLisandro Dalcin }
21422d747510SLisandro Dalcin 
21432d747510SLisandro Dalcin /*
21442d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
214563fe8743SVaclav Hapla      Empty string is considered as true.
21462d747510SLisandro Dalcin */
2147d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2148d71ae5a4SJacob Faibussowitsch {
21492d747510SLisandro Dalcin   PetscBool istrue, isfalse;
21502d747510SLisandro Dalcin   size_t    len;
21512d747510SLisandro Dalcin 
21522d747510SLisandro Dalcin   PetscFunctionBegin;
215363fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
21549566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
21559371c9d4SSatish Balay   if (!len) {
21569371c9d4SSatish Balay     *a = PETSC_TRUE;
21573ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21589371c9d4SSatish Balay   }
21599566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
21609371c9d4SSatish Balay   if (istrue) {
21619371c9d4SSatish Balay     *a = PETSC_TRUE;
21623ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21639371c9d4SSatish Balay   }
21649566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
21659371c9d4SSatish Balay   if (istrue) {
21669371c9d4SSatish Balay     *a = PETSC_TRUE;
21673ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21689371c9d4SSatish Balay   }
21699566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
21709371c9d4SSatish Balay   if (istrue) {
21719371c9d4SSatish Balay     *a = PETSC_TRUE;
21723ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21739371c9d4SSatish Balay   }
21749566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
21759371c9d4SSatish Balay   if (istrue) {
21769371c9d4SSatish Balay     *a = PETSC_TRUE;
21773ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21789371c9d4SSatish Balay   }
21799566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
21809371c9d4SSatish Balay   if (isfalse) {
21819371c9d4SSatish Balay     *a = PETSC_FALSE;
21823ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21839371c9d4SSatish Balay   }
21849566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
21859371c9d4SSatish Balay   if (isfalse) {
21869371c9d4SSatish Balay     *a = PETSC_FALSE;
21873ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21889371c9d4SSatish Balay   }
21899566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
21909371c9d4SSatish Balay   if (isfalse) {
21919371c9d4SSatish Balay     *a = PETSC_FALSE;
21923ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21939371c9d4SSatish Balay   }
21949566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
21959371c9d4SSatish Balay   if (isfalse) {
21969371c9d4SSatish Balay     *a = PETSC_FALSE;
21973ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21989371c9d4SSatish Balay   }
219998921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
22002d747510SLisandro Dalcin }
22012d747510SLisandro Dalcin 
22022d747510SLisandro Dalcin /*
22032d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
22042d747510SLisandro Dalcin */
2205d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2206d71ae5a4SJacob Faibussowitsch {
22072d747510SLisandro Dalcin   size_t    len;
2208b3480c81SBarry Smith   PetscBool decide, tdefault, mouse, unlimited;
22092d747510SLisandro Dalcin 
22102d747510SLisandro Dalcin   PetscFunctionBegin;
22119566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
22125f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22132d747510SLisandro Dalcin 
22149566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
221548a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
22169566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
221748a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
2218b3480c81SBarry Smith   if (!decide) PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &decide));
2219b3480c81SBarry Smith   if (!decide) PetscCall(PetscStrcasecmp(name, "DETERMINE", &decide));
2220b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &unlimited));
2221b3480c81SBarry Smith   if (!unlimited) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &unlimited));
22229566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
22232d747510SLisandro Dalcin 
22242d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
22252d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
2226b3480c81SBarry Smith   else if (unlimited) *a = PETSC_UNLIMITED;
22272d747510SLisandro Dalcin   else if (mouse) *a = -1;
22282d747510SLisandro Dalcin   else {
22292d747510SLisandro Dalcin     char *endptr;
22302d747510SLisandro Dalcin     long  strtolval;
22312d747510SLisandro Dalcin 
22322d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2233cc73adaaSBarry 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);
22342d747510SLisandro Dalcin 
22352d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
22362d747510SLisandro Dalcin     (void)strtolval;
22372d747510SLisandro Dalcin     *a = atoll(name);
22382d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
22392d747510SLisandro Dalcin     (void)strtolval;
22402d747510SLisandro Dalcin     *a = _atoi64(name);
22412d747510SLisandro Dalcin #else
22422d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
22432d747510SLisandro Dalcin #endif
22442d747510SLisandro Dalcin   }
22453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22462d747510SLisandro Dalcin }
22472d747510SLisandro Dalcin 
22482d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22492d747510SLisandro Dalcin   #include <quadmath.h>
22502d747510SLisandro Dalcin #endif
22512d747510SLisandro Dalcin 
2252d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2253d71ae5a4SJacob Faibussowitsch {
22542d747510SLisandro Dalcin   PetscFunctionBegin;
22552d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22562d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
22572d747510SLisandro Dalcin #else
22582d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
22592d747510SLisandro Dalcin #endif
22603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22612d747510SLisandro Dalcin }
22622d747510SLisandro Dalcin 
2263d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2264d71ae5a4SJacob Faibussowitsch {
22652d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
22662d747510SLisandro Dalcin   char     *ptr;
22672d747510SLisandro Dalcin   PetscReal strtoval;
22682d747510SLisandro Dalcin 
22692d747510SLisandro Dalcin   PetscFunctionBegin;
22709566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
22712d747510SLisandro Dalcin   if (ptr == name) {
22722d747510SLisandro Dalcin     strtoval = 1.;
22732d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
22742d747510SLisandro Dalcin     if (name[0] == 'i') {
22752d747510SLisandro Dalcin       ptr++;
22762d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
22772d747510SLisandro Dalcin       ptr += 2;
22782d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
22792d747510SLisandro Dalcin       strtoval = -1.;
22802d747510SLisandro Dalcin       ptr += 2;
22812d747510SLisandro Dalcin     }
22822d747510SLisandro Dalcin   } else if (*ptr == 'i') {
22832d747510SLisandro Dalcin     hasi = PETSC_TRUE;
22842d747510SLisandro Dalcin     ptr++;
22852d747510SLisandro Dalcin   }
22862d747510SLisandro Dalcin   *endptr      = ptr;
22872d747510SLisandro Dalcin   *isImaginary = hasi;
22882d747510SLisandro Dalcin   if (hasi) {
22892d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
229098921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
22912d747510SLisandro Dalcin #else
22922d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
22932d747510SLisandro Dalcin #endif
22942d747510SLisandro Dalcin   } else {
22952d747510SLisandro Dalcin     *a = strtoval;
22962d747510SLisandro Dalcin   }
22973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22982d747510SLisandro Dalcin }
22992d747510SLisandro Dalcin 
23002d747510SLisandro Dalcin /*
23012d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
23022d747510SLisandro Dalcin */
2303d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2304d71ae5a4SJacob Faibussowitsch {
23052d747510SLisandro Dalcin   size_t    len;
23062d747510SLisandro Dalcin   PetscBool match;
23072d747510SLisandro Dalcin   char     *endptr;
23082d747510SLisandro Dalcin 
23092d747510SLisandro Dalcin   PetscFunctionBegin;
23109566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
231128b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
23122d747510SLisandro Dalcin 
23139566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
23149566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
23159371c9d4SSatish Balay   if (match) {
23169371c9d4SSatish Balay     *a = PETSC_DEFAULT;
23173ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23189371c9d4SSatish Balay   }
23192d747510SLisandro Dalcin 
23209566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
23219566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
23229371c9d4SSatish Balay   if (match) {
23239371c9d4SSatish Balay     *a = PETSC_DECIDE;
23243ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23259371c9d4SSatish Balay   }
23262d747510SLisandro Dalcin 
2327b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &match));
2328b3480c81SBarry Smith   if (!match) PetscCall(PetscStrcasecmp(name, "DETERMINE", &match));
2329b3480c81SBarry Smith   if (match) {
2330b3480c81SBarry Smith     *a = PETSC_DETERMINE;
2331b3480c81SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
2332b3480c81SBarry Smith   }
2333b3480c81SBarry Smith 
2334b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &match));
2335b3480c81SBarry Smith   if (!match) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &match));
2336b3480c81SBarry Smith   if (match) {
2337b3480c81SBarry Smith     *a = PETSC_UNLIMITED;
2338b3480c81SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
2339b3480c81SBarry Smith   }
2340b3480c81SBarry Smith 
23419566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
234239a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
23433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23442d747510SLisandro Dalcin }
23452d747510SLisandro Dalcin 
2346d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2347d71ae5a4SJacob Faibussowitsch {
23482d747510SLisandro Dalcin   PetscBool   imag1;
23492d747510SLisandro Dalcin   size_t      len;
23502d747510SLisandro Dalcin   PetscScalar val = 0.;
23512d747510SLisandro Dalcin   char       *ptr = NULL;
23522d747510SLisandro Dalcin 
23532d747510SLisandro Dalcin   PetscFunctionBegin;
23549566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
235528b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
23569566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
23572d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
23582d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
23592d747510SLisandro Dalcin     PetscBool   imag2;
23602d747510SLisandro Dalcin     PetscScalar val2;
23612d747510SLisandro Dalcin 
23629566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
236339a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
23642d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
23652d747510SLisandro Dalcin   }
23662d747510SLisandro Dalcin #endif
236739a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
23682d747510SLisandro Dalcin   *a = val;
23693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23702d747510SLisandro Dalcin }
23712d747510SLisandro Dalcin 
23722d747510SLisandro Dalcin /*@C
23732d747510SLisandro Dalcin   PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
23742d747510SLisandro Dalcin   option in the database.
2375e5c89e4eSSatish Balay 
2376e5c89e4eSSatish Balay   Not Collective
2377e5c89e4eSSatish Balay 
2378e5c89e4eSSatish Balay   Input Parameters:
237920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
238020f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2381e5c89e4eSSatish Balay - name    - the option one is seeking
2382e5c89e4eSSatish Balay 
2383d8d19677SJose E. Roman   Output Parameters:
23842d747510SLisandro Dalcin + ivalue - the logical value to return
2385811af0c4SBarry Smith - set    - `PETSC_TRUE`  if found, else `PETSC_FALSE`
2386e5c89e4eSSatish Balay 
2387e5c89e4eSSatish Balay   Level: beginner
2388e5c89e4eSSatish Balay 
238995452b02SPatrick Sanan   Notes:
23909e296098SJunchao Zhang   TRUE, true, YES, yes, ON, on, nostring, and 1 all translate to `PETSC_TRUE`
23919e296098SJunchao Zhang   FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_FALSE`
23922d747510SLisandro Dalcin 
23939314d9b7SBarry 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`
23949314d9b7SBarry Smith   is equivalent to `-requested_bool true`
23952d747510SLisandro Dalcin 
23969314d9b7SBarry Smith   If the user does not supply the option at all `ivalue` is NOT changed. Thus
23979314d9b7SBarry Smith   you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
23982efd9cb1SBarry Smith 
23999e296098SJunchao Zhang .seealso: `PetscOptionsGetBool3()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2400db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2401db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2402c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2403db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2404db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2405e5c89e4eSSatish Balay @*/
2406d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2407d71ae5a4SJacob Faibussowitsch {
24082d747510SLisandro Dalcin   const char *value;
2409ace3abfcSBarry Smith   PetscBool   flag;
2410e5c89e4eSSatish Balay 
2411e5c89e4eSSatish Balay   PetscFunctionBegin;
24124f572ea9SToby Isaac   PetscAssertPointer(name, 3);
24134f572ea9SToby Isaac   if (ivalue) PetscAssertPointer(ivalue, 4);
24149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2415e5c89e4eSSatish Balay   if (flag) {
241696ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
24179566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
24182d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2419e5c89e4eSSatish Balay   } else {
242096ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2421e5c89e4eSSatish Balay   }
24223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2423e5c89e4eSSatish Balay }
2424e5c89e4eSSatish Balay 
2425e5c89e4eSSatish Balay /*@C
2426d7c1f440SPierre Jolivet   PetscOptionsGetBool3 - Gets the ternary logical (true, false or unknown) value for a particular
24279e296098SJunchao Zhang   option in the database.
24289e296098SJunchao Zhang 
24299e296098SJunchao Zhang   Not Collective
24309e296098SJunchao Zhang 
24319e296098SJunchao Zhang   Input Parameters:
24329e296098SJunchao Zhang + options - options database, use `NULL` for default global database
24339e296098SJunchao Zhang . pre     - the string to prepend to the name or `NULL`
24349e296098SJunchao Zhang - name    - the option one is seeking
24359e296098SJunchao Zhang 
24369e296098SJunchao Zhang   Output Parameters:
24379e296098SJunchao Zhang + ivalue - the ternary logical value to return
24389e296098SJunchao Zhang - set    - `PETSC_TRUE`  if found, else `PETSC_FALSE`
24399e296098SJunchao Zhang 
24409e296098SJunchao Zhang   Level: beginner
24419e296098SJunchao Zhang 
24429e296098SJunchao Zhang   Notes:
24439e296098SJunchao Zhang   TRUE, true, YES, yes, ON, on, nostring and 1 all translate to `PETSC_BOOL3_TRUE`
24449e296098SJunchao Zhang   FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_BOOL3_FALSE`
24459e296098SJunchao Zhang   UNKNOWN, unknown, AUTO and auto all translate to `PETSC_BOOL3_UNKNOWN`
24469e296098SJunchao Zhang 
24479e296098SJunchao Zhang   If the option is given, but no value is provided, then `ivalue` will be set to `PETSC_BOOL3_TRUE` and `set` will be set to `PETSC_TRUE`. That is `-requested_bool3`
24489e296098SJunchao Zhang   is equivalent to `-requested_bool3 true`
24499e296098SJunchao Zhang 
24509e296098SJunchao Zhang   If the user does not supply the option at all `ivalue` is NOT changed. Thus
24519e296098SJunchao Zhang   you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
24529e296098SJunchao Zhang 
24539e296098SJunchao Zhang .seealso: `PetscOptionsGetBool()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
24549e296098SJunchao Zhang           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
24559e296098SJunchao Zhang           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
24569e296098SJunchao Zhang           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
24579e296098SJunchao Zhang           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
24589e296098SJunchao Zhang           `PetscOptionsFList()`, `PetscOptionsEList()`
24599e296098SJunchao Zhang @*/
24609e296098SJunchao Zhang PetscErrorCode PetscOptionsGetBool3(PetscOptions options, const char pre[], const char name[], PetscBool3 *ivalue, PetscBool *set)
24619e296098SJunchao Zhang {
24629e296098SJunchao Zhang   const char *value;
24639e296098SJunchao Zhang   PetscBool   flag;
24649e296098SJunchao Zhang 
24659e296098SJunchao Zhang   PetscFunctionBegin;
24669e296098SJunchao Zhang   PetscAssertPointer(name, 3);
24679e296098SJunchao Zhang   if (ivalue) PetscAssertPointer(ivalue, 4);
24689e296098SJunchao Zhang   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
24699e296098SJunchao Zhang   if (flag) { // found the option
24709e296098SJunchao Zhang     PetscBool isAUTO = PETSC_FALSE, isUNKNOWN = PETSC_FALSE;
24719e296098SJunchao Zhang 
24729e296098SJunchao Zhang     if (set) *set = PETSC_TRUE;
24739e296098SJunchao Zhang     PetscCall(PetscStrcasecmp("AUTO", value, &isAUTO));                    // auto or AUTO
24749e296098SJunchao Zhang     if (!isAUTO) PetscCall(PetscStrcasecmp("UNKNOWN", value, &isUNKNOWN)); // unknown or UNKNOWN
24759e296098SJunchao Zhang     if (isAUTO || isUNKNOWN) {
24769e296098SJunchao Zhang       if (ivalue) *ivalue = PETSC_BOOL3_UNKNOWN;
24779e296098SJunchao Zhang     } else { // handle boolean values (if no value is given, it returns true)
24789e296098SJunchao Zhang       PetscCall(PetscOptionsStringToBool(value, &flag));
24799e296098SJunchao Zhang       if (ivalue) *ivalue = PetscBoolToBool3(flag);
24809e296098SJunchao Zhang     }
24819e296098SJunchao Zhang   } else {
24829e296098SJunchao Zhang     if (set) *set = PETSC_FALSE;
24839e296098SJunchao Zhang   }
24849e296098SJunchao Zhang   PetscFunctionReturn(PETSC_SUCCESS);
24859e296098SJunchao Zhang }
24869e296098SJunchao Zhang 
24879e296098SJunchao Zhang /*@C
2488e5c89e4eSSatish Balay   PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2489e5c89e4eSSatish Balay 
2490e5c89e4eSSatish Balay   Not Collective
2491e5c89e4eSSatish Balay 
2492e5c89e4eSSatish Balay   Input Parameters:
249320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
249420f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2495e5c89e4eSSatish Balay . opt     - option name
2496a264d7a6SBarry Smith . list    - the possible choices (one of these must be selected, anything else is invalid)
2497a2b725a8SWilliam Gropp - ntext   - number of choices
2498e5c89e4eSSatish Balay 
2499d8d19677SJose E. Roman   Output Parameters:
25002efd9cb1SBarry Smith + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2501811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2502e5c89e4eSSatish Balay 
2503e5c89e4eSSatish Balay   Level: intermediate
2504e5c89e4eSSatish Balay 
250595452b02SPatrick Sanan   Notes:
25069314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
25079314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
25082efd9cb1SBarry Smith 
2509811af0c4SBarry Smith   See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2510e5c89e4eSSatish Balay 
2511db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2512db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2513db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2514c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2515db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2516db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2517e5c89e4eSSatish Balay @*/
2518ce78bad3SBarry Smith PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const list[], PetscInt ntext, PetscInt *value, PetscBool *set)
2519d71ae5a4SJacob Faibussowitsch {
252058b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2521e5c89e4eSSatish Balay   char     *svalue;
2522ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2523e5c89e4eSSatish Balay   PetscInt  i;
2524e5c89e4eSSatish Balay 
2525e5c89e4eSSatish Balay   PetscFunctionBegin;
25264f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2527e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
25289566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2529e5c89e4eSSatish Balay     if (alen > len) len = alen;
253058b0ac4eSStefano Zampini     tlen += len + 1;
2531e5c89e4eSSatish Balay   }
2532e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
25339566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
25349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2535e5c89e4eSSatish Balay   if (aset) {
25369566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
253758b0ac4eSStefano Zampini     if (!flg) {
2538c6a7a370SJeremy L Thompson       char *avail;
253958b0ac4eSStefano Zampini 
25409566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
2541c6a7a370SJeremy L Thompson       avail[0] = '\0';
254258b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
2543c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, list[i], tlen));
2544c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, " ", tlen));
254558b0ac4eSStefano Zampini       }
25469566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
254798921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
254858b0ac4eSStefano Zampini     }
2549fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2550a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
25519566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
25523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2553e5c89e4eSSatish Balay }
2554e5c89e4eSSatish Balay 
2555e5c89e4eSSatish Balay /*@C
2556e5c89e4eSSatish Balay   PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2557e5c89e4eSSatish Balay 
2558e5c89e4eSSatish Balay   Not Collective
2559e5c89e4eSSatish Balay 
2560e5c89e4eSSatish Balay   Input Parameters:
256120f4b53cSBarry Smith + options - options database, use `NULL` for default global database
256220f4b53cSBarry Smith . pre     - option prefix or `NULL`
2563e5c89e4eSSatish Balay . opt     - option name
25646b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2565e5c89e4eSSatish Balay 
2566d8d19677SJose E. Roman   Output Parameters:
2567e5c89e4eSSatish Balay + value - the value to return
2568811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2569e5c89e4eSSatish Balay 
2570e5c89e4eSSatish Balay   Level: beginner
2571e5c89e4eSSatish Balay 
257295452b02SPatrick Sanan   Notes:
25739314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
25749314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2575e5c89e4eSSatish Balay 
25769314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names
2577e5c89e4eSSatish Balay 
2578db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2579db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2580aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2581db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2582c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2583db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2584db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2585e5c89e4eSSatish Balay @*/
2586*6f8503afSBarry Smith PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const list[], PetscEnum *value, PetscBool *set) PeNSS
2587d71ae5a4SJacob Faibussowitsch {
258869a24498SJed Brown   PetscInt  ntext = 0, tval;
2589ace3abfcSBarry Smith   PetscBool fset;
2590e5c89e4eSSatish Balay 
2591e5c89e4eSSatish Balay   PetscFunctionBegin;
25924f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2593ad540459SPierre 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");
259408401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2595e5c89e4eSSatish Balay   ntext -= 3;
25969566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
259769a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2598809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2599809ceb46SBarry Smith   if (set) *set = fset;
26003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2601e5c89e4eSSatish Balay }
2602e5c89e4eSSatish Balay 
2603e5c89e4eSSatish Balay /*@C
26042d747510SLisandro Dalcin   PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2605e5c89e4eSSatish Balay 
2606e5c89e4eSSatish Balay   Not Collective
2607e5c89e4eSSatish Balay 
2608e5c89e4eSSatish Balay   Input Parameters:
260920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
261020f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2611e5c89e4eSSatish Balay - name    - the option one is seeking
2612e5c89e4eSSatish Balay 
2613d8d19677SJose E. Roman   Output Parameters:
26142d747510SLisandro Dalcin + ivalue - the integer value to return
2615811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2616e5c89e4eSSatish Balay 
2617e5c89e4eSSatish Balay   Level: beginner
2618e5c89e4eSSatish Balay 
2619e5c89e4eSSatish Balay   Notes:
26209314d9b7SBarry Smith   If the user does not supply the option `ivalue` is NOT changed. Thus
26219314d9b7SBarry Smith   you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
26225c07ccb8SBarry Smith 
2623b3480c81SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
2624b3480c81SBarry Smith 
2625b3480c81SBarry Smith   Accepts the deprecated value `default`.
2626b3480c81SBarry Smith 
2627db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2628db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2629aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2630db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2631c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2632db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2633db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2634e5c89e4eSSatish Balay @*/
2635d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2636d71ae5a4SJacob Faibussowitsch {
26372d747510SLisandro Dalcin   const char *value;
26382d747510SLisandro Dalcin   PetscBool   flag;
2639e5c89e4eSSatish Balay 
2640e5c89e4eSSatish Balay   PetscFunctionBegin;
26414f572ea9SToby Isaac   PetscAssertPointer(name, 3);
26424f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
26439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2644e5c89e4eSSatish Balay   if (flag) {
264534a9cc2cSBarry Smith     if (!value) {
26462d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
264734a9cc2cSBarry Smith     } else {
26482d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
26499566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2650e5c89e4eSSatish Balay     }
2651e5c89e4eSSatish Balay   } else {
265296ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2653e5c89e4eSSatish Balay   }
26543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2655e5c89e4eSSatish Balay }
2656e5c89e4eSSatish Balay 
2657e2446a98SMatthew Knepley /*@C
26586497c311SBarry Smith   PetscOptionsGetMPIInt - Gets the MPI integer value for a particular option in the database.
26596497c311SBarry Smith 
26606497c311SBarry Smith   Not Collective
26616497c311SBarry Smith 
26626497c311SBarry Smith   Input Parameters:
26636497c311SBarry Smith + options - options database, use `NULL` for default global database
26646497c311SBarry Smith . pre     - the string to prepend to the name or `NULL`
26656497c311SBarry Smith - name    - the option one is seeking
26666497c311SBarry Smith 
26676497c311SBarry Smith   Output Parameters:
26686497c311SBarry Smith + ivalue - the MPI integer value to return
26696497c311SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
26706497c311SBarry Smith 
26716497c311SBarry Smith   Level: beginner
26726497c311SBarry Smith 
26736497c311SBarry Smith   Notes:
26746497c311SBarry Smith   If the user does not supply the option `ivalue` is NOT changed. Thus
26756497c311SBarry Smith   you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
26766497c311SBarry Smith 
26776497c311SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
26786497c311SBarry Smith 
26796497c311SBarry Smith   Accepts the deprecated value `default`.
26806497c311SBarry Smith 
26816497c311SBarry Smith .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
26826497c311SBarry Smith           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
26836497c311SBarry Smith           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
26846497c311SBarry Smith           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
26856497c311SBarry Smith           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
26866497c311SBarry Smith           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
26876497c311SBarry Smith           `PetscOptionsFList()`, `PetscOptionsEList()`
26886497c311SBarry Smith @*/
26896497c311SBarry Smith PetscErrorCode PetscOptionsGetMPIInt(PetscOptions options, const char pre[], const char name[], PetscMPIInt *ivalue, PetscBool *set)
26906497c311SBarry Smith {
26916497c311SBarry Smith   PetscInt  value;
26926497c311SBarry Smith   PetscBool flag;
26936497c311SBarry Smith 
26946497c311SBarry Smith   PetscFunctionBegin;
26956497c311SBarry Smith   PetscCall(PetscOptionsGetInt(options, pre, name, &value, &flag));
26966497c311SBarry Smith   if (flag) PetscCall(PetscMPIIntCast(value, ivalue));
26976497c311SBarry Smith   if (set) *set = flag;
26986497c311SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
26996497c311SBarry Smith }
27006497c311SBarry Smith 
27016497c311SBarry Smith /*@C
2702e5c89e4eSSatish Balay   PetscOptionsGetReal - Gets the double precision value for a particular
2703e5c89e4eSSatish Balay   option in the database.
2704e5c89e4eSSatish Balay 
2705e5c89e4eSSatish Balay   Not Collective
2706e5c89e4eSSatish Balay 
2707e5c89e4eSSatish Balay   Input Parameters:
270820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
270920f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2710e5c89e4eSSatish Balay - name    - the option one is seeking
2711e5c89e4eSSatish Balay 
2712d8d19677SJose E. Roman   Output Parameters:
2713e5c89e4eSSatish Balay + dvalue - the double value to return
2714811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2715e5c89e4eSSatish Balay 
271620f4b53cSBarry Smith   Level: beginner
271720f4b53cSBarry Smith 
2718b3480c81SBarry Smith   Notes:
2719b3480c81SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
2720b3480c81SBarry Smith 
2721b3480c81SBarry Smith   Accepts the deprecated value `default`
2722b3480c81SBarry Smith 
27239314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
27249314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking that the `set` flag is true.
2725e4974155SBarry Smith 
2726db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2727c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2728db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2729c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2730db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2731db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2732e5c89e4eSSatish Balay @*/
2733d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2734d71ae5a4SJacob Faibussowitsch {
27352d747510SLisandro Dalcin   const char *value;
2736ace3abfcSBarry Smith   PetscBool   flag;
2737e5c89e4eSSatish Balay 
2738e5c89e4eSSatish Balay   PetscFunctionBegin;
27394f572ea9SToby Isaac   PetscAssertPointer(name, 3);
27404f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
27419566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2742e5c89e4eSSatish Balay   if (flag) {
2743a297a907SKarl Rupp     if (!value) {
2744a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2745a297a907SKarl Rupp     } else {
2746a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
27479566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2748a297a907SKarl Rupp     }
2749e5c89e4eSSatish Balay   } else {
275096ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2751e5c89e4eSSatish Balay   }
27523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2753e5c89e4eSSatish Balay }
2754e5c89e4eSSatish Balay 
2755e5c89e4eSSatish Balay /*@C
2756e5c89e4eSSatish Balay   PetscOptionsGetScalar - Gets the scalar value for a particular
2757e5c89e4eSSatish Balay   option in the database.
2758e5c89e4eSSatish Balay 
2759e5c89e4eSSatish Balay   Not Collective
2760e5c89e4eSSatish Balay 
2761e5c89e4eSSatish Balay   Input Parameters:
276220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
276320f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2764e5c89e4eSSatish Balay - name    - the option one is seeking
2765e5c89e4eSSatish Balay 
2766d8d19677SJose E. Roman   Output Parameters:
27679314d9b7SBarry Smith + dvalue - the scalar value to return
2768811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2769e5c89e4eSSatish Balay 
2770e5c89e4eSSatish Balay   Level: beginner
2771e5c89e4eSSatish Balay 
277210450e9eSJacob Faibussowitsch   Example Usage:
2773eb4ae41dSBarry Smith   A complex number 2+3i must be specified with NO spaces
2774e5c89e4eSSatish Balay 
2775811af0c4SBarry Smith   Note:
27769314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
27779314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking if the `set` flag is true.
2778e4974155SBarry Smith 
2779db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2780db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2781db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2782c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2783db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2784db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2785e5c89e4eSSatish Balay @*/
2786d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2787d71ae5a4SJacob Faibussowitsch {
27882d747510SLisandro Dalcin   const char *value;
2789ace3abfcSBarry Smith   PetscBool   flag;
2790e5c89e4eSSatish Balay 
2791e5c89e4eSSatish Balay   PetscFunctionBegin;
27924f572ea9SToby Isaac   PetscAssertPointer(name, 3);
27934f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
27949566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2795e5c89e4eSSatish Balay   if (flag) {
2796e5c89e4eSSatish Balay     if (!value) {
279796ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2798e5c89e4eSSatish Balay     } else {
2799e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
28009566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2801e5c89e4eSSatish Balay #else
28029566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2803e5c89e4eSSatish Balay #endif
280496ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2805e5c89e4eSSatish Balay     }
2806e5c89e4eSSatish Balay   } else { /* flag */
280796ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2808e5c89e4eSSatish Balay   }
28093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2810e5c89e4eSSatish Balay }
2811e5c89e4eSSatish Balay 
2812e5c89e4eSSatish Balay /*@C
2813e5c89e4eSSatish Balay   PetscOptionsGetString - Gets the string value for a particular option in
2814e5c89e4eSSatish Balay   the database.
2815e5c89e4eSSatish Balay 
2816e5c89e4eSSatish Balay   Not Collective
2817e5c89e4eSSatish Balay 
2818e5c89e4eSSatish Balay   Input Parameters:
281920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
282020f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
2821e5c89e4eSSatish Balay . name    - the option one is seeking
2822bcbf2dc5SJed Brown - len     - maximum length of the string including null termination
2823e5c89e4eSSatish Balay 
2824e5c89e4eSSatish Balay   Output Parameters:
2825e5c89e4eSSatish Balay + string - location to copy string
2826811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2827e5c89e4eSSatish Balay 
2828e5c89e4eSSatish Balay   Level: beginner
2829e5c89e4eSSatish Balay 
283020f4b53cSBarry Smith   Note:
28319314d9b7SBarry 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`
283220f4b53cSBarry Smith 
28339314d9b7SBarry Smith   If the user does not use the option then `string` is not changed. Thus
28349314d9b7SBarry Smith   you should ALWAYS initialize `string` if you access it without first checking that the `set` flag is true.
283520f4b53cSBarry Smith 
2836aec76313SJacob Faibussowitsch   Fortran Notes:
2837e5c89e4eSSatish Balay   The Fortran interface is slightly different from the C/C++
2838feaf08eaSBarry Smith   interface.  Sample usage in Fortran follows
2839e5c89e4eSSatish Balay .vb
2840e5c89e4eSSatish Balay       character *20    string
284193e6ba5cSBarry Smith       PetscErrorCode   ierr
284293e6ba5cSBarry Smith       PetscBool        set
28431b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2844e5c89e4eSSatish Balay .ve
2845e5c89e4eSSatish Balay 
2846db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2847db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2848db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2849c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2850db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2851db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2852e5c89e4eSSatish Balay @*/
2853ce78bad3SBarry Smith PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set) PeNS
2854d71ae5a4SJacob Faibussowitsch {
28552d747510SLisandro Dalcin   const char *value;
2856ace3abfcSBarry Smith   PetscBool   flag;
2857e5c89e4eSSatish Balay 
2858e5c89e4eSSatish Balay   PetscFunctionBegin;
28594f572ea9SToby Isaac   PetscAssertPointer(name, 3);
28604f572ea9SToby Isaac   PetscAssertPointer(string, 4);
28619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2862e5c89e4eSSatish Balay   if (!flag) {
286396ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2864e5c89e4eSSatish Balay   } else {
286596ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
28669566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
28679566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2868e5c89e4eSSatish Balay   }
28693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2870e5c89e4eSSatish Balay }
2871e5c89e4eSSatish Balay 
28722d747510SLisandro Dalcin /*@C
28732d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2874f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
28752d747510SLisandro Dalcin 
28762d747510SLisandro Dalcin   Not Collective
28772d747510SLisandro Dalcin 
28782d747510SLisandro Dalcin   Input Parameters:
287920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
288020f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
28816b867d5aSJose E. Roman - name    - the option one is seeking
28826b867d5aSJose E. Roman 
2883d8d19677SJose E. Roman   Output Parameters:
28849314d9b7SBarry Smith + dvalue - the Boolean values to return
2885f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2886811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
28872d747510SLisandro Dalcin 
28882d747510SLisandro Dalcin   Level: beginner
28892d747510SLisandro Dalcin 
2890811af0c4SBarry Smith   Note:
289120f4b53cSBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`. FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
28922d747510SLisandro Dalcin 
2893db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2894db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2895db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2896c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2897db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2898db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
28992d747510SLisandro Dalcin @*/
2900d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2901d71ae5a4SJacob Faibussowitsch {
29022d747510SLisandro Dalcin   const char *svalue;
2903ce78bad3SBarry Smith   const char *value;
29042d747510SLisandro Dalcin   PetscInt    n = 0;
29052d747510SLisandro Dalcin   PetscBool   flag;
29062d747510SLisandro Dalcin   PetscToken  token;
29072d747510SLisandro Dalcin 
29082d747510SLisandro Dalcin   PetscFunctionBegin;
29094f572ea9SToby Isaac   PetscAssertPointer(name, 3);
29104f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
29114f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
29122d747510SLisandro Dalcin 
29139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29149371c9d4SSatish Balay   if (!flag || !svalue) {
29159371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29169371c9d4SSatish Balay     *nmax = 0;
29173ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29189371c9d4SSatish Balay   }
29192d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29209566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29219566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29222d747510SLisandro Dalcin   while (value && n < *nmax) {
29239566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
29249566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29252d747510SLisandro Dalcin     dvalue++;
29262d747510SLisandro Dalcin     n++;
29272d747510SLisandro Dalcin   }
29289566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29292d747510SLisandro Dalcin   *nmax = n;
29303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29312d747510SLisandro Dalcin }
29322d747510SLisandro Dalcin 
29332d747510SLisandro Dalcin /*@C
29342d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
29352d747510SLisandro Dalcin 
29362d747510SLisandro Dalcin   Not Collective
29372d747510SLisandro Dalcin 
29382d747510SLisandro Dalcin   Input Parameters:
293920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
294020f4b53cSBarry Smith . pre     - option prefix or `NULL`
29412d747510SLisandro Dalcin . name    - option name
29426b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
29436b867d5aSJose E. Roman 
29442d747510SLisandro Dalcin   Output Parameters:
29452d747510SLisandro Dalcin + ivalue - the  enum values to return
2946f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2947811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
29482d747510SLisandro Dalcin 
29492d747510SLisandro Dalcin   Level: beginner
29502d747510SLisandro Dalcin 
29512d747510SLisandro Dalcin   Notes:
29529314d9b7SBarry Smith   The array must be passed as a comma separated list with no spaces between the items.
29532d747510SLisandro Dalcin 
29549314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names.
29552d747510SLisandro Dalcin 
2956db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2957db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2958aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsName()`,
2959c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2960db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2961db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
29622d747510SLisandro Dalcin @*/
2963ce78bad3SBarry Smith PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const list[], PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
2964d71ae5a4SJacob Faibussowitsch {
29652d747510SLisandro Dalcin   const char *svalue;
2966ce78bad3SBarry Smith   const char *value;
29672d747510SLisandro Dalcin   PetscInt    n = 0;
29682d747510SLisandro Dalcin   PetscEnum   evalue;
29692d747510SLisandro Dalcin   PetscBool   flag;
29702d747510SLisandro Dalcin   PetscToken  token;
29712d747510SLisandro Dalcin 
29722d747510SLisandro Dalcin   PetscFunctionBegin;
29734f572ea9SToby Isaac   PetscAssertPointer(name, 3);
29744f572ea9SToby Isaac   PetscAssertPointer(list, 4);
29754f572ea9SToby Isaac   PetscAssertPointer(ivalue, 5);
29764f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
29772d747510SLisandro Dalcin 
29789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29799371c9d4SSatish Balay   if (!flag || !svalue) {
29809371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29819371c9d4SSatish Balay     *nmax = 0;
29823ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29839371c9d4SSatish Balay   }
29842d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29859566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29869566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29872d747510SLisandro Dalcin   while (value && n < *nmax) {
29889566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
298928b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
29902d747510SLisandro Dalcin     ivalue[n++] = evalue;
29919566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29922d747510SLisandro Dalcin   }
29939566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29942d747510SLisandro Dalcin   *nmax = n;
29953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29962d747510SLisandro Dalcin }
29972d747510SLisandro Dalcin 
29982d747510SLisandro Dalcin /*@C
2999f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
30002d747510SLisandro Dalcin 
30012d747510SLisandro Dalcin   Not Collective
30022d747510SLisandro Dalcin 
30032d747510SLisandro Dalcin   Input Parameters:
300420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
300520f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
30066b867d5aSJose E. Roman - name    - the option one is seeking
30076b867d5aSJose E. Roman 
3008d8d19677SJose E. Roman   Output Parameters:
30092d747510SLisandro Dalcin + ivalue - the integer values to return
3010f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3011811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
30122d747510SLisandro Dalcin 
30132d747510SLisandro Dalcin   Level: beginner
30142d747510SLisandro Dalcin 
30152d747510SLisandro Dalcin   Notes:
30162d747510SLisandro Dalcin   The array can be passed as
3017811af0c4SBarry Smith +  a comma separated list -                                 0,1,2,3,4,5,6,7
3018811af0c4SBarry Smith .  a range (start\-end+1) -                                 0-8
3019811af0c4SBarry Smith .  a range with given increment (start\-end+1:inc) -        0-7:2
3020811af0c4SBarry Smith -  a combination of values and ranges separated by commas - 0,1-8,8-15:2
30212d747510SLisandro Dalcin 
30222d747510SLisandro Dalcin   There must be no intervening spaces between the values.
30232d747510SLisandro Dalcin 
3024db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3025db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3026db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3027c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3028db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3029db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30302d747510SLisandro Dalcin @*/
3031d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
3032d71ae5a4SJacob Faibussowitsch {
30332d747510SLisandro Dalcin   const char *svalue;
3034ce78bad3SBarry Smith   const char *value;
30352d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
30362d747510SLisandro Dalcin   size_t      len;
30372d747510SLisandro Dalcin   PetscBool   flag, foundrange;
30382d747510SLisandro Dalcin   PetscToken  token;
30392d747510SLisandro Dalcin 
30402d747510SLisandro Dalcin   PetscFunctionBegin;
30414f572ea9SToby Isaac   PetscAssertPointer(name, 3);
30424f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
30434f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
30442d747510SLisandro Dalcin 
30459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30469371c9d4SSatish Balay   if (!flag || !svalue) {
30479371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30489371c9d4SSatish Balay     *nmax = 0;
30493ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
30509371c9d4SSatish Balay   }
30512d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30529566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30539566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30542d747510SLisandro Dalcin   while (value && n < *nmax) {
3055ce78bad3SBarry Smith     char *iivalue;
3056ce78bad3SBarry Smith 
30572d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
3058ce78bad3SBarry Smith     PetscCall(PetscStrallocpy(value, &iivalue));
30592d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
3060ce78bad3SBarry Smith     PetscCall(PetscStrlen(iivalue, &len));
3061ce78bad3SBarry Smith     if (iivalue[0] == '-') i = 2;
30622d747510SLisandro Dalcin     else i = 1;
30632d747510SLisandro Dalcin     for (; i < (int)len; i++) {
3064ce78bad3SBarry Smith       if (iivalue[i] == '-') {
3065ce78bad3SBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, iivalue);
3066ce78bad3SBarry Smith         iivalue[i] = 0;
30672d747510SLisandro Dalcin 
3068ce78bad3SBarry Smith         PetscCall(PetscOptionsStringToInt(iivalue, &start));
30692d747510SLisandro Dalcin         inc = 1;
30702d747510SLisandro Dalcin         j   = i + 1;
30712d747510SLisandro Dalcin         for (; j < (int)len; j++) {
3072ce78bad3SBarry Smith           if (iivalue[j] == ':') {
3073ce78bad3SBarry Smith             iivalue[j] = 0;
30742d747510SLisandro Dalcin 
3075ce78bad3SBarry Smith             PetscCall(PetscOptionsStringToInt(iivalue + j + 1, &inc));
3076ce78bad3SBarry Smith             PetscCheck(inc > 0, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry,%s cannot have negative increment", n, iivalue + j + 1);
30772d747510SLisandro Dalcin             break;
30782d747510SLisandro Dalcin           }
30792d747510SLisandro Dalcin         }
3080ce78bad3SBarry Smith         PetscCall(PetscOptionsStringToInt(iivalue + i + 1, &end));
3081ce78bad3SBarry Smith         PetscCheck(end > start, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, %s-%s cannot have decreasing list", n, iivalue, iivalue + i + 1);
30822d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
3083cc73adaaSBarry 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);
30842d747510SLisandro Dalcin         for (; start < end; start += inc) {
30859371c9d4SSatish Balay           *ivalue = start;
30869371c9d4SSatish Balay           ivalue++;
30879371c9d4SSatish Balay           n++;
30882d747510SLisandro Dalcin         }
30892d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
30902d747510SLisandro Dalcin         break;
30912d747510SLisandro Dalcin       }
30922d747510SLisandro Dalcin     }
30932d747510SLisandro Dalcin     if (!foundrange) {
30949566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
30952d747510SLisandro Dalcin       ivalue++;
30962d747510SLisandro Dalcin       n++;
30972d747510SLisandro Dalcin     }
3098ce78bad3SBarry Smith     PetscCall(PetscFree(iivalue));
30999566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
31002d747510SLisandro Dalcin   }
31019566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
31022d747510SLisandro Dalcin   *nmax = n;
31033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31042d747510SLisandro Dalcin }
31052d747510SLisandro Dalcin 
31062d747510SLisandro Dalcin /*@C
31072d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
3108f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
31092d747510SLisandro Dalcin 
31102d747510SLisandro Dalcin   Not Collective
31112d747510SLisandro Dalcin 
31122d747510SLisandro Dalcin   Input Parameters:
311320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
311420f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
31156b867d5aSJose E. Roman - name    - the option one is seeking
31166b867d5aSJose E. Roman 
31172d747510SLisandro Dalcin   Output Parameters:
31182d747510SLisandro Dalcin + dvalue - the double values to return
3119f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3120811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
31212d747510SLisandro Dalcin 
31222d747510SLisandro Dalcin   Level: beginner
31232d747510SLisandro Dalcin 
3124db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3125db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3126db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3127c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3128db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3129db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
31302d747510SLisandro Dalcin @*/
3131d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
3132d71ae5a4SJacob Faibussowitsch {
31332d747510SLisandro Dalcin   const char *svalue;
3134ce78bad3SBarry Smith   const char *value;
31352d747510SLisandro Dalcin   PetscInt    n = 0;
31362d747510SLisandro Dalcin   PetscBool   flag;
31372d747510SLisandro Dalcin   PetscToken  token;
31382d747510SLisandro Dalcin 
31392d747510SLisandro Dalcin   PetscFunctionBegin;
31404f572ea9SToby Isaac   PetscAssertPointer(name, 3);
31414f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
31424f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
31432d747510SLisandro Dalcin 
31449566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
31459371c9d4SSatish Balay   if (!flag || !svalue) {
31469371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
31479371c9d4SSatish Balay     *nmax = 0;
31483ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
31499371c9d4SSatish Balay   }
31502d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31519566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31529566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31532d747510SLisandro Dalcin   while (value && n < *nmax) {
31549566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
31559566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
31562d747510SLisandro Dalcin     n++;
31572d747510SLisandro Dalcin   }
31589566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
31592d747510SLisandro Dalcin   *nmax = n;
31603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31612d747510SLisandro Dalcin }
31622d747510SLisandro Dalcin 
31632d747510SLisandro Dalcin /*@C
31642d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
3165f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
31662d747510SLisandro Dalcin 
31672d747510SLisandro Dalcin   Not Collective
31682d747510SLisandro Dalcin 
31692d747510SLisandro Dalcin   Input Parameters:
317020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
317120f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
31726b867d5aSJose E. Roman - name    - the option one is seeking
31736b867d5aSJose E. Roman 
31742d747510SLisandro Dalcin   Output Parameters:
31752d747510SLisandro Dalcin + dvalue - the scalar values to return
3176f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3177811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
31782d747510SLisandro Dalcin 
31792d747510SLisandro Dalcin   Level: beginner
31802d747510SLisandro Dalcin 
3181db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3182db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3183db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3184c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3185db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3186db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
31872d747510SLisandro Dalcin @*/
3188d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3189d71ae5a4SJacob Faibussowitsch {
31902d747510SLisandro Dalcin   const char *svalue;
3191ce78bad3SBarry Smith   const char *value;
31922d747510SLisandro Dalcin   PetscInt    n = 0;
31932d747510SLisandro Dalcin   PetscBool   flag;
31942d747510SLisandro Dalcin   PetscToken  token;
31952d747510SLisandro Dalcin 
31962d747510SLisandro Dalcin   PetscFunctionBegin;
31974f572ea9SToby Isaac   PetscAssertPointer(name, 3);
31984f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
31994f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
32002d747510SLisandro Dalcin 
32019566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
32029371c9d4SSatish Balay   if (!flag || !svalue) {
32039371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
32049371c9d4SSatish Balay     *nmax = 0;
32053ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
32069371c9d4SSatish Balay   }
32072d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
32089566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
32099566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
32102d747510SLisandro Dalcin   while (value && n < *nmax) {
32119566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value, dvalue++));
32129566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
32132d747510SLisandro Dalcin     n++;
32142d747510SLisandro Dalcin   }
32159566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
32162d747510SLisandro Dalcin   *nmax = n;
32173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32182d747510SLisandro Dalcin }
321914ce751eSBarry Smith 
3220e5c89e4eSSatish Balay /*@C
3221e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
3222f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
3223e5c89e4eSSatish Balay 
3224cf53795eSBarry Smith   Not Collective; No Fortran Support
3225e5c89e4eSSatish Balay 
3226e5c89e4eSSatish Balay   Input Parameters:
322720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
322820f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
32296b867d5aSJose E. Roman - name    - the option one is seeking
32306b867d5aSJose E. Roman 
3231e7b76fa7SPatrick Sanan   Output Parameters:
3232e5c89e4eSSatish Balay + strings - location to copy strings
3233f1a722f8SMatthew G. Knepley . nmax    - On input maximum number of strings, on output the actual number of strings found
3234811af0c4SBarry Smith - set     - `PETSC_TRUE` if found, else `PETSC_FALSE`
3235e5c89e4eSSatish Balay 
3236e5c89e4eSSatish Balay   Level: beginner
3237e5c89e4eSSatish Balay 
3238e5c89e4eSSatish Balay   Notes:
32399314d9b7SBarry Smith   The `nmax` parameter is used for both input and output.
3240e7b76fa7SPatrick Sanan 
3241ce78bad3SBarry Smith   The user should pass in an array of pointers to `char`, to hold all the
3242e5c89e4eSSatish Balay   strings returned by this function.
3243e5c89e4eSSatish Balay 
3244e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3245cf53795eSBarry Smith   returned.
3246e5c89e4eSSatish Balay 
3247db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3248db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3249db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3250c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3251db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3252db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3253e5c89e4eSSatish Balay @*/
3254ce78bad3SBarry Smith PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set) PeNS
3255d71ae5a4SJacob Faibussowitsch {
32562d747510SLisandro Dalcin   const char *svalue;
3257ce78bad3SBarry Smith   const char *value;
32582d747510SLisandro Dalcin   PetscInt    n = 0;
3259ace3abfcSBarry Smith   PetscBool   flag;
32609c9d3cfdSBarry Smith   PetscToken  token;
3261e5c89e4eSSatish Balay 
3262e5c89e4eSSatish Balay   PetscFunctionBegin;
32634f572ea9SToby Isaac   PetscAssertPointer(name, 3);
32644f572ea9SToby Isaac   PetscAssertPointer(strings, 4);
32654f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
3266e5c89e4eSSatish Balay 
32679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
32689371c9d4SSatish Balay   if (!flag || !svalue) {
32699371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
32709371c9d4SSatish Balay     *nmax = 0;
32713ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
32729371c9d4SSatish Balay   }
32732d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
32749566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
32759566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
32762d747510SLisandro Dalcin   while (value && n < *nmax) {
32779566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
32789566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3279e5c89e4eSSatish Balay     n++;
3280e5c89e4eSSatish Balay   }
32819566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3282e5c89e4eSSatish Balay   *nmax = n;
32833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3284e5c89e4eSSatish Balay }
328506824ed3SPatrick Sanan 
328606824ed3SPatrick Sanan /*@C
3287aec76313SJacob Faibussowitsch   PetscOptionsDeprecated_Private - mark an option as deprecated, optionally replacing it with `newname`
328806824ed3SPatrick Sanan 
328906824ed3SPatrick Sanan   Prints a deprecation warning, unless an option is supplied to suppress.
329006824ed3SPatrick Sanan 
32911c9f3c13SBarry Smith   Logically Collective
329206824ed3SPatrick Sanan 
329306824ed3SPatrick Sanan   Input Parameters:
3294aec76313SJacob Faibussowitsch + PetscOptionsObject - string to prepend to name or `NULL`
329506824ed3SPatrick Sanan . oldname            - the old, deprecated option
329620f4b53cSBarry Smith . newname            - the new option, or `NULL` if option is purely removed
32979f3a6782SPatrick Sanan . version            - a string describing the version of first deprecation, e.g. "3.9"
329820f4b53cSBarry Smith - info               - additional information string, or `NULL`.
329906824ed3SPatrick Sanan 
3300811af0c4SBarry Smith   Options Database Key:
330106824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
330206824ed3SPatrick Sanan 
330320f4b53cSBarry Smith   Level: developer
330420f4b53cSBarry Smith 
330506824ed3SPatrick Sanan   Notes:
33064ead3382SBarry Smith   If `newname` is provided then the options database will automatically check the database for `oldname`.
33074ead3382SBarry Smith 
33084ead3382SBarry Smith   The old call `PetscOptionsXXX`(`oldname`) should be removed from the source code when both (1) the call to `PetscOptionsDeprecated()` occurs before the
33094ead3382SBarry Smith   new call to `PetscOptionsXXX`(`newname`) and (2) the argument handling of the new call to `PetscOptionsXXX`(`newname`) is identical to the previous call.
33104ead3382SBarry Smith   See `PTScotch_PartGraph_Seq()` for an example of when (1) fails and `SNESTestJacobian()` where an example of (2) fails.
33114ead3382SBarry Smith 
3312811af0c4SBarry Smith   Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
331335cb6cd3SPierre Jolivet   Only the process of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3314811af0c4SBarry Smith   `PetscObjectOptionsBegin()` prints the information
3315b40114eaSPatrick Sanan   If newname is provided, the old option is replaced. Otherwise, it remains
3316b40114eaSPatrick Sanan   in the options database.
33179f3a6782SPatrick Sanan   If an option is not replaced, the info argument should be used to advise the user
33189f3a6782SPatrick Sanan   on how to proceed.
33199f3a6782SPatrick Sanan   There is a limit on the length of the warning printed, so very long strings
33209f3a6782SPatrick Sanan   provided as info may be truncated.
332106824ed3SPatrick Sanan 
3322db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
332306824ed3SPatrick Sanan @*/
3324ce78bad3SBarry Smith PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3325d71ae5a4SJacob Faibussowitsch {
332606824ed3SPatrick Sanan   PetscBool         found, quiet;
332706824ed3SPatrick Sanan   const char       *value;
332806824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
33299f3a6782SPatrick Sanan   char              msg[4096];
3330b0bdc838SStefano Zampini   char             *prefix  = NULL;
3331b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3332b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
333306824ed3SPatrick Sanan 
333406824ed3SPatrick Sanan   PetscFunctionBegin;
33354f572ea9SToby Isaac   PetscAssertPointer(oldname, 2);
33364f572ea9SToby Isaac   PetscAssertPointer(version, 4);
3337b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3338b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3339b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3340b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3341b0bdc838SStefano Zampini   }
33429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
334306824ed3SPatrick Sanan   if (found) {
334406824ed3SPatrick Sanan     if (newname) {
33455669f5d8SStefano Zampini       PetscBool newfound;
33465669f5d8SStefano Zampini 
33475669f5d8SStefano Zampini       /* do not overwrite if the new option has been provided */
33485669f5d8SStefano Zampini       PetscCall(PetscOptionsFindPair(options, prefix, newname, NULL, &newfound));
33495669f5d8SStefano Zampini       if (!newfound) {
33501baa6e33SBarry Smith         if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
33519566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options, newname, value));
33521baa6e33SBarry Smith         if (prefix) PetscCall(PetscOptionsPrefixPop(options));
33535669f5d8SStefano Zampini       }
33549566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3355b40114eaSPatrick Sanan     }
335606824ed3SPatrick Sanan     quiet = PETSC_FALSE;
33579566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
335806824ed3SPatrick Sanan     if (!quiet) {
3359b82c1cbeSPierre Jolivet       PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option -", sizeof(msg)));
3360b82c1cbeSPierre Jolivet       PetscCall(PetscStrlcat(msg, prefix, sizeof(msg)));
3361b82c1cbeSPierre Jolivet       PetscCall(PetscStrlcat(msg, oldname + 1, sizeof(msg)));
3362c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3363c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
33644bd3d7f8SBarry Smith       PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
336506824ed3SPatrick Sanan       if (newname) {
3366b82c1cbeSPierre Jolivet         PetscCall(PetscStrlcat(msg, "   Use the option -", sizeof(msg)));
3367b82c1cbeSPierre Jolivet         PetscCall(PetscStrlcat(msg, prefix, sizeof(msg)));
3368b82c1cbeSPierre Jolivet         PetscCall(PetscStrlcat(msg, newname + 1, sizeof(msg)));
3369c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
337006824ed3SPatrick Sanan       }
33719f3a6782SPatrick Sanan       if (info) {
3372c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3373c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
33749f3a6782SPatrick Sanan       }
3375c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3376c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3377c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
33789566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
337906824ed3SPatrick Sanan     }
338006824ed3SPatrick Sanan   }
33813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
338206824ed3SPatrick Sanan }
3383