xref: /petsc/src/sys/objects/options.c (revision 49abdd8a111d9c2ef7fc48ade253ef64e07f9b37)
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 */
99*49abdd8aSBarry Smith   PetscCtxDestroyFn *monitordestroy[MAXOPTIONSMONITORS];                                                /* callback for monitor destruction */
100081c24baSBoyana Norris   void              *monitorcontext[MAXOPTIONSMONITORS];                                                /* to pass arbitrary user data into monitor */
101081c24baSBoyana Norris   PetscInt           numbermonitors;                                                                    /* to, for instance, detect options being set */
1024416b707SBarry Smith };
103e5c89e4eSSatish Balay 
104b4205f0bSBarry Smith static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
1052d747510SLisandro Dalcin 
106aaa8cc7dSPierre Jolivet /* list of options which precede others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
107660278c0SBarry Smith /* these options can only take boolean values, the code will crash if given a non-boolean value */
108660278c0SBarry Smith static const char *precedentOptions[] = {"-petsc_ci", "-options_monitor", "-options_monitor_cancel", "-help", "-skip_petscrc"};
1099371c9d4SSatish Balay enum PetscPrecedentOption {
1109371c9d4SSatish Balay   PO_CI_ENABLE,
1119371c9d4SSatish Balay   PO_OPTIONS_MONITOR,
1129371c9d4SSatish Balay   PO_OPTIONS_MONITOR_CANCEL,
1139371c9d4SSatish Balay   PO_HELP,
1149371c9d4SSatish Balay   PO_SKIP_PETSCRC,
1159371c9d4SSatish Balay   PO_NUM
1169371c9d4SSatish Balay };
117c5b5d8d5SVaclav Hapla 
1189355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsSetValue_Private(PetscOptions, const char[], const char[], int *, PetscOptionSource);
1199355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsInsertStringYAML_Private(PetscOptions, const char[], PetscOptionSource);
120c5b5d8d5SVaclav Hapla 
121081c24baSBoyana Norris /*
122081c24baSBoyana Norris     Options events monitor
123081c24baSBoyana Norris */
1249355ec05SMatthew G. Knepley static PetscErrorCode PetscOptionsMonitor(PetscOptions options, const char name[], const char value[], PetscOptionSource source)
125d71ae5a4SJacob Faibussowitsch {
126e5c89e4eSSatish Balay   PetscFunctionBegin;
1279355ec05SMatthew G. Knepley   if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name, value, source, NULL));
1289355ec05SMatthew G. Knepley   for (PetscInt i = 0; i < options->numbermonitors; i++) PetscCall((*options->monitor[i])(name, value, source, options->monitorcontext[i]));
1293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
130e5c89e4eSSatish Balay }
131e5c89e4eSSatish Balay 
1322d747510SLisandro Dalcin /*@
1332d747510SLisandro Dalcin   PetscOptionsCreate - Creates an empty options database.
134e5c89e4eSSatish Balay 
13520f4b53cSBarry Smith   Logically Collective
1361c9f3c13SBarry Smith 
137e5c89e4eSSatish Balay   Output Parameter:
1382d747510SLisandro Dalcin . options - Options database object
139e5c89e4eSSatish Balay 
140e5c89e4eSSatish Balay   Level: advanced
141e5c89e4eSSatish Balay 
142811af0c4SBarry Smith   Note:
143811af0c4SBarry Smith   Though PETSc has a concept of multiple options database the current code uses a single default `PetscOptions` object
144811af0c4SBarry Smith 
145811af0c4SBarry Smith   Developer Notes:
146811af0c4SBarry Smith   We may want eventually to pass a `MPI_Comm` to determine the ownership of the object
147811af0c4SBarry Smith 
148811af0c4SBarry Smith   This object never got developed after being introduced, it is not clear that supporting multiple `PetscOptions` objects is useful
1491c9f3c13SBarry Smith 
150db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
151e5c89e4eSSatish Balay @*/
152d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreate(PetscOptions *options)
153d71ae5a4SJacob Faibussowitsch {
15439a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1554f572ea9SToby Isaac   PetscAssertPointer(options, 1);
1562d747510SLisandro Dalcin   *options = (PetscOptions)calloc(1, sizeof(**options));
15739a651e2SJacob Faibussowitsch   PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
1583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1592d747510SLisandro Dalcin }
1602d747510SLisandro Dalcin 
1612d747510SLisandro Dalcin /*@
1622d747510SLisandro Dalcin   PetscOptionsDestroy - Destroys an option database.
1632d747510SLisandro Dalcin 
16420f4b53cSBarry Smith   Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
1651c9f3c13SBarry Smith 
1662d747510SLisandro Dalcin   Input Parameter:
167811af0c4SBarry Smith . options - the `PetscOptions` object
1682d747510SLisandro Dalcin 
1693de2bfdfSBarry Smith   Level: advanced
1702d747510SLisandro Dalcin 
171aec76313SJacob Faibussowitsch .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsSetValue()`
1722d747510SLisandro Dalcin @*/
173d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
174d71ae5a4SJacob Faibussowitsch {
175362febeeSStefano Zampini   PetscFunctionBegin;
1764f572ea9SToby Isaac   PetscAssertPointer(options, 1);
1773ba16761SJacob Faibussowitsch   if (!*options) PetscFunctionReturn(PETSC_SUCCESS);
1785f80ce2aSJacob Faibussowitsch   PetscCheck(!(*options)->previous, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "You are destroying an option that has been used with PetscOptionsPush() but does not have a corresponding PetscOptionsPop()");
1799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsClear(*options));
1802d747510SLisandro Dalcin   /* XXX what about monitors ? */
1812800570dSLisandro Dalcin   free(*options);
1822d747510SLisandro Dalcin   *options = NULL;
1833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
184e5c89e4eSSatish Balay }
185e5c89e4eSSatish Balay 
1862d747510SLisandro Dalcin /*
1872d747510SLisandro Dalcin     PetscOptionsCreateDefault - Creates the default global options database
1882d747510SLisandro Dalcin */
189d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreateDefault(void)
190d71ae5a4SJacob Faibussowitsch {
19139a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1929566063dSJacob Faibussowitsch   if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
1933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1942d747510SLisandro Dalcin }
1952d747510SLisandro Dalcin 
196b4205f0bSBarry Smith /*@
197811af0c4SBarry Smith   PetscOptionsPush - Push a new `PetscOptions` object as the default provider of options
1981c9f3c13SBarry Smith   Allows using different parts of a code to use different options databases
199b4205f0bSBarry Smith 
200b4205f0bSBarry Smith   Logically Collective
201b4205f0bSBarry Smith 
202b4205f0bSBarry Smith   Input Parameter:
203811af0c4SBarry Smith . opt - the options obtained with `PetscOptionsCreate()`
204b4205f0bSBarry Smith 
20520f4b53cSBarry Smith   Level: advanced
20620f4b53cSBarry Smith 
207b4205f0bSBarry Smith   Notes:
208811af0c4SBarry Smith   Use `PetscOptionsPop()` to return to the previous default options database
2091c9f3c13SBarry Smith 
210811af0c4SBarry Smith   The collectivity of this routine is complex; only the MPI ranks that call this routine will
2111c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
2121c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
2131c9f3c13SBarry Smith   on different ranks.
214b4205f0bSBarry Smith 
215aec76313SJacob Faibussowitsch   Developer Notes:
216811af0c4SBarry Smith   Though this functionality has been provided it has never been used in PETSc and might be removed.
217811af0c4SBarry Smith 
218db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
219b4205f0bSBarry Smith @*/
220d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPush(PetscOptions opt)
221d71ae5a4SJacob Faibussowitsch {
222b4205f0bSBarry Smith   PetscFunctionBegin;
2239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsCreateDefault());
224b4205f0bSBarry Smith   opt->previous  = defaultoptions;
225b4205f0bSBarry Smith   defaultoptions = opt;
2263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
227b4205f0bSBarry Smith }
228b4205f0bSBarry Smith 
229b4205f0bSBarry Smith /*@
230811af0c4SBarry Smith   PetscOptionsPop - Pop the most recent `PetscOptionsPush()` to return to the previous default options
231b4205f0bSBarry Smith 
23220f4b53cSBarry Smith   Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
233b4205f0bSBarry Smith 
2343de2bfdfSBarry Smith   Level: advanced
2353de2bfdfSBarry Smith 
23642747ad1SJacob Faibussowitsch .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
237b4205f0bSBarry Smith @*/
238d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPop(void)
239d71ae5a4SJacob Faibussowitsch {
2403de2bfdfSBarry Smith   PetscOptions current = defaultoptions;
2413de2bfdfSBarry Smith 
242b4205f0bSBarry Smith   PetscFunctionBegin;
24328b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing default options");
24428b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions->previous, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscOptionsPop() called too many times");
245b4205f0bSBarry Smith   defaultoptions    = defaultoptions->previous;
2463de2bfdfSBarry Smith   current->previous = NULL;
2473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
248b4205f0bSBarry Smith }
249b4205f0bSBarry Smith 
2502d747510SLisandro Dalcin /*
2512d747510SLisandro Dalcin     PetscOptionsDestroyDefault - Destroys the default global options database
2522d747510SLisandro Dalcin */
253d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroyDefault(void)
254d71ae5a4SJacob Faibussowitsch {
25539a651e2SJacob Faibussowitsch   PetscFunctionBegin;
2563ba16761SJacob Faibussowitsch   if (!defaultoptions) PetscFunctionReturn(PETSC_SUCCESS);
2573de2bfdfSBarry Smith   /* Destroy any options that the user forgot to pop */
2583de2bfdfSBarry Smith   while (defaultoptions->previous) {
25939a651e2SJacob Faibussowitsch     PetscOptions tmp = defaultoptions;
26039a651e2SJacob Faibussowitsch 
2619566063dSJacob Faibussowitsch     PetscCall(PetscOptionsPop());
2629566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDestroy(&tmp));
2633de2bfdfSBarry Smith   }
2649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDestroy(&defaultoptions));
2653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
266e5c89e4eSSatish Balay }
267e5c89e4eSSatish Balay 
268cc4c1da9SBarry Smith /*@
2697cd08cecSJed Brown   PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
2703fc1eb6aSBarry Smith 
27120f4b53cSBarry Smith   Not Collective
2721c9f3c13SBarry Smith 
2733fc1eb6aSBarry Smith   Input Parameter:
2742d747510SLisandro Dalcin . key - string to check if valid
2753fc1eb6aSBarry Smith 
2763fc1eb6aSBarry Smith   Output Parameter:
277811af0c4SBarry Smith . valid - `PETSC_TRUE` if a valid key
2783fc1eb6aSBarry Smith 
279f6680f47SSatish Balay   Level: intermediate
28010450e9eSJacob Faibussowitsch 
28110450e9eSJacob Faibussowitsch .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`
2823fc1eb6aSBarry Smith @*/
283d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid)
284d71ae5a4SJacob Faibussowitsch {
285f603b5e9SToby Isaac   char               *ptr;
28627304958SStefano Zampini   PETSC_UNUSED double d;
2877c5db45bSBarry Smith 
28896fc60bcSBarry Smith   PetscFunctionBegin;
2894f572ea9SToby Isaac   if (key) PetscAssertPointer(key, 1);
2904f572ea9SToby Isaac   PetscAssertPointer(valid, 2);
2912d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2923ba16761SJacob Faibussowitsch   if (!key) PetscFunctionReturn(PETSC_SUCCESS);
2933ba16761SJacob Faibussowitsch   if (key[0] != '-') PetscFunctionReturn(PETSC_SUCCESS);
2942d747510SLisandro Dalcin   if (key[1] == '-') key++;
2953ba16761SJacob Faibussowitsch   if (!isalpha((int)key[1])) PetscFunctionReturn(PETSC_SUCCESS);
29627304958SStefano Zampini   d = strtod(key, &ptr);
2973ba16761SJacob Faibussowitsch   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(PETSC_SUCCESS);
2982d747510SLisandro Dalcin   *valid = PETSC_TRUE;
2993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30096fc60bcSBarry Smith }
30196fc60bcSBarry Smith 
30210c654e6SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertString_Private(PetscOptions options, const char in_str[], PetscOptionSource source)
303d71ae5a4SJacob Faibussowitsch {
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 
4729566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
4739566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
4748c0b561eSLisandro Dalcin 
475e5c89e4eSSatish Balay     fd = fopen(fname, "r");
4769566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname, 'r', &isdir));
47708401ef6SPierre Jolivet     PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
478ad38b122SPatrick Sanan     if (fd && !isdir) {
4793a018368SJed Brown       PetscSegBuffer vseg, aseg;
4809566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4819566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4823a018368SJed Brown 
4839b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4849566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
485e24ecc5dSJed Brown 
4865fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4874704e885SBarry Smith         /* eliminate comments from each line */
4889566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
48990f79514SSatish Balay         if (cmatch) *cmatch = 0;
4909566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4915981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
492dd460d27SBarry Smith         for (size_t i = 0; i < len; i++) {
493ad540459SPierre Jolivet           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
494e5c89e4eSSatish Balay         }
4959566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4969566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4977fb43599SVaclav Hapla         if (!tokens[0]) {
49802b0d46eSSatish Balay           goto destroy;
4997fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
5009566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
50190f79514SSatish Balay         }
502dd460d27SBarry Smith         for (PetscInt i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
5037fb43599SVaclav Hapla         if (!tokens[0]) {
5042662f744SSatish Balay           goto destroy;
5057fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
5069566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
50728b400f6SJacob 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]);
5089566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
5099566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
5109566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
511e24ecc5dSJed Brown           vstring[len] = ' ';
5127fb43599SVaclav Hapla           if (tokens[1]) {
5139566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
51428b400f6SJacob 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]);
5159566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5169566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
517e24ecc5dSJed Brown             vstring[0] = '"';
5189566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
519e24ecc5dSJed Brown             vstring[len + 1] = '"';
520e24ecc5dSJed Brown             vstring[len + 2] = ' ';
52109192fe3SBarry Smith           }
52290f79514SSatish Balay         } else {
5239566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
5249210b8eaSVaclav Hapla           if (alias) {
5259566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
52628b400f6SJacob 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]);
52708401ef6SPierre 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]);
5289566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
52928b400f6SJacob 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]);
5309566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5319566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5329566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
533e24ecc5dSJed Brown             astring[len] = ' ';
534e24ecc5dSJed Brown 
5359566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5369566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5379566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
538e24ecc5dSJed Brown             astring[len] = ' ';
53998921bdaSJacob 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]);
5409210b8eaSVaclav Hapla         }
5419210b8eaSVaclav Hapla         {
5429210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
54328b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
544e5c89e4eSSatish Balay         }
54502b0d46eSSatish Balay       destroy:
5464b40f50bSBarry Smith         free(string);
5479566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5489210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5499210b8eaSVaclav Hapla         line++;
550e5c89e4eSSatish Balay       }
551ed9cf6e9SBarry Smith       err = fclose(fd);
55228b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5539566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5549566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5559566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
556e24ecc5dSJed Brown       astring[0] = 0;
5579566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5589566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5599566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
560e24ecc5dSJed Brown       vstring[0] = 0;
5619566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5629566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5639566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5649566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5659566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
56628b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5679b754dc9SBarry Smith   }
56805c7dedfSBarry Smith 
5693a018368SJed Brown   counts[0] = acnt;
5703a018368SJed Brown   counts[1] = cnt;
5714201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
57228b400f6SJacob 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/");
5733a018368SJed Brown   acnt = counts[0];
5743a018368SJed Brown   cnt  = counts[1];
57548a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5763a018368SJed Brown   if (acnt || cnt) {
5779566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5783a018368SJed Brown     astring = packed;
5793a018368SJed Brown     vstring = packed + acnt + 1;
5803a018368SJed Brown   }
5813a018368SJed Brown 
5829b754dc9SBarry Smith   if (acnt) {
5839566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5849566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5857fb43599SVaclav Hapla     while (tokens[0]) {
5869566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5879566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5889566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5899b754dc9SBarry Smith     }
5909566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5919b754dc9SBarry Smith   }
5929b754dc9SBarry Smith 
5939355ec05SMatthew G. Knepley   if (cnt) PetscCall(PetscOptionsInsertString_Private(options, vstring, PETSC_OPT_FILE));
5949566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
5953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
596e5c89e4eSSatish Balay }
597e5c89e4eSSatish Balay 
5985d83a8b1SBarry Smith /*@
599be10d61cSLisandro Dalcin   PetscOptionsInsertFile - Inserts options into the database from a file.
600be10d61cSLisandro Dalcin 
601be10d61cSLisandro Dalcin   Collective
602be10d61cSLisandro Dalcin 
603d8d19677SJose E. Roman   Input Parameters:
604811af0c4SBarry Smith + comm    - the processes that will share the options (usually `PETSC_COMM_WORLD`)
60520f4b53cSBarry Smith . options - options database, use `NULL` for default global database
606be10d61cSLisandro Dalcin . file    - name of file,
607be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
608be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
609811af0c4SBarry Smith - require - if `PETSC_TRUE` will generate an error if the file does not exist
610be10d61cSLisandro Dalcin 
61120f4b53cSBarry Smith   Level: developer
61220f4b53cSBarry Smith 
613be10d61cSLisandro Dalcin   Notes:
614be10d61cSLisandro Dalcin   Use  # for lines that are comments and which should be ignored.
615811af0c4SBarry Smith   Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
61621532e8aSBarry 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
61721532e8aSBarry Smith   calls to `XXXSetFromOptions()`, it should not be used for options listed under PetscInitialize().
61821532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes in comm will
61921532e8aSBarry Smith   have the effect of these options. If some processes that create objects call this routine and others do
620be10d61cSLisandro Dalcin   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
621be10d61cSLisandro Dalcin   on different ranks.
622be10d61cSLisandro Dalcin 
623db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
624db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
625db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
626c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
627db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
628db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
629be10d61cSLisandro Dalcin @*/
630d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
631d71ae5a4SJacob Faibussowitsch {
632be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
633be10d61cSLisandro Dalcin   PetscBool yaml;
634be10d61cSLisandro Dalcin 
635be10d61cSLisandro Dalcin   PetscFunctionBegin;
6369566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
637be10d61cSLisandro Dalcin   if (yaml) {
6389566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
639be10d61cSLisandro Dalcin   } else {
6409566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
641be10d61cSLisandro Dalcin   }
6423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
643be10d61cSLisandro Dalcin }
644be10d61cSLisandro Dalcin 
645be10d61cSLisandro Dalcin /*@C
646d06005cbSLisandro Dalcin   PetscOptionsInsertArgs - Inserts options into the database from a array of strings
647d06005cbSLisandro Dalcin 
648d06005cbSLisandro Dalcin   Logically Collective
649d06005cbSLisandro Dalcin 
650d8d19677SJose E. Roman   Input Parameters:
651d06005cbSLisandro Dalcin + options - options object
6526aad120cSJose E. Roman . argc    - the array length
653d06005cbSLisandro Dalcin - args    - the string array
654d06005cbSLisandro Dalcin 
655d06005cbSLisandro Dalcin   Level: intermediate
656d06005cbSLisandro Dalcin 
657db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
658d06005cbSLisandro Dalcin @*/
659d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, char *args[])
660d71ae5a4SJacob Faibussowitsch {
661d06005cbSLisandro Dalcin   MPI_Comm     comm  = PETSC_COMM_WORLD;
662d06005cbSLisandro Dalcin   int          left  = PetscMax(argc, 0);
663d06005cbSLisandro Dalcin   char *const *eargs = args;
66485079163SJed Brown 
66585079163SJed Brown   PetscFunctionBegin;
66685079163SJed Brown   while (left) {
667d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6689566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6699566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6709566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6719566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6729566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6739566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
674093de6efSBarry Smith     if (!key) {
6759371c9d4SSatish Balay       eargs++;
6769371c9d4SSatish Balay       left--;
677d06005cbSLisandro Dalcin     } else if (isfile) {
678cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6799566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6809371c9d4SSatish Balay       eargs += 2;
6819371c9d4SSatish Balay       left -= 2;
682d06005cbSLisandro Dalcin     } else if (isfileyaml) {
683cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6849566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6859371c9d4SSatish Balay       eargs += 2;
6869371c9d4SSatish Balay       left -= 2;
687d06005cbSLisandro Dalcin     } else if (isstringyaml) {
688cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6899355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
6909371c9d4SSatish Balay       eargs += 2;
6919371c9d4SSatish Balay       left -= 2;
692d06005cbSLisandro Dalcin     } else if (ispush) {
69308401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
694cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6959566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6969371c9d4SSatish Balay       eargs += 2;
6979371c9d4SSatish Balay       left -= 2;
698d06005cbSLisandro Dalcin     } else if (ispop) {
6999566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
7009371c9d4SSatish Balay       eargs++;
7019371c9d4SSatish Balay       left--;
7027935c3d8SJed Brown     } else {
7037935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
7049566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
70598b6bf53SJed Brown       if (left < 2 || nextiskey) {
7069355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
7079371c9d4SSatish Balay         eargs++;
7089371c9d4SSatish Balay         left--;
70985079163SJed Brown       } else {
7109355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
7119371c9d4SSatish Balay         eargs += 2;
7129371c9d4SSatish Balay         left -= 2;
71385079163SJed Brown       }
71485079163SJed Brown     }
7157935c3d8SJed Brown   }
7163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71785079163SJed Brown }
71885079163SJed Brown 
71910c654e6SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], const PetscBool set[], PetscBool *flg)
720d71ae5a4SJacob Faibussowitsch {
721c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
722c5b5d8d5SVaclav Hapla   if (set[opt]) {
7239566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
724c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
7253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
726c5b5d8d5SVaclav Hapla }
727c5b5d8d5SVaclav Hapla 
728660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
729d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
730d71ae5a4SJacob Faibussowitsch {
731c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
732c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
733c5b5d8d5SVaclav Hapla   size_t             o;
734c5b5d8d5SVaclav Hapla   int                a;
735c5b5d8d5SVaclav Hapla   const char       **val;
7360c99d500SBarry Smith   char             **cval;
737660278c0SBarry Smith   PetscBool         *set, unneeded;
738c5b5d8d5SVaclav Hapla 
739c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7400c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7410c99d500SBarry Smith   val = (const char **)cval;
742c5b5d8d5SVaclav Hapla 
743c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
74448a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
745c5b5d8d5SVaclav Hapla 
746a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
747c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
748c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
749c5b5d8d5SVaclav Hapla 
7509566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
751c5b5d8d5SVaclav Hapla     if (!valid) continue;
752c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7539566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
754c5b5d8d5SVaclav Hapla       if (eq) {
755c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
756c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
757c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
758c5b5d8d5SVaclav Hapla         break;
759c5b5d8d5SVaclav Hapla       }
760c5b5d8d5SVaclav Hapla     }
761c5b5d8d5SVaclav Hapla   }
762c5b5d8d5SVaclav Hapla 
763c5b5d8d5SVaclav Hapla   /* Process flags */
7649566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
765d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7669566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
767660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
768660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
7699355ec05SMatthew G. Knepley   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
7709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
773c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
774c5b5d8d5SVaclav Hapla 
775c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
776660278c0SBarry Smith   for (o = 1; o < n; o++) {
777c5b5d8d5SVaclav Hapla     if (set[o]) {
7789355ec05SMatthew G. Knepley       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
779d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
780c5b5d8d5SVaclav Hapla     }
781c5b5d8d5SVaclav Hapla   }
7820c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
783c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
7843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
785c5b5d8d5SVaclav Hapla }
786c5b5d8d5SVaclav Hapla 
787d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
788d71ae5a4SJacob Faibussowitsch {
78939a651e2SJacob Faibussowitsch   PetscFunctionBegin;
7904f572ea9SToby Isaac   PetscAssertPointer(flg, 3);
791c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
792c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
79339a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
794c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
795c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7969566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
797c5b5d8d5SVaclav Hapla         if (*flg) break;
798c5b5d8d5SVaclav Hapla       }
799c5b5d8d5SVaclav Hapla     }
800c5b5d8d5SVaclav Hapla   }
8013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
802c5b5d8d5SVaclav Hapla }
80385079163SJed Brown 
804e5c89e4eSSatish Balay /*@C
805e5c89e4eSSatish Balay   PetscOptionsInsert - Inserts into the options database from the command line,
806e5c89e4eSSatish Balay   the environmental variable and a file.
807e5c89e4eSSatish Balay 
808811af0c4SBarry Smith   Collective on `PETSC_COMM_WORLD`
8091c9f3c13SBarry Smith 
810e5c89e4eSSatish Balay   Input Parameters:
81120f4b53cSBarry Smith + options - options database or `NULL` for the default global database
812c5929fdfSBarry Smith . argc    - count of number of command line arguments
813e5c89e4eSSatish Balay . args    - the command line arguments
814be10d61cSLisandro Dalcin - file    - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
81520f4b53cSBarry Smith           Use `NULL` or empty string to not check for code specific file.
816be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
817c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
818e5c89e4eSSatish Balay 
819081c24baSBoyana Norris   Options Database Keys:
820d06005cbSLisandro Dalcin + -options_file <filename>      - read options from a file
821d06005cbSLisandro Dalcin - -options_file_yaml <filename> - read options from a YAML file
822c5b5d8d5SVaclav Hapla 
82320f4b53cSBarry Smith   Level: advanced
82420f4b53cSBarry Smith 
825811af0c4SBarry Smith   Notes:
82620f4b53cSBarry Smith   Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
827811af0c4SBarry Smith   the user does not typically need to call this routine. `PetscOptionsInsert()`
828811af0c4SBarry Smith   can be called several times, adding additional entries into the database.
829811af0c4SBarry Smith 
830811af0c4SBarry Smith   See `PetscInitialize()` for options related to option database monitoring.
831081c24baSBoyana Norris 
832db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
833db781477SPatrick Sanan           `PetscInitialize()`
834e5c89e4eSSatish Balay @*/
835d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[])
836d71ae5a4SJacob Faibussowitsch {
837d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
838e5c89e4eSSatish Balay   PetscMPIInt rank;
839c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
840c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
8416497c311SBarry Smith   char       *eoptions = NULL;
8426497c311SBarry Smith   size_t      len      = 0;
843e5c89e4eSSatish Balay 
844e5c89e4eSSatish Balay   PetscFunctionBegin;
84508401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8469566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
847e5c89e4eSSatish Balay 
848c5b5d8d5SVaclav Hapla   if (!options) {
8499566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
850c5b5d8d5SVaclav Hapla     options = defaultoptions;
851c5b5d8d5SVaclav Hapla   }
852c5b5d8d5SVaclav Hapla   if (hasArgs) {
853c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8549566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
855660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
856c5b5d8d5SVaclav Hapla   }
8574b09e917SBarry Smith   if (file && file[0]) {
8589566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
859c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8609566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
861321366bcSBarry Smith   }
862c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
863be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8646497c311SBarry Smith 
8659566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8669566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
867c6a7a370SJeremy L Thompson     if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
8689566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8699566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8709566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
871e5c89e4eSSatish Balay   }
872e5c89e4eSSatish Balay 
8732d747510SLisandro Dalcin   /* insert environment options */
874dd400576SPatrick Sanan   if (rank == 0) {
875e5c89e4eSSatish Balay     eoptions = (char *)getenv("PETSC_OPTIONS");
8769566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(eoptions, &len));
877e5c89e4eSSatish Balay   }
8789566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
879e5c89e4eSSatish Balay   if (len) {
8809566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8816497c311SBarry Smith     PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, comm));
88296fc60bcSBarry Smith     if (rank) eoptions[len] = 0;
8839355ec05SMatthew G. Knepley     PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8849566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscFree(eoptions));
885e5c89e4eSSatish Balay   }
886e5c89e4eSSatish Balay 
887d06005cbSLisandro Dalcin   /* insert YAML environment options */
888dd400576SPatrick Sanan   if (rank == 0) {
8899fc438c3SToby Isaac     eoptions = (char *)getenv("PETSC_OPTIONS_YAML");
8909566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(eoptions, &len));
8919fc438c3SToby Isaac   }
8929566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8939fc438c3SToby Isaac   if (len) {
8949566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8956497c311SBarry Smith     PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, comm));
8969fc438c3SToby Isaac     if (rank) eoptions[len] = 0;
8979355ec05SMatthew G. Knepley     PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8989566063dSJacob Faibussowitsch     if (rank) PetscCall(PetscFree(eoptions));
8999fc438c3SToby Isaac   }
9003bcbd388SSean Farley 
901c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
9029566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, *args + 1));
903660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
9043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
905e5c89e4eSSatish Balay }
906e5c89e4eSSatish Balay 
907660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
908660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
909e9a33e21SBarry 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"};
910660278c0SBarry Smith 
911d71ae5a4SJacob Faibussowitsch static PetscBool PetscCIOption(const char *name)
912d71ae5a4SJacob Faibussowitsch {
913660278c0SBarry Smith   PetscInt  idx;
914660278c0SBarry Smith   PetscBool found;
915660278c0SBarry Smith 
916660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
9173ba16761SJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
918660278c0SBarry Smith   return found;
919660278c0SBarry Smith }
920660278c0SBarry Smith 
9215d83a8b1SBarry Smith /*@
92288c29154SBarry Smith   PetscOptionsView - Prints the options that have been loaded. This is
923e5c89e4eSSatish Balay   useful for debugging purposes.
924e5c89e4eSSatish Balay 
925ffeef943SBarry Smith   Logically Collective, No Fortran Support
926e5c89e4eSSatish Balay 
927d8d19677SJose E. Roman   Input Parameters:
92820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
929811af0c4SBarry Smith - viewer  - must be an `PETSCVIEWERASCII` viewer
930e5c89e4eSSatish Balay 
931e5c89e4eSSatish Balay   Options Database Key:
932811af0c4SBarry Smith . -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
933e5c89e4eSSatish Balay 
93420f4b53cSBarry Smith   Level: advanced
93520f4b53cSBarry Smith 
936811af0c4SBarry Smith   Note:
93721532e8aSBarry Smith   Only the MPI rank 0 of the `MPI_Comm` used to create view prints the option values. Other processes
9381c9f3c13SBarry Smith   may have different values but they are not printed.
9391c9f3c13SBarry Smith 
940db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
941e5c89e4eSSatish Balay @*/
942d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
943d71ae5a4SJacob Faibussowitsch {
944660278c0SBarry Smith   PetscInt  i, N = 0;
94588c29154SBarry Smith   PetscBool isascii;
946e5c89e4eSSatish Balay 
947e5c89e4eSSatish Balay   PetscFunctionBegin;
9482d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
949c5929fdfSBarry Smith   options = options ? options : defaultoptions;
95088c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
95228b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
95388c29154SBarry Smith 
954660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
955660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
956660278c0SBarry Smith     N++;
957660278c0SBarry Smith   }
958660278c0SBarry Smith 
959660278c0SBarry Smith   if (!N) {
9609566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9613ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
96230694fe9SBarry Smith   }
9632d747510SLisandro Dalcin 
9649566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
965e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
966660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
967e5c89e4eSSatish Balay     if (options->values[i]) {
9689355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
969e5c89e4eSSatish Balay     } else {
9709355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
971e5c89e4eSSatish Balay     }
9729355ec05SMatthew G. Knepley     PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
973e5c89e4eSSatish Balay   }
9749566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
9753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
976e5c89e4eSSatish Balay }
977e5c89e4eSSatish Balay 
978e11779c2SBarry Smith /*
979e11779c2SBarry Smith    Called by error handlers to print options used in run
980e11779c2SBarry Smith */
981d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftError(void)
982d71ae5a4SJacob Faibussowitsch {
983f4bc716fSBarry Smith   PetscInt i, nopt = 0;
984f4bc716fSBarry Smith 
985f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
986f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
987f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
988f4bc716fSBarry Smith       nopt++;
989f4bc716fSBarry Smith     }
990f4bc716fSBarry Smith   }
991f4bc716fSBarry Smith   if (nopt) {
9927d44c3adSBarry Smith     PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
993f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
994f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
995f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
9963ba16761SJacob 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]]));
9973ba16761SJacob Faibussowitsch         else PetscCall((*PetscErrorPrintf)("  Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
998f4bc716fSBarry Smith       }
999f4bc716fSBarry Smith     }
1000f4bc716fSBarry Smith   }
10013ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1002f4bc716fSBarry Smith }
1003f4bc716fSBarry Smith 
1004d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1005d71ae5a4SJacob Faibussowitsch {
1006660278c0SBarry Smith   PetscInt     i, N = 0;
10074416b707SBarry Smith   PetscOptions options = defaultoptions;
1008e11779c2SBarry Smith 
1009660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
1010660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1011660278c0SBarry Smith     N++;
1012660278c0SBarry Smith   }
1013660278c0SBarry Smith 
1014660278c0SBarry Smith   if (N) {
10153ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1016e11779c2SBarry Smith   } else {
10173ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1018e11779c2SBarry Smith   }
1019e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1020660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1021e11779c2SBarry Smith     if (options->values[i]) {
10223ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1023e11779c2SBarry Smith     } else {
10243ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1025e11779c2SBarry Smith     }
1026e11779c2SBarry Smith   }
10273ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1028e11779c2SBarry Smith }
1029e11779c2SBarry Smith 
10305d83a8b1SBarry Smith /*@
103174e0666dSJed Brown   PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
103274e0666dSJed Brown 
10331c9f3c13SBarry Smith   Logically Collective
103474e0666dSJed Brown 
1035d8d19677SJose E. Roman   Input Parameters:
103620f4b53cSBarry Smith + options - options database, or `NULL` for the default global database
1037c5929fdfSBarry Smith - prefix  - The string to append to the existing prefix
10389db968c8SJed Brown 
10399db968c8SJed Brown   Options Database Keys:
10409db968c8SJed Brown + -prefix_push <some_prefix_> - push the given prefix
10419db968c8SJed Brown - -prefix_pop                 - pop the last prefix
10429db968c8SJed Brown 
104320f4b53cSBarry Smith   Level: advanced
104420f4b53cSBarry Smith 
10459db968c8SJed Brown   Notes:
104621532e8aSBarry Smith   It is common to use this in conjunction with `-options_file` as in
10479314d9b7SBarry Smith .vb
10489314d9b7SBarry Smith  -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10499314d9b7SBarry Smith .ve
105021532e8aSBarry Smith   where the files no longer require all options to be prefixed with `-system2_`.
105174e0666dSJed Brown 
105221532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
10531c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
10541c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10551c9f3c13SBarry Smith   on different ranks.
10561c9f3c13SBarry Smith 
1057db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
105874e0666dSJed Brown @*/
1059d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1060d71ae5a4SJacob Faibussowitsch {
106174e0666dSJed Brown   size_t    n;
106274e0666dSJed Brown   PetscInt  start;
10639355ec05SMatthew G. Knepley   char      key[PETSC_MAX_OPTION_NAME + 1];
10642d747510SLisandro Dalcin   PetscBool valid;
106574e0666dSJed Brown 
106674e0666dSJed Brown   PetscFunctionBegin;
10674f572ea9SToby Isaac   PetscAssertPointer(prefix, 2);
1068c5929fdfSBarry Smith   options = options ? options : defaultoptions;
106900045ab3SPierre 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);
10702d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10719566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10738bf569ecSLisandro 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 */
107428b400f6SJacob 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" : "");
107574e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10769566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
107708401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10789566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
10796497c311SBarry Smith   options->prefixstack[options->prefixind++] = (int)(start + n);
10803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108174e0666dSJed Brown }
108274e0666dSJed Brown 
10835d83a8b1SBarry Smith /*@
1084811af0c4SBarry Smith   PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
108574e0666dSJed Brown 
1086811af0c4SBarry Smith   Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
108774e0666dSJed Brown 
1088811af0c4SBarry Smith   Input Parameter:
108920f4b53cSBarry Smith . options - options database, or `NULL` for the default global database
1090c5929fdfSBarry Smith 
109174e0666dSJed Brown   Level: advanced
109274e0666dSJed Brown 
1093db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
109474e0666dSJed Brown @*/
1095d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1096d71ae5a4SJacob Faibussowitsch {
109774e0666dSJed Brown   PetscInt offset;
109874e0666dSJed Brown 
109974e0666dSJed Brown   PetscFunctionBegin;
1100c5929fdfSBarry Smith   options = options ? options : defaultoptions;
110108401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
110274e0666dSJed Brown   options->prefixind--;
110374e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
110474e0666dSJed Brown   options->prefix[offset] = 0;
11053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
110674e0666dSJed Brown }
110774e0666dSJed Brown 
11085d83a8b1SBarry Smith /*@
1109a542b6e8SBarry Smith   PetscOptionsClear - Removes all options form the database leaving it empty.
1110a542b6e8SBarry Smith 
11111c9f3c13SBarry Smith   Logically Collective
11121c9f3c13SBarry Smith 
1113811af0c4SBarry Smith   Input Parameter:
111420f4b53cSBarry Smith . options - options database, use `NULL` for the default global database
1115c5929fdfSBarry Smith 
111620f4b53cSBarry Smith   Level: developer
111720f4b53cSBarry Smith 
111820f4b53cSBarry Smith   Note:
111921532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11201c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11211c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11221c9f3c13SBarry Smith   on different ranks.
11231c9f3c13SBarry Smith 
11247e6f8dd6SBarry Smith   Developer Note:
11257e6f8dd6SBarry Smith   Uses `free()` directly because the current option values were set with `malloc()`
11267e6f8dd6SBarry Smith 
1127db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1128a542b6e8SBarry Smith @*/
1129d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClear(PetscOptions options)
1130d71ae5a4SJacob Faibussowitsch {
1131a542b6e8SBarry Smith   PetscInt i;
1132a542b6e8SBarry Smith 
113339a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1134c5929fdfSBarry Smith   options = options ? options : defaultoptions;
11353ba16761SJacob Faibussowitsch   if (!options) PetscFunctionReturn(PETSC_SUCCESS);
11362d747510SLisandro Dalcin 
1137a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1138a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1139a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1140a542b6e8SBarry Smith   }
11412d747510SLisandro Dalcin   options->N = 0;
11429355ec05SMatthew G. Knepley   free(options->names);
11439355ec05SMatthew G. Knepley   free(options->values);
11449355ec05SMatthew G. Knepley   free(options->used);
11459355ec05SMatthew G. Knepley   free(options->source);
11469355ec05SMatthew G. Knepley   options->names  = NULL;
11479355ec05SMatthew G. Knepley   options->values = NULL;
11489355ec05SMatthew G. Knepley   options->used   = NULL;
11499355ec05SMatthew G. Knepley   options->source = NULL;
11509355ec05SMatthew G. Knepley   options->Nalloc = 0;
11512d747510SLisandro Dalcin 
11529355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
1153a542b6e8SBarry Smith     free(options->aliases1[i]);
1154a542b6e8SBarry Smith     free(options->aliases2[i]);
1155a542b6e8SBarry Smith   }
11569355ec05SMatthew G. Knepley   options->Na = 0;
11579355ec05SMatthew G. Knepley   free(options->aliases1);
11589355ec05SMatthew G. Knepley   free(options->aliases2);
11599355ec05SMatthew G. Knepley   options->aliases1 = options->aliases2 = NULL;
11609355ec05SMatthew G. Knepley   options->Naalloc                      = 0;
1161a542b6e8SBarry Smith 
11622d747510SLisandro Dalcin   /* destroy hash table */
11632d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11642d747510SLisandro Dalcin   options->ht = NULL;
11650eb63584SBarry Smith 
11662d747510SLisandro Dalcin   options->prefixind  = 0;
11672d747510SLisandro Dalcin   options->prefix[0]  = 0;
11682d747510SLisandro Dalcin   options->help       = PETSC_FALSE;
11699355ec05SMatthew G. Knepley   options->help_intro = PETSC_FALSE;
11703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11714416b707SBarry Smith }
11724416b707SBarry Smith 
11735d83a8b1SBarry Smith /*@
11742d747510SLisandro Dalcin   PetscOptionsSetAlias - Makes a key and alias for another key
11752d747510SLisandro Dalcin 
11761c9f3c13SBarry Smith   Logically Collective
11772d747510SLisandro Dalcin 
11782d747510SLisandro Dalcin   Input Parameters:
117920f4b53cSBarry Smith + options - options database, or `NULL` for default global database
11802d747510SLisandro Dalcin . newname - the alias
11812d747510SLisandro Dalcin - oldname - the name that alias will refer to
11822d747510SLisandro Dalcin 
11832d747510SLisandro Dalcin   Level: advanced
11842d747510SLisandro Dalcin 
118520f4b53cSBarry Smith   Note:
118621532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11871c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11881c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11891c9f3c13SBarry Smith   on different ranks.
11901c9f3c13SBarry Smith 
11917e6f8dd6SBarry Smith   Developer Note:
11927e6f8dd6SBarry Smith   Uses `malloc()` directly because PETSc may not be initialized yet.
11937e6f8dd6SBarry Smith 
11940241b274SPierre Jolivet .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1195c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1196db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1197c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1198db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1199db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
12002d747510SLisandro Dalcin @*/
1201d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1202d71ae5a4SJacob Faibussowitsch {
12032d747510SLisandro Dalcin   size_t    len;
12049210b8eaSVaclav Hapla   PetscBool valid;
12052d747510SLisandro Dalcin 
12062d747510SLisandro Dalcin   PetscFunctionBegin;
12074f572ea9SToby Isaac   PetscAssertPointer(newname, 2);
12084f572ea9SToby Isaac   PetscAssertPointer(oldname, 3);
12092d747510SLisandro Dalcin   options = options ? options : defaultoptions;
12109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
121128b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
12129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
121328b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
12142d747510SLisandro Dalcin 
12159355ec05SMatthew G. Knepley   if (options->Na == options->Naalloc) {
12169355ec05SMatthew G. Knepley     char **tmpA1, **tmpA2;
12172d747510SLisandro Dalcin 
12189355ec05SMatthew G. Knepley     options->Naalloc = PetscMax(4, options->Naalloc * 2);
12199355ec05SMatthew G. Knepley     tmpA1            = (char **)malloc(options->Naalloc * sizeof(char *));
12209355ec05SMatthew G. Knepley     tmpA2            = (char **)malloc(options->Naalloc * sizeof(char *));
12219355ec05SMatthew G. Knepley     for (int i = 0; i < options->Na; ++i) {
12229355ec05SMatthew G. Knepley       tmpA1[i] = options->aliases1[i];
12239355ec05SMatthew G. Knepley       tmpA2[i] = options->aliases2[i];
12249355ec05SMatthew G. Knepley     }
12259355ec05SMatthew G. Knepley     free(options->aliases1);
12269355ec05SMatthew G. Knepley     free(options->aliases2);
12279355ec05SMatthew G. Knepley     options->aliases1 = tmpA1;
12289355ec05SMatthew G. Knepley     options->aliases2 = tmpA2;
12299355ec05SMatthew G. Knepley   }
12309371c9d4SSatish Balay   newname++;
12319371c9d4SSatish Balay   oldname++;
12329566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
12339355ec05SMatthew G. Knepley   options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1234c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
12359566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
12369355ec05SMatthew G. Knepley   options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1237c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
12389355ec05SMatthew G. Knepley   ++options->Na;
12393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12402d747510SLisandro Dalcin }
12414416b707SBarry Smith 
12425d83a8b1SBarry Smith /*@
1243e5c89e4eSSatish Balay   PetscOptionsSetValue - Sets an option name-value pair in the options
1244e5c89e4eSSatish Balay   database, overriding whatever is already present.
1245e5c89e4eSSatish Balay 
12461c9f3c13SBarry Smith   Logically Collective
1247e5c89e4eSSatish Balay 
1248e5c89e4eSSatish Balay   Input Parameters:
124920f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1250c5929fdfSBarry Smith . name    - name of option, this SHOULD have the - prepended
125120f4b53cSBarry Smith - value   - the option value (not used for all options, so can be `NULL`)
1252e5c89e4eSSatish Balay 
1253e5c89e4eSSatish Balay   Level: intermediate
1254e5c89e4eSSatish Balay 
1255e5c89e4eSSatish Balay   Note:
1256811af0c4SBarry Smith   This function can be called BEFORE `PetscInitialize()`
1257d49172ceSBarry Smith 
125821532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
12591c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
12601c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12611c9f3c13SBarry Smith   on different ranks.
12621c9f3c13SBarry Smith 
12637e6f8dd6SBarry Smith   Developer Note:
12647e6f8dd6SBarry Smith   Uses `malloc()` directly because PETSc may not be initialized yet.
1265b0250c70SBarry Smith 
1266db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1267e5c89e4eSSatish Balay @*/
1268d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1269d71ae5a4SJacob Faibussowitsch {
127039a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12719355ec05SMatthew G. Knepley   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
12723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1273c5b5d8d5SVaclav Hapla }
1274c5b5d8d5SVaclav Hapla 
12759355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1276d71ae5a4SJacob Faibussowitsch {
1277e5c89e4eSSatish Balay   size_t    len;
12789355ec05SMatthew G. Knepley   int       n, i;
1279e5c89e4eSSatish Balay   char    **names;
12809355ec05SMatthew G. Knepley   char      fullname[PETSC_MAX_OPTION_NAME] = "";
1281c5b5d8d5SVaclav Hapla   PetscBool flg;
1282e5c89e4eSSatish Balay 
128339a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12847272c0d2SVaclav Hapla   if (!options) {
12859566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12867272c0d2SVaclav Hapla     options = defaultoptions;
1287c5929fdfSBarry Smith   }
128839a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
12892d747510SLisandro Dalcin 
12909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
12913ba16761SJacob Faibussowitsch   if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1292e5c89e4eSSatish Balay 
12932d747510SLisandro Dalcin   name++; /* skip starting dash */
12942d747510SLisandro Dalcin 
129574e0666dSJed Brown   if (options->prefixind > 0) {
1296d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
12972d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
129889ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
12992d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
130074e0666dSJed Brown     name                           = fullname;
130174e0666dSJed Brown   }
130274e0666dSJed Brown 
130374e0666dSJed Brown   /* check against aliases */
13049355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
13052d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
13069371c9d4SSatish Balay     if (!result) {
13079371c9d4SSatish Balay       name = options->aliases2[i];
13089371c9d4SSatish Balay       break;
13099371c9d4SSatish Balay     }
1310e5c89e4eSSatish Balay   }
1311e5c89e4eSSatish Balay 
13122d747510SLisandro Dalcin   /* slow search */
13139355ec05SMatthew G. Knepley   n     = options->N;
1314e5c89e4eSSatish Balay   names = options->names;
13159355ec05SMatthew G. Knepley   for (i = 0; i < options->N; i++) {
13162d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13172d747510SLisandro Dalcin     if (!result) {
13189371c9d4SSatish Balay       n = i;
13199371c9d4SSatish Balay       goto setvalue;
13202d747510SLisandro Dalcin     } else if (result > 0) {
13219371c9d4SSatish Balay       n = i;
13229371c9d4SSatish Balay       break;
1323e5c89e4eSSatish Balay     }
1324e5c89e4eSSatish Balay   }
13259355ec05SMatthew G. Knepley   if (options->N == options->Nalloc) {
13269355ec05SMatthew G. Knepley     char             **names, **values;
13279355ec05SMatthew G. Knepley     PetscBool         *used;
13289355ec05SMatthew G. Knepley     PetscOptionSource *source;
13299355ec05SMatthew G. Knepley 
13309355ec05SMatthew G. Knepley     options->Nalloc = PetscMax(10, options->Nalloc * 2);
13319355ec05SMatthew G. Knepley     names           = (char **)malloc(options->Nalloc * sizeof(char *));
13329355ec05SMatthew G. Knepley     values          = (char **)malloc(options->Nalloc * sizeof(char *));
13339355ec05SMatthew G. Knepley     used            = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
13349355ec05SMatthew G. Knepley     source          = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
13359355ec05SMatthew G. Knepley     for (int i = 0; i < options->N; ++i) {
13369355ec05SMatthew G. Knepley       names[i]  = options->names[i];
13379355ec05SMatthew G. Knepley       values[i] = options->values[i];
13389355ec05SMatthew G. Knepley       used[i]   = options->used[i];
13399355ec05SMatthew G. Knepley       source[i] = options->source[i];
13409355ec05SMatthew G. Knepley     }
13419355ec05SMatthew G. Knepley     free(options->names);
13429355ec05SMatthew G. Knepley     free(options->values);
13439355ec05SMatthew G. Knepley     free(options->used);
13449355ec05SMatthew G. Knepley     free(options->source);
13459355ec05SMatthew G. Knepley     options->names  = names;
13469355ec05SMatthew G. Knepley     options->values = values;
13479355ec05SMatthew G. Knepley     options->used   = used;
13489355ec05SMatthew G. Knepley     options->source = source;
13499355ec05SMatthew G. Knepley   }
135039a651e2SJacob Faibussowitsch 
13512d747510SLisandro Dalcin   /* shift remaining values up 1 */
13529355ec05SMatthew G. Knepley   for (i = options->N; i > n; i--) {
13535e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1354e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1355e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
13569355ec05SMatthew G. Knepley     options->source[i] = options->source[i - 1];
1357e5c89e4eSSatish Balay   }
13582d747510SLisandro Dalcin   options->names[n]  = NULL;
13592d747510SLisandro Dalcin   options->values[n] = NULL;
13602d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
13619355ec05SMatthew G. Knepley   options->source[n] = PETSC_OPT_CODE;
13622d747510SLisandro Dalcin   options->N++;
13632d747510SLisandro Dalcin 
13642d747510SLisandro Dalcin   /* destroy hash table */
13652d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13662d747510SLisandro Dalcin   options->ht = NULL;
13672d747510SLisandro Dalcin 
13682d747510SLisandro Dalcin   /* set new name */
136970d8d27cSBarry Smith   len               = strlen(name);
13705e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
137139a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1372d49172ceSBarry Smith   strcpy(options->names[n], name);
13732d747510SLisandro Dalcin 
13742d747510SLisandro Dalcin setvalue:
13752d747510SLisandro Dalcin   /* set new value */
13762d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1377d49172ceSBarry Smith   len = value ? strlen(value) : 0;
13785e8c5e88SLisandro Dalcin   if (len) {
1379e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1380d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1381d49172ceSBarry Smith     strcpy(options->values[n], value);
1382432b765aSRené Chenard     options->values[n][len] = '\0';
13832d747510SLisandro Dalcin   } else {
13842d747510SLisandro Dalcin     options->values[n] = NULL;
13852d747510SLisandro Dalcin   }
13869355ec05SMatthew G. Knepley   options->source[n] = source;
13872d747510SLisandro Dalcin 
138891ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
138991ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
139091ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1391d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
139291ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
139391ad3481SVaclav Hapla   }
139491ad3481SVaclav Hapla 
1395432b765aSRené Chenard   PetscCall(PetscOptionsMonitor(options, name, value ? value : "", source));
1396c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
13973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1398e5c89e4eSSatish Balay }
1399e5c89e4eSSatish Balay 
14005d83a8b1SBarry Smith /*@
1401e5c89e4eSSatish Balay   PetscOptionsClearValue - Clears an option name-value pair in the options
1402e5c89e4eSSatish Balay   database, overriding whatever is already present.
1403e5c89e4eSSatish Balay 
14041c9f3c13SBarry Smith   Logically Collective
1405e5c89e4eSSatish Balay 
1406d8d19677SJose E. Roman   Input Parameters:
140720f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1408a2b725a8SWilliam Gropp - name    - name of option, this SHOULD have the - prepended
1409e5c89e4eSSatish Balay 
1410e5c89e4eSSatish Balay   Level: intermediate
1411e5c89e4eSSatish Balay 
1412811af0c4SBarry Smith   Note:
141321532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
14141c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
14151c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
14161c9f3c13SBarry Smith   on different ranks.
14171c9f3c13SBarry Smith 
14187e6f8dd6SBarry Smith   Developer Note:
14197e6f8dd6SBarry Smith   Uses `free()` directly because the options have been set with `malloc()`
14207e6f8dd6SBarry Smith 
1421db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1422e5c89e4eSSatish Balay @*/
1423d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1424d71ae5a4SJacob Faibussowitsch {
14252d747510SLisandro Dalcin   int    N, n, i;
14262d747510SLisandro Dalcin   char **names;
1427e5c89e4eSSatish Balay 
1428e5c89e4eSSatish Balay   PetscFunctionBegin;
1429c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1430cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1431c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
14322d747510SLisandro Dalcin 
14332d747510SLisandro Dalcin   name++; /* skip starting dash */
14342d747510SLisandro Dalcin 
14352d747510SLisandro Dalcin   /* slow search */
14362d747510SLisandro Dalcin   N = n = options->N;
1437e5c89e4eSSatish Balay   names = options->names;
1438e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
14392d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
14402d747510SLisandro Dalcin     if (!result) {
14419371c9d4SSatish Balay       n = i;
14429371c9d4SSatish Balay       break;
14432d747510SLisandro Dalcin     } else if (result > 0) {
14449371c9d4SSatish Balay       n = N;
14459371c9d4SSatish Balay       break;
1446e5c89e4eSSatish Balay     }
14472d747510SLisandro Dalcin   }
14483ba16761SJacob Faibussowitsch   if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1449e5c89e4eSSatish Balay 
14502d747510SLisandro Dalcin   /* remove name and value */
14512d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
14522d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1453e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1454e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
14555e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1456e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1457e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
14589355ec05SMatthew G. Knepley     options->source[i] = options->source[i + 1];
1459e5c89e4eSSatish Balay   }
1460e5c89e4eSSatish Balay   options->N--;
14612d747510SLisandro Dalcin 
14622d747510SLisandro Dalcin   /* destroy hash table */
14632d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
14642d747510SLisandro Dalcin   options->ht = NULL;
14652d747510SLisandro Dalcin 
14669355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
14673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1468e5c89e4eSSatish Balay }
1469e5c89e4eSSatish Balay 
1470e5c89e4eSSatish Balay /*@C
14712d747510SLisandro Dalcin   PetscOptionsFindPair - Gets an option name-value pair from the options database.
1472e5c89e4eSSatish Balay 
14732d747510SLisandro Dalcin   Not Collective
1474e5c89e4eSSatish Balay 
1475e5c89e4eSSatish Balay   Input Parameters:
147620f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
147720f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
14782d747510SLisandro Dalcin - name    - name of option, this SHOULD have the "-" prepended
1479e5c89e4eSSatish Balay 
14802d747510SLisandro Dalcin   Output Parameters:
14812d747510SLisandro Dalcin + value - the option value (optional, not used for all options)
14822d747510SLisandro Dalcin - set   - whether the option is set (optional)
1483e5c89e4eSSatish Balay 
148420f4b53cSBarry Smith   Level: developer
148520f4b53cSBarry Smith 
1486811af0c4SBarry Smith   Note:
14879666a313SBarry Smith   Each process may find different values or no value depending on how options were inserted into the database
14881c9f3c13SBarry Smith 
1489db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1490e5c89e4eSSatish Balay @*/
1491d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1492d71ae5a4SJacob Faibussowitsch {
14939355ec05SMatthew G. Knepley   char      buf[PETSC_MAX_OPTION_NAME];
1494daabea38SBarry Smith   PetscBool usehashtable = PETSC_TRUE;
14952d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1496e5c89e4eSSatish Balay 
1497e5c89e4eSSatish Balay   PetscFunctionBegin;
1498b33a4df8SMatthew G. Knepley   if (!options) {
1499b33a4df8SMatthew G. Knepley     PetscCall(PetscOptionsCreateDefault());
1500b33a4df8SMatthew G. Knepley     options = defaultoptions;
1501b33a4df8SMatthew G. Knepley   }
150208401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1503cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1504e5c89e4eSSatish Balay 
15052d747510SLisandro Dalcin   name++; /* skip starting dash */
1506e5c89e4eSSatish Balay 
15077cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
15082d747510SLisandro Dalcin   if (pre && pre[0]) {
15092d747510SLisandro Dalcin     char *ptr = buf;
15109371c9d4SSatish Balay     if (name[0] == '-') {
15119371c9d4SSatish Balay       *ptr++ = '-';
15129371c9d4SSatish Balay       name++;
15139371c9d4SSatish Balay     }
15149566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
15159566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
15162d747510SLisandro Dalcin     name = buf;
15177cd08cecSJed Brown   }
15182d747510SLisandro Dalcin 
151976bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
15202f828895SJed Brown     PetscBool valid;
15219355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
15229566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
15239566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
152428b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
15252f828895SJed Brown   }
1526e5c89e4eSSatish Balay 
15272d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
15282d747510SLisandro Dalcin     int          i, ret;
15292d747510SLisandro Dalcin     khiter_t     it;
15302d747510SLisandro Dalcin     khash_t(HO) *ht;
15312d747510SLisandro Dalcin     ht = kh_init(HO);
153228b400f6SJacob Faibussowitsch     PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15332d747510SLisandro Dalcin     ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
153428b400f6SJacob Faibussowitsch     PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15352d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
15362d747510SLisandro Dalcin       it = kh_put(HO, ht, options->names[i], &ret);
153708401ef6SPierre Jolivet       PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15382d747510SLisandro Dalcin       kh_val(ht, it) = i;
15392d747510SLisandro Dalcin     }
15402d747510SLisandro Dalcin     options->ht = ht;
15412d747510SLisandro Dalcin   }
15422d747510SLisandro Dalcin 
15439371c9d4SSatish Balay   if (usehashtable) { /* fast search */
15442d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
15452d747510SLisandro Dalcin     khiter_t     it = kh_get(HO, ht, name);
15462d747510SLisandro Dalcin     if (it != kh_end(ht)) {
15472d747510SLisandro Dalcin       int i            = kh_val(ht, it);
1548e5c89e4eSSatish Balay       options->used[i] = PETSC_TRUE;
15492d747510SLisandro Dalcin       if (value) *value = options->values[i];
15502d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
15513ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
15522d747510SLisandro Dalcin     }
15539371c9d4SSatish Balay   } else { /* slow search */
15542d747510SLisandro Dalcin     int i, N = options->N;
15552d747510SLisandro Dalcin     for (i = 0; i < N; i++) {
1556daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i], name);
15572d747510SLisandro Dalcin       if (!result) {
15582d747510SLisandro Dalcin         options->used[i] = PETSC_TRUE;
15592d747510SLisandro Dalcin         if (value) *value = options->values[i];
15602d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
15613ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15622d747510SLisandro Dalcin       } else if (result > 0) {
1563e5c89e4eSSatish Balay         break;
1564e5c89e4eSSatish Balay       }
1565e5c89e4eSSatish Balay     }
15662d747510SLisandro Dalcin   }
15672d747510SLisandro Dalcin 
15682d747510SLisandro Dalcin   /*
15692d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
15702d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
15712d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
15722d747510SLisandro Dalcin    */
15732d747510SLisandro Dalcin   if (matchnumbers) {
15742d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1575e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
15762d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
15772d747510SLisandro Dalcin       if (name[i] == '_') {
15782d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
15792d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
15802d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1581e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1582e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1583e5c89e4eSSatish Balay           }
15842d747510SLisandro Dalcin           i = j - 1;
1585e5c89e4eSSatish Balay           break;
1586e5c89e4eSSatish Balay         }
1587e5c89e4eSSatish Balay       }
1588e5c89e4eSSatish Balay     }
1589e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
15902d747510SLisandro Dalcin       PetscBool found;
15919355ec05SMatthew G. Knepley       char      opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
15929566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
15939566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15949566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
15959566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
15969371c9d4SSatish Balay       if (found) {
15979371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
15983ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15999371c9d4SSatish Balay       }
1600e5c89e4eSSatish Balay     }
1601e5c89e4eSSatish Balay   }
16022d747510SLisandro Dalcin 
16032d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1605e5c89e4eSSatish Balay }
1606e5c89e4eSSatish Balay 
1607d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
160854a546c1SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *option[], const char *value[], PetscBool *set)
1609d71ae5a4SJacob Faibussowitsch {
16109355ec05SMatthew G. Knepley   char buf[PETSC_MAX_OPTION_NAME];
1611d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1612514bf10dSMatthew G Knepley 
1613514bf10dSMatthew G Knepley   PetscFunctionBegin;
1614c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1615cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1616cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1617514bf10dSMatthew G Knepley 
16182d747510SLisandro Dalcin   name++; /* skip starting dash */
1619514bf10dSMatthew G Knepley 
1620514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
16212d747510SLisandro Dalcin   if (pre && pre[0]) {
16222d747510SLisandro Dalcin     char *ptr = buf;
16239371c9d4SSatish Balay     if (name[0] == '-') {
16249371c9d4SSatish Balay       *ptr++ = '-';
16259371c9d4SSatish Balay       name++;
16269371c9d4SSatish Balay     }
16279b15cf9aSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
16289566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
16292d747510SLisandro Dalcin     name = buf;
1630514bf10dSMatthew G Knepley   }
16312d747510SLisandro Dalcin 
163276bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1633514bf10dSMatthew G Knepley     PetscBool valid;
16349355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
16359566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
16369566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
163728b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1638514bf10dSMatthew G Knepley   }
1639514bf10dSMatthew G Knepley 
1640d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1641d6ced9c0SMatthew G. Knepley   {
1642d6ced9c0SMatthew G. Knepley     int i, j;
1643d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1644d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1645d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1646d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1647d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1648d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1649d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1650d6ced9c0SMatthew G. Knepley           }
1651d6ced9c0SMatthew G. Knepley           i = j - 1;
1652d6ced9c0SMatthew G. Knepley           break;
1653d6ced9c0SMatthew G. Knepley         }
1654d6ced9c0SMatthew G. Knepley       }
1655d6ced9c0SMatthew G. Knepley     }
1656d6ced9c0SMatthew G. Knepley   }
1657d6ced9c0SMatthew G. Knepley 
1658363da2dcSJacob Faibussowitsch   /* slow search */
1659363da2dcSJacob Faibussowitsch   for (int c = -1; c < numCnt; ++c) {
1660363da2dcSJacob Faibussowitsch     char   opt[PETSC_MAX_OPTION_NAME + 2] = "";
16612d747510SLisandro Dalcin     size_t len;
1662d6ced9c0SMatthew G. Knepley 
1663d6ced9c0SMatthew G. Knepley     if (c < 0) {
1664c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1665d6ced9c0SMatthew G. Knepley     } else {
1666363da2dcSJacob Faibussowitsch       PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1667363da2dcSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1668d6ced9c0SMatthew G. Knepley     }
16699566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(opt, &len));
1670363da2dcSJacob Faibussowitsch     for (int i = 0; i < options->N; i++) {
1671363da2dcSJacob Faibussowitsch       PetscBool match;
1672363da2dcSJacob Faibussowitsch 
16739566063dSJacob Faibussowitsch       PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1674514bf10dSMatthew G Knepley       if (match) {
1675514bf10dSMatthew G Knepley         options->used[i] = PETSC_TRUE;
167654a546c1SMatthew G. Knepley         if (option) *option = options->names[i];
16772d747510SLisandro Dalcin         if (value) *value = options->values[i];
16782d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
16793ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
1680514bf10dSMatthew G Knepley       }
1681514bf10dSMatthew G Knepley     }
16822d747510SLisandro Dalcin   }
16832d747510SLisandro Dalcin 
16842d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1686514bf10dSMatthew G Knepley }
1687514bf10dSMatthew G Knepley 
16885d83a8b1SBarry Smith /*@
1689e5c89e4eSSatish Balay   PetscOptionsReject - Generates an error if a certain option is given.
1690e5c89e4eSSatish Balay 
16911c9f3c13SBarry Smith   Not Collective
1692e5c89e4eSSatish Balay 
1693e5c89e4eSSatish Balay   Input Parameters:
169420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
169520f4b53cSBarry Smith . pre     - the option prefix (may be `NULL`)
16962d747510SLisandro Dalcin . name    - the option name one is seeking
169720f4b53cSBarry Smith - mess    - error message (may be `NULL`)
1698e5c89e4eSSatish Balay 
1699e5c89e4eSSatish Balay   Level: advanced
1700e5c89e4eSSatish Balay 
17010241b274SPierre Jolivet .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1702db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1703db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1704c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1705db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1706db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1707e5c89e4eSSatish Balay @*/
1708d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1709d71ae5a4SJacob Faibussowitsch {
1710ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1711e5c89e4eSSatish Balay 
1712e5c89e4eSSatish Balay   PetscFunctionBegin;
17139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1714e5c89e4eSSatish Balay   if (flag) {
171508401ef6SPierre 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);
1716f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1717e5c89e4eSSatish Balay   }
17183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1719e5c89e4eSSatish Balay }
1720e5c89e4eSSatish Balay 
17215d83a8b1SBarry Smith /*@
17222d747510SLisandro Dalcin   PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
17232d747510SLisandro Dalcin 
17242d747510SLisandro Dalcin   Not Collective
17252d747510SLisandro Dalcin 
1726811af0c4SBarry Smith   Input Parameter:
172720f4b53cSBarry Smith . options - options database, use `NULL` for default global database
17282d747510SLisandro Dalcin 
1729811af0c4SBarry Smith   Output Parameter:
1730811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
17312d747510SLisandro Dalcin 
17322d747510SLisandro Dalcin   Level: advanced
17332d747510SLisandro Dalcin 
1734db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
17352d747510SLisandro Dalcin @*/
1736d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1737d71ae5a4SJacob Faibussowitsch {
17382d747510SLisandro Dalcin   PetscFunctionBegin;
17394f572ea9SToby Isaac   PetscAssertPointer(set, 2);
17402d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17412d747510SLisandro Dalcin   *set    = options->help;
17423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17432d747510SLisandro Dalcin }
17442d747510SLisandro Dalcin 
1745d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1746d71ae5a4SJacob Faibussowitsch {
1747d314f959SVaclav Hapla   PetscFunctionBegin;
17484f572ea9SToby Isaac   PetscAssertPointer(set, 2);
1749d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1750d314f959SVaclav Hapla   *set    = options->help_intro;
17513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1752d314f959SVaclav Hapla }
1753d314f959SVaclav Hapla 
17545d83a8b1SBarry Smith /*@
1755e24fcbf7SPierre 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
1756e24fcbf7SPierre Jolivet   if its value is set to false.
1757e5c89e4eSSatish Balay 
1758e5c89e4eSSatish Balay   Not Collective
1759e5c89e4eSSatish Balay 
1760e5c89e4eSSatish Balay   Input Parameters:
176120f4b53cSBarry Smith + options - options database, use `NULL` for default global database
176220f4b53cSBarry Smith . pre     - string to prepend to the name or `NULL`
17633de71b31SHong Zhang - name    - the option one is seeking
1764e5c89e4eSSatish Balay 
1765811af0c4SBarry Smith   Output Parameter:
1766811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1767e5c89e4eSSatish Balay 
1768e5c89e4eSSatish Balay   Level: beginner
1769e5c89e4eSSatish Balay 
1770811af0c4SBarry Smith   Note:
1771811af0c4SBarry Smith   In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
177290d69ab7SBarry Smith 
1773db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1774db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1775db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1776c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1777db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1778db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1779e5c89e4eSSatish Balay @*/
1780d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1781d71ae5a4SJacob Faibussowitsch {
17822d747510SLisandro Dalcin   const char *value;
1783ace3abfcSBarry Smith   PetscBool   flag;
1784e5c89e4eSSatish Balay 
1785e5c89e4eSSatish Balay   PetscFunctionBegin;
17869566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
178796ef3cdfSSatish Balay   if (set) *set = flag;
17883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1789e5c89e4eSSatish Balay }
1790e5c89e4eSSatish Balay 
1791e5c89e4eSSatish Balay /*@C
17922d747510SLisandro Dalcin   PetscOptionsGetAll - Lists all the options the program was run with in a single string.
17932d747510SLisandro Dalcin 
17942d747510SLisandro Dalcin   Not Collective
17952d747510SLisandro Dalcin 
1796fd292e60Sprj-   Input Parameter:
179720f4b53cSBarry Smith . options - the options database, use `NULL` for the default global database
17982d747510SLisandro Dalcin 
17992d747510SLisandro Dalcin   Output Parameter:
18002d747510SLisandro Dalcin . copts - pointer where string pointer is stored
18012d747510SLisandro Dalcin 
180220f4b53cSBarry Smith   Level: advanced
180320f4b53cSBarry Smith 
18042d747510SLisandro Dalcin   Notes:
1805811af0c4SBarry Smith   The array and each entry in the array should be freed with `PetscFree()`
1806811af0c4SBarry Smith 
18071c9f3c13SBarry Smith   Each process may have different values depending on how the options were inserted into the database
18082d747510SLisandro Dalcin 
1809db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
18102d747510SLisandro Dalcin @*/
1811d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[])
1812d71ae5a4SJacob Faibussowitsch {
18132d747510SLisandro Dalcin   PetscInt i;
18142d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
18152d747510SLisandro Dalcin   char    *coptions = NULL;
18162d747510SLisandro Dalcin 
18172d747510SLisandro Dalcin   PetscFunctionBegin;
18184f572ea9SToby Isaac   PetscAssertPointer(copts, 2);
18192d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18202d747510SLisandro Dalcin   /* count the length of the required string */
18212d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18229566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
18232d747510SLisandro Dalcin     len += 2 + lent;
18242d747510SLisandro Dalcin     if (options->values[i]) {
18259566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
18262d747510SLisandro Dalcin       len += 1 + lent;
18272d747510SLisandro Dalcin     }
18282d747510SLisandro Dalcin   }
18299566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
18302d747510SLisandro Dalcin   coptions[0] = 0;
18312d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1832c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, "-", len));
1833c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, options->names[i], len));
1834c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, " ", len));
18352d747510SLisandro Dalcin     if (options->values[i]) {
1836c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, options->values[i], len));
1837c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, " ", len));
18382d747510SLisandro Dalcin     }
18392d747510SLisandro Dalcin   }
18402d747510SLisandro Dalcin   *copts = coptions;
18413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18422d747510SLisandro Dalcin }
18432d747510SLisandro Dalcin 
18445d83a8b1SBarry Smith /*@
18452d747510SLisandro Dalcin   PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
18462d747510SLisandro Dalcin 
18472d747510SLisandro Dalcin   Not Collective
18482d747510SLisandro Dalcin 
1849d8d19677SJose E. Roman   Input Parameters:
185020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
18512d747510SLisandro Dalcin - name    - string name of option
18522d747510SLisandro Dalcin 
18532d747510SLisandro Dalcin   Output Parameter:
1854811af0c4SBarry Smith . used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
18552d747510SLisandro Dalcin 
18562d747510SLisandro Dalcin   Level: advanced
18572d747510SLisandro Dalcin 
1858811af0c4SBarry Smith   Note:
18599666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18601c9f3c13SBarry Smith   on the given process
18611c9f3c13SBarry Smith 
1862db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
18632d747510SLisandro Dalcin @*/
1864d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1865d71ae5a4SJacob Faibussowitsch {
18662d747510SLisandro Dalcin   PetscInt i;
18672d747510SLisandro Dalcin 
18682d747510SLisandro Dalcin   PetscFunctionBegin;
18694f572ea9SToby Isaac   PetscAssertPointer(name, 2);
18704f572ea9SToby Isaac   PetscAssertPointer(used, 3);
18712d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18722d747510SLisandro Dalcin   *used   = PETSC_FALSE;
18732d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18749566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
18752d747510SLisandro Dalcin     if (*used) {
18762d747510SLisandro Dalcin       *used = options->used[i];
18772d747510SLisandro Dalcin       break;
18782d747510SLisandro Dalcin     }
18792d747510SLisandro Dalcin   }
18803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18812d747510SLisandro Dalcin }
18822d747510SLisandro Dalcin 
1883487a658cSBarry Smith /*@
18842d747510SLisandro Dalcin   PetscOptionsAllUsed - Returns a count of the number of options in the
18852d747510SLisandro Dalcin   database that have never been selected.
18862d747510SLisandro Dalcin 
18872d747510SLisandro Dalcin   Not Collective
18882d747510SLisandro Dalcin 
18892d747510SLisandro Dalcin   Input Parameter:
189020f4b53cSBarry Smith . options - options database, use `NULL` for default global database
18912d747510SLisandro Dalcin 
18922d747510SLisandro Dalcin   Output Parameter:
18932d747510SLisandro Dalcin . N - count of options not used
18942d747510SLisandro Dalcin 
18952d747510SLisandro Dalcin   Level: advanced
18962d747510SLisandro Dalcin 
1897811af0c4SBarry Smith   Note:
18989666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18991c9f3c13SBarry Smith   on the given process
19001c9f3c13SBarry Smith 
1901db781477SPatrick Sanan .seealso: `PetscOptionsView()`
19022d747510SLisandro Dalcin @*/
1903d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1904d71ae5a4SJacob Faibussowitsch {
19052d747510SLisandro Dalcin   PetscInt i, n = 0;
19062d747510SLisandro Dalcin 
19072d747510SLisandro Dalcin   PetscFunctionBegin;
19084f572ea9SToby Isaac   PetscAssertPointer(N, 2);
19092d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19102d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
19112d747510SLisandro Dalcin     if (!options->used[i]) n++;
19122d747510SLisandro Dalcin   }
19132d747510SLisandro Dalcin   *N = n;
19143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19152d747510SLisandro Dalcin }
19162d747510SLisandro Dalcin 
1917487a658cSBarry Smith /*@
19182d747510SLisandro Dalcin   PetscOptionsLeft - Prints to screen any options that were set and never used.
19192d747510SLisandro Dalcin 
19202d747510SLisandro Dalcin   Not Collective
19212d747510SLisandro Dalcin 
19222d747510SLisandro Dalcin   Input Parameter:
192320f4b53cSBarry Smith . options - options database; use `NULL` for default global database
19242d747510SLisandro Dalcin 
19252d747510SLisandro Dalcin   Options Database Key:
1926811af0c4SBarry Smith . -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
19272d747510SLisandro Dalcin 
192820f4b53cSBarry Smith   Level: advanced
192920f4b53cSBarry Smith 
19303de2bfdfSBarry Smith   Notes:
1931811af0c4SBarry Smith   This is rarely used directly, it is called by `PetscFinalize()` in debug more or if -options_left
19321c9f3c13SBarry Smith   is passed otherwise to help users determine possible mistakes in their usage of options. This
1933811af0c4SBarry Smith   only prints values on process zero of `PETSC_COMM_WORLD`.
1934811af0c4SBarry Smith 
1935811af0c4SBarry Smith   Other processes depending the objects
19361c9f3c13SBarry Smith   used may have different options that are left unused.
19373de2bfdfSBarry Smith 
1938db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
19392d747510SLisandro Dalcin @*/
1940d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeft(PetscOptions options)
1941d71ae5a4SJacob Faibussowitsch {
19422d747510SLisandro Dalcin   PetscInt     i;
19433de2bfdfSBarry Smith   PetscInt     cnt = 0;
19443de2bfdfSBarry Smith   PetscOptions toptions;
19452d747510SLisandro Dalcin 
19462d747510SLisandro Dalcin   PetscFunctionBegin;
19473de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
19483de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
19493de2bfdfSBarry Smith     if (!toptions->used[i]) {
1950660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
19513de2bfdfSBarry Smith       if (toptions->values[i]) {
19529355ec05SMatthew 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]]));
19532d747510SLisandro Dalcin       } else {
19549355ec05SMatthew G. Knepley         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
19552d747510SLisandro Dalcin       }
19562d747510SLisandro Dalcin     }
19572d747510SLisandro Dalcin   }
19583de2bfdfSBarry Smith   if (!options) {
19593de2bfdfSBarry Smith     toptions = defaultoptions;
19603de2bfdfSBarry Smith     while (toptions->previous) {
19613de2bfdfSBarry Smith       cnt++;
19623de2bfdfSBarry Smith       toptions = toptions->previous;
19633de2bfdfSBarry Smith     }
196448a46eb9SPierre 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));
19653de2bfdfSBarry Smith   }
19663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19672d747510SLisandro Dalcin }
19682d747510SLisandro Dalcin 
19692d747510SLisandro Dalcin /*@C
19702d747510SLisandro Dalcin   PetscOptionsLeftGet - Returns all options that were set and never used.
19712d747510SLisandro Dalcin 
19722d747510SLisandro Dalcin   Not Collective
19732d747510SLisandro Dalcin 
19742d747510SLisandro Dalcin   Input Parameter:
197520f4b53cSBarry Smith . options - options database, use `NULL` for default global database
19762d747510SLisandro Dalcin 
1977d8d19677SJose E. Roman   Output Parameters:
1978a2b725a8SWilliam Gropp + N      - count of options not used
19792d747510SLisandro Dalcin . names  - names of options not used
1980a2b725a8SWilliam Gropp - values - values of options not used
19812d747510SLisandro Dalcin 
19822d747510SLisandro Dalcin   Level: advanced
19832d747510SLisandro Dalcin 
19842d747510SLisandro Dalcin   Notes:
1985811af0c4SBarry Smith   Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1986811af0c4SBarry Smith 
1987811af0c4SBarry Smith   The value returned may be different on each process and depends on which options have been processed
19881c9f3c13SBarry Smith   on the given process
19892d747510SLisandro Dalcin 
1990db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
19912d747510SLisandro Dalcin @*/
1992d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
1993d71ae5a4SJacob Faibussowitsch {
19942d747510SLisandro Dalcin   PetscInt i, n;
19952d747510SLisandro Dalcin 
19962d747510SLisandro Dalcin   PetscFunctionBegin;
19974f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
19984f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
19994f572ea9SToby Isaac   if (values) PetscAssertPointer(values, 4);
20002d747510SLisandro Dalcin   options = options ? options : defaultoptions;
20012d747510SLisandro Dalcin 
20022d747510SLisandro Dalcin   /* The number of unused PETSc options */
20032d747510SLisandro Dalcin   n = 0;
20042d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
2005660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
20062d747510SLisandro Dalcin     if (!options->used[i]) n++;
20072d747510SLisandro Dalcin   }
2008ad540459SPierre Jolivet   if (N) *N = n;
20099566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
20109566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
20112d747510SLisandro Dalcin 
20122d747510SLisandro Dalcin   n = 0;
20132d747510SLisandro Dalcin   if (names || values) {
20142d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
20152d747510SLisandro Dalcin       if (!options->used[i]) {
2016660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
20172d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
20182d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
20192d747510SLisandro Dalcin         n++;
20202d747510SLisandro Dalcin       }
20212d747510SLisandro Dalcin     }
20222d747510SLisandro Dalcin   }
20233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20242d747510SLisandro Dalcin }
20252d747510SLisandro Dalcin 
20262d747510SLisandro Dalcin /*@C
2027811af0c4SBarry Smith   PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
20282d747510SLisandro Dalcin 
20292d747510SLisandro Dalcin   Not Collective
20302d747510SLisandro Dalcin 
2031d8d19677SJose E. Roman   Input Parameters:
203220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
203310450e9eSJacob Faibussowitsch . N       - count of options not used
20342d747510SLisandro Dalcin . names   - names of options not used
2035a2b725a8SWilliam Gropp - values  - values of options not used
20362d747510SLisandro Dalcin 
20372d747510SLisandro Dalcin   Level: advanced
20382d747510SLisandro Dalcin 
203910450e9eSJacob Faibussowitsch   Notes:
204010450e9eSJacob Faibussowitsch   The user should pass the same pointer to `N` as they did when calling `PetscOptionsLeftGet()`
204110450e9eSJacob Faibussowitsch 
2042db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
20432d747510SLisandro Dalcin @*/
2044d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2045d71ae5a4SJacob Faibussowitsch {
20462d747510SLisandro Dalcin   PetscFunctionBegin;
204710450e9eSJacob Faibussowitsch   (void)options;
20484f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
20494f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
20504f572ea9SToby Isaac   if (values) PetscAssertPointer(values, 4);
2051ad540459SPierre Jolivet   if (N) *N = 0;
20529566063dSJacob Faibussowitsch   if (names) PetscCall(PetscFree(*names));
20539566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
20543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20552d747510SLisandro Dalcin }
20562d747510SLisandro Dalcin 
20572d747510SLisandro Dalcin /*@C
2058811af0c4SBarry Smith   PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
20592d747510SLisandro Dalcin 
2060c3339decSBarry Smith   Logically Collective
20612d747510SLisandro Dalcin 
20622d747510SLisandro Dalcin   Input Parameters:
20632d747510SLisandro Dalcin + name   - option name string
20642d747510SLisandro Dalcin . value  - option value string
20659355ec05SMatthew G. Knepley . source - The source for the option
206620f4b53cSBarry Smith - ctx    - a `PETSCVIEWERASCII` or `NULL`
20672d747510SLisandro Dalcin 
20682d747510SLisandro Dalcin   Level: intermediate
20692d747510SLisandro Dalcin 
20709666a313SBarry Smith   Notes:
207120f4b53cSBarry Smith   If ctx is `NULL`, `PetscPrintf()` is used.
20729314d9b7SBarry Smith   The first MPI process in the `PetscViewer` viewer actually prints the values, other
20731c9f3c13SBarry Smith   processes may have different values set
20741c9f3c13SBarry Smith 
2075811af0c4SBarry Smith   If `PetscCIEnabled` then do not print the test harness options
2076660278c0SBarry Smith 
2077db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
20782d747510SLisandro Dalcin @*/
20799355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], PetscOptionSource source, void *ctx)
2080d71ae5a4SJacob Faibussowitsch {
20812d747510SLisandro Dalcin   PetscFunctionBegin;
20823ba16761SJacob Faibussowitsch   if (PetscCIOption(name)) PetscFunctionReturn(PETSC_SUCCESS);
2083660278c0SBarry Smith 
20849060e2f9SVaclav Hapla   if (ctx) {
20859060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
20862d747510SLisandro Dalcin     if (!value) {
20879566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
20882d747510SLisandro Dalcin     } else if (!value[0]) {
20899355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20902d747510SLisandro Dalcin     } else {
20919355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20922d747510SLisandro Dalcin     }
20939060e2f9SVaclav Hapla   } else {
20949060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
20959060e2f9SVaclav Hapla     if (!value) {
20969566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
20979060e2f9SVaclav Hapla     } else if (!value[0]) {
20989355ec05SMatthew G. Knepley       PetscCall(PetscPrintf(comm, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20999060e2f9SVaclav Hapla     } else {
2100aaa8cc7dSPierre Jolivet       PetscCall(PetscPrintf(comm, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
21019060e2f9SVaclav Hapla     }
21029060e2f9SVaclav Hapla   }
21033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21042d747510SLisandro Dalcin }
21052d747510SLisandro Dalcin 
21062d747510SLisandro Dalcin /*@C
21072d747510SLisandro Dalcin   PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
21082d747510SLisandro Dalcin   modified the PETSc options database.
21092d747510SLisandro Dalcin 
21102d747510SLisandro Dalcin   Not Collective
21112d747510SLisandro Dalcin 
21122d747510SLisandro Dalcin   Input Parameters:
211320f4b53cSBarry Smith + monitor        - pointer to function (if this is `NULL`, it turns off monitoring
211410450e9eSJacob Faibussowitsch . mctx           - [optional] context for private data for the monitor routine (use `NULL` if
211510450e9eSJacob Faibussowitsch                    no context is desired)
2116*49abdd8aSBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`), see `PetscCtxDestroyFn` for its calling sequence
21172d747510SLisandro Dalcin 
211810450e9eSJacob Faibussowitsch   Calling sequence of `monitor`:
21192d747510SLisandro Dalcin + name   - option name string
2120432b765aSRené Chenard . value  - option value string, a value of `NULL` indicates the option is being removed from the database. A value
2121432b765aSRené Chenard            of "" indicates the option is in the database but has no value.
21229355ec05SMatthew G. Knepley . source - option source
2123811af0c4SBarry Smith - mctx   - optional monitoring context, as set by `PetscOptionsMonitorSet()`
21242d747510SLisandro Dalcin 
2125432b765aSRené Chenard   Options Database Keys:
2126432b765aSRené Chenard + -options_monitor <viewer> - turn on default monitoring
2127432b765aSRené Chenard - -options_monitor_cancel   - turn off any option monitors except the default monitor obtained with `-options_monitor`
2128432b765aSRené Chenard 
212920f4b53cSBarry Smith   Level: intermediate
213020f4b53cSBarry Smith 
21312d747510SLisandro Dalcin   Notes:
213210450e9eSJacob Faibussowitsch   See `PetscInitialize()` for options related to option database monitoring.
213310450e9eSJacob Faibussowitsch 
2134432b765aSRené Chenard   The default is to do no monitoring.  To print the name and value of options
2135811af0c4SBarry Smith   being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
2136432b765aSRené Chenard   with a `NULL` monitoring context. Or use the option `-options_monitor` <viewer>.
21372d747510SLisandro Dalcin 
21382d747510SLisandro Dalcin   Several different monitoring routines may be set by calling
2139811af0c4SBarry Smith   `PetscOptionsMonitorSet()` multiple times; all will be called in the
21402d747510SLisandro Dalcin   order in which they were set.
21412d747510SLisandro Dalcin 
2142*49abdd8aSBarry Smith .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`, `PetscCtxDestroyFn`
21432d747510SLisandro Dalcin @*/
2144*49abdd8aSBarry Smith PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource source, void *mctx), void *mctx, PetscCtxDestroyFn *monitordestroy)
2145d71ae5a4SJacob Faibussowitsch {
21462d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
21472d747510SLisandro Dalcin 
21482d747510SLisandro Dalcin   PetscFunctionBegin;
21493ba16761SJacob Faibussowitsch   if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
215008401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
21512d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
21522d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
21532d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void *)mctx;
21543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21552d747510SLisandro Dalcin }
21562d747510SLisandro Dalcin 
21572d747510SLisandro Dalcin /*
21582d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
215963fe8743SVaclav Hapla      Empty string is considered as true.
21602d747510SLisandro Dalcin */
2161d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2162d71ae5a4SJacob Faibussowitsch {
21632d747510SLisandro Dalcin   PetscBool istrue, isfalse;
21642d747510SLisandro Dalcin   size_t    len;
21652d747510SLisandro Dalcin 
21662d747510SLisandro Dalcin   PetscFunctionBegin;
216763fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
21689566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
21699371c9d4SSatish Balay   if (!len) {
21709371c9d4SSatish Balay     *a = PETSC_TRUE;
21713ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21729371c9d4SSatish Balay   }
21739566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
21749371c9d4SSatish Balay   if (istrue) {
21759371c9d4SSatish Balay     *a = PETSC_TRUE;
21763ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21779371c9d4SSatish Balay   }
21789566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
21799371c9d4SSatish Balay   if (istrue) {
21809371c9d4SSatish Balay     *a = PETSC_TRUE;
21813ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21829371c9d4SSatish Balay   }
21839566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
21849371c9d4SSatish Balay   if (istrue) {
21859371c9d4SSatish Balay     *a = PETSC_TRUE;
21863ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21879371c9d4SSatish Balay   }
21889566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
21899371c9d4SSatish Balay   if (istrue) {
21909371c9d4SSatish Balay     *a = PETSC_TRUE;
21913ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21929371c9d4SSatish Balay   }
21939566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
21949371c9d4SSatish Balay   if (isfalse) {
21959371c9d4SSatish Balay     *a = PETSC_FALSE;
21963ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21979371c9d4SSatish Balay   }
21989566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
21999371c9d4SSatish Balay   if (isfalse) {
22009371c9d4SSatish Balay     *a = PETSC_FALSE;
22013ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22029371c9d4SSatish Balay   }
22039566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
22049371c9d4SSatish Balay   if (isfalse) {
22059371c9d4SSatish Balay     *a = PETSC_FALSE;
22063ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22079371c9d4SSatish Balay   }
22089566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
22099371c9d4SSatish Balay   if (isfalse) {
22109371c9d4SSatish Balay     *a = PETSC_FALSE;
22113ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22129371c9d4SSatish Balay   }
221398921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
22142d747510SLisandro Dalcin }
22152d747510SLisandro Dalcin 
22162d747510SLisandro Dalcin /*
22172d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
22182d747510SLisandro Dalcin */
2219d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2220d71ae5a4SJacob Faibussowitsch {
22212d747510SLisandro Dalcin   size_t    len;
2222b3480c81SBarry Smith   PetscBool decide, tdefault, mouse, unlimited;
22232d747510SLisandro Dalcin 
22242d747510SLisandro Dalcin   PetscFunctionBegin;
22259566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
22265f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22272d747510SLisandro Dalcin 
22289566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
222948a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
22309566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
223148a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
2232b3480c81SBarry Smith   if (!decide) PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &decide));
2233b3480c81SBarry Smith   if (!decide) PetscCall(PetscStrcasecmp(name, "DETERMINE", &decide));
2234b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &unlimited));
2235b3480c81SBarry Smith   if (!unlimited) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &unlimited));
22369566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
22372d747510SLisandro Dalcin 
22382d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
22392d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
2240b3480c81SBarry Smith   else if (unlimited) *a = PETSC_UNLIMITED;
22412d747510SLisandro Dalcin   else if (mouse) *a = -1;
22422d747510SLisandro Dalcin   else {
22432d747510SLisandro Dalcin     char *endptr;
22442d747510SLisandro Dalcin     long  strtolval;
22452d747510SLisandro Dalcin 
22462d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2247cc73adaaSBarry 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);
22482d747510SLisandro Dalcin 
22492d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
22502d747510SLisandro Dalcin     (void)strtolval;
22512d747510SLisandro Dalcin     *a = atoll(name);
22522d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
22532d747510SLisandro Dalcin     (void)strtolval;
22542d747510SLisandro Dalcin     *a = _atoi64(name);
22552d747510SLisandro Dalcin #else
22562d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
22572d747510SLisandro Dalcin #endif
22582d747510SLisandro Dalcin   }
22593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22602d747510SLisandro Dalcin }
22612d747510SLisandro Dalcin 
22622d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22632d747510SLisandro Dalcin   #include <quadmath.h>
22642d747510SLisandro Dalcin #endif
22652d747510SLisandro Dalcin 
2266d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2267d71ae5a4SJacob Faibussowitsch {
22682d747510SLisandro Dalcin   PetscFunctionBegin;
22692d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22702d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
22712d747510SLisandro Dalcin #else
22722d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
22732d747510SLisandro Dalcin #endif
22743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22752d747510SLisandro Dalcin }
22762d747510SLisandro Dalcin 
2277d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2278d71ae5a4SJacob Faibussowitsch {
22792d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
22802d747510SLisandro Dalcin   char     *ptr;
22812d747510SLisandro Dalcin   PetscReal strtoval;
22822d747510SLisandro Dalcin 
22832d747510SLisandro Dalcin   PetscFunctionBegin;
22849566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
22852d747510SLisandro Dalcin   if (ptr == name) {
22862d747510SLisandro Dalcin     strtoval = 1.;
22872d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
22882d747510SLisandro Dalcin     if (name[0] == 'i') {
22892d747510SLisandro Dalcin       ptr++;
22902d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
22912d747510SLisandro Dalcin       ptr += 2;
22922d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
22932d747510SLisandro Dalcin       strtoval = -1.;
22942d747510SLisandro Dalcin       ptr += 2;
22952d747510SLisandro Dalcin     }
22962d747510SLisandro Dalcin   } else if (*ptr == 'i') {
22972d747510SLisandro Dalcin     hasi = PETSC_TRUE;
22982d747510SLisandro Dalcin     ptr++;
22992d747510SLisandro Dalcin   }
23002d747510SLisandro Dalcin   *endptr      = ptr;
23012d747510SLisandro Dalcin   *isImaginary = hasi;
23022d747510SLisandro Dalcin   if (hasi) {
23032d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
230498921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
23052d747510SLisandro Dalcin #else
23062d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
23072d747510SLisandro Dalcin #endif
23082d747510SLisandro Dalcin   } else {
23092d747510SLisandro Dalcin     *a = strtoval;
23102d747510SLisandro Dalcin   }
23113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23122d747510SLisandro Dalcin }
23132d747510SLisandro Dalcin 
23142d747510SLisandro Dalcin /*
23152d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
23162d747510SLisandro Dalcin */
2317d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2318d71ae5a4SJacob Faibussowitsch {
23192d747510SLisandro Dalcin   size_t    len;
23202d747510SLisandro Dalcin   PetscBool match;
23212d747510SLisandro Dalcin   char     *endptr;
23222d747510SLisandro Dalcin 
23232d747510SLisandro Dalcin   PetscFunctionBegin;
23249566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
232528b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
23262d747510SLisandro Dalcin 
23279566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
23289566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
23299371c9d4SSatish Balay   if (match) {
23309371c9d4SSatish Balay     *a = PETSC_DEFAULT;
23313ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23329371c9d4SSatish Balay   }
23332d747510SLisandro Dalcin 
23349566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
23359566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
23369371c9d4SSatish Balay   if (match) {
23379371c9d4SSatish Balay     *a = PETSC_DECIDE;
23383ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23399371c9d4SSatish Balay   }
23402d747510SLisandro Dalcin 
2341b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &match));
2342b3480c81SBarry Smith   if (!match) PetscCall(PetscStrcasecmp(name, "DETERMINE", &match));
2343b3480c81SBarry Smith   if (match) {
2344b3480c81SBarry Smith     *a = PETSC_DETERMINE;
2345b3480c81SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
2346b3480c81SBarry Smith   }
2347b3480c81SBarry Smith 
2348b3480c81SBarry Smith   PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &match));
2349b3480c81SBarry Smith   if (!match) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &match));
2350b3480c81SBarry Smith   if (match) {
2351b3480c81SBarry Smith     *a = PETSC_UNLIMITED;
2352b3480c81SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
2353b3480c81SBarry Smith   }
2354b3480c81SBarry Smith 
23559566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
235639a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
23573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23582d747510SLisandro Dalcin }
23592d747510SLisandro Dalcin 
2360d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2361d71ae5a4SJacob Faibussowitsch {
23622d747510SLisandro Dalcin   PetscBool   imag1;
23632d747510SLisandro Dalcin   size_t      len;
23642d747510SLisandro Dalcin   PetscScalar val = 0.;
23652d747510SLisandro Dalcin   char       *ptr = NULL;
23662d747510SLisandro Dalcin 
23672d747510SLisandro Dalcin   PetscFunctionBegin;
23689566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
236928b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
23709566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
23712d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
23722d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
23732d747510SLisandro Dalcin     PetscBool   imag2;
23742d747510SLisandro Dalcin     PetscScalar val2;
23752d747510SLisandro Dalcin 
23769566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
237739a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
23782d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
23792d747510SLisandro Dalcin   }
23802d747510SLisandro Dalcin #endif
238139a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
23822d747510SLisandro Dalcin   *a = val;
23833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23842d747510SLisandro Dalcin }
23852d747510SLisandro Dalcin 
23862d747510SLisandro Dalcin /*@C
23872d747510SLisandro Dalcin   PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
23882d747510SLisandro Dalcin   option in the database.
2389e5c89e4eSSatish Balay 
2390e5c89e4eSSatish Balay   Not Collective
2391e5c89e4eSSatish Balay 
2392e5c89e4eSSatish Balay   Input Parameters:
239320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
239420f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2395e5c89e4eSSatish Balay - name    - the option one is seeking
2396e5c89e4eSSatish Balay 
2397d8d19677SJose E. Roman   Output Parameters:
23982d747510SLisandro Dalcin + ivalue - the logical value to return
2399811af0c4SBarry Smith - set    - `PETSC_TRUE`  if found, else `PETSC_FALSE`
2400e5c89e4eSSatish Balay 
2401e5c89e4eSSatish Balay   Level: beginner
2402e5c89e4eSSatish Balay 
240395452b02SPatrick Sanan   Notes:
24049e296098SJunchao Zhang   TRUE, true, YES, yes, ON, on, nostring, and 1 all translate to `PETSC_TRUE`
24059e296098SJunchao Zhang   FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_FALSE`
24062d747510SLisandro Dalcin 
24079314d9b7SBarry 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`
24089314d9b7SBarry Smith   is equivalent to `-requested_bool true`
24092d747510SLisandro Dalcin 
24109314d9b7SBarry Smith   If the user does not supply the option at all `ivalue` is NOT changed. Thus
24119314d9b7SBarry Smith   you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
24122efd9cb1SBarry Smith 
24139e296098SJunchao Zhang .seealso: `PetscOptionsGetBool3()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2414db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2415db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2416c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2417db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2418db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2419e5c89e4eSSatish Balay @*/
2420d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2421d71ae5a4SJacob Faibussowitsch {
24222d747510SLisandro Dalcin   const char *value;
2423ace3abfcSBarry Smith   PetscBool   flag;
2424e5c89e4eSSatish Balay 
2425e5c89e4eSSatish Balay   PetscFunctionBegin;
24264f572ea9SToby Isaac   PetscAssertPointer(name, 3);
24274f572ea9SToby Isaac   if (ivalue) PetscAssertPointer(ivalue, 4);
24289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2429e5c89e4eSSatish Balay   if (flag) {
243096ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
24319566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
24322d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2433e5c89e4eSSatish Balay   } else {
243496ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2435e5c89e4eSSatish Balay   }
24363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2437e5c89e4eSSatish Balay }
2438e5c89e4eSSatish Balay 
2439e5c89e4eSSatish Balay /*@C
2440d7c1f440SPierre Jolivet   PetscOptionsGetBool3 - Gets the ternary logical (true, false or unknown) value for a particular
24419e296098SJunchao Zhang   option in the database.
24429e296098SJunchao Zhang 
24439e296098SJunchao Zhang   Not Collective
24449e296098SJunchao Zhang 
24459e296098SJunchao Zhang   Input Parameters:
24469e296098SJunchao Zhang + options - options database, use `NULL` for default global database
24479e296098SJunchao Zhang . pre     - the string to prepend to the name or `NULL`
24489e296098SJunchao Zhang - name    - the option one is seeking
24499e296098SJunchao Zhang 
24509e296098SJunchao Zhang   Output Parameters:
24519e296098SJunchao Zhang + ivalue - the ternary logical value to return
24529e296098SJunchao Zhang - set    - `PETSC_TRUE`  if found, else `PETSC_FALSE`
24539e296098SJunchao Zhang 
24549e296098SJunchao Zhang   Level: beginner
24559e296098SJunchao Zhang 
24569e296098SJunchao Zhang   Notes:
24579e296098SJunchao Zhang   TRUE, true, YES, yes, ON, on, nostring and 1 all translate to `PETSC_BOOL3_TRUE`
24589e296098SJunchao Zhang   FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_BOOL3_FALSE`
24599e296098SJunchao Zhang   UNKNOWN, unknown, AUTO and auto all translate to `PETSC_BOOL3_UNKNOWN`
24609e296098SJunchao Zhang 
24619e296098SJunchao 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`
24629e296098SJunchao Zhang   is equivalent to `-requested_bool3 true`
24639e296098SJunchao Zhang 
24649e296098SJunchao Zhang   If the user does not supply the option at all `ivalue` is NOT changed. Thus
24659e296098SJunchao Zhang   you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
24669e296098SJunchao Zhang 
24679e296098SJunchao Zhang .seealso: `PetscOptionsGetBool()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
24689e296098SJunchao Zhang           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
24699e296098SJunchao Zhang           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
24709e296098SJunchao Zhang           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
24719e296098SJunchao Zhang           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
24729e296098SJunchao Zhang           `PetscOptionsFList()`, `PetscOptionsEList()`
24739e296098SJunchao Zhang @*/
24749e296098SJunchao Zhang PetscErrorCode PetscOptionsGetBool3(PetscOptions options, const char pre[], const char name[], PetscBool3 *ivalue, PetscBool *set)
24759e296098SJunchao Zhang {
24769e296098SJunchao Zhang   const char *value;
24779e296098SJunchao Zhang   PetscBool   flag;
24789e296098SJunchao Zhang 
24799e296098SJunchao Zhang   PetscFunctionBegin;
24809e296098SJunchao Zhang   PetscAssertPointer(name, 3);
24819e296098SJunchao Zhang   if (ivalue) PetscAssertPointer(ivalue, 4);
24829e296098SJunchao Zhang   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
24839e296098SJunchao Zhang   if (flag) { // found the option
24849e296098SJunchao Zhang     PetscBool isAUTO = PETSC_FALSE, isUNKNOWN = PETSC_FALSE;
24859e296098SJunchao Zhang 
24869e296098SJunchao Zhang     if (set) *set = PETSC_TRUE;
24879e296098SJunchao Zhang     PetscCall(PetscStrcasecmp("AUTO", value, &isAUTO));                    // auto or AUTO
24889e296098SJunchao Zhang     if (!isAUTO) PetscCall(PetscStrcasecmp("UNKNOWN", value, &isUNKNOWN)); // unknown or UNKNOWN
24899e296098SJunchao Zhang     if (isAUTO || isUNKNOWN) {
24909e296098SJunchao Zhang       if (ivalue) *ivalue = PETSC_BOOL3_UNKNOWN;
24919e296098SJunchao Zhang     } else { // handle boolean values (if no value is given, it returns true)
24929e296098SJunchao Zhang       PetscCall(PetscOptionsStringToBool(value, &flag));
24939e296098SJunchao Zhang       if (ivalue) *ivalue = PetscBoolToBool3(flag);
24949e296098SJunchao Zhang     }
24959e296098SJunchao Zhang   } else {
24969e296098SJunchao Zhang     if (set) *set = PETSC_FALSE;
24979e296098SJunchao Zhang   }
24989e296098SJunchao Zhang   PetscFunctionReturn(PETSC_SUCCESS);
24999e296098SJunchao Zhang }
25009e296098SJunchao Zhang 
25019e296098SJunchao Zhang /*@C
2502e5c89e4eSSatish Balay   PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2503e5c89e4eSSatish Balay 
2504e5c89e4eSSatish Balay   Not Collective
2505e5c89e4eSSatish Balay 
2506e5c89e4eSSatish Balay   Input Parameters:
250720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
250820f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2509e5c89e4eSSatish Balay . opt     - option name
2510a264d7a6SBarry Smith . list    - the possible choices (one of these must be selected, anything else is invalid)
2511a2b725a8SWilliam Gropp - ntext   - number of choices
2512e5c89e4eSSatish Balay 
2513d8d19677SJose E. Roman   Output Parameters:
25142efd9cb1SBarry Smith + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2515811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2516e5c89e4eSSatish Balay 
2517e5c89e4eSSatish Balay   Level: intermediate
2518e5c89e4eSSatish Balay 
251995452b02SPatrick Sanan   Notes:
25209314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
25219314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
25222efd9cb1SBarry Smith 
2523811af0c4SBarry Smith   See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2524e5c89e4eSSatish Balay 
2525db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2526db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2527db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2528c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2529db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2530db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2531e5c89e4eSSatish Balay @*/
2532d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscInt ntext, PetscInt *value, PetscBool *set)
2533d71ae5a4SJacob Faibussowitsch {
253458b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2535e5c89e4eSSatish Balay   char     *svalue;
2536ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2537e5c89e4eSSatish Balay   PetscInt  i;
2538e5c89e4eSSatish Balay 
2539e5c89e4eSSatish Balay   PetscFunctionBegin;
25404f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2541e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
25429566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2543e5c89e4eSSatish Balay     if (alen > len) len = alen;
254458b0ac4eSStefano Zampini     tlen += len + 1;
2545e5c89e4eSSatish Balay   }
2546e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
25479566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
25489566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2549e5c89e4eSSatish Balay   if (aset) {
25509566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
255158b0ac4eSStefano Zampini     if (!flg) {
2552c6a7a370SJeremy L Thompson       char *avail;
255358b0ac4eSStefano Zampini 
25549566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
2555c6a7a370SJeremy L Thompson       avail[0] = '\0';
255658b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
2557c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, list[i], tlen));
2558c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, " ", tlen));
255958b0ac4eSStefano Zampini       }
25609566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
256198921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
256258b0ac4eSStefano Zampini     }
2563fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2564a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
25659566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
25663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2567e5c89e4eSSatish Balay }
2568e5c89e4eSSatish Balay 
2569e5c89e4eSSatish Balay /*@C
2570e5c89e4eSSatish Balay   PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2571e5c89e4eSSatish Balay 
2572e5c89e4eSSatish Balay   Not Collective
2573e5c89e4eSSatish Balay 
2574e5c89e4eSSatish Balay   Input Parameters:
257520f4b53cSBarry Smith + options - options database, use `NULL` for default global database
257620f4b53cSBarry Smith . pre     - option prefix or `NULL`
2577e5c89e4eSSatish Balay . opt     - option name
25786b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2579e5c89e4eSSatish Balay 
2580d8d19677SJose E. Roman   Output Parameters:
2581e5c89e4eSSatish Balay + value - the value to return
2582811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2583e5c89e4eSSatish Balay 
2584e5c89e4eSSatish Balay   Level: beginner
2585e5c89e4eSSatish Balay 
258695452b02SPatrick Sanan   Notes:
25879314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
25889314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2589e5c89e4eSSatish Balay 
25909314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names
2591e5c89e4eSSatish Balay 
2592db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2593db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2594aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2595db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2596c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2597db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2598db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2599e5c89e4eSSatish Balay @*/
2600d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscEnum *value, PetscBool *set)
2601d71ae5a4SJacob Faibussowitsch {
260269a24498SJed Brown   PetscInt  ntext = 0, tval;
2603ace3abfcSBarry Smith   PetscBool fset;
2604e5c89e4eSSatish Balay 
2605e5c89e4eSSatish Balay   PetscFunctionBegin;
26064f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2607ad540459SPierre 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");
260808401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2609e5c89e4eSSatish Balay   ntext -= 3;
26109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
261169a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2612809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2613809ceb46SBarry Smith   if (set) *set = fset;
26143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2615e5c89e4eSSatish Balay }
2616e5c89e4eSSatish Balay 
2617e5c89e4eSSatish Balay /*@C
26182d747510SLisandro Dalcin   PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2619e5c89e4eSSatish Balay 
2620e5c89e4eSSatish Balay   Not Collective
2621e5c89e4eSSatish Balay 
2622e5c89e4eSSatish Balay   Input Parameters:
262320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
262420f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2625e5c89e4eSSatish Balay - name    - the option one is seeking
2626e5c89e4eSSatish Balay 
2627d8d19677SJose E. Roman   Output Parameters:
26282d747510SLisandro Dalcin + ivalue - the integer value to return
2629811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2630e5c89e4eSSatish Balay 
2631e5c89e4eSSatish Balay   Level: beginner
2632e5c89e4eSSatish Balay 
2633e5c89e4eSSatish Balay   Notes:
26349314d9b7SBarry Smith   If the user does not supply the option `ivalue` is NOT changed. Thus
26359314d9b7SBarry Smith   you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
26365c07ccb8SBarry Smith 
2637b3480c81SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
2638b3480c81SBarry Smith 
2639b3480c81SBarry Smith   Accepts the deprecated value `default`.
2640b3480c81SBarry Smith 
2641db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2642db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2643aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2644db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2645c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2646db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2647db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2648e5c89e4eSSatish Balay @*/
2649d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2650d71ae5a4SJacob Faibussowitsch {
26512d747510SLisandro Dalcin   const char *value;
26522d747510SLisandro Dalcin   PetscBool   flag;
2653e5c89e4eSSatish Balay 
2654e5c89e4eSSatish Balay   PetscFunctionBegin;
26554f572ea9SToby Isaac   PetscAssertPointer(name, 3);
26564f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
26579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2658e5c89e4eSSatish Balay   if (flag) {
265934a9cc2cSBarry Smith     if (!value) {
26602d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
266134a9cc2cSBarry Smith     } else {
26622d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
26639566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2664e5c89e4eSSatish Balay     }
2665e5c89e4eSSatish Balay   } else {
266696ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2667e5c89e4eSSatish Balay   }
26683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2669e5c89e4eSSatish Balay }
2670e5c89e4eSSatish Balay 
2671e2446a98SMatthew Knepley /*@C
26726497c311SBarry Smith   PetscOptionsGetMPIInt - Gets the MPI integer value for a particular option in the database.
26736497c311SBarry Smith 
26746497c311SBarry Smith   Not Collective
26756497c311SBarry Smith 
26766497c311SBarry Smith   Input Parameters:
26776497c311SBarry Smith + options - options database, use `NULL` for default global database
26786497c311SBarry Smith . pre     - the string to prepend to the name or `NULL`
26796497c311SBarry Smith - name    - the option one is seeking
26806497c311SBarry Smith 
26816497c311SBarry Smith   Output Parameters:
26826497c311SBarry Smith + ivalue - the MPI integer value to return
26836497c311SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
26846497c311SBarry Smith 
26856497c311SBarry Smith   Level: beginner
26866497c311SBarry Smith 
26876497c311SBarry Smith   Notes:
26886497c311SBarry Smith   If the user does not supply the option `ivalue` is NOT changed. Thus
26896497c311SBarry Smith   you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
26906497c311SBarry Smith 
26916497c311SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
26926497c311SBarry Smith 
26936497c311SBarry Smith   Accepts the deprecated value `default`.
26946497c311SBarry Smith 
26956497c311SBarry Smith .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
26966497c311SBarry Smith           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
26976497c311SBarry Smith           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
26986497c311SBarry Smith           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
26996497c311SBarry Smith           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
27006497c311SBarry Smith           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
27016497c311SBarry Smith           `PetscOptionsFList()`, `PetscOptionsEList()`
27026497c311SBarry Smith @*/
27036497c311SBarry Smith PetscErrorCode PetscOptionsGetMPIInt(PetscOptions options, const char pre[], const char name[], PetscMPIInt *ivalue, PetscBool *set)
27046497c311SBarry Smith {
27056497c311SBarry Smith   PetscInt  value;
27066497c311SBarry Smith   PetscBool flag;
27076497c311SBarry Smith 
27086497c311SBarry Smith   PetscFunctionBegin;
27096497c311SBarry Smith   PetscCall(PetscOptionsGetInt(options, pre, name, &value, &flag));
27106497c311SBarry Smith   if (flag) PetscCall(PetscMPIIntCast(value, ivalue));
27116497c311SBarry Smith   if (set) *set = flag;
27126497c311SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
27136497c311SBarry Smith }
27146497c311SBarry Smith 
27156497c311SBarry Smith /*@C
2716e5c89e4eSSatish Balay   PetscOptionsGetReal - Gets the double precision value for a particular
2717e5c89e4eSSatish Balay   option in the database.
2718e5c89e4eSSatish Balay 
2719e5c89e4eSSatish Balay   Not Collective
2720e5c89e4eSSatish Balay 
2721e5c89e4eSSatish Balay   Input Parameters:
272220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
272320f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2724e5c89e4eSSatish Balay - name    - the option one is seeking
2725e5c89e4eSSatish Balay 
2726d8d19677SJose E. Roman   Output Parameters:
2727e5c89e4eSSatish Balay + dvalue - the double value to return
2728811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2729e5c89e4eSSatish Balay 
273020f4b53cSBarry Smith   Level: beginner
273120f4b53cSBarry Smith 
2732b3480c81SBarry Smith   Notes:
2733b3480c81SBarry Smith   Accepts the special values `determine`, `decide` and `unlimited`.
2734b3480c81SBarry Smith 
2735b3480c81SBarry Smith   Accepts the deprecated value `default`
2736b3480c81SBarry Smith 
27379314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
27389314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking that the `set` flag is true.
2739e4974155SBarry Smith 
2740db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2741c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2742db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2743c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2744db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2745db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2746e5c89e4eSSatish Balay @*/
2747d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2748d71ae5a4SJacob Faibussowitsch {
27492d747510SLisandro Dalcin   const char *value;
2750ace3abfcSBarry Smith   PetscBool   flag;
2751e5c89e4eSSatish Balay 
2752e5c89e4eSSatish Balay   PetscFunctionBegin;
27534f572ea9SToby Isaac   PetscAssertPointer(name, 3);
27544f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
27559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2756e5c89e4eSSatish Balay   if (flag) {
2757a297a907SKarl Rupp     if (!value) {
2758a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2759a297a907SKarl Rupp     } else {
2760a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
27619566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2762a297a907SKarl Rupp     }
2763e5c89e4eSSatish Balay   } else {
276496ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2765e5c89e4eSSatish Balay   }
27663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2767e5c89e4eSSatish Balay }
2768e5c89e4eSSatish Balay 
2769e5c89e4eSSatish Balay /*@C
2770e5c89e4eSSatish Balay   PetscOptionsGetScalar - Gets the scalar value for a particular
2771e5c89e4eSSatish Balay   option in the database.
2772e5c89e4eSSatish Balay 
2773e5c89e4eSSatish Balay   Not Collective
2774e5c89e4eSSatish Balay 
2775e5c89e4eSSatish Balay   Input Parameters:
277620f4b53cSBarry Smith + options - options database, use `NULL` for default global database
277720f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2778e5c89e4eSSatish Balay - name    - the option one is seeking
2779e5c89e4eSSatish Balay 
2780d8d19677SJose E. Roman   Output Parameters:
27819314d9b7SBarry Smith + dvalue - the scalar value to return
2782811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2783e5c89e4eSSatish Balay 
2784e5c89e4eSSatish Balay   Level: beginner
2785e5c89e4eSSatish Balay 
278610450e9eSJacob Faibussowitsch   Example Usage:
2787eb4ae41dSBarry Smith   A complex number 2+3i must be specified with NO spaces
2788e5c89e4eSSatish Balay 
2789811af0c4SBarry Smith   Note:
27909314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
27919314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking if the `set` flag is true.
2792e4974155SBarry Smith 
2793db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2794db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2795db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2796c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2797db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2798db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2799e5c89e4eSSatish Balay @*/
2800d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2801d71ae5a4SJacob Faibussowitsch {
28022d747510SLisandro Dalcin   const char *value;
2803ace3abfcSBarry Smith   PetscBool   flag;
2804e5c89e4eSSatish Balay 
2805e5c89e4eSSatish Balay   PetscFunctionBegin;
28064f572ea9SToby Isaac   PetscAssertPointer(name, 3);
28074f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
28089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2809e5c89e4eSSatish Balay   if (flag) {
2810e5c89e4eSSatish Balay     if (!value) {
281196ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2812e5c89e4eSSatish Balay     } else {
2813e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
28149566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2815e5c89e4eSSatish Balay #else
28169566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2817e5c89e4eSSatish Balay #endif
281896ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2819e5c89e4eSSatish Balay     }
2820e5c89e4eSSatish Balay   } else { /* flag */
282196ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2822e5c89e4eSSatish Balay   }
28233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2824e5c89e4eSSatish Balay }
2825e5c89e4eSSatish Balay 
2826e5c89e4eSSatish Balay /*@C
2827e5c89e4eSSatish Balay   PetscOptionsGetString - Gets the string value for a particular option in
2828e5c89e4eSSatish Balay   the database.
2829e5c89e4eSSatish Balay 
2830e5c89e4eSSatish Balay   Not Collective
2831e5c89e4eSSatish Balay 
2832e5c89e4eSSatish Balay   Input Parameters:
283320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
283420f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
2835e5c89e4eSSatish Balay . name    - the option one is seeking
2836bcbf2dc5SJed Brown - len     - maximum length of the string including null termination
2837e5c89e4eSSatish Balay 
2838e5c89e4eSSatish Balay   Output Parameters:
2839e5c89e4eSSatish Balay + string - location to copy string
2840811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2841e5c89e4eSSatish Balay 
2842e5c89e4eSSatish Balay   Level: beginner
2843e5c89e4eSSatish Balay 
284420f4b53cSBarry Smith   Note:
28459314d9b7SBarry 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`
284620f4b53cSBarry Smith 
28479314d9b7SBarry Smith   If the user does not use the option then `string` is not changed. Thus
28489314d9b7SBarry Smith   you should ALWAYS initialize `string` if you access it without first checking that the `set` flag is true.
284920f4b53cSBarry Smith 
2850aec76313SJacob Faibussowitsch   Fortran Notes:
2851e5c89e4eSSatish Balay   The Fortran interface is slightly different from the C/C++
2852e5c89e4eSSatish Balay   interface (len is not used).  Sample usage in Fortran follows
2853e5c89e4eSSatish Balay .vb
2854e5c89e4eSSatish Balay       character *20    string
285593e6ba5cSBarry Smith       PetscErrorCode   ierr
285693e6ba5cSBarry Smith       PetscBool        set
28571b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2858e5c89e4eSSatish Balay .ve
2859e5c89e4eSSatish Balay 
2860db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2861db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2862db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2863c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2864db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2865db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2866e5c89e4eSSatish Balay @*/
2867d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set)
2868d71ae5a4SJacob Faibussowitsch {
28692d747510SLisandro Dalcin   const char *value;
2870ace3abfcSBarry Smith   PetscBool   flag;
2871e5c89e4eSSatish Balay 
2872e5c89e4eSSatish Balay   PetscFunctionBegin;
28734f572ea9SToby Isaac   PetscAssertPointer(name, 3);
28744f572ea9SToby Isaac   PetscAssertPointer(string, 4);
28759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2876e5c89e4eSSatish Balay   if (!flag) {
287796ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2878e5c89e4eSSatish Balay   } else {
287996ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
28809566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
28819566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2882e5c89e4eSSatish Balay   }
28833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2884e5c89e4eSSatish Balay }
2885e5c89e4eSSatish Balay 
28862d747510SLisandro Dalcin /*@C
28872d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2888f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
28892d747510SLisandro Dalcin 
28902d747510SLisandro Dalcin   Not Collective
28912d747510SLisandro Dalcin 
28922d747510SLisandro Dalcin   Input Parameters:
289320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
289420f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
28956b867d5aSJose E. Roman - name    - the option one is seeking
28966b867d5aSJose E. Roman 
2897d8d19677SJose E. Roman   Output Parameters:
28989314d9b7SBarry Smith + dvalue - the Boolean values to return
2899f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2900811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
29012d747510SLisandro Dalcin 
29022d747510SLisandro Dalcin   Level: beginner
29032d747510SLisandro Dalcin 
2904811af0c4SBarry Smith   Note:
290520f4b53cSBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`. FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
29062d747510SLisandro Dalcin 
2907db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2908db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2909db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2910c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2911db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2912db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29132d747510SLisandro Dalcin @*/
2914d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2915d71ae5a4SJacob Faibussowitsch {
29162d747510SLisandro Dalcin   const char *svalue;
29172d747510SLisandro Dalcin   char       *value;
29182d747510SLisandro Dalcin   PetscInt    n = 0;
29192d747510SLisandro Dalcin   PetscBool   flag;
29202d747510SLisandro Dalcin   PetscToken  token;
29212d747510SLisandro Dalcin 
29222d747510SLisandro Dalcin   PetscFunctionBegin;
29234f572ea9SToby Isaac   PetscAssertPointer(name, 3);
29244f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
29254f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
29262d747510SLisandro Dalcin 
29279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29289371c9d4SSatish Balay   if (!flag || !svalue) {
29299371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29309371c9d4SSatish Balay     *nmax = 0;
29313ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29329371c9d4SSatish Balay   }
29332d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29349566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29359566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29362d747510SLisandro Dalcin   while (value && n < *nmax) {
29379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
29389566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29392d747510SLisandro Dalcin     dvalue++;
29402d747510SLisandro Dalcin     n++;
29412d747510SLisandro Dalcin   }
29429566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29432d747510SLisandro Dalcin   *nmax = n;
29443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29452d747510SLisandro Dalcin }
29462d747510SLisandro Dalcin 
29472d747510SLisandro Dalcin /*@C
29482d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
29492d747510SLisandro Dalcin 
29502d747510SLisandro Dalcin   Not Collective
29512d747510SLisandro Dalcin 
29522d747510SLisandro Dalcin   Input Parameters:
295320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
295420f4b53cSBarry Smith . pre     - option prefix or `NULL`
29552d747510SLisandro Dalcin . name    - option name
29566b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
29576b867d5aSJose E. Roman 
29582d747510SLisandro Dalcin   Output Parameters:
29592d747510SLisandro Dalcin + ivalue - the  enum values to return
2960f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2961811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
29622d747510SLisandro Dalcin 
29632d747510SLisandro Dalcin   Level: beginner
29642d747510SLisandro Dalcin 
29652d747510SLisandro Dalcin   Notes:
29669314d9b7SBarry Smith   The array must be passed as a comma separated list with no spaces between the items.
29672d747510SLisandro Dalcin 
29689314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names.
29692d747510SLisandro Dalcin 
2970db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2971db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2972aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsName()`,
2973c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2974db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2975db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
29762d747510SLisandro Dalcin @*/
2977d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const *list, PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
2978d71ae5a4SJacob Faibussowitsch {
29792d747510SLisandro Dalcin   const char *svalue;
29802d747510SLisandro Dalcin   char       *value;
29812d747510SLisandro Dalcin   PetscInt    n = 0;
29822d747510SLisandro Dalcin   PetscEnum   evalue;
29832d747510SLisandro Dalcin   PetscBool   flag;
29842d747510SLisandro Dalcin   PetscToken  token;
29852d747510SLisandro Dalcin 
29862d747510SLisandro Dalcin   PetscFunctionBegin;
29874f572ea9SToby Isaac   PetscAssertPointer(name, 3);
29884f572ea9SToby Isaac   PetscAssertPointer(list, 4);
29894f572ea9SToby Isaac   PetscAssertPointer(ivalue, 5);
29904f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
29912d747510SLisandro Dalcin 
29929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29939371c9d4SSatish Balay   if (!flag || !svalue) {
29949371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29959371c9d4SSatish Balay     *nmax = 0;
29963ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29979371c9d4SSatish Balay   }
29982d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29999566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30009566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30012d747510SLisandro Dalcin   while (value && n < *nmax) {
30029566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
300328b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
30042d747510SLisandro Dalcin     ivalue[n++] = evalue;
30059566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30062d747510SLisandro Dalcin   }
30079566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30082d747510SLisandro Dalcin   *nmax = n;
30093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30102d747510SLisandro Dalcin }
30112d747510SLisandro Dalcin 
30122d747510SLisandro Dalcin /*@C
3013f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
30142d747510SLisandro Dalcin 
30152d747510SLisandro Dalcin   Not Collective
30162d747510SLisandro Dalcin 
30172d747510SLisandro Dalcin   Input Parameters:
301820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
301920f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
30206b867d5aSJose E. Roman - name    - the option one is seeking
30216b867d5aSJose E. Roman 
3022d8d19677SJose E. Roman   Output Parameters:
30232d747510SLisandro Dalcin + ivalue - the integer values to return
3024f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3025811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
30262d747510SLisandro Dalcin 
30272d747510SLisandro Dalcin   Level: beginner
30282d747510SLisandro Dalcin 
30292d747510SLisandro Dalcin   Notes:
30302d747510SLisandro Dalcin   The array can be passed as
3031811af0c4SBarry Smith +  a comma separated list -                                 0,1,2,3,4,5,6,7
3032811af0c4SBarry Smith .  a range (start\-end+1) -                                 0-8
3033811af0c4SBarry Smith .  a range with given increment (start\-end+1:inc) -        0-7:2
3034811af0c4SBarry Smith -  a combination of values and ranges separated by commas - 0,1-8,8-15:2
30352d747510SLisandro Dalcin 
30362d747510SLisandro Dalcin   There must be no intervening spaces between the values.
30372d747510SLisandro Dalcin 
3038db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3039db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3040db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3041c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3042db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3043db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30442d747510SLisandro Dalcin @*/
3045d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
3046d71ae5a4SJacob Faibussowitsch {
30472d747510SLisandro Dalcin   const char *svalue;
30482d747510SLisandro Dalcin   char       *value;
30492d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
30502d747510SLisandro Dalcin   size_t      len;
30512d747510SLisandro Dalcin   PetscBool   flag, foundrange;
30522d747510SLisandro Dalcin   PetscToken  token;
30532d747510SLisandro Dalcin 
30542d747510SLisandro Dalcin   PetscFunctionBegin;
30554f572ea9SToby Isaac   PetscAssertPointer(name, 3);
30564f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
30574f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
30582d747510SLisandro Dalcin 
30599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30609371c9d4SSatish Balay   if (!flag || !svalue) {
30619371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30629371c9d4SSatish Balay     *nmax = 0;
30633ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
30649371c9d4SSatish Balay   }
30652d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30669566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30679566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30682d747510SLisandro Dalcin   while (value && n < *nmax) {
30692d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
30702d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
30719566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value, &len));
30722d747510SLisandro Dalcin     if (value[0] == '-') i = 2;
30732d747510SLisandro Dalcin     else i = 1;
30742d747510SLisandro Dalcin     for (; i < (int)len; i++) {
30752d747510SLisandro Dalcin       if (value[i] == '-') {
3076cc73adaaSBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
30772d747510SLisandro Dalcin         value[i] = 0;
30782d747510SLisandro Dalcin 
30799566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value, &start));
30802d747510SLisandro Dalcin         inc = 1;
30812d747510SLisandro Dalcin         j   = i + 1;
30822d747510SLisandro Dalcin         for (; j < (int)len; j++) {
30832d747510SLisandro Dalcin           if (value[j] == ':') {
30842d747510SLisandro Dalcin             value[j] = 0;
30852d747510SLisandro Dalcin 
30869566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value + j + 1, &inc));
308708401ef6SPierre 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);
30882d747510SLisandro Dalcin             break;
30892d747510SLisandro Dalcin           }
30902d747510SLisandro Dalcin         }
30919566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
309208401ef6SPierre 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);
30932d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
3094cc73adaaSBarry 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);
30952d747510SLisandro Dalcin         for (; start < end; start += inc) {
30969371c9d4SSatish Balay           *ivalue = start;
30979371c9d4SSatish Balay           ivalue++;
30989371c9d4SSatish Balay           n++;
30992d747510SLisandro Dalcin         }
31002d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
31012d747510SLisandro Dalcin         break;
31022d747510SLisandro Dalcin       }
31032d747510SLisandro Dalcin     }
31042d747510SLisandro Dalcin     if (!foundrange) {
31059566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
31062d747510SLisandro Dalcin       ivalue++;
31072d747510SLisandro Dalcin       n++;
31082d747510SLisandro Dalcin     }
31099566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
31102d747510SLisandro Dalcin   }
31119566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
31122d747510SLisandro Dalcin   *nmax = n;
31133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31142d747510SLisandro Dalcin }
31152d747510SLisandro Dalcin 
31162d747510SLisandro Dalcin /*@C
31172d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
3118f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
31192d747510SLisandro Dalcin 
31202d747510SLisandro Dalcin   Not Collective
31212d747510SLisandro Dalcin 
31222d747510SLisandro Dalcin   Input Parameters:
312320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
312420f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
31256b867d5aSJose E. Roman - name    - the option one is seeking
31266b867d5aSJose E. Roman 
31272d747510SLisandro Dalcin   Output Parameters:
31282d747510SLisandro Dalcin + dvalue - the double values to return
3129f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3130811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
31312d747510SLisandro Dalcin 
31322d747510SLisandro Dalcin   Level: beginner
31332d747510SLisandro Dalcin 
3134db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3135db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3136db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3137c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3138db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3139db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
31402d747510SLisandro Dalcin @*/
3141d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
3142d71ae5a4SJacob Faibussowitsch {
31432d747510SLisandro Dalcin   const char *svalue;
31442d747510SLisandro Dalcin   char       *value;
31452d747510SLisandro Dalcin   PetscInt    n = 0;
31462d747510SLisandro Dalcin   PetscBool   flag;
31472d747510SLisandro Dalcin   PetscToken  token;
31482d747510SLisandro Dalcin 
31492d747510SLisandro Dalcin   PetscFunctionBegin;
31504f572ea9SToby Isaac   PetscAssertPointer(name, 3);
31514f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
31524f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
31532d747510SLisandro Dalcin 
31549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
31559371c9d4SSatish Balay   if (!flag || !svalue) {
31569371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
31579371c9d4SSatish Balay     *nmax = 0;
31583ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
31599371c9d4SSatish Balay   }
31602d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31619566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31629566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31632d747510SLisandro Dalcin   while (value && n < *nmax) {
31649566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
31659566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
31662d747510SLisandro Dalcin     n++;
31672d747510SLisandro Dalcin   }
31689566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
31692d747510SLisandro Dalcin   *nmax = n;
31703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31712d747510SLisandro Dalcin }
31722d747510SLisandro Dalcin 
31732d747510SLisandro Dalcin /*@C
31742d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
3175f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
31762d747510SLisandro Dalcin 
31772d747510SLisandro Dalcin   Not Collective
31782d747510SLisandro Dalcin 
31792d747510SLisandro Dalcin   Input Parameters:
318020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
318120f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
31826b867d5aSJose E. Roman - name    - the option one is seeking
31836b867d5aSJose E. Roman 
31842d747510SLisandro Dalcin   Output Parameters:
31852d747510SLisandro Dalcin + dvalue - the scalar values to return
3186f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3187811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
31882d747510SLisandro Dalcin 
31892d747510SLisandro Dalcin   Level: beginner
31902d747510SLisandro Dalcin 
3191db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3192db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3193db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3194c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3195db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3196db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
31972d747510SLisandro Dalcin @*/
3198d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3199d71ae5a4SJacob Faibussowitsch {
32002d747510SLisandro Dalcin   const char *svalue;
32012d747510SLisandro Dalcin   char       *value;
32022d747510SLisandro Dalcin   PetscInt    n = 0;
32032d747510SLisandro Dalcin   PetscBool   flag;
32042d747510SLisandro Dalcin   PetscToken  token;
32052d747510SLisandro Dalcin 
32062d747510SLisandro Dalcin   PetscFunctionBegin;
32074f572ea9SToby Isaac   PetscAssertPointer(name, 3);
32084f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
32094f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
32102d747510SLisandro Dalcin 
32119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
32129371c9d4SSatish Balay   if (!flag || !svalue) {
32139371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
32149371c9d4SSatish Balay     *nmax = 0;
32153ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
32169371c9d4SSatish Balay   }
32172d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
32189566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
32199566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
32202d747510SLisandro Dalcin   while (value && n < *nmax) {
32219566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value, dvalue++));
32229566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
32232d747510SLisandro Dalcin     n++;
32242d747510SLisandro Dalcin   }
32259566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
32262d747510SLisandro Dalcin   *nmax = n;
32273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32282d747510SLisandro Dalcin }
322914ce751eSBarry Smith 
3230e5c89e4eSSatish Balay /*@C
3231e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
3232f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
3233e5c89e4eSSatish Balay 
3234cf53795eSBarry Smith   Not Collective; No Fortran Support
3235e5c89e4eSSatish Balay 
3236e5c89e4eSSatish Balay   Input Parameters:
323720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
323820f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
32396b867d5aSJose E. Roman - name    - the option one is seeking
32406b867d5aSJose E. Roman 
3241e7b76fa7SPatrick Sanan   Output Parameters:
3242e5c89e4eSSatish Balay + strings - location to copy strings
3243f1a722f8SMatthew G. Knepley . nmax    - On input maximum number of strings, on output the actual number of strings found
3244811af0c4SBarry Smith - set     - `PETSC_TRUE` if found, else `PETSC_FALSE`
3245e5c89e4eSSatish Balay 
3246e5c89e4eSSatish Balay   Level: beginner
3247e5c89e4eSSatish Balay 
3248e5c89e4eSSatish Balay   Notes:
32499314d9b7SBarry Smith   The `nmax` parameter is used for both input and output.
3250e7b76fa7SPatrick Sanan 
3251e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
3252e5c89e4eSSatish Balay   strings returned by this function.
3253e5c89e4eSSatish Balay 
3254e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3255cf53795eSBarry Smith   returned.
3256e5c89e4eSSatish Balay 
3257db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3258db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3259db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3260c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3261db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3262db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3263e5c89e4eSSatish Balay @*/
3264d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set)
3265d71ae5a4SJacob Faibussowitsch {
32662d747510SLisandro Dalcin   const char *svalue;
3267e5c89e4eSSatish Balay   char       *value;
32682d747510SLisandro Dalcin   PetscInt    n = 0;
3269ace3abfcSBarry Smith   PetscBool   flag;
32709c9d3cfdSBarry Smith   PetscToken  token;
3271e5c89e4eSSatish Balay 
3272e5c89e4eSSatish Balay   PetscFunctionBegin;
32734f572ea9SToby Isaac   PetscAssertPointer(name, 3);
32744f572ea9SToby Isaac   PetscAssertPointer(strings, 4);
32754f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
3276e5c89e4eSSatish Balay 
32779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
32789371c9d4SSatish Balay   if (!flag || !svalue) {
32799371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
32809371c9d4SSatish Balay     *nmax = 0;
32813ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
32829371c9d4SSatish Balay   }
32832d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
32849566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
32859566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
32862d747510SLisandro Dalcin   while (value && n < *nmax) {
32879566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
32889566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3289e5c89e4eSSatish Balay     n++;
3290e5c89e4eSSatish Balay   }
32919566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3292e5c89e4eSSatish Balay   *nmax = n;
32933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3294e5c89e4eSSatish Balay }
329506824ed3SPatrick Sanan 
329606824ed3SPatrick Sanan /*@C
3297aec76313SJacob Faibussowitsch   PetscOptionsDeprecated_Private - mark an option as deprecated, optionally replacing it with `newname`
329806824ed3SPatrick Sanan 
329906824ed3SPatrick Sanan   Prints a deprecation warning, unless an option is supplied to suppress.
330006824ed3SPatrick Sanan 
33011c9f3c13SBarry Smith   Logically Collective
330206824ed3SPatrick Sanan 
330306824ed3SPatrick Sanan   Input Parameters:
3304aec76313SJacob Faibussowitsch + PetscOptionsObject - string to prepend to name or `NULL`
330506824ed3SPatrick Sanan . oldname            - the old, deprecated option
330620f4b53cSBarry Smith . newname            - the new option, or `NULL` if option is purely removed
33079f3a6782SPatrick Sanan . version            - a string describing the version of first deprecation, e.g. "3.9"
330820f4b53cSBarry Smith - info               - additional information string, or `NULL`.
330906824ed3SPatrick Sanan 
3310811af0c4SBarry Smith   Options Database Key:
331106824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
331206824ed3SPatrick Sanan 
331320f4b53cSBarry Smith   Level: developer
331420f4b53cSBarry Smith 
331506824ed3SPatrick Sanan   Notes:
33164ead3382SBarry Smith   If `newname` is provided then the options database will automatically check the database for `oldname`.
33174ead3382SBarry Smith 
33184ead3382SBarry Smith   The old call `PetscOptionsXXX`(`oldname`) should be removed from the source code when both (1) the call to `PetscOptionsDeprecated()` occurs before the
33194ead3382SBarry Smith   new call to `PetscOptionsXXX`(`newname`) and (2) the argument handling of the new call to `PetscOptionsXXX`(`newname`) is identical to the previous call.
33204ead3382SBarry Smith   See `PTScotch_PartGraph_Seq()` for an example of when (1) fails and `SNESTestJacobian()` where an example of (2) fails.
33214ead3382SBarry Smith 
3322811af0c4SBarry Smith   Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
332335cb6cd3SPierre Jolivet   Only the process of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3324811af0c4SBarry Smith   `PetscObjectOptionsBegin()` prints the information
3325b40114eaSPatrick Sanan   If newname is provided, the old option is replaced. Otherwise, it remains
3326b40114eaSPatrick Sanan   in the options database.
33279f3a6782SPatrick Sanan   If an option is not replaced, the info argument should be used to advise the user
33289f3a6782SPatrick Sanan   on how to proceed.
33299f3a6782SPatrick Sanan   There is a limit on the length of the warning printed, so very long strings
33309f3a6782SPatrick Sanan   provided as info may be truncated.
333106824ed3SPatrick Sanan 
3332db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
333306824ed3SPatrick Sanan @*/
3334d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3335d71ae5a4SJacob Faibussowitsch {
333606824ed3SPatrick Sanan   PetscBool         found, quiet;
333706824ed3SPatrick Sanan   const char       *value;
333806824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
33399f3a6782SPatrick Sanan   char              msg[4096];
3340b0bdc838SStefano Zampini   char             *prefix  = NULL;
3341b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3342b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
334306824ed3SPatrick Sanan 
334406824ed3SPatrick Sanan   PetscFunctionBegin;
33454f572ea9SToby Isaac   PetscAssertPointer(oldname, 2);
33464f572ea9SToby Isaac   PetscAssertPointer(version, 4);
3347b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3348b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3349b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3350b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3351b0bdc838SStefano Zampini   }
33529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
335306824ed3SPatrick Sanan   if (found) {
335406824ed3SPatrick Sanan     if (newname) {
33551baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
33569566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options, newname, value));
33571baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
33589566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3359b40114eaSPatrick Sanan     }
336006824ed3SPatrick Sanan     quiet = PETSC_FALSE;
33619566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
336206824ed3SPatrick Sanan     if (!quiet) {
3363c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option ", sizeof(msg)));
3364c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, oldname, sizeof(msg)));
3365c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3366c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
33674bd3d7f8SBarry Smith       PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
336806824ed3SPatrick Sanan       if (newname) {
33694bd3d7f8SBarry Smith         PetscCall(PetscStrlcat(msg, "   Use the option ", sizeof(msg)));
3370c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, newname, sizeof(msg)));
3371c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
337206824ed3SPatrick Sanan       }
33739f3a6782SPatrick Sanan       if (info) {
3374c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3375c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
33769f3a6782SPatrick Sanan       }
3377c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3378c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3379c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
33809566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
338106824ed3SPatrick Sanan     }
338206824ed3SPatrick Sanan   }
33833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
338406824ed3SPatrick Sanan }
3385