xref: /petsc/src/sys/objects/options.c (revision 7255af2bd2331935c12adb05db5efab3771c4d24)
173fca5a0SBarry Smith /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
20039db0dSBarry Smith #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for atoll() */
3e5ea902fSJed Brown 
4e5c89e4eSSatish Balay /*
53fc1eb6aSBarry Smith    These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
63fc1eb6aSBarry Smith    This provides the low-level interface, the high level interface is in aoptions.c
7e5c89e4eSSatish Balay 
83fc1eb6aSBarry Smith    Some routines use regular malloc and free because it cannot know  what malloc is requested with the
93fc1eb6aSBarry Smith    options database until it has already processed the input.
10e5c89e4eSSatish Balay */
11e5c89e4eSSatish Balay 
12af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I  "petscsys.h"   I*/
13665c2dedSJed Brown #include <petscviewer.h>
14ad1ac5ecSJed Brown #include <ctype.h>
15e5c89e4eSSatish Balay #if defined(PETSC_HAVE_MALLOC_H)
16e5c89e4eSSatish Balay   #include <malloc.h>
17e5c89e4eSSatish Balay #endif
18ef279fd6SBarry Smith #if defined(PETSC_HAVE_STRINGS_H)
19ef279fd6SBarry Smith   #include <strings.h> /* strcasecmp */
20ef279fd6SBarry Smith #endif
21e5c89e4eSSatish Balay 
222d747510SLisandro Dalcin #if defined(PETSC_HAVE_STRCASECMP)
232d747510SLisandro Dalcin   #define PetscOptNameCmp(a, b) strcasecmp(a, b)
242d747510SLisandro Dalcin #elif defined(PETSC_HAVE_STRICMP)
252d747510SLisandro Dalcin   #define PetscOptNameCmp(a, b) stricmp(a, b)
262d747510SLisandro Dalcin #else
272d747510SLisandro Dalcin   #define PetscOptNameCmp(a, b) Error_strcasecmp_not_found
282d747510SLisandro Dalcin #endif
292d747510SLisandro Dalcin 
302d747510SLisandro Dalcin #include <petsc/private/hashtable.h>
312d747510SLisandro Dalcin 
322d747510SLisandro Dalcin /* This assumes ASCII encoding and ignores locale settings */
332d747510SLisandro Dalcin /* Using tolower() is about 2X slower in microbenchmarks   */
34d71ae5a4SJacob Faibussowitsch static inline int PetscToLower(int c)
35d71ae5a4SJacob Faibussowitsch {
362d747510SLisandro Dalcin   return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
372d747510SLisandro Dalcin }
382d747510SLisandro Dalcin 
392d747510SLisandro Dalcin /* Bob Jenkins's one at a time hash function (case-insensitive) */
40d71ae5a4SJacob Faibussowitsch static inline unsigned int PetscOptHash(const char key[])
41d71ae5a4SJacob Faibussowitsch {
422d747510SLisandro Dalcin   unsigned int hash = 0;
432d747510SLisandro Dalcin   while (*key) {
442d747510SLisandro Dalcin     hash += PetscToLower(*key++);
452d747510SLisandro Dalcin     hash += hash << 10;
462d747510SLisandro Dalcin     hash ^= hash >> 6;
472d747510SLisandro Dalcin   }
482d747510SLisandro Dalcin   hash += hash << 3;
492d747510SLisandro Dalcin   hash ^= hash >> 11;
502d747510SLisandro Dalcin   hash += hash << 15;
512d747510SLisandro Dalcin   return hash;
522d747510SLisandro Dalcin }
532d747510SLisandro Dalcin 
54d71ae5a4SJacob Faibussowitsch static inline int PetscOptEqual(const char a[], const char b[])
55d71ae5a4SJacob Faibussowitsch {
562d747510SLisandro Dalcin   return !PetscOptNameCmp(a, b);
572d747510SLisandro Dalcin }
582d747510SLisandro Dalcin 
592d747510SLisandro Dalcin KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
602d747510SLisandro Dalcin 
6174e0666dSJed Brown #define MAXPREFIXES        25
622d747510SLisandro Dalcin #define MAXOPTIONSMONITORS 5
63e5c89e4eSSatish Balay 
649355ec05SMatthew G. Knepley const char *PetscOptionSources[] = {"code", "command line", "file", "environment"};
659355ec05SMatthew G. Knepley 
669355ec05SMatthew G. Knepley // This table holds all the options set by the user
674416b707SBarry Smith struct _n_PetscOptions {
683de2bfdfSBarry Smith   PetscOptions previous;
699355ec05SMatthew G. Knepley 
702d747510SLisandro Dalcin   int                N;      /* number of options */
719355ec05SMatthew G. Knepley   int                Nalloc; /* number of allocated options */
729355ec05SMatthew G. Knepley   char             **names;  /* option names */
739355ec05SMatthew G. Knepley   char             **values; /* option values */
749355ec05SMatthew G. Knepley   PetscBool         *used;   /* flag option use */
759355ec05SMatthew G. Knepley   PetscOptionSource *source; /* source for option value */
76c5b5d8d5SVaclav Hapla   PetscBool          precedentProcessed;
77081c24baSBoyana Norris 
782d747510SLisandro Dalcin   /* Hash table */
792d747510SLisandro Dalcin   khash_t(HO) *ht;
802d747510SLisandro Dalcin 
812d747510SLisandro Dalcin   /* Prefixes */
822d747510SLisandro Dalcin   int  prefixind;
832d747510SLisandro Dalcin   int  prefixstack[MAXPREFIXES];
849355ec05SMatthew G. Knepley   char prefix[PETSC_MAX_OPTION_NAME];
852d747510SLisandro Dalcin 
862d747510SLisandro Dalcin   /* Aliases */
879355ec05SMatthew G. Knepley   int    Na;       /* number or aliases */
889355ec05SMatthew G. Knepley   int    Naalloc;  /* number of allocated aliases */
899355ec05SMatthew G. Knepley   char **aliases1; /* aliased */
909355ec05SMatthew G. Knepley   char **aliases2; /* aliasee */
912d747510SLisandro Dalcin 
922d747510SLisandro Dalcin   /* Help */
932d747510SLisandro Dalcin   PetscBool help;       /* flag whether "-help" is in the database */
94d314f959SVaclav Hapla   PetscBool help_intro; /* flag whether "-help intro" is in the database */
952d747510SLisandro Dalcin 
962d747510SLisandro Dalcin   /* Monitors */
97c5b5d8d5SVaclav Hapla   PetscBool monitorFromOptions, monitorCancel;
989355ec05SMatthew G. Knepley   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], PetscOptionSource, void *); /* returns control to user after */
999355ec05SMatthew G. Knepley   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void **);                                        /* callback for monitor destruction */
100081c24baSBoyana Norris   void    *monitorcontext[MAXOPTIONSMONITORS];                                                          /* to pass arbitrary user data into monitor */
101081c24baSBoyana Norris   PetscInt numbermonitors;                                                                              /* to, for instance, detect options being set */
1024416b707SBarry Smith };
103e5c89e4eSSatish Balay 
104b4205f0bSBarry Smith static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
1052d747510SLisandro Dalcin 
106aaa8cc7dSPierre Jolivet /* list of options which precede others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
107660278c0SBarry Smith /* these options can only take boolean values, the code will crash if given a non-boolean value */
108660278c0SBarry Smith static const char *precedentOptions[] = {"-petsc_ci", "-options_monitor", "-options_monitor_cancel", "-help", "-skip_petscrc"};
1099371c9d4SSatish Balay enum PetscPrecedentOption {
1109371c9d4SSatish Balay   PO_CI_ENABLE,
1119371c9d4SSatish Balay   PO_OPTIONS_MONITOR,
1129371c9d4SSatish Balay   PO_OPTIONS_MONITOR_CANCEL,
1139371c9d4SSatish Balay   PO_HELP,
1149371c9d4SSatish Balay   PO_SKIP_PETSCRC,
1159371c9d4SSatish Balay   PO_NUM
1169371c9d4SSatish Balay };
117c5b5d8d5SVaclav Hapla 
1189355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsSetValue_Private(PetscOptions, const char[], const char[], int *, PetscOptionSource);
1199355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsInsertStringYAML_Private(PetscOptions, const char[], PetscOptionSource);
120c5b5d8d5SVaclav Hapla 
121081c24baSBoyana Norris /*
122081c24baSBoyana Norris     Options events monitor
123081c24baSBoyana Norris */
1249355ec05SMatthew G. Knepley static PetscErrorCode PetscOptionsMonitor(PetscOptions options, const char name[], const char value[], PetscOptionSource source)
125d71ae5a4SJacob Faibussowitsch {
126e5c89e4eSSatish Balay   PetscFunctionBegin;
1279355ec05SMatthew G. Knepley   if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name, value, source, NULL));
1289355ec05SMatthew G. Knepley   for (PetscInt i = 0; i < options->numbermonitors; i++) PetscCall((*options->monitor[i])(name, value, source, options->monitorcontext[i]));
1293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
130e5c89e4eSSatish Balay }
131e5c89e4eSSatish Balay 
1322d747510SLisandro Dalcin /*@
1332d747510SLisandro Dalcin   PetscOptionsCreate - Creates an empty options database.
134e5c89e4eSSatish Balay 
13520f4b53cSBarry Smith   Logically Collective
1361c9f3c13SBarry Smith 
137e5c89e4eSSatish Balay   Output Parameter:
1382d747510SLisandro Dalcin . options - Options database object
139e5c89e4eSSatish Balay 
140e5c89e4eSSatish Balay   Level: advanced
141e5c89e4eSSatish Balay 
142811af0c4SBarry Smith   Note:
143811af0c4SBarry Smith   Though PETSc has a concept of multiple options database the current code uses a single default `PetscOptions` object
144811af0c4SBarry Smith 
145811af0c4SBarry Smith   Developer Notes:
146811af0c4SBarry Smith   We may want eventually to pass a `MPI_Comm` to determine the ownership of the object
147811af0c4SBarry Smith 
148811af0c4SBarry Smith   This object never got developed after being introduced, it is not clear that supporting multiple `PetscOptions` objects is useful
1491c9f3c13SBarry Smith 
150db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
151e5c89e4eSSatish Balay @*/
152d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreate(PetscOptions *options)
153d71ae5a4SJacob Faibussowitsch {
15439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1554f572ea9SToby Isaac   PetscAssertPointer(options, 1);
1562d747510SLisandro Dalcin   *options = (PetscOptions)calloc(1, sizeof(**options));
15739a651e2SJacob Faibussowitsch   PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
1583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1592d747510SLisandro Dalcin }
1602d747510SLisandro Dalcin 
1612d747510SLisandro Dalcin /*@
1622d747510SLisandro Dalcin   PetscOptionsDestroy - Destroys an option database.
1632d747510SLisandro Dalcin 
16420f4b53cSBarry Smith   Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
1651c9f3c13SBarry Smith 
1662d747510SLisandro Dalcin   Input Parameter:
167811af0c4SBarry Smith . options - the `PetscOptions` object
1682d747510SLisandro Dalcin 
1693de2bfdfSBarry Smith   Level: advanced
1702d747510SLisandro Dalcin 
171aec76313SJacob Faibussowitsch .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsSetValue()`
1722d747510SLisandro Dalcin @*/
173d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
174d71ae5a4SJacob Faibussowitsch {
175362febeeSStefano Zampini   PetscFunctionBegin;
1764f572ea9SToby Isaac   PetscAssertPointer(options, 1);
1773ba16761SJacob Faibussowitsch   if (!*options) PetscFunctionReturn(PETSC_SUCCESS);
1785f80ce2aSJacob Faibussowitsch   PetscCheck(!(*options)->previous, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "You are destroying an option that has been used with PetscOptionsPush() but does not have a corresponding PetscOptionsPop()");
1799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsClear(*options));
1802d747510SLisandro Dalcin   /* XXX what about monitors ? */
1812800570dSLisandro Dalcin   free(*options);
1822d747510SLisandro Dalcin   *options = NULL;
1833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
184e5c89e4eSSatish Balay }
185e5c89e4eSSatish Balay 
1862d747510SLisandro Dalcin /*
1872d747510SLisandro Dalcin     PetscOptionsCreateDefault - Creates the default global options database
1882d747510SLisandro Dalcin */
189d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreateDefault(void)
190d71ae5a4SJacob Faibussowitsch {
19139a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1929566063dSJacob Faibussowitsch   if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
1933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1942d747510SLisandro Dalcin }
1952d747510SLisandro Dalcin 
196b4205f0bSBarry Smith /*@
197811af0c4SBarry Smith   PetscOptionsPush - Push a new `PetscOptions` object as the default provider of options
1981c9f3c13SBarry Smith   Allows using different parts of a code to use different options databases
199b4205f0bSBarry Smith 
200b4205f0bSBarry Smith   Logically Collective
201b4205f0bSBarry Smith 
202b4205f0bSBarry Smith   Input Parameter:
203811af0c4SBarry Smith . opt - the options obtained with `PetscOptionsCreate()`
204b4205f0bSBarry Smith 
20520f4b53cSBarry Smith   Level: advanced
20620f4b53cSBarry Smith 
207b4205f0bSBarry Smith   Notes:
208811af0c4SBarry Smith   Use `PetscOptionsPop()` to return to the previous default options database
2091c9f3c13SBarry Smith 
210811af0c4SBarry Smith   The collectivity of this routine is complex; only the MPI ranks that call this routine will
2111c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
2121c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
2131c9f3c13SBarry Smith   on different ranks.
214b4205f0bSBarry Smith 
215aec76313SJacob Faibussowitsch   Developer Notes:
216811af0c4SBarry Smith   Though this functionality has been provided it has never been used in PETSc and might be removed.
217811af0c4SBarry Smith 
218db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
219b4205f0bSBarry Smith @*/
220d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPush(PetscOptions opt)
221d71ae5a4SJacob Faibussowitsch {
222b4205f0bSBarry Smith   PetscFunctionBegin;
2239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsCreateDefault());
224b4205f0bSBarry Smith   opt->previous  = defaultoptions;
225b4205f0bSBarry Smith   defaultoptions = opt;
2263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
227b4205f0bSBarry Smith }
228b4205f0bSBarry Smith 
229b4205f0bSBarry Smith /*@
230811af0c4SBarry Smith   PetscOptionsPop - Pop the most recent `PetscOptionsPush()` to return to the previous default options
231b4205f0bSBarry Smith 
23220f4b53cSBarry Smith   Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
233b4205f0bSBarry Smith 
2343de2bfdfSBarry Smith   Level: advanced
2353de2bfdfSBarry Smith 
23642747ad1SJacob Faibussowitsch .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
237b4205f0bSBarry Smith @*/
238d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPop(void)
239d71ae5a4SJacob Faibussowitsch {
2403de2bfdfSBarry Smith   PetscOptions current = defaultoptions;
2413de2bfdfSBarry Smith 
242b4205f0bSBarry Smith   PetscFunctionBegin;
24328b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing default options");
24428b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions->previous, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscOptionsPop() called too many times");
245b4205f0bSBarry Smith   defaultoptions    = defaultoptions->previous;
2463de2bfdfSBarry Smith   current->previous = NULL;
2473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
248b4205f0bSBarry Smith }
249b4205f0bSBarry Smith 
2502d747510SLisandro Dalcin /*
2512d747510SLisandro Dalcin     PetscOptionsDestroyDefault - Destroys the default global options database
2522d747510SLisandro Dalcin */
253d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroyDefault(void)
254d71ae5a4SJacob Faibussowitsch {
25539a651e2SJacob Faibussowitsch   PetscFunctionBegin;
2563ba16761SJacob Faibussowitsch   if (!defaultoptions) PetscFunctionReturn(PETSC_SUCCESS);
2573de2bfdfSBarry Smith   /* Destroy any options that the user forgot to pop */
2583de2bfdfSBarry Smith   while (defaultoptions->previous) {
25939a651e2SJacob Faibussowitsch     PetscOptions tmp = defaultoptions;
26039a651e2SJacob Faibussowitsch 
2619566063dSJacob Faibussowitsch     PetscCall(PetscOptionsPop());
2629566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDestroy(&tmp));
2633de2bfdfSBarry Smith   }
2649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDestroy(&defaultoptions));
2653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
266e5c89e4eSSatish Balay }
267e5c89e4eSSatish Balay 
268cc4c1da9SBarry Smith /*@
2697cd08cecSJed Brown   PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
2703fc1eb6aSBarry Smith 
27120f4b53cSBarry Smith   Not Collective
2721c9f3c13SBarry Smith 
2733fc1eb6aSBarry Smith   Input Parameter:
2742d747510SLisandro Dalcin . key - string to check if valid
2753fc1eb6aSBarry Smith 
2763fc1eb6aSBarry Smith   Output Parameter:
277811af0c4SBarry Smith . valid - `PETSC_TRUE` if a valid key
2783fc1eb6aSBarry Smith 
279f6680f47SSatish Balay   Level: intermediate
28010450e9eSJacob Faibussowitsch 
28110450e9eSJacob Faibussowitsch .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`
2823fc1eb6aSBarry Smith @*/
283d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid)
284d71ae5a4SJacob Faibussowitsch {
285f603b5e9SToby Isaac   char               *ptr;
28627304958SStefano Zampini   PETSC_UNUSED double d;
2877c5db45bSBarry Smith 
28896fc60bcSBarry Smith   PetscFunctionBegin;
2894f572ea9SToby Isaac   if (key) PetscAssertPointer(key, 1);
2904f572ea9SToby Isaac   PetscAssertPointer(valid, 2);
2912d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2923ba16761SJacob Faibussowitsch   if (!key) PetscFunctionReturn(PETSC_SUCCESS);
2933ba16761SJacob Faibussowitsch   if (key[0] != '-') PetscFunctionReturn(PETSC_SUCCESS);
2942d747510SLisandro Dalcin   if (key[1] == '-') key++;
2953ba16761SJacob Faibussowitsch   if (!isalpha((int)key[1])) PetscFunctionReturn(PETSC_SUCCESS);
29627304958SStefano Zampini   d = strtod(key, &ptr);
2973ba16761SJacob Faibussowitsch   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(PETSC_SUCCESS);
2982d747510SLisandro Dalcin   *valid = PETSC_TRUE;
2993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30096fc60bcSBarry Smith }
30196fc60bcSBarry Smith 
30210c654e6SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertString_Private(PetscOptions options, const char in_str[], PetscOptionSource source)
303d71ae5a4SJacob Faibussowitsch {
304d06005cbSLisandro Dalcin   char      *first, *second;
3059c9d3cfdSBarry Smith   PetscToken token;
306e5c89e4eSSatish Balay 
307e5c89e4eSSatish Balay   PetscFunctionBegin;
3089566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(in_str, ' ', &token));
3099566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &first));
31096fc60bcSBarry Smith   while (first) {
311d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
31210c654e6SJacob Faibussowitsch 
3139566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
3149566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
3159566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
3169566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
3179566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
3189566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(first, &key));
319d06005cbSLisandro Dalcin     if (!key) {
3209566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
321d06005cbSLisandro Dalcin     } else if (isfile) {
3229566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
32310c654e6SJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(PETSC_COMM_SELF, options, second, PETSC_TRUE));
3249566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
325d06005cbSLisandro Dalcin     } else if (isfileyaml) {
3269566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
32710c654e6SJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(PETSC_COMM_SELF, options, second, PETSC_TRUE));
3289566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
329d06005cbSLisandro Dalcin     } else if (isstringyaml) {
3309566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3319355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, second, source));
3329566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
333d06005cbSLisandro Dalcin     } else if (ispush) {
3349566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3359566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, second));
3369566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
3379db968c8SJed Brown     } else if (ispop) {
3389566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
3399566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
340d06005cbSLisandro Dalcin     } else {
3419566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3429566063dSJacob Faibussowitsch       PetscCall(PetscOptionsValidKey(second, &key));
34396fc60bcSBarry Smith       if (!key) {
3449355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, second, NULL, source));
3459566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &first));
34696fc60bcSBarry Smith       } else {
3479355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, NULL, NULL, source));
34896fc60bcSBarry Smith         first = second;
34996fc60bcSBarry Smith       }
350e5c89e4eSSatish Balay     }
351e5c89e4eSSatish Balay   }
3529566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
354e5c89e4eSSatish Balay }
355e5c89e4eSSatish Balay 
3565d83a8b1SBarry Smith /*@
3579355ec05SMatthew G. Knepley   PetscOptionsInsertString - Inserts options into the database from a string
3589355ec05SMatthew G. Knepley 
3599355ec05SMatthew G. Knepley   Logically Collective
3609355ec05SMatthew G. Knepley 
3619355ec05SMatthew G. Knepley   Input Parameters:
3629355ec05SMatthew G. Knepley + options - options object
3639355ec05SMatthew G. Knepley - in_str  - string that contains options separated by blanks
3649355ec05SMatthew G. Knepley 
3659355ec05SMatthew G. Knepley   Level: intermediate
3669355ec05SMatthew G. Knepley 
36720f4b53cSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
3689355ec05SMatthew G. Knepley   have the affect of these options. If some processes that create objects call this routine and others do
3699355ec05SMatthew G. Knepley   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
3709355ec05SMatthew G. Knepley   on different ranks.
3719355ec05SMatthew G. Knepley 
3729355ec05SMatthew G. Knepley    Contributed by Boyana Norris
3739355ec05SMatthew G. Knepley 
3749355ec05SMatthew G. Knepley .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
3759355ec05SMatthew G. Knepley           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3769355ec05SMatthew G. Knepley           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3779355ec05SMatthew G. Knepley           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3789355ec05SMatthew G. Knepley           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3799355ec05SMatthew G. Knepley           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
3809355ec05SMatthew G. Knepley @*/
3819355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[])
3829355ec05SMatthew G. Knepley {
3839355ec05SMatthew G. Knepley   PetscFunctionBegin;
3849355ec05SMatthew G. Knepley   PetscCall(PetscOptionsInsertString_Private(options, in_str, PETSC_OPT_CODE));
3853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3869355ec05SMatthew G. Knepley }
3879355ec05SMatthew G. Knepley 
3883fc1eb6aSBarry Smith /*
3893fc1eb6aSBarry Smith     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
3903fc1eb6aSBarry Smith */
391d71ae5a4SJacob Faibussowitsch static char *Petscgetline(FILE *f)
392d71ae5a4SJacob Faibussowitsch {
3935fa91da5SBarry Smith   size_t size = 0;
3945fa91da5SBarry Smith   size_t len  = 0;
3955fa91da5SBarry Smith   size_t last = 0;
3960298fd71SBarry Smith   char  *buf  = NULL;
3975fa91da5SBarry Smith 
39802c9f0b5SLisandro Dalcin   if (feof(f)) return NULL;
3995fa91da5SBarry Smith   do {
4005fa91da5SBarry Smith     size += 1024;                             /* BUFSIZ is defined as "the optimal read size for this platform" */
4016e0c8459SSatish Balay     buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
4025fa91da5SBarry Smith     /* Actually do the read. Note that fgets puts a terminal '\0' on the
4035fa91da5SBarry Smith     end of the string, so we make sure we overwrite this */
404e86f3e45SDave May     if (!fgets(buf + len, 1024, f)) buf[len] = 0;
4053ba16761SJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, PetscStrlen(buf, &len));
4065fa91da5SBarry Smith     last = len - 1;
4075fa91da5SBarry Smith   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
40808ac41f7SSatish Balay   if (len) return buf;
4095fa91da5SBarry Smith   free(buf);
41002c9f0b5SLisandro Dalcin   return NULL;
4115fa91da5SBarry Smith }
4125fa91da5SBarry Smith 
413d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml)
414d71ae5a4SJacob Faibussowitsch {
415be10d61cSLisandro Dalcin   char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
416e5c89e4eSSatish Balay 
417be10d61cSLisandro Dalcin   PetscFunctionBegin;
418362febeeSStefano Zampini   *yaml = PETSC_FALSE;
4199566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
4209566063dSJacob Faibussowitsch   PetscCall(PetscFixFilename(fname, path));
4219566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(path, ":yaml", yaml));
422be10d61cSLisandro Dalcin   if (*yaml) {
4239566063dSJacob Faibussowitsch     PetscCall(PetscStrrchr(path, ':', &tail));
424be10d61cSLisandro Dalcin     tail[-1] = 0; /* remove ":yaml" suffix from path */
425be10d61cSLisandro Dalcin   }
4269566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
427a1d2f846SLisandro Dalcin   /* check for standard YAML and JSON filename extensions */
4289566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
4299566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
4309566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
431a1d2f846SLisandro Dalcin   if (!*yaml) { /* check file contents */
432a1d2f846SLisandro Dalcin     PetscMPIInt rank;
4339566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
434dd400576SPatrick Sanan     if (rank == 0) {
435a1d2f846SLisandro Dalcin       FILE *fh = fopen(filename, "r");
436a1d2f846SLisandro Dalcin       if (fh) {
437a1d2f846SLisandro Dalcin         char buf[6] = "";
438a1d2f846SLisandro Dalcin         if (fread(buf, 1, 6, fh) > 0) {
4399566063dSJacob Faibussowitsch           PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml));          /* check for '%YAML' tag */
4409566063dSJacob Faibussowitsch           if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
441a1d2f846SLisandro Dalcin         }
442a1d2f846SLisandro Dalcin         (void)fclose(fh);
443a1d2f846SLisandro Dalcin       }
444a1d2f846SLisandro Dalcin     }
4459566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(yaml, 1, MPIU_BOOL, 0, comm));
446a1d2f846SLisandro Dalcin   }
4473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
448be10d61cSLisandro Dalcin }
449e5c89e4eSSatish Balay 
450d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
451d71ae5a4SJacob Faibussowitsch {
4528c0b561eSLisandro Dalcin   char       *string, *vstring = NULL, *astring = NULL, *packed = NULL;
4537fb43599SVaclav Hapla   char       *tokens[4];
454dd460d27SBarry Smith   PetscCount  bytes;
4556497c311SBarry Smith   size_t      len;
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 
472*7255af2bSBarry Smith     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fname, sizeof(fname)));
473*7255af2bSBarry Smith     PetscCall(PetscFixFilename(fname, fpath));
474*7255af2bSBarry 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;
4819566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4829566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4833a018368SJed Brown 
4849b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4859566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
486e24ecc5dSJed Brown 
4875fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4884704e885SBarry Smith         /* eliminate comments from each line */
4899566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
49090f79514SSatish Balay         if (cmatch) *cmatch = 0;
4919566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4925981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
493dd460d27SBarry Smith         for (size_t i = 0; i < len; i++) {
494ad540459SPierre Jolivet           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
495e5c89e4eSSatish Balay         }
4969566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4979566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4987fb43599SVaclav Hapla         if (!tokens[0]) {
49902b0d46eSSatish Balay           goto destroy;
5007fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
5019566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
50290f79514SSatish Balay         }
503dd460d27SBarry Smith         for (PetscInt i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
5047fb43599SVaclav Hapla         if (!tokens[0]) {
5052662f744SSatish Balay           goto destroy;
5067fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
5079566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
50828b400f6SJacob 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]);
5099566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
5109566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
5119566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
512e24ecc5dSJed Brown           vstring[len] = ' ';
5137fb43599SVaclav Hapla           if (tokens[1]) {
5149566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
51528b400f6SJacob 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]);
5169566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5179566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
518e24ecc5dSJed Brown             vstring[0] = '"';
5199566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
520e24ecc5dSJed Brown             vstring[len + 1] = '"';
521e24ecc5dSJed Brown             vstring[len + 2] = ' ';
52209192fe3SBarry Smith           }
52390f79514SSatish Balay         } else {
5249566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
5259210b8eaSVaclav Hapla           if (alias) {
5269566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
52728b400f6SJacob 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]);
52808401ef6SPierre 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]);
5299566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
53028b400f6SJacob 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]);
5319566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5329566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5339566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
534e24ecc5dSJed Brown             astring[len] = ' ';
535e24ecc5dSJed Brown 
5369566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5379566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5389566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
539e24ecc5dSJed Brown             astring[len] = ' ';
54098921bdaSJacob 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]);
5419210b8eaSVaclav Hapla         }
5429210b8eaSVaclav Hapla         {
5439210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
54428b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
545e5c89e4eSSatish Balay         }
54602b0d46eSSatish Balay       destroy:
5474b40f50bSBarry Smith         free(string);
5489566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5499210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5509210b8eaSVaclav Hapla         line++;
551e5c89e4eSSatish Balay       }
552ed9cf6e9SBarry Smith       err = fclose(fd);
55328b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5549566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5559566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5569566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
557e24ecc5dSJed Brown       astring[0] = 0;
5589566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5599566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5609566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
561e24ecc5dSJed Brown       vstring[0] = 0;
5629566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5639566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5649566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5659566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5669566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
56728b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5689b754dc9SBarry Smith   }
56905c7dedfSBarry Smith 
5703a018368SJed Brown   counts[0] = acnt;
5713a018368SJed Brown   counts[1] = cnt;
5724201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
57328b400f6SJacob 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/");
5743a018368SJed Brown   acnt = counts[0];
5753a018368SJed Brown   cnt  = counts[1];
57648a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5773a018368SJed Brown   if (acnt || cnt) {
5789566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5793a018368SJed Brown     astring = packed;
5803a018368SJed Brown     vstring = packed + acnt + 1;
5813a018368SJed Brown   }
5823a018368SJed Brown 
5839b754dc9SBarry Smith   if (acnt) {
5849566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5859566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5867fb43599SVaclav Hapla     while (tokens[0]) {
5879566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5889566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5899566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5909b754dc9SBarry Smith     }
5919566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5929b754dc9SBarry Smith   }
5939b754dc9SBarry Smith 
5949355ec05SMatthew G. Knepley   if (cnt) PetscCall(PetscOptionsInsertString_Private(options, vstring, PETSC_OPT_FILE));
5959566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
5963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
597e5c89e4eSSatish Balay }
598e5c89e4eSSatish Balay 
5995d83a8b1SBarry Smith /*@
600be10d61cSLisandro Dalcin   PetscOptionsInsertFile - Inserts options into the database from a file.
601be10d61cSLisandro Dalcin 
602be10d61cSLisandro Dalcin   Collective
603be10d61cSLisandro Dalcin 
604d8d19677SJose E. Roman   Input Parameters:
605811af0c4SBarry Smith + comm    - the processes that will share the options (usually `PETSC_COMM_WORLD`)
60620f4b53cSBarry Smith . options - options database, use `NULL` for default global database
607be10d61cSLisandro Dalcin . file    - name of file,
608be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
609be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
610811af0c4SBarry Smith - require - if `PETSC_TRUE` will generate an error if the file does not exist
611be10d61cSLisandro Dalcin 
61220f4b53cSBarry Smith   Level: developer
61320f4b53cSBarry Smith 
614be10d61cSLisandro Dalcin   Notes:
615be10d61cSLisandro Dalcin   Use  # for lines that are comments and which should be ignored.
616811af0c4SBarry Smith   Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
61721532e8aSBarry 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
61821532e8aSBarry Smith   calls to `XXXSetFromOptions()`, it should not be used for options listed under PetscInitialize().
61921532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes in comm will
62021532e8aSBarry Smith   have the effect of these options. If some processes that create objects call this routine and others do
621be10d61cSLisandro Dalcin   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
622be10d61cSLisandro Dalcin   on different ranks.
623be10d61cSLisandro Dalcin 
624db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
625db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
626db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
627c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
628db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
629db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
630be10d61cSLisandro Dalcin @*/
631d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
632d71ae5a4SJacob Faibussowitsch {
633be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
634be10d61cSLisandro Dalcin   PetscBool yaml;
635be10d61cSLisandro Dalcin 
636be10d61cSLisandro Dalcin   PetscFunctionBegin;
6379566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
638be10d61cSLisandro Dalcin   if (yaml) {
6399566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
640be10d61cSLisandro Dalcin   } else {
6419566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
642be10d61cSLisandro Dalcin   }
6433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
644be10d61cSLisandro Dalcin }
645be10d61cSLisandro Dalcin 
646be10d61cSLisandro Dalcin /*@C
647d06005cbSLisandro Dalcin   PetscOptionsInsertArgs - Inserts options into the database from a array of strings
648d06005cbSLisandro Dalcin 
649d06005cbSLisandro Dalcin   Logically Collective
650d06005cbSLisandro Dalcin 
651d8d19677SJose E. Roman   Input Parameters:
652d06005cbSLisandro Dalcin + options - options object
6536aad120cSJose E. Roman . argc    - the array length
654d06005cbSLisandro Dalcin - args    - the string array
655d06005cbSLisandro Dalcin 
656d06005cbSLisandro Dalcin   Level: intermediate
657d06005cbSLisandro Dalcin 
658db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
659d06005cbSLisandro Dalcin @*/
660d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, char *args[])
661d71ae5a4SJacob Faibussowitsch {
662d06005cbSLisandro Dalcin   MPI_Comm     comm  = PETSC_COMM_WORLD;
663d06005cbSLisandro Dalcin   int          left  = PetscMax(argc, 0);
664d06005cbSLisandro Dalcin   char *const *eargs = args;
66585079163SJed Brown 
66685079163SJed Brown   PetscFunctionBegin;
66785079163SJed Brown   while (left) {
668d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6699566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6709566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6719566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6729566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6739566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6749566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
675093de6efSBarry Smith     if (!key) {
6769371c9d4SSatish Balay       eargs++;
6779371c9d4SSatish Balay       left--;
678d06005cbSLisandro Dalcin     } else if (isfile) {
679cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6809566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6819371c9d4SSatish Balay       eargs += 2;
6829371c9d4SSatish Balay       left -= 2;
683d06005cbSLisandro Dalcin     } else if (isfileyaml) {
684cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6859566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6869371c9d4SSatish Balay       eargs += 2;
6879371c9d4SSatish Balay       left -= 2;
688d06005cbSLisandro Dalcin     } else if (isstringyaml) {
689cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6909355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
6919371c9d4SSatish Balay       eargs += 2;
6929371c9d4SSatish Balay       left -= 2;
693d06005cbSLisandro Dalcin     } else if (ispush) {
69408401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
695cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6969566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6979371c9d4SSatish Balay       eargs += 2;
6989371c9d4SSatish Balay       left -= 2;
699d06005cbSLisandro Dalcin     } else if (ispop) {
7009566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
7019371c9d4SSatish Balay       eargs++;
7029371c9d4SSatish Balay       left--;
7037935c3d8SJed Brown     } else {
7047935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
7059566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
70698b6bf53SJed Brown       if (left < 2 || nextiskey) {
7079355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
7089371c9d4SSatish Balay         eargs++;
7099371c9d4SSatish Balay         left--;
71085079163SJed Brown       } else {
7119355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
7129371c9d4SSatish Balay         eargs += 2;
7139371c9d4SSatish Balay         left -= 2;
71485079163SJed Brown       }
71585079163SJed Brown     }
7167935c3d8SJed Brown   }
7173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71885079163SJed Brown }
71985079163SJed Brown 
72010c654e6SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], const PetscBool set[], PetscBool *flg)
721d71ae5a4SJacob Faibussowitsch {
722c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
723c5b5d8d5SVaclav Hapla   if (set[opt]) {
7249566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
725c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
7263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
727c5b5d8d5SVaclav Hapla }
728c5b5d8d5SVaclav Hapla 
729660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
730d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
731d71ae5a4SJacob Faibussowitsch {
732c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
733c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
734c5b5d8d5SVaclav Hapla   size_t             o;
735c5b5d8d5SVaclav Hapla   int                a;
736c5b5d8d5SVaclav Hapla   const char       **val;
7370c99d500SBarry Smith   char             **cval;
738660278c0SBarry Smith   PetscBool         *set, unneeded;
739c5b5d8d5SVaclav Hapla 
740c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7410c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7420c99d500SBarry Smith   val = (const char **)cval;
743c5b5d8d5SVaclav Hapla 
744c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
74548a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
746c5b5d8d5SVaclav Hapla 
747a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
748c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
749c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
750c5b5d8d5SVaclav Hapla 
7519566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
752c5b5d8d5SVaclav Hapla     if (!valid) continue;
753c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7549566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
755c5b5d8d5SVaclav Hapla       if (eq) {
756c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
757c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
758c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
759c5b5d8d5SVaclav Hapla         break;
760c5b5d8d5SVaclav Hapla       }
761c5b5d8d5SVaclav Hapla     }
762c5b5d8d5SVaclav Hapla   }
763c5b5d8d5SVaclav Hapla 
764c5b5d8d5SVaclav Hapla   /* Process flags */
7659566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
766d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7679566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
768660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
769660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
7709355ec05SMatthew G. Knepley   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
7719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
774c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
775c5b5d8d5SVaclav Hapla 
776c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
777660278c0SBarry Smith   for (o = 1; o < n; o++) {
778c5b5d8d5SVaclav Hapla     if (set[o]) {
7799355ec05SMatthew G. Knepley       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
780d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
781c5b5d8d5SVaclav Hapla     }
782c5b5d8d5SVaclav Hapla   }
7830c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
784c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
7853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
786c5b5d8d5SVaclav Hapla }
787c5b5d8d5SVaclav Hapla 
788d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
789d71ae5a4SJacob Faibussowitsch {
79039a651e2SJacob Faibussowitsch   PetscFunctionBegin;
7914f572ea9SToby Isaac   PetscAssertPointer(flg, 3);
792c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
793c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
79439a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
795c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
796c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7979566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
798c5b5d8d5SVaclav Hapla         if (*flg) break;
799c5b5d8d5SVaclav Hapla       }
800c5b5d8d5SVaclav Hapla     }
801c5b5d8d5SVaclav Hapla   }
8023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
803c5b5d8d5SVaclav Hapla }
80485079163SJed Brown 
805e5c89e4eSSatish Balay /*@C
806e5c89e4eSSatish Balay   PetscOptionsInsert - Inserts into the options database from the command line,
807e5c89e4eSSatish Balay   the environmental variable and a file.
808e5c89e4eSSatish Balay 
809811af0c4SBarry Smith   Collective on `PETSC_COMM_WORLD`
8101c9f3c13SBarry Smith 
811e5c89e4eSSatish Balay   Input Parameters:
81220f4b53cSBarry Smith + options - options database or `NULL` for the default global database
813c5929fdfSBarry Smith . argc    - count of number of command line arguments
814e5c89e4eSSatish Balay . args    - the command line arguments
815be10d61cSLisandro Dalcin - file    - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
81620f4b53cSBarry Smith           Use `NULL` or empty string to not check for code specific file.
817be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
818c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
819e5c89e4eSSatish Balay 
820081c24baSBoyana Norris   Options Database Keys:
821d06005cbSLisandro Dalcin + -options_file <filename>      - read options from a file
822d06005cbSLisandro Dalcin - -options_file_yaml <filename> - read options from a YAML file
823c5b5d8d5SVaclav Hapla 
82420f4b53cSBarry Smith   Level: advanced
82520f4b53cSBarry Smith 
826811af0c4SBarry Smith   Notes:
82720f4b53cSBarry Smith   Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
828811af0c4SBarry Smith   the user does not typically need to call this routine. `PetscOptionsInsert()`
829811af0c4SBarry Smith   can be called several times, adding additional entries into the database.
830811af0c4SBarry Smith 
831811af0c4SBarry Smith   See `PetscInitialize()` for options related to option database monitoring.
832081c24baSBoyana Norris 
833db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
834db781477SPatrick Sanan           `PetscInitialize()`
835e5c89e4eSSatish Balay @*/
836d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[])
837d71ae5a4SJacob Faibussowitsch {
838d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
839e5c89e4eSSatish Balay   PetscMPIInt rank;
840c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
841c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
8426497c311SBarry Smith   char       *eoptions = NULL;
8436497c311SBarry Smith   size_t      len      = 0;
844e5c89e4eSSatish Balay 
845e5c89e4eSSatish Balay   PetscFunctionBegin;
84608401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8479566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
848e5c89e4eSSatish Balay 
849c5b5d8d5SVaclav Hapla   if (!options) {
8509566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
851c5b5d8d5SVaclav Hapla     options = defaultoptions;
852c5b5d8d5SVaclav Hapla   }
853c5b5d8d5SVaclav Hapla   if (hasArgs) {
854c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8559566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
856660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
857c5b5d8d5SVaclav Hapla   }
8584b09e917SBarry Smith   if (file && file[0]) {
8599566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
860c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8619566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
862321366bcSBarry Smith   }
863c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
864be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8656497c311SBarry Smith 
8669566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8679566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
868c6a7a370SJeremy L Thompson     if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
8699566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8709566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8719566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
872e5c89e4eSSatish Balay   }
873e5c89e4eSSatish Balay 
8742d747510SLisandro Dalcin   /* insert environment options */
875dd400576SPatrick Sanan   if (rank == 0) {
876e5c89e4eSSatish Balay     eoptions = (char *)getenv("PETSC_OPTIONS");
8779566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(eoptions, &len));
878e5c89e4eSSatish Balay   }
8799566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
880e5c89e4eSSatish Balay   if (len) {
8819566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8826497c311SBarry Smith     PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, comm));
88396fc60bcSBarry Smith     if (rank) eoptions[len] = 0;
8849355ec05SMatthew G. Knepley     PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8859566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscFree(eoptions));
886e5c89e4eSSatish Balay   }
887e5c89e4eSSatish Balay 
888d06005cbSLisandro Dalcin   /* insert YAML environment options */
889dd400576SPatrick Sanan   if (rank == 0) {
8909fc438c3SToby Isaac     eoptions = (char *)getenv("PETSC_OPTIONS_YAML");
8919566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(eoptions, &len));
8929fc438c3SToby Isaac   }
8939566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8949fc438c3SToby Isaac   if (len) {
8959566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8966497c311SBarry Smith     PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, comm));
8979fc438c3SToby Isaac     if (rank) eoptions[len] = 0;
8989355ec05SMatthew G. Knepley     PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8999566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscFree(eoptions));
9009fc438c3SToby Isaac   }
9013bcbd388SSean Farley 
902c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
9039566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, *args + 1));
904660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
9053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
906e5c89e4eSSatish Balay }
907e5c89e4eSSatish Balay 
908660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
909660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
910e9a33e21SBarry 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"};
911660278c0SBarry Smith 
912d71ae5a4SJacob Faibussowitsch static PetscBool PetscCIOption(const char *name)
913d71ae5a4SJacob Faibussowitsch {
914660278c0SBarry Smith   PetscInt  idx;
915660278c0SBarry Smith   PetscBool found;
916660278c0SBarry Smith 
917660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
9183ba16761SJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
919660278c0SBarry Smith   return found;
920660278c0SBarry Smith }
921660278c0SBarry Smith 
9225d83a8b1SBarry Smith /*@
92388c29154SBarry Smith   PetscOptionsView - Prints the options that have been loaded. This is
924e5c89e4eSSatish Balay   useful for debugging purposes.
925e5c89e4eSSatish Balay 
926ffeef943SBarry Smith   Logically Collective, No Fortran Support
927e5c89e4eSSatish Balay 
928d8d19677SJose E. Roman   Input Parameters:
92920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
930811af0c4SBarry Smith - viewer  - must be an `PETSCVIEWERASCII` viewer
931e5c89e4eSSatish Balay 
932e5c89e4eSSatish Balay   Options Database Key:
933811af0c4SBarry Smith . -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
934e5c89e4eSSatish Balay 
93520f4b53cSBarry Smith   Level: advanced
93620f4b53cSBarry Smith 
937811af0c4SBarry Smith   Note:
93821532e8aSBarry Smith   Only the MPI rank 0 of the `MPI_Comm` used to create view prints the option values. Other processes
9391c9f3c13SBarry Smith   may have different values but they are not printed.
9401c9f3c13SBarry Smith 
941db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
942e5c89e4eSSatish Balay @*/
943d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
944d71ae5a4SJacob Faibussowitsch {
945660278c0SBarry Smith   PetscInt  i, N = 0;
94688c29154SBarry Smith   PetscBool isascii;
947e5c89e4eSSatish Balay 
948e5c89e4eSSatish Balay   PetscFunctionBegin;
9492d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
950c5929fdfSBarry Smith   options = options ? options : defaultoptions;
95188c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
95328b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
95488c29154SBarry Smith 
955660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
956660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
957660278c0SBarry Smith     N++;
958660278c0SBarry Smith   }
959660278c0SBarry Smith 
960660278c0SBarry Smith   if (!N) {
9619566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9623ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
96330694fe9SBarry Smith   }
9642d747510SLisandro Dalcin 
9659566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
966e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
967660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
968e5c89e4eSSatish Balay     if (options->values[i]) {
9699355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
970e5c89e4eSSatish Balay     } else {
9719355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
972e5c89e4eSSatish Balay     }
9739355ec05SMatthew G. Knepley     PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
974e5c89e4eSSatish Balay   }
9759566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
9763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
977e5c89e4eSSatish Balay }
978e5c89e4eSSatish Balay 
979e11779c2SBarry Smith /*
980e11779c2SBarry Smith    Called by error handlers to print options used in run
981e11779c2SBarry Smith */
982d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftError(void)
983d71ae5a4SJacob Faibussowitsch {
984f4bc716fSBarry Smith   PetscInt i, nopt = 0;
985f4bc716fSBarry Smith 
986f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
987f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
988f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
989f4bc716fSBarry Smith       nopt++;
990f4bc716fSBarry Smith     }
991f4bc716fSBarry Smith   }
992f4bc716fSBarry Smith   if (nopt) {
9937d44c3adSBarry Smith     PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
994f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
995f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
996f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
9973ba16761SJacob 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]]));
9983ba16761SJacob Faibussowitsch         else PetscCall((*PetscErrorPrintf)("  Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
999f4bc716fSBarry Smith       }
1000f4bc716fSBarry Smith     }
1001f4bc716fSBarry Smith   }
10023ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1003f4bc716fSBarry Smith }
1004f4bc716fSBarry Smith 
1005d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1006d71ae5a4SJacob Faibussowitsch {
1007660278c0SBarry Smith   PetscInt     i, N = 0;
10084416b707SBarry Smith   PetscOptions options = defaultoptions;
1009e11779c2SBarry Smith 
1010660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
1011660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1012660278c0SBarry Smith     N++;
1013660278c0SBarry Smith   }
1014660278c0SBarry Smith 
1015660278c0SBarry Smith   if (N) {
10163ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1017e11779c2SBarry Smith   } else {
10183ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1019e11779c2SBarry Smith   }
1020e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1021660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1022e11779c2SBarry Smith     if (options->values[i]) {
10233ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1024e11779c2SBarry Smith     } else {
10253ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1026e11779c2SBarry Smith     }
1027e11779c2SBarry Smith   }
10283ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1029e11779c2SBarry Smith }
1030e11779c2SBarry Smith 
10315d83a8b1SBarry Smith /*@
103274e0666dSJed Brown   PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
103374e0666dSJed Brown 
10341c9f3c13SBarry Smith   Logically Collective
103574e0666dSJed Brown 
1036d8d19677SJose E. Roman   Input Parameters:
103720f4b53cSBarry Smith + options - options database, or `NULL` for the default global database
1038c5929fdfSBarry Smith - prefix  - The string to append to the existing prefix
10399db968c8SJed Brown 
10409db968c8SJed Brown   Options Database Keys:
10419db968c8SJed Brown + -prefix_push <some_prefix_> - push the given prefix
10429db968c8SJed Brown - -prefix_pop                 - pop the last prefix
10439db968c8SJed Brown 
104420f4b53cSBarry Smith   Level: advanced
104520f4b53cSBarry Smith 
10469db968c8SJed Brown   Notes:
104721532e8aSBarry Smith   It is common to use this in conjunction with `-options_file` as in
10489314d9b7SBarry Smith .vb
10499314d9b7SBarry Smith  -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10509314d9b7SBarry Smith .ve
105121532e8aSBarry Smith   where the files no longer require all options to be prefixed with `-system2_`.
105274e0666dSJed Brown 
105321532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
10541c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
10551c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10561c9f3c13SBarry Smith   on different ranks.
10571c9f3c13SBarry Smith 
1058db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
105974e0666dSJed Brown @*/
1060d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1061d71ae5a4SJacob Faibussowitsch {
106274e0666dSJed Brown   size_t    n;
106374e0666dSJed Brown   PetscInt  start;
10649355ec05SMatthew G. Knepley   char      key[PETSC_MAX_OPTION_NAME + 1];
10652d747510SLisandro Dalcin   PetscBool valid;
106674e0666dSJed Brown 
106774e0666dSJed Brown   PetscFunctionBegin;
10684f572ea9SToby Isaac   PetscAssertPointer(prefix, 2);
1069c5929fdfSBarry Smith   options = options ? options : defaultoptions;
107000045ab3SPierre 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);
10712d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10729566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10748bf569ecSLisandro 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 */
107528b400f6SJacob 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" : "");
107674e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10779566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
107808401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10799566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
10806497c311SBarry Smith   options->prefixstack[options->prefixind++] = (int)(start + n);
10813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108274e0666dSJed Brown }
108374e0666dSJed Brown 
10845d83a8b1SBarry Smith /*@
1085811af0c4SBarry Smith   PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
108674e0666dSJed Brown 
1087811af0c4SBarry Smith   Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
108874e0666dSJed Brown 
1089811af0c4SBarry Smith   Input Parameter:
109020f4b53cSBarry Smith . options - options database, or `NULL` for the default global database
1091c5929fdfSBarry Smith 
109274e0666dSJed Brown   Level: advanced
109374e0666dSJed Brown 
1094db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
109574e0666dSJed Brown @*/
1096d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1097d71ae5a4SJacob Faibussowitsch {
109874e0666dSJed Brown   PetscInt offset;
109974e0666dSJed Brown 
110074e0666dSJed Brown   PetscFunctionBegin;
1101c5929fdfSBarry Smith   options = options ? options : defaultoptions;
110208401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
110374e0666dSJed Brown   options->prefixind--;
110474e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
110574e0666dSJed Brown   options->prefix[offset] = 0;
11063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
110774e0666dSJed Brown }
110874e0666dSJed Brown 
11095d83a8b1SBarry Smith /*@
1110a542b6e8SBarry Smith   PetscOptionsClear - Removes all options form the database leaving it empty.
1111a542b6e8SBarry Smith 
11121c9f3c13SBarry Smith   Logically Collective
11131c9f3c13SBarry Smith 
1114811af0c4SBarry Smith   Input Parameter:
111520f4b53cSBarry Smith . options - options database, use `NULL` for the default global database
1116c5929fdfSBarry Smith 
111720f4b53cSBarry Smith   Level: developer
111820f4b53cSBarry Smith 
111920f4b53cSBarry Smith   Note:
112021532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11211c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11221c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11231c9f3c13SBarry Smith   on different ranks.
11241c9f3c13SBarry Smith 
11257e6f8dd6SBarry Smith   Developer Note:
11267e6f8dd6SBarry Smith   Uses `free()` directly because the current option values were set with `malloc()`
11277e6f8dd6SBarry Smith 
1128db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1129a542b6e8SBarry Smith @*/
1130d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClear(PetscOptions options)
1131d71ae5a4SJacob Faibussowitsch {
1132a542b6e8SBarry Smith   PetscInt i;
1133a542b6e8SBarry Smith 
113439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1135c5929fdfSBarry Smith   options = options ? options : defaultoptions;
11363ba16761SJacob Faibussowitsch   if (!options) PetscFunctionReturn(PETSC_SUCCESS);
11372d747510SLisandro Dalcin 
1138a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1139a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1140a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1141a542b6e8SBarry Smith   }
11422d747510SLisandro Dalcin   options->N = 0;
11439355ec05SMatthew G. Knepley   free(options->names);
11449355ec05SMatthew G. Knepley   free(options->values);
11459355ec05SMatthew G. Knepley   free(options->used);
11469355ec05SMatthew G. Knepley   free(options->source);
11479355ec05SMatthew G. Knepley   options->names  = NULL;
11489355ec05SMatthew G. Knepley   options->values = NULL;
11499355ec05SMatthew G. Knepley   options->used   = NULL;
11509355ec05SMatthew G. Knepley   options->source = NULL;
11519355ec05SMatthew G. Knepley   options->Nalloc = 0;
11522d747510SLisandro Dalcin 
11539355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
1154a542b6e8SBarry Smith     free(options->aliases1[i]);
1155a542b6e8SBarry Smith     free(options->aliases2[i]);
1156a542b6e8SBarry Smith   }
11579355ec05SMatthew G. Knepley   options->Na = 0;
11589355ec05SMatthew G. Knepley   free(options->aliases1);
11599355ec05SMatthew G. Knepley   free(options->aliases2);
11609355ec05SMatthew G. Knepley   options->aliases1 = options->aliases2 = NULL;
11619355ec05SMatthew G. Knepley   options->Naalloc                      = 0;
1162a542b6e8SBarry Smith 
11632d747510SLisandro Dalcin   /* destroy hash table */
11642d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11652d747510SLisandro Dalcin   options->ht = NULL;
11660eb63584SBarry Smith 
11672d747510SLisandro Dalcin   options->prefixind  = 0;
11682d747510SLisandro Dalcin   options->prefix[0]  = 0;
11692d747510SLisandro Dalcin   options->help       = PETSC_FALSE;
11709355ec05SMatthew G. Knepley   options->help_intro = PETSC_FALSE;
11713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11724416b707SBarry Smith }
11734416b707SBarry Smith 
11745d83a8b1SBarry Smith /*@
11752d747510SLisandro Dalcin   PetscOptionsSetAlias - Makes a key and alias for another key
11762d747510SLisandro Dalcin 
11771c9f3c13SBarry Smith   Logically Collective
11782d747510SLisandro Dalcin 
11792d747510SLisandro Dalcin   Input Parameters:
118020f4b53cSBarry Smith + options - options database, or `NULL` for default global database
11812d747510SLisandro Dalcin . newname - the alias
11822d747510SLisandro Dalcin - oldname - the name that alias will refer to
11832d747510SLisandro Dalcin 
11842d747510SLisandro Dalcin   Level: advanced
11852d747510SLisandro Dalcin 
118620f4b53cSBarry Smith   Note:
118721532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11881c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11891c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11901c9f3c13SBarry Smith   on different ranks.
11911c9f3c13SBarry Smith 
11927e6f8dd6SBarry Smith   Developer Note:
11937e6f8dd6SBarry Smith   Uses `malloc()` directly because PETSc may not be initialized yet.
11947e6f8dd6SBarry Smith 
11950241b274SPierre Jolivet .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1196c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1197db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1198c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1199db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1200db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
12012d747510SLisandro Dalcin @*/
1202d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1203d71ae5a4SJacob Faibussowitsch {
12042d747510SLisandro Dalcin   size_t    len;
12059210b8eaSVaclav Hapla   PetscBool valid;
12062d747510SLisandro Dalcin 
12072d747510SLisandro Dalcin   PetscFunctionBegin;
12084f572ea9SToby Isaac   PetscAssertPointer(newname, 2);
12094f572ea9SToby Isaac   PetscAssertPointer(oldname, 3);
12102d747510SLisandro Dalcin   options = options ? options : defaultoptions;
12119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
121228b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
12139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
121428b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
12152d747510SLisandro Dalcin 
12169355ec05SMatthew G. Knepley   if (options->Na == options->Naalloc) {
12179355ec05SMatthew G. Knepley     char **tmpA1, **tmpA2;
12182d747510SLisandro Dalcin 
12199355ec05SMatthew G. Knepley     options->Naalloc = PetscMax(4, options->Naalloc * 2);
12209355ec05SMatthew G. Knepley     tmpA1            = (char **)malloc(options->Naalloc * sizeof(char *));
12219355ec05SMatthew G. Knepley     tmpA2            = (char **)malloc(options->Naalloc * sizeof(char *));
12229355ec05SMatthew G. Knepley     for (int i = 0; i < options->Na; ++i) {
12239355ec05SMatthew G. Knepley       tmpA1[i] = options->aliases1[i];
12249355ec05SMatthew G. Knepley       tmpA2[i] = options->aliases2[i];
12259355ec05SMatthew G. Knepley     }
12269355ec05SMatthew G. Knepley     free(options->aliases1);
12279355ec05SMatthew G. Knepley     free(options->aliases2);
12289355ec05SMatthew G. Knepley     options->aliases1 = tmpA1;
12299355ec05SMatthew G. Knepley     options->aliases2 = tmpA2;
12309355ec05SMatthew G. Knepley   }
12319371c9d4SSatish Balay   newname++;
12329371c9d4SSatish Balay   oldname++;
12339566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
12349355ec05SMatthew G. Knepley   options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1235c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
12369566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
12379355ec05SMatthew G. Knepley   options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1238c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
12399355ec05SMatthew G. Knepley   ++options->Na;
12403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12412d747510SLisandro Dalcin }
12424416b707SBarry Smith 
12435d83a8b1SBarry Smith /*@
1244e5c89e4eSSatish Balay   PetscOptionsSetValue - Sets an option name-value pair in the options
1245e5c89e4eSSatish Balay   database, overriding whatever is already present.
1246e5c89e4eSSatish Balay 
12471c9f3c13SBarry Smith   Logically Collective
1248e5c89e4eSSatish Balay 
1249e5c89e4eSSatish Balay   Input Parameters:
125020f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1251c5929fdfSBarry Smith . name    - name of option, this SHOULD have the - prepended
125220f4b53cSBarry Smith - value   - the option value (not used for all options, so can be `NULL`)
1253e5c89e4eSSatish Balay 
1254e5c89e4eSSatish Balay   Level: intermediate
1255e5c89e4eSSatish Balay 
1256e5c89e4eSSatish Balay   Note:
1257811af0c4SBarry Smith   This function can be called BEFORE `PetscInitialize()`
1258d49172ceSBarry Smith 
125921532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
12601c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
12611c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12621c9f3c13SBarry Smith   on different ranks.
12631c9f3c13SBarry Smith 
12647e6f8dd6SBarry Smith   Developer Note:
12657e6f8dd6SBarry Smith   Uses `malloc()` directly because PETSc may not be initialized yet.
1266b0250c70SBarry Smith 
1267db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1268e5c89e4eSSatish Balay @*/
1269d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1270d71ae5a4SJacob Faibussowitsch {
127139a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12729355ec05SMatthew G. Knepley   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
12733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1274c5b5d8d5SVaclav Hapla }
1275c5b5d8d5SVaclav Hapla 
12769355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1277d71ae5a4SJacob Faibussowitsch {
1278e5c89e4eSSatish Balay   size_t    len;
12799355ec05SMatthew G. Knepley   int       n, i;
1280e5c89e4eSSatish Balay   char    **names;
12819355ec05SMatthew G. Knepley   char      fullname[PETSC_MAX_OPTION_NAME] = "";
1282c5b5d8d5SVaclav Hapla   PetscBool flg;
1283e5c89e4eSSatish Balay 
128439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12857272c0d2SVaclav Hapla   if (!options) {
12869566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12877272c0d2SVaclav Hapla     options = defaultoptions;
1288c5929fdfSBarry Smith   }
128939a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
12902d747510SLisandro Dalcin 
12919566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
12923ba16761SJacob Faibussowitsch   if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1293e5c89e4eSSatish Balay 
12942d747510SLisandro Dalcin   name++; /* skip starting dash */
12952d747510SLisandro Dalcin 
129674e0666dSJed Brown   if (options->prefixind > 0) {
1297d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
12982d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
129989ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
13002d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
130174e0666dSJed Brown     name                           = fullname;
130274e0666dSJed Brown   }
130374e0666dSJed Brown 
130474e0666dSJed Brown   /* check against aliases */
13059355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
13062d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
13079371c9d4SSatish Balay     if (!result) {
13089371c9d4SSatish Balay       name = options->aliases2[i];
13099371c9d4SSatish Balay       break;
13109371c9d4SSatish Balay     }
1311e5c89e4eSSatish Balay   }
1312e5c89e4eSSatish Balay 
13132d747510SLisandro Dalcin   /* slow search */
13149355ec05SMatthew G. Knepley   n     = options->N;
1315e5c89e4eSSatish Balay   names = options->names;
13169355ec05SMatthew G. Knepley   for (i = 0; i < options->N; i++) {
13172d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13182d747510SLisandro Dalcin     if (!result) {
13199371c9d4SSatish Balay       n = i;
13209371c9d4SSatish Balay       goto setvalue;
13212d747510SLisandro Dalcin     } else if (result > 0) {
13229371c9d4SSatish Balay       n = i;
13239371c9d4SSatish Balay       break;
1324e5c89e4eSSatish Balay     }
1325e5c89e4eSSatish Balay   }
13269355ec05SMatthew G. Knepley   if (options->N == options->Nalloc) {
13279355ec05SMatthew G. Knepley     char             **names, **values;
13289355ec05SMatthew G. Knepley     PetscBool         *used;
13299355ec05SMatthew G. Knepley     PetscOptionSource *source;
13309355ec05SMatthew G. Knepley 
13319355ec05SMatthew G. Knepley     options->Nalloc = PetscMax(10, options->Nalloc * 2);
13329355ec05SMatthew G. Knepley     names           = (char **)malloc(options->Nalloc * sizeof(char *));
13339355ec05SMatthew G. Knepley     values          = (char **)malloc(options->Nalloc * sizeof(char *));
13349355ec05SMatthew G. Knepley     used            = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
13359355ec05SMatthew G. Knepley     source          = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
13369355ec05SMatthew G. Knepley     for (int i = 0; i < options->N; ++i) {
13379355ec05SMatthew G. Knepley       names[i]  = options->names[i];
13389355ec05SMatthew G. Knepley       values[i] = options->values[i];
13399355ec05SMatthew G. Knepley       used[i]   = options->used[i];
13409355ec05SMatthew G. Knepley       source[i] = options->source[i];
13419355ec05SMatthew G. Knepley     }
13429355ec05SMatthew G. Knepley     free(options->names);
13439355ec05SMatthew G. Knepley     free(options->values);
13449355ec05SMatthew G. Knepley     free(options->used);
13459355ec05SMatthew G. Knepley     free(options->source);
13469355ec05SMatthew G. Knepley     options->names  = names;
13479355ec05SMatthew G. Knepley     options->values = values;
13489355ec05SMatthew G. Knepley     options->used   = used;
13499355ec05SMatthew G. Knepley     options->source = source;
13509355ec05SMatthew G. Knepley   }
135139a651e2SJacob Faibussowitsch 
13522d747510SLisandro Dalcin   /* shift remaining values up 1 */
13539355ec05SMatthew G. Knepley   for (i = options->N; i > n; i--) {
13545e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1355e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1356e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
13579355ec05SMatthew G. Knepley     options->source[i] = options->source[i - 1];
1358e5c89e4eSSatish Balay   }
13592d747510SLisandro Dalcin   options->names[n]  = NULL;
13602d747510SLisandro Dalcin   options->values[n] = NULL;
13612d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
13629355ec05SMatthew G. Knepley   options->source[n] = PETSC_OPT_CODE;
13632d747510SLisandro Dalcin   options->N++;
13642d747510SLisandro Dalcin 
13652d747510SLisandro Dalcin   /* destroy hash table */
13662d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13672d747510SLisandro Dalcin   options->ht = NULL;
13682d747510SLisandro Dalcin 
13692d747510SLisandro Dalcin   /* set new name */
137070d8d27cSBarry Smith   len               = strlen(name);
13715e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
137239a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1373d49172ceSBarry Smith   strcpy(options->names[n], name);
13742d747510SLisandro Dalcin 
13752d747510SLisandro Dalcin setvalue:
13762d747510SLisandro Dalcin   /* set new value */
13772d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1378d49172ceSBarry Smith   len = value ? strlen(value) : 0;
13795e8c5e88SLisandro Dalcin   if (len) {
1380e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1381d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1382d49172ceSBarry Smith     strcpy(options->values[n], value);
1383432b765aSRené Chenard     options->values[n][len] = '\0';
13842d747510SLisandro Dalcin   } else {
13852d747510SLisandro Dalcin     options->values[n] = NULL;
13862d747510SLisandro Dalcin   }
13879355ec05SMatthew G. Knepley   options->source[n] = source;
13882d747510SLisandro Dalcin 
138991ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
139091ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
139191ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1392d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
139391ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
139491ad3481SVaclav Hapla   }
139591ad3481SVaclav Hapla 
1396432b765aSRené Chenard   PetscCall(PetscOptionsMonitor(options, name, value ? value : "", source));
1397c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
13983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1399e5c89e4eSSatish Balay }
1400e5c89e4eSSatish Balay 
14015d83a8b1SBarry Smith /*@
1402e5c89e4eSSatish Balay   PetscOptionsClearValue - Clears an option name-value pair in the options
1403e5c89e4eSSatish Balay   database, overriding whatever is already present.
1404e5c89e4eSSatish Balay 
14051c9f3c13SBarry Smith   Logically Collective
1406e5c89e4eSSatish Balay 
1407d8d19677SJose E. Roman   Input Parameters:
140820f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1409a2b725a8SWilliam Gropp - name    - name of option, this SHOULD have the - prepended
1410e5c89e4eSSatish Balay 
1411e5c89e4eSSatish Balay   Level: intermediate
1412e5c89e4eSSatish Balay 
1413811af0c4SBarry Smith   Note:
141421532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
14151c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
14161c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
14171c9f3c13SBarry Smith   on different ranks.
14181c9f3c13SBarry Smith 
14197e6f8dd6SBarry Smith   Developer Note:
14207e6f8dd6SBarry Smith   Uses `free()` directly because the options have been set with `malloc()`
14217e6f8dd6SBarry Smith 
1422db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1423e5c89e4eSSatish Balay @*/
1424d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1425d71ae5a4SJacob Faibussowitsch {
14262d747510SLisandro Dalcin   int    N, n, i;
14272d747510SLisandro Dalcin   char **names;
1428e5c89e4eSSatish Balay 
1429e5c89e4eSSatish Balay   PetscFunctionBegin;
1430c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1431cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1432c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
14332d747510SLisandro Dalcin 
14342d747510SLisandro Dalcin   name++; /* skip starting dash */
14352d747510SLisandro Dalcin 
14362d747510SLisandro Dalcin   /* slow search */
14372d747510SLisandro Dalcin   N = n = options->N;
1438e5c89e4eSSatish Balay   names = options->names;
1439e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
14402d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
14412d747510SLisandro Dalcin     if (!result) {
14429371c9d4SSatish Balay       n = i;
14439371c9d4SSatish Balay       break;
14442d747510SLisandro Dalcin     } else if (result > 0) {
14459371c9d4SSatish Balay       n = N;
14469371c9d4SSatish Balay       break;
1447e5c89e4eSSatish Balay     }
14482d747510SLisandro Dalcin   }
14493ba16761SJacob Faibussowitsch   if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1450e5c89e4eSSatish Balay 
14512d747510SLisandro Dalcin   /* remove name and value */
14522d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
14532d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1454e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1455e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
14565e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1457e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1458e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
14599355ec05SMatthew G. Knepley     options->source[i] = options->source[i + 1];
1460e5c89e4eSSatish Balay   }
1461e5c89e4eSSatish Balay   options->N--;
14622d747510SLisandro Dalcin 
14632d747510SLisandro Dalcin   /* destroy hash table */
14642d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
14652d747510SLisandro Dalcin   options->ht = NULL;
14662d747510SLisandro Dalcin 
14679355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
14683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1469e5c89e4eSSatish Balay }
1470e5c89e4eSSatish Balay 
1471e5c89e4eSSatish Balay /*@C
14722d747510SLisandro Dalcin   PetscOptionsFindPair - Gets an option name-value pair from the options database.
1473e5c89e4eSSatish Balay 
14742d747510SLisandro Dalcin   Not Collective
1475e5c89e4eSSatish Balay 
1476e5c89e4eSSatish Balay   Input Parameters:
147720f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
147820f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
14792d747510SLisandro Dalcin - name    - name of option, this SHOULD have the "-" prepended
1480e5c89e4eSSatish Balay 
14812d747510SLisandro Dalcin   Output Parameters:
14822d747510SLisandro Dalcin + value - the option value (optional, not used for all options)
14832d747510SLisandro Dalcin - set   - whether the option is set (optional)
1484e5c89e4eSSatish Balay 
148520f4b53cSBarry Smith   Level: developer
148620f4b53cSBarry Smith 
1487811af0c4SBarry Smith   Note:
14889666a313SBarry Smith   Each process may find different values or no value depending on how options were inserted into the database
14891c9f3c13SBarry Smith 
1490db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1491e5c89e4eSSatish Balay @*/
1492d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1493d71ae5a4SJacob Faibussowitsch {
14949355ec05SMatthew G. Knepley   char      buf[PETSC_MAX_OPTION_NAME];
1495daabea38SBarry Smith   PetscBool usehashtable = PETSC_TRUE;
14962d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1497e5c89e4eSSatish Balay 
1498e5c89e4eSSatish Balay   PetscFunctionBegin;
1499c5929fdfSBarry Smith   options = options ? options : defaultoptions;
150008401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1501cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1502e5c89e4eSSatish Balay 
15032d747510SLisandro Dalcin   name++; /* skip starting dash */
1504e5c89e4eSSatish Balay 
15057cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
15062d747510SLisandro Dalcin   if (pre && pre[0]) {
15072d747510SLisandro Dalcin     char *ptr = buf;
15089371c9d4SSatish Balay     if (name[0] == '-') {
15099371c9d4SSatish Balay       *ptr++ = '-';
15109371c9d4SSatish Balay       name++;
15119371c9d4SSatish Balay     }
15129566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
15139566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
15142d747510SLisandro Dalcin     name = buf;
15157cd08cecSJed Brown   }
15162d747510SLisandro Dalcin 
151776bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
15182f828895SJed Brown     PetscBool valid;
15199355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
15209566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
15219566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
152228b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
15232f828895SJed Brown   }
1524e5c89e4eSSatish Balay 
15252d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
15262d747510SLisandro Dalcin     int          i, ret;
15272d747510SLisandro Dalcin     khiter_t     it;
15282d747510SLisandro Dalcin     khash_t(HO) *ht;
15292d747510SLisandro Dalcin     ht = kh_init(HO);
153028b400f6SJacob Faibussowitsch     PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15312d747510SLisandro Dalcin     ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
153228b400f6SJacob Faibussowitsch     PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15332d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
15342d747510SLisandro Dalcin       it = kh_put(HO, ht, options->names[i], &ret);
153508401ef6SPierre Jolivet       PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15362d747510SLisandro Dalcin       kh_val(ht, it) = i;
15372d747510SLisandro Dalcin     }
15382d747510SLisandro Dalcin     options->ht = ht;
15392d747510SLisandro Dalcin   }
15402d747510SLisandro Dalcin 
15419371c9d4SSatish Balay   if (usehashtable) { /* fast search */
15422d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
15432d747510SLisandro Dalcin     khiter_t     it = kh_get(HO, ht, name);
15442d747510SLisandro Dalcin     if (it != kh_end(ht)) {
15452d747510SLisandro Dalcin       int i            = kh_val(ht, it);
1546e5c89e4eSSatish Balay       options->used[i] = PETSC_TRUE;
15472d747510SLisandro Dalcin       if (value) *value = options->values[i];
15482d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
15493ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
15502d747510SLisandro Dalcin     }
15519371c9d4SSatish Balay   } else { /* slow search */
15522d747510SLisandro Dalcin     int i, N = options->N;
15532d747510SLisandro Dalcin     for (i = 0; i < N; i++) {
1554daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i], name);
15552d747510SLisandro Dalcin       if (!result) {
15562d747510SLisandro Dalcin         options->used[i] = PETSC_TRUE;
15572d747510SLisandro Dalcin         if (value) *value = options->values[i];
15582d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
15593ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15602d747510SLisandro Dalcin       } else if (result > 0) {
1561e5c89e4eSSatish Balay         break;
1562e5c89e4eSSatish Balay       }
1563e5c89e4eSSatish Balay     }
15642d747510SLisandro Dalcin   }
15652d747510SLisandro Dalcin 
15662d747510SLisandro Dalcin   /*
15672d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
15682d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
15692d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
15702d747510SLisandro Dalcin    */
15712d747510SLisandro Dalcin   if (matchnumbers) {
15722d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1573e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
15742d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
15752d747510SLisandro Dalcin       if (name[i] == '_') {
15762d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
15772d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
15782d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1579e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1580e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1581e5c89e4eSSatish Balay           }
15822d747510SLisandro Dalcin           i = j - 1;
1583e5c89e4eSSatish Balay           break;
1584e5c89e4eSSatish Balay         }
1585e5c89e4eSSatish Balay       }
1586e5c89e4eSSatish Balay     }
1587e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
15882d747510SLisandro Dalcin       PetscBool found;
15899355ec05SMatthew G. Knepley       char      opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
15909566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
15919566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15929566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
15939566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
15949371c9d4SSatish Balay       if (found) {
15959371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
15963ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15979371c9d4SSatish Balay       }
1598e5c89e4eSSatish Balay     }
1599e5c89e4eSSatish Balay   }
16002d747510SLisandro Dalcin 
16012d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1603e5c89e4eSSatish Balay }
1604e5c89e4eSSatish Balay 
1605d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
160654a546c1SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *option[], const char *value[], PetscBool *set)
1607d71ae5a4SJacob Faibussowitsch {
16089355ec05SMatthew G. Knepley   char buf[PETSC_MAX_OPTION_NAME];
1609d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1610514bf10dSMatthew G Knepley 
1611514bf10dSMatthew G Knepley   PetscFunctionBegin;
1612c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1613cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1614cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1615514bf10dSMatthew G Knepley 
16162d747510SLisandro Dalcin   name++; /* skip starting dash */
1617514bf10dSMatthew G Knepley 
1618514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
16192d747510SLisandro Dalcin   if (pre && pre[0]) {
16202d747510SLisandro Dalcin     char *ptr = buf;
16219371c9d4SSatish Balay     if (name[0] == '-') {
16229371c9d4SSatish Balay       *ptr++ = '-';
16239371c9d4SSatish Balay       name++;
16249371c9d4SSatish Balay     }
16259b15cf9aSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
16269566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
16272d747510SLisandro Dalcin     name = buf;
1628514bf10dSMatthew G Knepley   }
16292d747510SLisandro Dalcin 
163076bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1631514bf10dSMatthew G Knepley     PetscBool valid;
16329355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
16339566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
16349566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
163528b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1636514bf10dSMatthew G Knepley   }
1637514bf10dSMatthew G Knepley 
1638d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1639d6ced9c0SMatthew G. Knepley   {
1640d6ced9c0SMatthew G. Knepley     int i, j;
1641d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1642d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1643d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1644d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1645d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1646d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1647d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1648d6ced9c0SMatthew G. Knepley           }
1649d6ced9c0SMatthew G. Knepley           i = j - 1;
1650d6ced9c0SMatthew G. Knepley           break;
1651d6ced9c0SMatthew G. Knepley         }
1652d6ced9c0SMatthew G. Knepley       }
1653d6ced9c0SMatthew G. Knepley     }
1654d6ced9c0SMatthew G. Knepley   }
1655d6ced9c0SMatthew G. Knepley 
1656363da2dcSJacob Faibussowitsch   /* slow search */
1657363da2dcSJacob Faibussowitsch   for (int c = -1; c < numCnt; ++c) {
1658363da2dcSJacob Faibussowitsch     char   opt[PETSC_MAX_OPTION_NAME + 2] = "";
16592d747510SLisandro Dalcin     size_t len;
1660d6ced9c0SMatthew G. Knepley 
1661d6ced9c0SMatthew G. Knepley     if (c < 0) {
1662c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1663d6ced9c0SMatthew G. Knepley     } else {
1664363da2dcSJacob Faibussowitsch       PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1665363da2dcSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1666d6ced9c0SMatthew G. Knepley     }
16679566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(opt, &len));
1668363da2dcSJacob Faibussowitsch     for (int i = 0; i < options->N; i++) {
1669363da2dcSJacob Faibussowitsch       PetscBool match;
1670363da2dcSJacob Faibussowitsch 
16719566063dSJacob Faibussowitsch       PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1672514bf10dSMatthew G Knepley       if (match) {
1673514bf10dSMatthew G Knepley         options->used[i] = PETSC_TRUE;
167454a546c1SMatthew G. Knepley         if (option) *option = options->names[i];
16752d747510SLisandro Dalcin         if (value) *value = options->values[i];
16762d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
16773ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
1678514bf10dSMatthew G Knepley       }
1679514bf10dSMatthew G Knepley     }
16802d747510SLisandro Dalcin   }
16812d747510SLisandro Dalcin 
16822d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1684514bf10dSMatthew G Knepley }
1685514bf10dSMatthew G Knepley 
16865d83a8b1SBarry Smith /*@
1687e5c89e4eSSatish Balay   PetscOptionsReject - Generates an error if a certain option is given.
1688e5c89e4eSSatish Balay 
16891c9f3c13SBarry Smith   Not Collective
1690e5c89e4eSSatish Balay 
1691e5c89e4eSSatish Balay   Input Parameters:
169220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
169320f4b53cSBarry Smith . pre     - the option prefix (may be `NULL`)
16942d747510SLisandro Dalcin . name    - the option name one is seeking
169520f4b53cSBarry Smith - mess    - error message (may be `NULL`)
1696e5c89e4eSSatish Balay 
1697e5c89e4eSSatish Balay   Level: advanced
1698e5c89e4eSSatish Balay 
16990241b274SPierre Jolivet .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1700db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1701db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1702c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1703db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1704db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1705e5c89e4eSSatish Balay @*/
1706d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1707d71ae5a4SJacob Faibussowitsch {
1708ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1709e5c89e4eSSatish Balay 
1710e5c89e4eSSatish Balay   PetscFunctionBegin;
17119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1712e5c89e4eSSatish Balay   if (flag) {
171308401ef6SPierre 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);
1714f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1715e5c89e4eSSatish Balay   }
17163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1717e5c89e4eSSatish Balay }
1718e5c89e4eSSatish Balay 
17195d83a8b1SBarry Smith /*@
17202d747510SLisandro Dalcin   PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
17212d747510SLisandro Dalcin 
17222d747510SLisandro Dalcin   Not Collective
17232d747510SLisandro Dalcin 
1724811af0c4SBarry Smith   Input Parameter:
172520f4b53cSBarry Smith . options - options database, use `NULL` for default global database
17262d747510SLisandro Dalcin 
1727811af0c4SBarry Smith   Output Parameter:
1728811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
17292d747510SLisandro Dalcin 
17302d747510SLisandro Dalcin   Level: advanced
17312d747510SLisandro Dalcin 
1732db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
17332d747510SLisandro Dalcin @*/
1734d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1735d71ae5a4SJacob Faibussowitsch {
17362d747510SLisandro Dalcin   PetscFunctionBegin;
17374f572ea9SToby Isaac   PetscAssertPointer(set, 2);
17382d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17392d747510SLisandro Dalcin   *set    = options->help;
17403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17412d747510SLisandro Dalcin }
17422d747510SLisandro Dalcin 
1743d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1744d71ae5a4SJacob Faibussowitsch {
1745d314f959SVaclav Hapla   PetscFunctionBegin;
17464f572ea9SToby Isaac   PetscAssertPointer(set, 2);
1747d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1748d314f959SVaclav Hapla   *set    = options->help_intro;
17493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1750d314f959SVaclav Hapla }
1751d314f959SVaclav Hapla 
17525d83a8b1SBarry Smith /*@
1753e24fcbf7SPierre 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
1754e24fcbf7SPierre Jolivet   if its value is set to false.
1755e5c89e4eSSatish Balay 
1756e5c89e4eSSatish Balay   Not Collective
1757e5c89e4eSSatish Balay 
1758e5c89e4eSSatish Balay   Input Parameters:
175920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
176020f4b53cSBarry Smith . pre     - string to prepend to the name or `NULL`
17613de71b31SHong Zhang - name    - the option one is seeking
1762e5c89e4eSSatish Balay 
1763811af0c4SBarry Smith   Output Parameter:
1764811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1765e5c89e4eSSatish Balay 
1766e5c89e4eSSatish Balay   Level: beginner
1767e5c89e4eSSatish Balay 
1768811af0c4SBarry Smith   Note:
1769811af0c4SBarry Smith   In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
177090d69ab7SBarry Smith 
1771db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1772db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1773db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1774c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1775db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1776db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1777e5c89e4eSSatish Balay @*/
1778d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1779d71ae5a4SJacob Faibussowitsch {
17802d747510SLisandro Dalcin   const char *value;
1781ace3abfcSBarry Smith   PetscBool   flag;
1782e5c89e4eSSatish Balay 
1783e5c89e4eSSatish Balay   PetscFunctionBegin;
17849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
178596ef3cdfSSatish Balay   if (set) *set = flag;
17863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1787e5c89e4eSSatish Balay }
1788e5c89e4eSSatish Balay 
1789e5c89e4eSSatish Balay /*@C
17902d747510SLisandro Dalcin   PetscOptionsGetAll - Lists all the options the program was run with in a single string.
17912d747510SLisandro Dalcin 
17922d747510SLisandro Dalcin   Not Collective
17932d747510SLisandro Dalcin 
1794fd292e60Sprj-   Input Parameter:
179520f4b53cSBarry Smith . options - the options database, use `NULL` for the default global database
17962d747510SLisandro Dalcin 
17972d747510SLisandro Dalcin   Output Parameter:
17982d747510SLisandro Dalcin . copts - pointer where string pointer is stored
17992d747510SLisandro Dalcin 
180020f4b53cSBarry Smith   Level: advanced
180120f4b53cSBarry Smith 
18022d747510SLisandro Dalcin   Notes:
1803811af0c4SBarry Smith   The array and each entry in the array should be freed with `PetscFree()`
1804811af0c4SBarry Smith 
18051c9f3c13SBarry Smith   Each process may have different values depending on how the options were inserted into the database
18062d747510SLisandro Dalcin 
1807db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
18082d747510SLisandro Dalcin @*/
1809d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[])
1810d71ae5a4SJacob Faibussowitsch {
18112d747510SLisandro Dalcin   PetscInt i;
18122d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
18132d747510SLisandro Dalcin   char    *coptions = NULL;
18142d747510SLisandro Dalcin 
18152d747510SLisandro Dalcin   PetscFunctionBegin;
18164f572ea9SToby Isaac   PetscAssertPointer(copts, 2);
18172d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18182d747510SLisandro Dalcin   /* count the length of the required string */
18192d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18209566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
18212d747510SLisandro Dalcin     len += 2 + lent;
18222d747510SLisandro Dalcin     if (options->values[i]) {
18239566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
18242d747510SLisandro Dalcin       len += 1 + lent;
18252d747510SLisandro Dalcin     }
18262d747510SLisandro Dalcin   }
18279566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
18282d747510SLisandro Dalcin   coptions[0] = 0;
18292d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1830c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, "-", len));
1831c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, options->names[i], len));
1832c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, " ", len));
18332d747510SLisandro Dalcin     if (options->values[i]) {
1834c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, options->values[i], len));
1835c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, " ", len));
18362d747510SLisandro Dalcin     }
18372d747510SLisandro Dalcin   }
18382d747510SLisandro Dalcin   *copts = coptions;
18393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18402d747510SLisandro Dalcin }
18412d747510SLisandro Dalcin 
18425d83a8b1SBarry Smith /*@
18432d747510SLisandro Dalcin   PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
18442d747510SLisandro Dalcin 
18452d747510SLisandro Dalcin   Not Collective
18462d747510SLisandro Dalcin 
1847d8d19677SJose E. Roman   Input Parameters:
184820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
18492d747510SLisandro Dalcin - name    - string name of option
18502d747510SLisandro Dalcin 
18512d747510SLisandro Dalcin   Output Parameter:
1852811af0c4SBarry Smith . used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
18532d747510SLisandro Dalcin 
18542d747510SLisandro Dalcin   Level: advanced
18552d747510SLisandro Dalcin 
1856811af0c4SBarry Smith   Note:
18579666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18581c9f3c13SBarry Smith   on the given process
18591c9f3c13SBarry Smith 
1860db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
18612d747510SLisandro Dalcin @*/
1862d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1863d71ae5a4SJacob Faibussowitsch {
18642d747510SLisandro Dalcin   PetscInt i;
18652d747510SLisandro Dalcin 
18662d747510SLisandro Dalcin   PetscFunctionBegin;
18674f572ea9SToby Isaac   PetscAssertPointer(name, 2);
18684f572ea9SToby Isaac   PetscAssertPointer(used, 3);
18692d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18702d747510SLisandro Dalcin   *used   = PETSC_FALSE;
18712d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18729566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
18732d747510SLisandro Dalcin     if (*used) {
18742d747510SLisandro Dalcin       *used = options->used[i];
18752d747510SLisandro Dalcin       break;
18762d747510SLisandro Dalcin     }
18772d747510SLisandro Dalcin   }
18783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18792d747510SLisandro Dalcin }
18802d747510SLisandro Dalcin 
1881487a658cSBarry Smith /*@
18822d747510SLisandro Dalcin   PetscOptionsAllUsed - Returns a count of the number of options in the
18832d747510SLisandro Dalcin   database that have never been selected.
18842d747510SLisandro Dalcin 
18852d747510SLisandro Dalcin   Not Collective
18862d747510SLisandro Dalcin 
18872d747510SLisandro Dalcin   Input Parameter:
188820f4b53cSBarry Smith . options - options database, use `NULL` for default global database
18892d747510SLisandro Dalcin 
18902d747510SLisandro Dalcin   Output Parameter:
18912d747510SLisandro Dalcin . N - count of options not used
18922d747510SLisandro Dalcin 
18932d747510SLisandro Dalcin   Level: advanced
18942d747510SLisandro Dalcin 
1895811af0c4SBarry Smith   Note:
18969666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18971c9f3c13SBarry Smith   on the given process
18981c9f3c13SBarry Smith 
1899db781477SPatrick Sanan .seealso: `PetscOptionsView()`
19002d747510SLisandro Dalcin @*/
1901d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1902d71ae5a4SJacob Faibussowitsch {
19032d747510SLisandro Dalcin   PetscInt i, n = 0;
19042d747510SLisandro Dalcin 
19052d747510SLisandro Dalcin   PetscFunctionBegin;
19064f572ea9SToby Isaac   PetscAssertPointer(N, 2);
19072d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19082d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
19092d747510SLisandro Dalcin     if (!options->used[i]) n++;
19102d747510SLisandro Dalcin   }
19112d747510SLisandro Dalcin   *N = n;
19123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19132d747510SLisandro Dalcin }
19142d747510SLisandro Dalcin 
1915487a658cSBarry Smith /*@
19162d747510SLisandro Dalcin   PetscOptionsLeft - Prints to screen any options that were set and never used.
19172d747510SLisandro Dalcin 
19182d747510SLisandro Dalcin   Not Collective
19192d747510SLisandro Dalcin 
19202d747510SLisandro Dalcin   Input Parameter:
192120f4b53cSBarry Smith . options - options database; use `NULL` for default global database
19222d747510SLisandro Dalcin 
19232d747510SLisandro Dalcin   Options Database Key:
1924811af0c4SBarry Smith . -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
19252d747510SLisandro Dalcin 
192620f4b53cSBarry Smith   Level: advanced
192720f4b53cSBarry Smith 
19283de2bfdfSBarry Smith   Notes:
1929811af0c4SBarry Smith   This is rarely used directly, it is called by `PetscFinalize()` in debug more or if -options_left
19301c9f3c13SBarry Smith   is passed otherwise to help users determine possible mistakes in their usage of options. This
1931811af0c4SBarry Smith   only prints values on process zero of `PETSC_COMM_WORLD`.
1932811af0c4SBarry Smith 
1933811af0c4SBarry Smith   Other processes depending the objects
19341c9f3c13SBarry Smith   used may have different options that are left unused.
19353de2bfdfSBarry Smith 
1936db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
19372d747510SLisandro Dalcin @*/
1938d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeft(PetscOptions options)
1939d71ae5a4SJacob Faibussowitsch {
19402d747510SLisandro Dalcin   PetscInt     i;
19413de2bfdfSBarry Smith   PetscInt     cnt = 0;
19423de2bfdfSBarry Smith   PetscOptions toptions;
19432d747510SLisandro Dalcin 
19442d747510SLisandro Dalcin   PetscFunctionBegin;
19453de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
19463de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
19473de2bfdfSBarry Smith     if (!toptions->used[i]) {
1948660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
19493de2bfdfSBarry Smith       if (toptions->values[i]) {
19509355ec05SMatthew 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]]));
19512d747510SLisandro Dalcin       } else {
19529355ec05SMatthew G. Knepley         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
19532d747510SLisandro Dalcin       }
19542d747510SLisandro Dalcin     }
19552d747510SLisandro Dalcin   }
19563de2bfdfSBarry Smith   if (!options) {
19573de2bfdfSBarry Smith     toptions = defaultoptions;
19583de2bfdfSBarry Smith     while (toptions->previous) {
19593de2bfdfSBarry Smith       cnt++;
19603de2bfdfSBarry Smith       toptions = toptions->previous;
19613de2bfdfSBarry Smith     }
196248a46eb9SPierre 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));
19633de2bfdfSBarry Smith   }
19643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19652d747510SLisandro Dalcin }
19662d747510SLisandro Dalcin 
19672d747510SLisandro Dalcin /*@C
19682d747510SLisandro Dalcin   PetscOptionsLeftGet - Returns all options that were set and never used.
19692d747510SLisandro Dalcin 
19702d747510SLisandro Dalcin   Not Collective
19712d747510SLisandro Dalcin 
19722d747510SLisandro Dalcin   Input Parameter:
197320f4b53cSBarry Smith . options - options database, use `NULL` for default global database
19742d747510SLisandro Dalcin 
1975d8d19677SJose E. Roman   Output Parameters:
1976a2b725a8SWilliam Gropp + N      - count of options not used
19772d747510SLisandro Dalcin . names  - names of options not used
1978a2b725a8SWilliam Gropp - values - values of options not used
19792d747510SLisandro Dalcin 
19802d747510SLisandro Dalcin   Level: advanced
19812d747510SLisandro Dalcin 
19822d747510SLisandro Dalcin   Notes:
1983811af0c4SBarry Smith   Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1984811af0c4SBarry Smith 
1985811af0c4SBarry Smith   The value returned may be different on each process and depends on which options have been processed
19861c9f3c13SBarry Smith   on the given process
19872d747510SLisandro Dalcin 
1988db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
19892d747510SLisandro Dalcin @*/
1990d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
1991d71ae5a4SJacob Faibussowitsch {
19922d747510SLisandro Dalcin   PetscInt i, n;
19932d747510SLisandro Dalcin 
19942d747510SLisandro Dalcin   PetscFunctionBegin;
19954f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
19964f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
19974f572ea9SToby Isaac   if (values) PetscAssertPointer(values, 4);
19982d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19992d747510SLisandro Dalcin 
20002d747510SLisandro Dalcin   /* The number of unused PETSc options */
20012d747510SLisandro Dalcin   n = 0;
20022d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
2003660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
20042d747510SLisandro Dalcin     if (!options->used[i]) n++;
20052d747510SLisandro Dalcin   }
2006ad540459SPierre Jolivet   if (N) *N = n;
20079566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
20089566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
20092d747510SLisandro Dalcin 
20102d747510SLisandro Dalcin   n = 0;
20112d747510SLisandro Dalcin   if (names || values) {
20122d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
20132d747510SLisandro Dalcin       if (!options->used[i]) {
2014660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
20152d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
20162d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
20172d747510SLisandro Dalcin         n++;
20182d747510SLisandro Dalcin       }
20192d747510SLisandro Dalcin     }
20202d747510SLisandro Dalcin   }
20213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20222d747510SLisandro Dalcin }
20232d747510SLisandro Dalcin 
20242d747510SLisandro Dalcin /*@C
2025811af0c4SBarry Smith   PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
20262d747510SLisandro Dalcin 
20272d747510SLisandro Dalcin   Not Collective
20282d747510SLisandro Dalcin 
2029d8d19677SJose E. Roman   Input Parameters:
203020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
203110450e9eSJacob Faibussowitsch . N       - count of options not used
20322d747510SLisandro Dalcin . names   - names of options not used
2033a2b725a8SWilliam Gropp - values  - values of options not used
20342d747510SLisandro Dalcin 
20352d747510SLisandro Dalcin   Level: advanced
20362d747510SLisandro Dalcin 
203710450e9eSJacob Faibussowitsch   Notes:
203810450e9eSJacob Faibussowitsch   The user should pass the same pointer to `N` as they did when calling `PetscOptionsLeftGet()`
203910450e9eSJacob Faibussowitsch 
2040db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
20412d747510SLisandro Dalcin @*/
2042d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2043d71ae5a4SJacob Faibussowitsch {
20442d747510SLisandro Dalcin   PetscFunctionBegin;
204510450e9eSJacob Faibussowitsch   (void)options;
20464f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
20474f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
20484f572ea9SToby Isaac   if (values) PetscAssertPointer(values, 4);
2049ad540459SPierre Jolivet   if (N) *N = 0;
20509566063dSJacob Faibussowitsch   if (names) PetscCall(PetscFree(*names));
20519566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
20523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20532d747510SLisandro Dalcin }
20542d747510SLisandro Dalcin 
20552d747510SLisandro Dalcin /*@C
2056811af0c4SBarry Smith   PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
20572d747510SLisandro Dalcin 
2058c3339decSBarry Smith   Logically Collective
20592d747510SLisandro Dalcin 
20602d747510SLisandro Dalcin   Input Parameters:
20612d747510SLisandro Dalcin + name   - option name string
20622d747510SLisandro Dalcin . value  - option value string
20639355ec05SMatthew G. Knepley . source - The source for the option
206420f4b53cSBarry Smith - ctx    - a `PETSCVIEWERASCII` or `NULL`
20652d747510SLisandro Dalcin 
20662d747510SLisandro Dalcin   Level: intermediate
20672d747510SLisandro Dalcin 
20689666a313SBarry Smith   Notes:
206920f4b53cSBarry Smith   If ctx is `NULL`, `PetscPrintf()` is used.
20709314d9b7SBarry Smith   The first MPI process in the `PetscViewer` viewer actually prints the values, other
20711c9f3c13SBarry Smith   processes may have different values set
20721c9f3c13SBarry Smith 
2073811af0c4SBarry Smith   If `PetscCIEnabled` then do not print the test harness options
2074660278c0SBarry Smith 
2075db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
20762d747510SLisandro Dalcin @*/
20779355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], PetscOptionSource source, void *ctx)
2078d71ae5a4SJacob Faibussowitsch {
20792d747510SLisandro Dalcin   PetscFunctionBegin;
20803ba16761SJacob Faibussowitsch   if (PetscCIOption(name)) PetscFunctionReturn(PETSC_SUCCESS);
2081660278c0SBarry Smith 
20829060e2f9SVaclav Hapla   if (ctx) {
20839060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
20842d747510SLisandro Dalcin     if (!value) {
20859566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
20862d747510SLisandro Dalcin     } else if (!value[0]) {
20879355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20882d747510SLisandro Dalcin     } else {
20899355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20902d747510SLisandro Dalcin     }
20919060e2f9SVaclav Hapla   } else {
20929060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
20939060e2f9SVaclav Hapla     if (!value) {
20949566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
20959060e2f9SVaclav Hapla     } else if (!value[0]) {
20969355ec05SMatthew G. Knepley       PetscCall(PetscPrintf(comm, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20979060e2f9SVaclav Hapla     } else {
2098aaa8cc7dSPierre Jolivet       PetscCall(PetscPrintf(comm, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20999060e2f9SVaclav Hapla     }
21009060e2f9SVaclav Hapla   }
21013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21022d747510SLisandro Dalcin }
21032d747510SLisandro Dalcin 
21042d747510SLisandro Dalcin /*@C
21052d747510SLisandro Dalcin   PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
21062d747510SLisandro Dalcin   modified the PETSc options database.
21072d747510SLisandro Dalcin 
21082d747510SLisandro Dalcin   Not Collective
21092d747510SLisandro Dalcin 
21102d747510SLisandro Dalcin   Input Parameters:
211120f4b53cSBarry Smith + monitor        - pointer to function (if this is `NULL`, it turns off monitoring
211210450e9eSJacob Faibussowitsch . mctx           - [optional] context for private data for the monitor routine (use `NULL` if
211310450e9eSJacob Faibussowitsch                    no context is desired)
211410450e9eSJacob Faibussowitsch - monitordestroy - [optional] routine that frees monitor context (may be `NULL`)
21152d747510SLisandro Dalcin 
211610450e9eSJacob Faibussowitsch   Calling sequence of `monitor`:
21172d747510SLisandro Dalcin + name   - option name string
2118432b765aSRené Chenard . value  - option value string, a value of `NULL` indicates the option is being removed from the database. A value
2119432b765aSRené Chenard            of "" indicates the option is in the database but has no value.
21209355ec05SMatthew G. Knepley . source - option source
2121811af0c4SBarry Smith - mctx   - optional monitoring context, as set by `PetscOptionsMonitorSet()`
21222d747510SLisandro Dalcin 
212310450e9eSJacob Faibussowitsch   Calling sequence of `monitordestroy`:
212410450e9eSJacob Faibussowitsch . mctx - [optional] pointer to context to destroy with
21252d747510SLisandro Dalcin 
2126432b765aSRené Chenard   Options Database Keys:
2127432b765aSRené Chenard + -options_monitor <viewer> - turn on default monitoring
2128432b765aSRené Chenard - -options_monitor_cancel   - turn off any option monitors except the default monitor obtained with `-options_monitor`
2129432b765aSRené Chenard 
213020f4b53cSBarry Smith   Level: intermediate
213120f4b53cSBarry Smith 
21322d747510SLisandro Dalcin   Notes:
213310450e9eSJacob Faibussowitsch   See `PetscInitialize()` for options related to option database monitoring.
213410450e9eSJacob Faibussowitsch 
2135432b765aSRené Chenard   The default is to do no monitoring.  To print the name and value of options
2136811af0c4SBarry Smith   being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
2137432b765aSRené Chenard   with a `NULL` monitoring context. Or use the option `-options_monitor` <viewer>.
21382d747510SLisandro Dalcin 
21392d747510SLisandro Dalcin   Several different monitoring routines may be set by calling
2140811af0c4SBarry Smith   `PetscOptionsMonitorSet()` multiple times; all will be called in the
21412d747510SLisandro Dalcin   order in which they were set.
21422d747510SLisandro Dalcin 
2143db781477SPatrick Sanan .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
21442d747510SLisandro Dalcin @*/
214510450e9eSJacob Faibussowitsch PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource source, void *mctx), void *mctx, PetscErrorCode (*monitordestroy)(void **mctx))
2146d71ae5a4SJacob Faibussowitsch {
21472d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
21482d747510SLisandro Dalcin 
21492d747510SLisandro Dalcin   PetscFunctionBegin;
21503ba16761SJacob Faibussowitsch   if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
215108401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
21522d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
21532d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
21542d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void *)mctx;
21553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21562d747510SLisandro Dalcin }
21572d747510SLisandro Dalcin 
21582d747510SLisandro Dalcin /*
21592d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
216063fe8743SVaclav Hapla      Empty string is considered as true.
21612d747510SLisandro Dalcin */
2162d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2163d71ae5a4SJacob Faibussowitsch {
21642d747510SLisandro Dalcin   PetscBool istrue, isfalse;
21652d747510SLisandro Dalcin   size_t    len;
21662d747510SLisandro Dalcin 
21672d747510SLisandro Dalcin   PetscFunctionBegin;
216863fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
21699566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
21709371c9d4SSatish Balay   if (!len) {
21719371c9d4SSatish Balay     *a = PETSC_TRUE;
21723ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21739371c9d4SSatish Balay   }
21749566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
21759371c9d4SSatish Balay   if (istrue) {
21769371c9d4SSatish Balay     *a = PETSC_TRUE;
21773ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21789371c9d4SSatish Balay   }
21799566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
21809371c9d4SSatish Balay   if (istrue) {
21819371c9d4SSatish Balay     *a = PETSC_TRUE;
21823ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21839371c9d4SSatish Balay   }
21849566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
21859371c9d4SSatish Balay   if (istrue) {
21869371c9d4SSatish Balay     *a = PETSC_TRUE;
21873ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21889371c9d4SSatish Balay   }
21899566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
21909371c9d4SSatish Balay   if (istrue) {
21919371c9d4SSatish Balay     *a = PETSC_TRUE;
21923ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21939371c9d4SSatish Balay   }
21949566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
21959371c9d4SSatish Balay   if (isfalse) {
21969371c9d4SSatish Balay     *a = PETSC_FALSE;
21973ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21989371c9d4SSatish Balay   }
21999566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
22009371c9d4SSatish Balay   if (isfalse) {
22019371c9d4SSatish Balay     *a = PETSC_FALSE;
22023ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22039371c9d4SSatish Balay   }
22049566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
22059371c9d4SSatish Balay   if (isfalse) {
22069371c9d4SSatish Balay     *a = PETSC_FALSE;
22073ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22089371c9d4SSatish Balay   }
22099566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
22109371c9d4SSatish Balay   if (isfalse) {
22119371c9d4SSatish Balay     *a = PETSC_FALSE;
22123ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22139371c9d4SSatish Balay   }
221498921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
22152d747510SLisandro Dalcin }
22162d747510SLisandro Dalcin 
22172d747510SLisandro Dalcin /*
22182d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
22192d747510SLisandro Dalcin */
2220d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2221d71ae5a4SJacob Faibussowitsch {
22222d747510SLisandro Dalcin   size_t    len;
2223b3480c81SBarry Smith   PetscBool decide, tdefault, mouse, unlimited;
22242d747510SLisandro Dalcin 
22252d747510SLisandro Dalcin   PetscFunctionBegin;
22269566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
22275f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22282d747510SLisandro Dalcin 
22299566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
223048a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
22319566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
223248a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
2233b3480c81SBarry Smith   if (!decide) PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &decide));
2234b3480c81SBarry Smith   if (!decide) PetscCall(PetscStrcasecmp(name, "DETERMINE", &decide));
2235b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &unlimited));
2236b3480c81SBarry Smith   if (!unlimited) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &unlimited));
22379566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
22382d747510SLisandro Dalcin 
22392d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
22402d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
2241b3480c81SBarry Smith   else if (unlimited) *a = PETSC_UNLIMITED;
22422d747510SLisandro Dalcin   else if (mouse) *a = -1;
22432d747510SLisandro Dalcin   else {
22442d747510SLisandro Dalcin     char *endptr;
22452d747510SLisandro Dalcin     long  strtolval;
22462d747510SLisandro Dalcin 
22472d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2248cc73adaaSBarry 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);
22492d747510SLisandro Dalcin 
22502d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
22512d747510SLisandro Dalcin     (void)strtolval;
22522d747510SLisandro Dalcin     *a = atoll(name);
22532d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
22542d747510SLisandro Dalcin     (void)strtolval;
22552d747510SLisandro Dalcin     *a = _atoi64(name);
22562d747510SLisandro Dalcin #else
22572d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
22582d747510SLisandro Dalcin #endif
22592d747510SLisandro Dalcin   }
22603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22612d747510SLisandro Dalcin }
22622d747510SLisandro Dalcin 
22632d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22642d747510SLisandro Dalcin   #include <quadmath.h>
22652d747510SLisandro Dalcin #endif
22662d747510SLisandro Dalcin 
2267d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2268d71ae5a4SJacob Faibussowitsch {
22692d747510SLisandro Dalcin   PetscFunctionBegin;
22702d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22712d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
22722d747510SLisandro Dalcin #else
22732d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
22742d747510SLisandro Dalcin #endif
22753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22762d747510SLisandro Dalcin }
22772d747510SLisandro Dalcin 
2278d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2279d71ae5a4SJacob Faibussowitsch {
22802d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
22812d747510SLisandro Dalcin   char     *ptr;
22822d747510SLisandro Dalcin   PetscReal strtoval;
22832d747510SLisandro Dalcin 
22842d747510SLisandro Dalcin   PetscFunctionBegin;
22859566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
22862d747510SLisandro Dalcin   if (ptr == name) {
22872d747510SLisandro Dalcin     strtoval = 1.;
22882d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
22892d747510SLisandro Dalcin     if (name[0] == 'i') {
22902d747510SLisandro Dalcin       ptr++;
22912d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
22922d747510SLisandro Dalcin       ptr += 2;
22932d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
22942d747510SLisandro Dalcin       strtoval = -1.;
22952d747510SLisandro Dalcin       ptr += 2;
22962d747510SLisandro Dalcin     }
22972d747510SLisandro Dalcin   } else if (*ptr == 'i') {
22982d747510SLisandro Dalcin     hasi = PETSC_TRUE;
22992d747510SLisandro Dalcin     ptr++;
23002d747510SLisandro Dalcin   }
23012d747510SLisandro Dalcin   *endptr      = ptr;
23022d747510SLisandro Dalcin   *isImaginary = hasi;
23032d747510SLisandro Dalcin   if (hasi) {
23042d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
230598921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
23062d747510SLisandro Dalcin #else
23072d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
23082d747510SLisandro Dalcin #endif
23092d747510SLisandro Dalcin   } else {
23102d747510SLisandro Dalcin     *a = strtoval;
23112d747510SLisandro Dalcin   }
23123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23132d747510SLisandro Dalcin }
23142d747510SLisandro Dalcin 
23152d747510SLisandro Dalcin /*
23162d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
23172d747510SLisandro Dalcin */
2318d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2319d71ae5a4SJacob Faibussowitsch {
23202d747510SLisandro Dalcin   size_t    len;
23212d747510SLisandro Dalcin   PetscBool match;
23222d747510SLisandro Dalcin   char     *endptr;
23232d747510SLisandro Dalcin 
23242d747510SLisandro Dalcin   PetscFunctionBegin;
23259566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
232628b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
23272d747510SLisandro Dalcin 
23289566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
23299566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
23309371c9d4SSatish Balay   if (match) {
23319371c9d4SSatish Balay     *a = PETSC_DEFAULT;
23323ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23339371c9d4SSatish Balay   }
23342d747510SLisandro Dalcin 
23359566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
23369566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
23379371c9d4SSatish Balay   if (match) {
23389371c9d4SSatish Balay     *a = PETSC_DECIDE;
23393ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23409371c9d4SSatish Balay   }
23412d747510SLisandro Dalcin 
2342b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &match));
2343b3480c81SBarry Smith   if (!match) PetscCall(PetscStrcasecmp(name, "DETERMINE", &match));
2344b3480c81SBarry Smith   if (match) {
2345b3480c81SBarry Smith     *a = PETSC_DETERMINE;
2346b3480c81SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
2347b3480c81SBarry Smith   }
2348b3480c81SBarry Smith 
2349b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &match));
2350b3480c81SBarry Smith   if (!match) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &match));
2351b3480c81SBarry Smith   if (match) {
2352b3480c81SBarry Smith     *a = PETSC_UNLIMITED;
2353b3480c81SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
2354b3480c81SBarry Smith   }
2355b3480c81SBarry Smith 
23569566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
235739a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
23583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23592d747510SLisandro Dalcin }
23602d747510SLisandro Dalcin 
2361d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2362d71ae5a4SJacob Faibussowitsch {
23632d747510SLisandro Dalcin   PetscBool   imag1;
23642d747510SLisandro Dalcin   size_t      len;
23652d747510SLisandro Dalcin   PetscScalar val = 0.;
23662d747510SLisandro Dalcin   char       *ptr = NULL;
23672d747510SLisandro Dalcin 
23682d747510SLisandro Dalcin   PetscFunctionBegin;
23699566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
237028b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
23719566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
23722d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
23732d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
23742d747510SLisandro Dalcin     PetscBool   imag2;
23752d747510SLisandro Dalcin     PetscScalar val2;
23762d747510SLisandro Dalcin 
23779566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
237839a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
23792d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
23802d747510SLisandro Dalcin   }
23812d747510SLisandro Dalcin #endif
238239a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
23832d747510SLisandro Dalcin   *a = val;
23843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23852d747510SLisandro Dalcin }
23862d747510SLisandro Dalcin 
23872d747510SLisandro Dalcin /*@C
23882d747510SLisandro Dalcin   PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
23892d747510SLisandro Dalcin   option in the database.
2390e5c89e4eSSatish Balay 
2391e5c89e4eSSatish Balay   Not Collective
2392e5c89e4eSSatish Balay 
2393e5c89e4eSSatish Balay   Input Parameters:
239420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
239520f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2396e5c89e4eSSatish Balay - name    - the option one is seeking
2397e5c89e4eSSatish Balay 
2398d8d19677SJose E. Roman   Output Parameters:
23992d747510SLisandro Dalcin + ivalue - the logical value to return
2400811af0c4SBarry Smith - set    - `PETSC_TRUE`  if found, else `PETSC_FALSE`
2401e5c89e4eSSatish Balay 
2402e5c89e4eSSatish Balay   Level: beginner
2403e5c89e4eSSatish Balay 
240495452b02SPatrick Sanan   Notes:
24059e296098SJunchao Zhang   TRUE, true, YES, yes, ON, on, nostring, and 1 all translate to `PETSC_TRUE`
24069e296098SJunchao Zhang   FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_FALSE`
24072d747510SLisandro Dalcin 
24089314d9b7SBarry 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`
24099314d9b7SBarry Smith   is equivalent to `-requested_bool true`
24102d747510SLisandro Dalcin 
24119314d9b7SBarry Smith   If the user does not supply the option at all `ivalue` is NOT changed. Thus
24129314d9b7SBarry Smith   you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
24132efd9cb1SBarry Smith 
24149e296098SJunchao Zhang .seealso: `PetscOptionsGetBool3()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2415db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2416db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2417c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2418db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2419db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2420e5c89e4eSSatish Balay @*/
2421d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2422d71ae5a4SJacob Faibussowitsch {
24232d747510SLisandro Dalcin   const char *value;
2424ace3abfcSBarry Smith   PetscBool   flag;
2425e5c89e4eSSatish Balay 
2426e5c89e4eSSatish Balay   PetscFunctionBegin;
24274f572ea9SToby Isaac   PetscAssertPointer(name, 3);
24284f572ea9SToby Isaac   if (ivalue) PetscAssertPointer(ivalue, 4);
24299566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2430e5c89e4eSSatish Balay   if (flag) {
243196ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
24329566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
24332d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2434e5c89e4eSSatish Balay   } else {
243596ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2436e5c89e4eSSatish Balay   }
24373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2438e5c89e4eSSatish Balay }
2439e5c89e4eSSatish Balay 
2440e5c89e4eSSatish Balay /*@C
2441d7c1f440SPierre Jolivet   PetscOptionsGetBool3 - Gets the ternary logical (true, false or unknown) value for a particular
24429e296098SJunchao Zhang   option in the database.
24439e296098SJunchao Zhang 
24449e296098SJunchao Zhang   Not Collective
24459e296098SJunchao Zhang 
24469e296098SJunchao Zhang   Input Parameters:
24479e296098SJunchao Zhang + options - options database, use `NULL` for default global database
24489e296098SJunchao Zhang . pre     - the string to prepend to the name or `NULL`
24499e296098SJunchao Zhang - name    - the option one is seeking
24509e296098SJunchao Zhang 
24519e296098SJunchao Zhang   Output Parameters:
24529e296098SJunchao Zhang + ivalue - the ternary logical value to return
24539e296098SJunchao Zhang - set    - `PETSC_TRUE`  if found, else `PETSC_FALSE`
24549e296098SJunchao Zhang 
24559e296098SJunchao Zhang   Level: beginner
24569e296098SJunchao Zhang 
24579e296098SJunchao Zhang   Notes:
24589e296098SJunchao Zhang   TRUE, true, YES, yes, ON, on, nostring and 1 all translate to `PETSC_BOOL3_TRUE`
24599e296098SJunchao Zhang   FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_BOOL3_FALSE`
24609e296098SJunchao Zhang   UNKNOWN, unknown, AUTO and auto all translate to `PETSC_BOOL3_UNKNOWN`
24619e296098SJunchao Zhang 
24629e296098SJunchao 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`
24639e296098SJunchao Zhang   is equivalent to `-requested_bool3 true`
24649e296098SJunchao Zhang 
24659e296098SJunchao Zhang   If the user does not supply the option at all `ivalue` is NOT changed. Thus
24669e296098SJunchao Zhang   you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
24679e296098SJunchao Zhang 
24689e296098SJunchao Zhang .seealso: `PetscOptionsGetBool()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
24699e296098SJunchao Zhang           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
24709e296098SJunchao Zhang           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
24719e296098SJunchao Zhang           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
24729e296098SJunchao Zhang           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
24739e296098SJunchao Zhang           `PetscOptionsFList()`, `PetscOptionsEList()`
24749e296098SJunchao Zhang @*/
24759e296098SJunchao Zhang PetscErrorCode PetscOptionsGetBool3(PetscOptions options, const char pre[], const char name[], PetscBool3 *ivalue, PetscBool *set)
24769e296098SJunchao Zhang {
24779e296098SJunchao Zhang   const char *value;
24789e296098SJunchao Zhang   PetscBool   flag;
24799e296098SJunchao Zhang 
24809e296098SJunchao Zhang   PetscFunctionBegin;
24819e296098SJunchao Zhang   PetscAssertPointer(name, 3);
24829e296098SJunchao Zhang   if (ivalue) PetscAssertPointer(ivalue, 4);
24839e296098SJunchao Zhang   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
24849e296098SJunchao Zhang   if (flag) { // found the option
24859e296098SJunchao Zhang     PetscBool isAUTO = PETSC_FALSE, isUNKNOWN = PETSC_FALSE;
24869e296098SJunchao Zhang 
24879e296098SJunchao Zhang     if (set) *set = PETSC_TRUE;
24889e296098SJunchao Zhang     PetscCall(PetscStrcasecmp("AUTO", value, &isAUTO));                    // auto or AUTO
24899e296098SJunchao Zhang     if (!isAUTO) PetscCall(PetscStrcasecmp("UNKNOWN", value, &isUNKNOWN)); // unknown or UNKNOWN
24909e296098SJunchao Zhang     if (isAUTO || isUNKNOWN) {
24919e296098SJunchao Zhang       if (ivalue) *ivalue = PETSC_BOOL3_UNKNOWN;
24929e296098SJunchao Zhang     } else { // handle boolean values (if no value is given, it returns true)
24939e296098SJunchao Zhang       PetscCall(PetscOptionsStringToBool(value, &flag));
24949e296098SJunchao Zhang       if (ivalue) *ivalue = PetscBoolToBool3(flag);
24959e296098SJunchao Zhang     }
24969e296098SJunchao Zhang   } else {
24979e296098SJunchao Zhang     if (set) *set = PETSC_FALSE;
24989e296098SJunchao Zhang   }
24999e296098SJunchao Zhang   PetscFunctionReturn(PETSC_SUCCESS);
25009e296098SJunchao Zhang }
25019e296098SJunchao Zhang 
25029e296098SJunchao Zhang /*@C
2503e5c89e4eSSatish Balay   PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2504e5c89e4eSSatish Balay 
2505e5c89e4eSSatish Balay   Not Collective
2506e5c89e4eSSatish Balay 
2507e5c89e4eSSatish Balay   Input Parameters:
250820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
250920f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2510e5c89e4eSSatish Balay . opt     - option name
2511a264d7a6SBarry Smith . list    - the possible choices (one of these must be selected, anything else is invalid)
2512a2b725a8SWilliam Gropp - ntext   - number of choices
2513e5c89e4eSSatish Balay 
2514d8d19677SJose E. Roman   Output Parameters:
25152efd9cb1SBarry Smith + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2516811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2517e5c89e4eSSatish Balay 
2518e5c89e4eSSatish Balay   Level: intermediate
2519e5c89e4eSSatish Balay 
252095452b02SPatrick Sanan   Notes:
25219314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
25229314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
25232efd9cb1SBarry Smith 
2524811af0c4SBarry Smith   See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2525e5c89e4eSSatish Balay 
2526db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2527db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2528db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2529c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2530db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2531db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2532e5c89e4eSSatish Balay @*/
2533d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscInt ntext, PetscInt *value, PetscBool *set)
2534d71ae5a4SJacob Faibussowitsch {
253558b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2536e5c89e4eSSatish Balay   char     *svalue;
2537ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2538e5c89e4eSSatish Balay   PetscInt  i;
2539e5c89e4eSSatish Balay 
2540e5c89e4eSSatish Balay   PetscFunctionBegin;
25414f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2542e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
25439566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2544e5c89e4eSSatish Balay     if (alen > len) len = alen;
254558b0ac4eSStefano Zampini     tlen += len + 1;
2546e5c89e4eSSatish Balay   }
2547e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
25489566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
25499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2550e5c89e4eSSatish Balay   if (aset) {
25519566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
255258b0ac4eSStefano Zampini     if (!flg) {
2553c6a7a370SJeremy L Thompson       char *avail;
255458b0ac4eSStefano Zampini 
25559566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
2556c6a7a370SJeremy L Thompson       avail[0] = '\0';
255758b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
2558c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, list[i], tlen));
2559c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, " ", tlen));
256058b0ac4eSStefano Zampini       }
25619566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
256298921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
256358b0ac4eSStefano Zampini     }
2564fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2565a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
25669566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
25673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2568e5c89e4eSSatish Balay }
2569e5c89e4eSSatish Balay 
2570e5c89e4eSSatish Balay /*@C
2571e5c89e4eSSatish Balay   PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2572e5c89e4eSSatish Balay 
2573e5c89e4eSSatish Balay   Not Collective
2574e5c89e4eSSatish Balay 
2575e5c89e4eSSatish Balay   Input Parameters:
257620f4b53cSBarry Smith + options - options database, use `NULL` for default global database
257720f4b53cSBarry Smith . pre     - option prefix or `NULL`
2578e5c89e4eSSatish Balay . opt     - option name
25796b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2580e5c89e4eSSatish Balay 
2581d8d19677SJose E. Roman   Output Parameters:
2582e5c89e4eSSatish Balay + value - the value to return
2583811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2584e5c89e4eSSatish Balay 
2585e5c89e4eSSatish Balay   Level: beginner
2586e5c89e4eSSatish Balay 
258795452b02SPatrick Sanan   Notes:
25889314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
25899314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2590e5c89e4eSSatish Balay 
25919314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names
2592e5c89e4eSSatish Balay 
2593db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2594db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2595aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2596db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2597c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2598db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2599db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2600e5c89e4eSSatish Balay @*/
2601d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscEnum *value, PetscBool *set)
2602d71ae5a4SJacob Faibussowitsch {
260369a24498SJed Brown   PetscInt  ntext = 0, tval;
2604ace3abfcSBarry Smith   PetscBool fset;
2605e5c89e4eSSatish Balay 
2606e5c89e4eSSatish Balay   PetscFunctionBegin;
26074f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2608ad540459SPierre 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");
260908401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2610e5c89e4eSSatish Balay   ntext -= 3;
26119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
261269a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2613809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2614809ceb46SBarry Smith   if (set) *set = fset;
26153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2616e5c89e4eSSatish Balay }
2617e5c89e4eSSatish Balay 
2618e5c89e4eSSatish Balay /*@C
26192d747510SLisandro Dalcin   PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2620e5c89e4eSSatish Balay 
2621e5c89e4eSSatish Balay   Not Collective
2622e5c89e4eSSatish Balay 
2623e5c89e4eSSatish Balay   Input Parameters:
262420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
262520f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2626e5c89e4eSSatish Balay - name    - the option one is seeking
2627e5c89e4eSSatish Balay 
2628d8d19677SJose E. Roman   Output Parameters:
26292d747510SLisandro Dalcin + ivalue - the integer value to return
2630811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2631e5c89e4eSSatish Balay 
2632e5c89e4eSSatish Balay   Level: beginner
2633e5c89e4eSSatish Balay 
2634e5c89e4eSSatish Balay   Notes:
26359314d9b7SBarry Smith   If the user does not supply the option `ivalue` is NOT changed. Thus
26369314d9b7SBarry Smith   you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
26375c07ccb8SBarry Smith 
2638b3480c81SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
2639b3480c81SBarry Smith 
2640b3480c81SBarry Smith   Accepts the deprecated value `default`.
2641b3480c81SBarry Smith 
2642db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2643db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2644aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2645db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2646c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2647db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2648db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2649e5c89e4eSSatish Balay @*/
2650d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2651d71ae5a4SJacob Faibussowitsch {
26522d747510SLisandro Dalcin   const char *value;
26532d747510SLisandro Dalcin   PetscBool   flag;
2654e5c89e4eSSatish Balay 
2655e5c89e4eSSatish Balay   PetscFunctionBegin;
26564f572ea9SToby Isaac   PetscAssertPointer(name, 3);
26574f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
26589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2659e5c89e4eSSatish Balay   if (flag) {
266034a9cc2cSBarry Smith     if (!value) {
26612d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
266234a9cc2cSBarry Smith     } else {
26632d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
26649566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2665e5c89e4eSSatish Balay     }
2666e5c89e4eSSatish Balay   } else {
266796ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2668e5c89e4eSSatish Balay   }
26693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2670e5c89e4eSSatish Balay }
2671e5c89e4eSSatish Balay 
2672e2446a98SMatthew Knepley /*@C
26736497c311SBarry Smith   PetscOptionsGetMPIInt - Gets the MPI integer value for a particular option in the database.
26746497c311SBarry Smith 
26756497c311SBarry Smith   Not Collective
26766497c311SBarry Smith 
26776497c311SBarry Smith   Input Parameters:
26786497c311SBarry Smith + options - options database, use `NULL` for default global database
26796497c311SBarry Smith . pre     - the string to prepend to the name or `NULL`
26806497c311SBarry Smith - name    - the option one is seeking
26816497c311SBarry Smith 
26826497c311SBarry Smith   Output Parameters:
26836497c311SBarry Smith + ivalue - the MPI integer value to return
26846497c311SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
26856497c311SBarry Smith 
26866497c311SBarry Smith   Level: beginner
26876497c311SBarry Smith 
26886497c311SBarry Smith   Notes:
26896497c311SBarry Smith   If the user does not supply the option `ivalue` is NOT changed. Thus
26906497c311SBarry Smith   you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
26916497c311SBarry Smith 
26926497c311SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
26936497c311SBarry Smith 
26946497c311SBarry Smith   Accepts the deprecated value `default`.
26956497c311SBarry Smith 
26966497c311SBarry Smith .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
26976497c311SBarry Smith           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
26986497c311SBarry Smith           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
26996497c311SBarry Smith           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
27006497c311SBarry Smith           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
27016497c311SBarry Smith           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
27026497c311SBarry Smith           `PetscOptionsFList()`, `PetscOptionsEList()`
27036497c311SBarry Smith @*/
27046497c311SBarry Smith PetscErrorCode PetscOptionsGetMPIInt(PetscOptions options, const char pre[], const char name[], PetscMPIInt *ivalue, PetscBool *set)
27056497c311SBarry Smith {
27066497c311SBarry Smith   PetscInt  value;
27076497c311SBarry Smith   PetscBool flag;
27086497c311SBarry Smith 
27096497c311SBarry Smith   PetscFunctionBegin;
27106497c311SBarry Smith   PetscCall(PetscOptionsGetInt(options, pre, name, &value, &flag));
27116497c311SBarry Smith   if (flag) PetscCall(PetscMPIIntCast(value, ivalue));
27126497c311SBarry Smith   if (set) *set = flag;
27136497c311SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
27146497c311SBarry Smith }
27156497c311SBarry Smith 
27166497c311SBarry Smith /*@C
2717e5c89e4eSSatish Balay   PetscOptionsGetReal - Gets the double precision value for a particular
2718e5c89e4eSSatish Balay   option in the database.
2719e5c89e4eSSatish Balay 
2720e5c89e4eSSatish Balay   Not Collective
2721e5c89e4eSSatish Balay 
2722e5c89e4eSSatish Balay   Input Parameters:
272320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
272420f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2725e5c89e4eSSatish Balay - name    - the option one is seeking
2726e5c89e4eSSatish Balay 
2727d8d19677SJose E. Roman   Output Parameters:
2728e5c89e4eSSatish Balay + dvalue - the double value to return
2729811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2730e5c89e4eSSatish Balay 
273120f4b53cSBarry Smith   Level: beginner
273220f4b53cSBarry Smith 
2733b3480c81SBarry Smith   Notes:
2734b3480c81SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
2735b3480c81SBarry Smith 
2736b3480c81SBarry Smith   Accepts the deprecated value `default`
2737b3480c81SBarry Smith 
27389314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
27399314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking that the `set` flag is true.
2740e4974155SBarry Smith 
2741db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2742c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2743db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2744c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2745db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2746db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2747e5c89e4eSSatish Balay @*/
2748d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2749d71ae5a4SJacob Faibussowitsch {
27502d747510SLisandro Dalcin   const char *value;
2751ace3abfcSBarry Smith   PetscBool   flag;
2752e5c89e4eSSatish Balay 
2753e5c89e4eSSatish Balay   PetscFunctionBegin;
27544f572ea9SToby Isaac   PetscAssertPointer(name, 3);
27554f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
27569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2757e5c89e4eSSatish Balay   if (flag) {
2758a297a907SKarl Rupp     if (!value) {
2759a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2760a297a907SKarl Rupp     } else {
2761a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
27629566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2763a297a907SKarl Rupp     }
2764e5c89e4eSSatish Balay   } else {
276596ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2766e5c89e4eSSatish Balay   }
27673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2768e5c89e4eSSatish Balay }
2769e5c89e4eSSatish Balay 
2770e5c89e4eSSatish Balay /*@C
2771e5c89e4eSSatish Balay   PetscOptionsGetScalar - Gets the scalar value for a particular
2772e5c89e4eSSatish Balay   option in the database.
2773e5c89e4eSSatish Balay 
2774e5c89e4eSSatish Balay   Not Collective
2775e5c89e4eSSatish Balay 
2776e5c89e4eSSatish Balay   Input Parameters:
277720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
277820f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2779e5c89e4eSSatish Balay - name    - the option one is seeking
2780e5c89e4eSSatish Balay 
2781d8d19677SJose E. Roman   Output Parameters:
27829314d9b7SBarry Smith + dvalue - the scalar value to return
2783811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2784e5c89e4eSSatish Balay 
2785e5c89e4eSSatish Balay   Level: beginner
2786e5c89e4eSSatish Balay 
278710450e9eSJacob Faibussowitsch   Example Usage:
2788eb4ae41dSBarry Smith   A complex number 2+3i must be specified with NO spaces
2789e5c89e4eSSatish Balay 
2790811af0c4SBarry Smith   Note:
27919314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
27929314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking if the `set` flag is true.
2793e4974155SBarry Smith 
2794db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2795db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2796db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2797c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2798db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2799db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2800e5c89e4eSSatish Balay @*/
2801d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2802d71ae5a4SJacob Faibussowitsch {
28032d747510SLisandro Dalcin   const char *value;
2804ace3abfcSBarry Smith   PetscBool   flag;
2805e5c89e4eSSatish Balay 
2806e5c89e4eSSatish Balay   PetscFunctionBegin;
28074f572ea9SToby Isaac   PetscAssertPointer(name, 3);
28084f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
28099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2810e5c89e4eSSatish Balay   if (flag) {
2811e5c89e4eSSatish Balay     if (!value) {
281296ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2813e5c89e4eSSatish Balay     } else {
2814e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
28159566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2816e5c89e4eSSatish Balay #else
28179566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2818e5c89e4eSSatish Balay #endif
281996ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2820e5c89e4eSSatish Balay     }
2821e5c89e4eSSatish Balay   } else { /* flag */
282296ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2823e5c89e4eSSatish Balay   }
28243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2825e5c89e4eSSatish Balay }
2826e5c89e4eSSatish Balay 
2827e5c89e4eSSatish Balay /*@C
2828e5c89e4eSSatish Balay   PetscOptionsGetString - Gets the string value for a particular option in
2829e5c89e4eSSatish Balay   the database.
2830e5c89e4eSSatish Balay 
2831e5c89e4eSSatish Balay   Not Collective
2832e5c89e4eSSatish Balay 
2833e5c89e4eSSatish Balay   Input Parameters:
283420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
283520f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
2836e5c89e4eSSatish Balay . name    - the option one is seeking
2837bcbf2dc5SJed Brown - len     - maximum length of the string including null termination
2838e5c89e4eSSatish Balay 
2839e5c89e4eSSatish Balay   Output Parameters:
2840e5c89e4eSSatish Balay + string - location to copy string
2841811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2842e5c89e4eSSatish Balay 
2843e5c89e4eSSatish Balay   Level: beginner
2844e5c89e4eSSatish Balay 
284520f4b53cSBarry Smith   Note:
28469314d9b7SBarry 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`
284720f4b53cSBarry Smith 
28489314d9b7SBarry Smith   If the user does not use the option then `string` is not changed. Thus
28499314d9b7SBarry Smith   you should ALWAYS initialize `string` if you access it without first checking that the `set` flag is true.
285020f4b53cSBarry Smith 
2851aec76313SJacob Faibussowitsch   Fortran Notes:
2852e5c89e4eSSatish Balay   The Fortran interface is slightly different from the C/C++
2853e5c89e4eSSatish Balay   interface (len is not used).  Sample usage in Fortran follows
2854e5c89e4eSSatish Balay .vb
2855e5c89e4eSSatish Balay       character *20    string
285693e6ba5cSBarry Smith       PetscErrorCode   ierr
285793e6ba5cSBarry Smith       PetscBool        set
28581b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2859e5c89e4eSSatish Balay .ve
2860e5c89e4eSSatish Balay 
2861db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2862db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2863db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2864c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2865db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2866db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2867e5c89e4eSSatish Balay @*/
2868d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set)
2869d71ae5a4SJacob Faibussowitsch {
28702d747510SLisandro Dalcin   const char *value;
2871ace3abfcSBarry Smith   PetscBool   flag;
2872e5c89e4eSSatish Balay 
2873e5c89e4eSSatish Balay   PetscFunctionBegin;
28744f572ea9SToby Isaac   PetscAssertPointer(name, 3);
28754f572ea9SToby Isaac   PetscAssertPointer(string, 4);
28769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2877e5c89e4eSSatish Balay   if (!flag) {
287896ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2879e5c89e4eSSatish Balay   } else {
288096ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
28819566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
28829566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2883e5c89e4eSSatish Balay   }
28843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2885e5c89e4eSSatish Balay }
2886e5c89e4eSSatish Balay 
28872d747510SLisandro Dalcin /*@C
28882d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2889f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
28902d747510SLisandro Dalcin 
28912d747510SLisandro Dalcin   Not Collective
28922d747510SLisandro Dalcin 
28932d747510SLisandro Dalcin   Input Parameters:
289420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
289520f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
28966b867d5aSJose E. Roman - name    - the option one is seeking
28976b867d5aSJose E. Roman 
2898d8d19677SJose E. Roman   Output Parameters:
28999314d9b7SBarry Smith + dvalue - the Boolean values to return
2900f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2901811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
29022d747510SLisandro Dalcin 
29032d747510SLisandro Dalcin   Level: beginner
29042d747510SLisandro Dalcin 
2905811af0c4SBarry Smith   Note:
290620f4b53cSBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`. FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
29072d747510SLisandro Dalcin 
2908db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2909db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2910db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2911c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2912db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2913db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29142d747510SLisandro Dalcin @*/
2915d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2916d71ae5a4SJacob Faibussowitsch {
29172d747510SLisandro Dalcin   const char *svalue;
29182d747510SLisandro Dalcin   char       *value;
29192d747510SLisandro Dalcin   PetscInt    n = 0;
29202d747510SLisandro Dalcin   PetscBool   flag;
29212d747510SLisandro Dalcin   PetscToken  token;
29222d747510SLisandro Dalcin 
29232d747510SLisandro Dalcin   PetscFunctionBegin;
29244f572ea9SToby Isaac   PetscAssertPointer(name, 3);
29254f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
29264f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
29272d747510SLisandro Dalcin 
29289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29299371c9d4SSatish Balay   if (!flag || !svalue) {
29309371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29319371c9d4SSatish Balay     *nmax = 0;
29323ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29339371c9d4SSatish Balay   }
29342d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29359566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29369566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29372d747510SLisandro Dalcin   while (value && n < *nmax) {
29389566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
29399566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29402d747510SLisandro Dalcin     dvalue++;
29412d747510SLisandro Dalcin     n++;
29422d747510SLisandro Dalcin   }
29439566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29442d747510SLisandro Dalcin   *nmax = n;
29453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29462d747510SLisandro Dalcin }
29472d747510SLisandro Dalcin 
29482d747510SLisandro Dalcin /*@C
29492d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
29502d747510SLisandro Dalcin 
29512d747510SLisandro Dalcin   Not Collective
29522d747510SLisandro Dalcin 
29532d747510SLisandro Dalcin   Input Parameters:
295420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
295520f4b53cSBarry Smith . pre     - option prefix or `NULL`
29562d747510SLisandro Dalcin . name    - option name
29576b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
29586b867d5aSJose E. Roman 
29592d747510SLisandro Dalcin   Output Parameters:
29602d747510SLisandro Dalcin + ivalue - the  enum values to return
2961f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2962811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
29632d747510SLisandro Dalcin 
29642d747510SLisandro Dalcin   Level: beginner
29652d747510SLisandro Dalcin 
29662d747510SLisandro Dalcin   Notes:
29679314d9b7SBarry Smith   The array must be passed as a comma separated list with no spaces between the items.
29682d747510SLisandro Dalcin 
29699314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names.
29702d747510SLisandro Dalcin 
2971db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2972db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2973aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsName()`,
2974c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2975db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2976db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
29772d747510SLisandro Dalcin @*/
2978d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const *list, PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
2979d71ae5a4SJacob Faibussowitsch {
29802d747510SLisandro Dalcin   const char *svalue;
29812d747510SLisandro Dalcin   char       *value;
29822d747510SLisandro Dalcin   PetscInt    n = 0;
29832d747510SLisandro Dalcin   PetscEnum   evalue;
29842d747510SLisandro Dalcin   PetscBool   flag;
29852d747510SLisandro Dalcin   PetscToken  token;
29862d747510SLisandro Dalcin 
29872d747510SLisandro Dalcin   PetscFunctionBegin;
29884f572ea9SToby Isaac   PetscAssertPointer(name, 3);
29894f572ea9SToby Isaac   PetscAssertPointer(list, 4);
29904f572ea9SToby Isaac   PetscAssertPointer(ivalue, 5);
29914f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
29922d747510SLisandro Dalcin 
29939566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29949371c9d4SSatish Balay   if (!flag || !svalue) {
29959371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29969371c9d4SSatish Balay     *nmax = 0;
29973ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29989371c9d4SSatish Balay   }
29992d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30009566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30019566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30022d747510SLisandro Dalcin   while (value && n < *nmax) {
30039566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
300428b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
30052d747510SLisandro Dalcin     ivalue[n++] = evalue;
30069566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30072d747510SLisandro Dalcin   }
30089566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30092d747510SLisandro Dalcin   *nmax = n;
30103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30112d747510SLisandro Dalcin }
30122d747510SLisandro Dalcin 
30132d747510SLisandro Dalcin /*@C
3014f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
30152d747510SLisandro Dalcin 
30162d747510SLisandro Dalcin   Not Collective
30172d747510SLisandro Dalcin 
30182d747510SLisandro Dalcin   Input Parameters:
301920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
302020f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
30216b867d5aSJose E. Roman - name    - the option one is seeking
30226b867d5aSJose E. Roman 
3023d8d19677SJose E. Roman   Output Parameters:
30242d747510SLisandro Dalcin + ivalue - the integer values to return
3025f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3026811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
30272d747510SLisandro Dalcin 
30282d747510SLisandro Dalcin   Level: beginner
30292d747510SLisandro Dalcin 
30302d747510SLisandro Dalcin   Notes:
30312d747510SLisandro Dalcin   The array can be passed as
3032811af0c4SBarry Smith +  a comma separated list -                                 0,1,2,3,4,5,6,7
3033811af0c4SBarry Smith .  a range (start\-end+1) -                                 0-8
3034811af0c4SBarry Smith .  a range with given increment (start\-end+1:inc) -        0-7:2
3035811af0c4SBarry Smith -  a combination of values and ranges separated by commas - 0,1-8,8-15:2
30362d747510SLisandro Dalcin 
30372d747510SLisandro Dalcin   There must be no intervening spaces between the values.
30382d747510SLisandro Dalcin 
3039db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3040db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3041db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3042c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3043db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3044db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30452d747510SLisandro Dalcin @*/
3046d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
3047d71ae5a4SJacob Faibussowitsch {
30482d747510SLisandro Dalcin   const char *svalue;
30492d747510SLisandro Dalcin   char       *value;
30502d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
30512d747510SLisandro Dalcin   size_t      len;
30522d747510SLisandro Dalcin   PetscBool   flag, foundrange;
30532d747510SLisandro Dalcin   PetscToken  token;
30542d747510SLisandro Dalcin 
30552d747510SLisandro Dalcin   PetscFunctionBegin;
30564f572ea9SToby Isaac   PetscAssertPointer(name, 3);
30574f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
30584f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
30592d747510SLisandro Dalcin 
30609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30619371c9d4SSatish Balay   if (!flag || !svalue) {
30629371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30639371c9d4SSatish Balay     *nmax = 0;
30643ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
30659371c9d4SSatish Balay   }
30662d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30679566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30689566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30692d747510SLisandro Dalcin   while (value && n < *nmax) {
30702d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
30712d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
30729566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value, &len));
30732d747510SLisandro Dalcin     if (value[0] == '-') i = 2;
30742d747510SLisandro Dalcin     else i = 1;
30752d747510SLisandro Dalcin     for (; i < (int)len; i++) {
30762d747510SLisandro Dalcin       if (value[i] == '-') {
3077cc73adaaSBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
30782d747510SLisandro Dalcin         value[i] = 0;
30792d747510SLisandro Dalcin 
30809566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value, &start));
30812d747510SLisandro Dalcin         inc = 1;
30822d747510SLisandro Dalcin         j   = i + 1;
30832d747510SLisandro Dalcin         for (; j < (int)len; j++) {
30842d747510SLisandro Dalcin           if (value[j] == ':') {
30852d747510SLisandro Dalcin             value[j] = 0;
30862d747510SLisandro Dalcin 
30879566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value + j + 1, &inc));
308808401ef6SPierre Jolivet             PetscCheck(inc > 0, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry,%s cannot have negative increment", n, value + j + 1);
30892d747510SLisandro Dalcin             break;
30902d747510SLisandro Dalcin           }
30912d747510SLisandro Dalcin         }
30929566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
309308401ef6SPierre Jolivet         PetscCheck(end > start, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, %s-%s cannot have decreasing list", n, value, value + i + 1);
30942d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
3095cc73adaaSBarry 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);
30962d747510SLisandro Dalcin         for (; start < end; start += inc) {
30979371c9d4SSatish Balay           *ivalue = start;
30989371c9d4SSatish Balay           ivalue++;
30999371c9d4SSatish Balay           n++;
31002d747510SLisandro Dalcin         }
31012d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
31022d747510SLisandro Dalcin         break;
31032d747510SLisandro Dalcin       }
31042d747510SLisandro Dalcin     }
31052d747510SLisandro Dalcin     if (!foundrange) {
31069566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
31072d747510SLisandro Dalcin       ivalue++;
31082d747510SLisandro Dalcin       n++;
31092d747510SLisandro Dalcin     }
31109566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
31112d747510SLisandro Dalcin   }
31129566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
31132d747510SLisandro Dalcin   *nmax = n;
31143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31152d747510SLisandro Dalcin }
31162d747510SLisandro Dalcin 
31172d747510SLisandro Dalcin /*@C
31182d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
3119f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
31202d747510SLisandro Dalcin 
31212d747510SLisandro Dalcin   Not Collective
31222d747510SLisandro Dalcin 
31232d747510SLisandro Dalcin   Input Parameters:
312420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
312520f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
31266b867d5aSJose E. Roman - name    - the option one is seeking
31276b867d5aSJose E. Roman 
31282d747510SLisandro Dalcin   Output Parameters:
31292d747510SLisandro Dalcin + dvalue - the double values to return
3130f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3131811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
31322d747510SLisandro Dalcin 
31332d747510SLisandro Dalcin   Level: beginner
31342d747510SLisandro Dalcin 
3135db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3136db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3137db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3138c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3139db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3140db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
31412d747510SLisandro Dalcin @*/
3142d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
3143d71ae5a4SJacob Faibussowitsch {
31442d747510SLisandro Dalcin   const char *svalue;
31452d747510SLisandro Dalcin   char       *value;
31462d747510SLisandro Dalcin   PetscInt    n = 0;
31472d747510SLisandro Dalcin   PetscBool   flag;
31482d747510SLisandro Dalcin   PetscToken  token;
31492d747510SLisandro Dalcin 
31502d747510SLisandro Dalcin   PetscFunctionBegin;
31514f572ea9SToby Isaac   PetscAssertPointer(name, 3);
31524f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
31534f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
31542d747510SLisandro Dalcin 
31559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
31569371c9d4SSatish Balay   if (!flag || !svalue) {
31579371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
31589371c9d4SSatish Balay     *nmax = 0;
31593ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
31609371c9d4SSatish Balay   }
31612d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31629566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31639566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31642d747510SLisandro Dalcin   while (value && n < *nmax) {
31659566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
31669566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
31672d747510SLisandro Dalcin     n++;
31682d747510SLisandro Dalcin   }
31699566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
31702d747510SLisandro Dalcin   *nmax = n;
31713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31722d747510SLisandro Dalcin }
31732d747510SLisandro Dalcin 
31742d747510SLisandro Dalcin /*@C
31752d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
3176f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
31772d747510SLisandro Dalcin 
31782d747510SLisandro Dalcin   Not Collective
31792d747510SLisandro Dalcin 
31802d747510SLisandro Dalcin   Input Parameters:
318120f4b53cSBarry Smith + options - options database, use `NULL` for default global database
318220f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
31836b867d5aSJose E. Roman - name    - the option one is seeking
31846b867d5aSJose E. Roman 
31852d747510SLisandro Dalcin   Output Parameters:
31862d747510SLisandro Dalcin + dvalue - the scalar values to return
3187f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3188811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
31892d747510SLisandro Dalcin 
31902d747510SLisandro Dalcin   Level: beginner
31912d747510SLisandro Dalcin 
3192db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3193db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3194db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3195c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3196db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3197db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
31982d747510SLisandro Dalcin @*/
3199d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3200d71ae5a4SJacob Faibussowitsch {
32012d747510SLisandro Dalcin   const char *svalue;
32022d747510SLisandro Dalcin   char       *value;
32032d747510SLisandro Dalcin   PetscInt    n = 0;
32042d747510SLisandro Dalcin   PetscBool   flag;
32052d747510SLisandro Dalcin   PetscToken  token;
32062d747510SLisandro Dalcin 
32072d747510SLisandro Dalcin   PetscFunctionBegin;
32084f572ea9SToby Isaac   PetscAssertPointer(name, 3);
32094f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
32104f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
32112d747510SLisandro Dalcin 
32129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
32139371c9d4SSatish Balay   if (!flag || !svalue) {
32149371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
32159371c9d4SSatish Balay     *nmax = 0;
32163ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
32179371c9d4SSatish Balay   }
32182d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
32199566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
32209566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
32212d747510SLisandro Dalcin   while (value && n < *nmax) {
32229566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value, dvalue++));
32239566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
32242d747510SLisandro Dalcin     n++;
32252d747510SLisandro Dalcin   }
32269566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
32272d747510SLisandro Dalcin   *nmax = n;
32283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32292d747510SLisandro Dalcin }
323014ce751eSBarry Smith 
3231e5c89e4eSSatish Balay /*@C
3232e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
3233f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
3234e5c89e4eSSatish Balay 
3235cf53795eSBarry Smith   Not Collective; No Fortran Support
3236e5c89e4eSSatish Balay 
3237e5c89e4eSSatish Balay   Input Parameters:
323820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
323920f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
32406b867d5aSJose E. Roman - name    - the option one is seeking
32416b867d5aSJose E. Roman 
3242e7b76fa7SPatrick Sanan   Output Parameters:
3243e5c89e4eSSatish Balay + strings - location to copy strings
3244f1a722f8SMatthew G. Knepley . nmax    - On input maximum number of strings, on output the actual number of strings found
3245811af0c4SBarry Smith - set     - `PETSC_TRUE` if found, else `PETSC_FALSE`
3246e5c89e4eSSatish Balay 
3247e5c89e4eSSatish Balay   Level: beginner
3248e5c89e4eSSatish Balay 
3249e5c89e4eSSatish Balay   Notes:
32509314d9b7SBarry Smith   The `nmax` parameter is used for both input and output.
3251e7b76fa7SPatrick Sanan 
3252e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
3253e5c89e4eSSatish Balay   strings returned by this function.
3254e5c89e4eSSatish Balay 
3255e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3256cf53795eSBarry Smith   returned.
3257e5c89e4eSSatish Balay 
3258db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3259db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3260db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3261c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3262db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3263db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3264e5c89e4eSSatish Balay @*/
3265d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set)
3266d71ae5a4SJacob Faibussowitsch {
32672d747510SLisandro Dalcin   const char *svalue;
3268e5c89e4eSSatish Balay   char       *value;
32692d747510SLisandro Dalcin   PetscInt    n = 0;
3270ace3abfcSBarry Smith   PetscBool   flag;
32719c9d3cfdSBarry Smith   PetscToken  token;
3272e5c89e4eSSatish Balay 
3273e5c89e4eSSatish Balay   PetscFunctionBegin;
32744f572ea9SToby Isaac   PetscAssertPointer(name, 3);
32754f572ea9SToby Isaac   PetscAssertPointer(strings, 4);
32764f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
3277e5c89e4eSSatish Balay 
32789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
32799371c9d4SSatish Balay   if (!flag || !svalue) {
32809371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
32819371c9d4SSatish Balay     *nmax = 0;
32823ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
32839371c9d4SSatish Balay   }
32842d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
32859566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
32869566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
32872d747510SLisandro Dalcin   while (value && n < *nmax) {
32889566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
32899566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3290e5c89e4eSSatish Balay     n++;
3291e5c89e4eSSatish Balay   }
32929566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3293e5c89e4eSSatish Balay   *nmax = n;
32943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3295e5c89e4eSSatish Balay }
329606824ed3SPatrick Sanan 
329706824ed3SPatrick Sanan /*@C
3298aec76313SJacob Faibussowitsch   PetscOptionsDeprecated_Private - mark an option as deprecated, optionally replacing it with `newname`
329906824ed3SPatrick Sanan 
330006824ed3SPatrick Sanan   Prints a deprecation warning, unless an option is supplied to suppress.
330106824ed3SPatrick Sanan 
33021c9f3c13SBarry Smith   Logically Collective
330306824ed3SPatrick Sanan 
330406824ed3SPatrick Sanan   Input Parameters:
3305aec76313SJacob Faibussowitsch + PetscOptionsObject - string to prepend to name or `NULL`
330606824ed3SPatrick Sanan . oldname            - the old, deprecated option
330720f4b53cSBarry Smith . newname            - the new option, or `NULL` if option is purely removed
33089f3a6782SPatrick Sanan . version            - a string describing the version of first deprecation, e.g. "3.9"
330920f4b53cSBarry Smith - info               - additional information string, or `NULL`.
331006824ed3SPatrick Sanan 
3311811af0c4SBarry Smith   Options Database Key:
331206824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
331306824ed3SPatrick Sanan 
331420f4b53cSBarry Smith   Level: developer
331520f4b53cSBarry Smith 
331606824ed3SPatrick Sanan   Notes:
33174ead3382SBarry Smith   If `newname` is provided then the options database will automatically check the database for `oldname`.
33184ead3382SBarry Smith 
33194ead3382SBarry Smith   The old call `PetscOptionsXXX`(`oldname`) should be removed from the source code when both (1) the call to `PetscOptionsDeprecated()` occurs before the
33204ead3382SBarry Smith   new call to `PetscOptionsXXX`(`newname`) and (2) the argument handling of the new call to `PetscOptionsXXX`(`newname`) is identical to the previous call.
33214ead3382SBarry Smith   See `PTScotch_PartGraph_Seq()` for an example of when (1) fails and `SNESTestJacobian()` where an example of (2) fails.
33224ead3382SBarry Smith 
3323811af0c4SBarry Smith   Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
332435cb6cd3SPierre Jolivet   Only the process of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3325811af0c4SBarry Smith   `PetscObjectOptionsBegin()` prints the information
3326b40114eaSPatrick Sanan   If newname is provided, the old option is replaced. Otherwise, it remains
3327b40114eaSPatrick Sanan   in the options database.
33289f3a6782SPatrick Sanan   If an option is not replaced, the info argument should be used to advise the user
33299f3a6782SPatrick Sanan   on how to proceed.
33309f3a6782SPatrick Sanan   There is a limit on the length of the warning printed, so very long strings
33319f3a6782SPatrick Sanan   provided as info may be truncated.
333206824ed3SPatrick Sanan 
3333db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
333406824ed3SPatrick Sanan @*/
3335d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3336d71ae5a4SJacob Faibussowitsch {
333706824ed3SPatrick Sanan   PetscBool         found, quiet;
333806824ed3SPatrick Sanan   const char       *value;
333906824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
33409f3a6782SPatrick Sanan   char              msg[4096];
3341b0bdc838SStefano Zampini   char             *prefix  = NULL;
3342b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3343b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
334406824ed3SPatrick Sanan 
334506824ed3SPatrick Sanan   PetscFunctionBegin;
33464f572ea9SToby Isaac   PetscAssertPointer(oldname, 2);
33474f572ea9SToby Isaac   PetscAssertPointer(version, 4);
3348b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3349b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3350b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3351b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3352b0bdc838SStefano Zampini   }
33539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
335406824ed3SPatrick Sanan   if (found) {
335506824ed3SPatrick Sanan     if (newname) {
33561baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
33579566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options, newname, value));
33581baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
33599566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3360b40114eaSPatrick Sanan     }
336106824ed3SPatrick Sanan     quiet = PETSC_FALSE;
33629566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
336306824ed3SPatrick Sanan     if (!quiet) {
3364c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option ", sizeof(msg)));
3365c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, oldname, sizeof(msg)));
3366c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3367c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
33684bd3d7f8SBarry Smith       PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
336906824ed3SPatrick Sanan       if (newname) {
33704bd3d7f8SBarry Smith         PetscCall(PetscStrlcat(msg, "   Use the option ", sizeof(msg)));
3371c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, newname, sizeof(msg)));
3372c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
337306824ed3SPatrick Sanan       }
33749f3a6782SPatrick Sanan       if (info) {
3375c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3376c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
33779f3a6782SPatrick Sanan       }
3378c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3379c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3380c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
33819566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
338206824ed3SPatrick Sanan     }
338306824ed3SPatrick Sanan   }
33843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
338506824ed3SPatrick Sanan }
3386