xref: /petsc/src/sys/objects/options.c (revision aec76313382a76d73a95f2051cbe4b1eab55c1c7)
173fca5a0SBarry Smith /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
20039db0dSBarry Smith #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for atoll() */
3e5ea902fSJed Brown 
4e5c89e4eSSatish Balay /*
53fc1eb6aSBarry Smith    These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
63fc1eb6aSBarry Smith    This provides the low-level interface, the high level interface is in aoptions.c
7e5c89e4eSSatish Balay 
83fc1eb6aSBarry Smith    Some routines use regular malloc and free because it cannot know  what malloc is requested with the
93fc1eb6aSBarry Smith    options database until it has already processed the input.
10e5c89e4eSSatish Balay */
11e5c89e4eSSatish Balay 
12af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I  "petscsys.h"   I*/
13665c2dedSJed Brown #include <petscviewer.h>
14ad1ac5ecSJed Brown #include <ctype.h>
15e5c89e4eSSatish Balay #if defined(PETSC_HAVE_MALLOC_H)
16e5c89e4eSSatish Balay   #include <malloc.h>
17e5c89e4eSSatish Balay #endif
18ef279fd6SBarry Smith #if defined(PETSC_HAVE_STRINGS_H)
19ef279fd6SBarry Smith   #include <strings.h> /* strcasecmp */
20ef279fd6SBarry Smith #endif
21e5c89e4eSSatish Balay 
222d747510SLisandro Dalcin #if defined(PETSC_HAVE_STRCASECMP)
232d747510SLisandro Dalcin   #define PetscOptNameCmp(a, b) strcasecmp(a, b)
242d747510SLisandro Dalcin #elif defined(PETSC_HAVE_STRICMP)
252d747510SLisandro Dalcin   #define PetscOptNameCmp(a, b) stricmp(a, b)
262d747510SLisandro Dalcin #else
272d747510SLisandro Dalcin   #define PetscOptNameCmp(a, b) Error_strcasecmp_not_found
282d747510SLisandro Dalcin #endif
292d747510SLisandro Dalcin 
302d747510SLisandro Dalcin #include <petsc/private/hashtable.h>
312d747510SLisandro Dalcin 
322d747510SLisandro Dalcin /* This assumes ASCII encoding and ignores locale settings */
332d747510SLisandro Dalcin /* Using tolower() is about 2X slower in microbenchmarks   */
34d71ae5a4SJacob Faibussowitsch static inline int PetscToLower(int c)
35d71ae5a4SJacob Faibussowitsch {
362d747510SLisandro Dalcin   return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
372d747510SLisandro Dalcin }
382d747510SLisandro Dalcin 
392d747510SLisandro Dalcin /* Bob Jenkins's one at a time hash function (case-insensitive) */
40d71ae5a4SJacob Faibussowitsch static inline unsigned int PetscOptHash(const char key[])
41d71ae5a4SJacob Faibussowitsch {
422d747510SLisandro Dalcin   unsigned int hash = 0;
432d747510SLisandro Dalcin   while (*key) {
442d747510SLisandro Dalcin     hash += PetscToLower(*key++);
452d747510SLisandro Dalcin     hash += hash << 10;
462d747510SLisandro Dalcin     hash ^= hash >> 6;
472d747510SLisandro Dalcin   }
482d747510SLisandro Dalcin   hash += hash << 3;
492d747510SLisandro Dalcin   hash ^= hash >> 11;
502d747510SLisandro Dalcin   hash += hash << 15;
512d747510SLisandro Dalcin   return hash;
522d747510SLisandro Dalcin }
532d747510SLisandro Dalcin 
54d71ae5a4SJacob Faibussowitsch static inline int PetscOptEqual(const char a[], const char b[])
55d71ae5a4SJacob Faibussowitsch {
562d747510SLisandro Dalcin   return !PetscOptNameCmp(a, b);
572d747510SLisandro Dalcin }
582d747510SLisandro Dalcin 
592d747510SLisandro Dalcin KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
602d747510SLisandro Dalcin 
6174e0666dSJed Brown #define MAXPREFIXES        25
622d747510SLisandro Dalcin #define MAXOPTIONSMONITORS 5
63e5c89e4eSSatish Balay 
649355ec05SMatthew G. Knepley const char *PetscOptionSources[] = {"code", "command line", "file", "environment"};
659355ec05SMatthew G. Knepley 
669355ec05SMatthew G. Knepley // This table holds all the options set by the user
674416b707SBarry Smith struct _n_PetscOptions {
683de2bfdfSBarry Smith   PetscOptions previous;
699355ec05SMatthew G. Knepley 
702d747510SLisandro Dalcin   int                N;      /* number of options */
719355ec05SMatthew G. Knepley   int                Nalloc; /* number of allocated options */
729355ec05SMatthew G. Knepley   char             **names;  /* option names */
739355ec05SMatthew G. Knepley   char             **values; /* option values */
749355ec05SMatthew G. Knepley   PetscBool         *used;   /* flag option use */
759355ec05SMatthew G. Knepley   PetscOptionSource *source; /* source for option value */
76c5b5d8d5SVaclav Hapla   PetscBool          precedentProcessed;
77081c24baSBoyana Norris 
782d747510SLisandro Dalcin   /* Hash table */
792d747510SLisandro Dalcin   khash_t(HO) *ht;
802d747510SLisandro Dalcin 
812d747510SLisandro Dalcin   /* Prefixes */
822d747510SLisandro Dalcin   int  prefixind;
832d747510SLisandro Dalcin   int  prefixstack[MAXPREFIXES];
849355ec05SMatthew G. Knepley   char prefix[PETSC_MAX_OPTION_NAME];
852d747510SLisandro Dalcin 
862d747510SLisandro Dalcin   /* Aliases */
879355ec05SMatthew G. Knepley   int    Na;       /* number or aliases */
889355ec05SMatthew G. Knepley   int    Naalloc;  /* number of allocated aliases */
899355ec05SMatthew G. Knepley   char **aliases1; /* aliased */
909355ec05SMatthew G. Knepley   char **aliases2; /* aliasee */
912d747510SLisandro Dalcin 
922d747510SLisandro Dalcin   /* Help */
932d747510SLisandro Dalcin   PetscBool help;       /* flag whether "-help" is in the database */
94d314f959SVaclav Hapla   PetscBool help_intro; /* flag whether "-help intro" is in the database */
952d747510SLisandro Dalcin 
962d747510SLisandro Dalcin   /* Monitors */
97c5b5d8d5SVaclav Hapla   PetscBool monitorFromOptions, monitorCancel;
989355ec05SMatthew G. Knepley   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], PetscOptionSource, void *); /* returns control to user after */
999355ec05SMatthew G. Knepley   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void **);                                        /* callback for monitor destruction */
100081c24baSBoyana Norris   void    *monitorcontext[MAXOPTIONSMONITORS];                                                          /* to pass arbitrary user data into monitor */
101081c24baSBoyana Norris   PetscInt numbermonitors;                                                                              /* to, for instance, detect options being set */
1024416b707SBarry Smith };
103e5c89e4eSSatish Balay 
104b4205f0bSBarry Smith static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
1052d747510SLisandro Dalcin 
106aaa8cc7dSPierre Jolivet /* list of options which precede others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
107660278c0SBarry Smith /* these options can only take boolean values, the code will crash if given a non-boolean value */
108660278c0SBarry Smith static const char *precedentOptions[] = {"-petsc_ci", "-options_monitor", "-options_monitor_cancel", "-help", "-skip_petscrc"};
1099371c9d4SSatish Balay enum PetscPrecedentOption {
1109371c9d4SSatish Balay   PO_CI_ENABLE,
1119371c9d4SSatish Balay   PO_OPTIONS_MONITOR,
1129371c9d4SSatish Balay   PO_OPTIONS_MONITOR_CANCEL,
1139371c9d4SSatish Balay   PO_HELP,
1149371c9d4SSatish Balay   PO_SKIP_PETSCRC,
1159371c9d4SSatish Balay   PO_NUM
1169371c9d4SSatish Balay };
117c5b5d8d5SVaclav Hapla 
1189355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsSetValue_Private(PetscOptions, const char[], const char[], int *, PetscOptionSource);
1199355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsInsertStringYAML_Private(PetscOptions, const char[], PetscOptionSource);
120c5b5d8d5SVaclav Hapla 
121081c24baSBoyana Norris /*
122081c24baSBoyana Norris     Options events monitor
123081c24baSBoyana Norris */
1249355ec05SMatthew G. Knepley static PetscErrorCode PetscOptionsMonitor(PetscOptions options, const char name[], const char value[], PetscOptionSource source)
125d71ae5a4SJacob Faibussowitsch {
126e5c89e4eSSatish Balay   PetscFunctionBegin;
127c5b5d8d5SVaclav Hapla   if (!value) value = "";
1289355ec05SMatthew G. Knepley   if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name, value, source, NULL));
1299355ec05SMatthew G. Knepley   for (PetscInt i = 0; i < options->numbermonitors; i++) PetscCall((*options->monitor[i])(name, value, source, options->monitorcontext[i]));
1303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
131e5c89e4eSSatish Balay }
132e5c89e4eSSatish Balay 
1332d747510SLisandro Dalcin /*@
1342d747510SLisandro Dalcin   PetscOptionsCreate - Creates an empty options database.
135e5c89e4eSSatish Balay 
13620f4b53cSBarry Smith   Logically Collective
1371c9f3c13SBarry Smith 
138e5c89e4eSSatish Balay   Output Parameter:
1392d747510SLisandro Dalcin . options - Options database object
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay   Level: advanced
142e5c89e4eSSatish Balay 
143811af0c4SBarry Smith   Note:
144811af0c4SBarry Smith   Though PETSc has a concept of multiple options database the current code uses a single default `PetscOptions` object
145811af0c4SBarry Smith 
146811af0c4SBarry Smith   Developer Notes:
147811af0c4SBarry Smith   We may want eventually to pass a `MPI_Comm` to determine the ownership of the object
148811af0c4SBarry Smith 
149811af0c4SBarry Smith   This object never got developed after being introduced, it is not clear that supporting multiple `PetscOptions` objects is useful
1501c9f3c13SBarry Smith 
151db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
152e5c89e4eSSatish Balay @*/
153d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreate(PetscOptions *options)
154d71ae5a4SJacob Faibussowitsch {
15539a651e2SJacob Faibussowitsch   PetscFunctionBegin;
15639a651e2SJacob Faibussowitsch   PetscValidPointer(options, 1);
1572d747510SLisandro Dalcin   *options = (PetscOptions)calloc(1, sizeof(**options));
15839a651e2SJacob Faibussowitsch   PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
1593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1602d747510SLisandro Dalcin }
1612d747510SLisandro Dalcin 
1622d747510SLisandro Dalcin /*@
1632d747510SLisandro Dalcin   PetscOptionsDestroy - Destroys an option database.
1642d747510SLisandro Dalcin 
16520f4b53cSBarry Smith   Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
1661c9f3c13SBarry Smith 
1672d747510SLisandro Dalcin   Input Parameter:
168811af0c4SBarry Smith . options - the `PetscOptions` object
1692d747510SLisandro Dalcin 
1703de2bfdfSBarry Smith   Level: advanced
1712d747510SLisandro Dalcin 
172*aec76313SJacob Faibussowitsch .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsSetValue()`
1732d747510SLisandro Dalcin @*/
174d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
175d71ae5a4SJacob Faibussowitsch {
176362febeeSStefano Zampini   PetscFunctionBegin;
17710c654e6SJacob Faibussowitsch   PetscValidPointer(options, 1);
1783ba16761SJacob Faibussowitsch   if (!*options) PetscFunctionReturn(PETSC_SUCCESS);
1795f80ce2aSJacob 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()");
1809566063dSJacob Faibussowitsch   PetscCall(PetscOptionsClear(*options));
1812d747510SLisandro Dalcin   /* XXX what about monitors ? */
1822800570dSLisandro Dalcin   free(*options);
1832d747510SLisandro Dalcin   *options = NULL;
1843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
185e5c89e4eSSatish Balay }
186e5c89e4eSSatish Balay 
1872d747510SLisandro Dalcin /*
1882d747510SLisandro Dalcin     PetscOptionsCreateDefault - Creates the default global options database
1892d747510SLisandro Dalcin */
190d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsCreateDefault(void)
191d71ae5a4SJacob Faibussowitsch {
19239a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1939566063dSJacob Faibussowitsch   if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
1943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1952d747510SLisandro Dalcin }
1962d747510SLisandro Dalcin 
197b4205f0bSBarry Smith /*@
198811af0c4SBarry Smith   PetscOptionsPush - Push a new `PetscOptions` object as the default provider of options
1991c9f3c13SBarry Smith   Allows using different parts of a code to use different options databases
200b4205f0bSBarry Smith 
201b4205f0bSBarry Smith   Logically Collective
202b4205f0bSBarry Smith 
203b4205f0bSBarry Smith   Input Parameter:
204811af0c4SBarry Smith . opt - the options obtained with `PetscOptionsCreate()`
205b4205f0bSBarry Smith 
20620f4b53cSBarry Smith   Level: advanced
20720f4b53cSBarry Smith 
208b4205f0bSBarry Smith   Notes:
209811af0c4SBarry Smith   Use `PetscOptionsPop()` to return to the previous default options database
2101c9f3c13SBarry Smith 
211811af0c4SBarry Smith   The collectivity of this routine is complex; only the MPI ranks that call this routine will
2121c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
2131c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
2141c9f3c13SBarry Smith   on different ranks.
215b4205f0bSBarry Smith 
216*aec76313SJacob Faibussowitsch   Developer Notes:
217811af0c4SBarry Smith   Though this functionality has been provided it has never been used in PETSc and might be removed.
218811af0c4SBarry Smith 
219db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
220b4205f0bSBarry Smith @*/
221d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPush(PetscOptions opt)
222d71ae5a4SJacob Faibussowitsch {
223b4205f0bSBarry Smith   PetscFunctionBegin;
2249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsCreateDefault());
225b4205f0bSBarry Smith   opt->previous  = defaultoptions;
226b4205f0bSBarry Smith   defaultoptions = opt;
2273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
228b4205f0bSBarry Smith }
229b4205f0bSBarry Smith 
230b4205f0bSBarry Smith /*@
231811af0c4SBarry Smith   PetscOptionsPop - Pop the most recent `PetscOptionsPush()` to return to the previous default options
232b4205f0bSBarry Smith 
23320f4b53cSBarry Smith   Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
234b4205f0bSBarry Smith 
2353de2bfdfSBarry Smith   Level: advanced
2363de2bfdfSBarry Smith 
237db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
238b4205f0bSBarry Smith @*/
239d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPop(void)
240d71ae5a4SJacob Faibussowitsch {
2413de2bfdfSBarry Smith   PetscOptions current = defaultoptions;
2423de2bfdfSBarry Smith 
243b4205f0bSBarry Smith   PetscFunctionBegin;
24428b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing default options");
24528b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions->previous, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscOptionsPop() called too many times");
246b4205f0bSBarry Smith   defaultoptions    = defaultoptions->previous;
2473de2bfdfSBarry Smith   current->previous = NULL;
2483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
249b4205f0bSBarry Smith }
250b4205f0bSBarry Smith 
2512d747510SLisandro Dalcin /*
2522d747510SLisandro Dalcin     PetscOptionsDestroyDefault - Destroys the default global options database
2532d747510SLisandro Dalcin */
254d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroyDefault(void)
255d71ae5a4SJacob Faibussowitsch {
25639a651e2SJacob Faibussowitsch   PetscFunctionBegin;
2573ba16761SJacob Faibussowitsch   if (!defaultoptions) PetscFunctionReturn(PETSC_SUCCESS);
2583de2bfdfSBarry Smith   /* Destroy any options that the user forgot to pop */
2593de2bfdfSBarry Smith   while (defaultoptions->previous) {
26039a651e2SJacob Faibussowitsch     PetscOptions tmp = defaultoptions;
26139a651e2SJacob Faibussowitsch 
2629566063dSJacob Faibussowitsch     PetscCall(PetscOptionsPop());
2639566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDestroy(&tmp));
2643de2bfdfSBarry Smith   }
2659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDestroy(&defaultoptions));
2663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
267e5c89e4eSSatish Balay }
268e5c89e4eSSatish Balay 
26994ef8ddeSSatish Balay /*@C
2707cd08cecSJed Brown   PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
2713fc1eb6aSBarry Smith 
27220f4b53cSBarry Smith   Not Collective
2731c9f3c13SBarry Smith 
2743fc1eb6aSBarry Smith   Input Parameter:
2752d747510SLisandro Dalcin . key - string to check if valid
2763fc1eb6aSBarry Smith 
2773fc1eb6aSBarry Smith   Output Parameter:
278811af0c4SBarry Smith . valid - `PETSC_TRUE` if a valid key
2793fc1eb6aSBarry Smith 
280f6680f47SSatish Balay   Level: intermediate
2813fc1eb6aSBarry Smith @*/
282d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid)
283d71ae5a4SJacob Faibussowitsch {
284f603b5e9SToby Isaac   char *ptr;
2857c5db45bSBarry Smith 
28696fc60bcSBarry Smith   PetscFunctionBegin;
2872d747510SLisandro Dalcin   if (key) PetscValidCharPointer(key, 1);
288dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(valid, 2);
2892d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2903ba16761SJacob Faibussowitsch   if (!key) PetscFunctionReturn(PETSC_SUCCESS);
2913ba16761SJacob Faibussowitsch   if (key[0] != '-') PetscFunctionReturn(PETSC_SUCCESS);
2922d747510SLisandro Dalcin   if (key[1] == '-') key++;
2933ba16761SJacob Faibussowitsch   if (!isalpha((int)key[1])) PetscFunctionReturn(PETSC_SUCCESS);
2942d747510SLisandro Dalcin   (void)strtod(key, &ptr);
2953ba16761SJacob Faibussowitsch   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(PETSC_SUCCESS);
2962d747510SLisandro Dalcin   *valid = PETSC_TRUE;
2973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29896fc60bcSBarry Smith }
29996fc60bcSBarry Smith 
30010c654e6SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertString_Private(PetscOptions options, const char in_str[], PetscOptionSource source)
301d71ae5a4SJacob Faibussowitsch {
302d06005cbSLisandro Dalcin   char      *first, *second;
3039c9d3cfdSBarry Smith   PetscToken token;
304e5c89e4eSSatish Balay 
305e5c89e4eSSatish Balay   PetscFunctionBegin;
3069566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(in_str, ' ', &token));
3079566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &first));
30896fc60bcSBarry Smith   while (first) {
309d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
31010c654e6SJacob Faibussowitsch 
3119566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
3129566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
3139566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
3149566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
3159566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
3169566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(first, &key));
317d06005cbSLisandro Dalcin     if (!key) {
3189566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
319d06005cbSLisandro Dalcin     } else if (isfile) {
3209566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
32110c654e6SJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(PETSC_COMM_SELF, options, second, PETSC_TRUE));
3229566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
323d06005cbSLisandro Dalcin     } else if (isfileyaml) {
3249566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
32510c654e6SJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(PETSC_COMM_SELF, options, second, PETSC_TRUE));
3269566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
327d06005cbSLisandro Dalcin     } else if (isstringyaml) {
3289566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3299355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, second, source));
3309566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
331d06005cbSLisandro Dalcin     } else if (ispush) {
3329566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3339566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, second));
3349566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
3359db968c8SJed Brown     } else if (ispop) {
3369566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
3379566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
338d06005cbSLisandro Dalcin     } else {
3399566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3409566063dSJacob Faibussowitsch       PetscCall(PetscOptionsValidKey(second, &key));
34196fc60bcSBarry Smith       if (!key) {
3429355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, second, NULL, source));
3439566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &first));
34496fc60bcSBarry Smith       } else {
3459355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, NULL, NULL, source));
34696fc60bcSBarry Smith         first = second;
34796fc60bcSBarry Smith       }
348e5c89e4eSSatish Balay     }
349e5c89e4eSSatish Balay   }
3509566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
352e5c89e4eSSatish Balay }
353e5c89e4eSSatish Balay 
3549355ec05SMatthew G. Knepley /*@C
3559355ec05SMatthew G. Knepley   PetscOptionsInsertString - Inserts options into the database from a string
3569355ec05SMatthew G. Knepley 
3579355ec05SMatthew G. Knepley   Logically Collective
3589355ec05SMatthew G. Knepley 
3599355ec05SMatthew G. Knepley   Input Parameters:
3609355ec05SMatthew G. Knepley + options - options object
3619355ec05SMatthew G. Knepley - in_str  - string that contains options separated by blanks
3629355ec05SMatthew G. Knepley 
3639355ec05SMatthew G. Knepley   Level: intermediate
3649355ec05SMatthew G. Knepley 
36520f4b53cSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
3669355ec05SMatthew G. Knepley   have the affect of these options. If some processes that create objects call this routine and others do
3679355ec05SMatthew G. Knepley   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
3689355ec05SMatthew G. Knepley   on different ranks.
3699355ec05SMatthew G. Knepley 
3709355ec05SMatthew G. Knepley    Contributed by Boyana Norris
3719355ec05SMatthew G. Knepley 
3729355ec05SMatthew G. Knepley .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
3739355ec05SMatthew G. Knepley           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3749355ec05SMatthew G. Knepley           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3759355ec05SMatthew G. Knepley           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3769355ec05SMatthew G. Knepley           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3779355ec05SMatthew G. Knepley           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
3789355ec05SMatthew G. Knepley @*/
3799355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[])
3809355ec05SMatthew G. Knepley {
3819355ec05SMatthew G. Knepley   PetscFunctionBegin;
3829355ec05SMatthew G. Knepley   PetscCall(PetscOptionsInsertString_Private(options, in_str, PETSC_OPT_CODE));
3833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3849355ec05SMatthew G. Knepley }
3859355ec05SMatthew G. Knepley 
3863fc1eb6aSBarry Smith /*
3873fc1eb6aSBarry Smith     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
3883fc1eb6aSBarry Smith */
389d71ae5a4SJacob Faibussowitsch static char *Petscgetline(FILE *f)
390d71ae5a4SJacob Faibussowitsch {
3915fa91da5SBarry Smith   size_t size = 0;
3925fa91da5SBarry Smith   size_t len  = 0;
3935fa91da5SBarry Smith   size_t last = 0;
3940298fd71SBarry Smith   char  *buf  = NULL;
3955fa91da5SBarry Smith 
39602c9f0b5SLisandro Dalcin   if (feof(f)) return NULL;
3975fa91da5SBarry Smith   do {
3985fa91da5SBarry Smith     size += 1024;                             /* BUFSIZ is defined as "the optimal read size for this platform" */
3996e0c8459SSatish Balay     buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
4005fa91da5SBarry Smith     /* Actually do the read. Note that fgets puts a terminal '\0' on the
4015fa91da5SBarry Smith     end of the string, so we make sure we overwrite this */
402e86f3e45SDave May     if (!fgets(buf + len, 1024, f)) buf[len] = 0;
4033ba16761SJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, PetscStrlen(buf, &len));
4045fa91da5SBarry Smith     last = len - 1;
4055fa91da5SBarry Smith   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
40608ac41f7SSatish Balay   if (len) return buf;
4075fa91da5SBarry Smith   free(buf);
40802c9f0b5SLisandro Dalcin   return NULL;
4095fa91da5SBarry Smith }
4105fa91da5SBarry Smith 
411d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml)
412d71ae5a4SJacob Faibussowitsch {
413be10d61cSLisandro Dalcin   char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
414e5c89e4eSSatish Balay 
415be10d61cSLisandro Dalcin   PetscFunctionBegin;
416362febeeSStefano Zampini   *yaml = PETSC_FALSE;
4179566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
4189566063dSJacob Faibussowitsch   PetscCall(PetscFixFilename(fname, path));
4199566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(path, ":yaml", yaml));
420be10d61cSLisandro Dalcin   if (*yaml) {
4219566063dSJacob Faibussowitsch     PetscCall(PetscStrrchr(path, ':', &tail));
422be10d61cSLisandro Dalcin     tail[-1] = 0; /* remove ":yaml" suffix from path */
423be10d61cSLisandro Dalcin   }
4249566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
425a1d2f846SLisandro Dalcin   /* check for standard YAML and JSON filename extensions */
4269566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
4279566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
4289566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
429a1d2f846SLisandro Dalcin   if (!*yaml) { /* check file contents */
430a1d2f846SLisandro Dalcin     PetscMPIInt rank;
4319566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
432dd400576SPatrick Sanan     if (rank == 0) {
433a1d2f846SLisandro Dalcin       FILE *fh = fopen(filename, "r");
434a1d2f846SLisandro Dalcin       if (fh) {
435a1d2f846SLisandro Dalcin         char buf[6] = "";
436a1d2f846SLisandro Dalcin         if (fread(buf, 1, 6, fh) > 0) {
4379566063dSJacob Faibussowitsch           PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml));          /* check for '%YAML' tag */
4389566063dSJacob Faibussowitsch           if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
439a1d2f846SLisandro Dalcin         }
440a1d2f846SLisandro Dalcin         (void)fclose(fh);
441a1d2f846SLisandro Dalcin       }
442a1d2f846SLisandro Dalcin     }
4439566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(yaml, 1, MPIU_BOOL, 0, comm));
444a1d2f846SLisandro Dalcin   }
4453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
446be10d61cSLisandro Dalcin }
447e5c89e4eSSatish Balay 
448d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
449d71ae5a4SJacob Faibussowitsch {
4508c0b561eSLisandro Dalcin   char       *string, *vstring = NULL, *astring = NULL, *packed = NULL;
4517fb43599SVaclav Hapla   char       *tokens[4];
45213e3f751SJed Brown   size_t      i, len, bytes;
453e5c89e4eSSatish Balay   FILE       *fd;
4547fb43599SVaclav Hapla   PetscToken  token = NULL;
455ed9cf6e9SBarry Smith   int         err;
456bbcf679cSJacob Faibussowitsch   char       *cmatch = NULL;
457581bbe83SVaclav Hapla   const char  cmt    = '#';
4589210b8eaSVaclav Hapla   PetscInt    line   = 1;
4593a018368SJed Brown   PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
4609210b8eaSVaclav Hapla   PetscBool   isdir, alias = PETSC_FALSE, valid;
461e5c89e4eSSatish Balay 
462e5c89e4eSSatish Balay   PetscFunctionBegin;
4639566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tokens, sizeof(tokens)));
4649566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
465dd400576SPatrick Sanan   if (rank == 0) {
4668c0b561eSLisandro Dalcin     char fpath[PETSC_MAX_PATH_LEN];
4678c0b561eSLisandro Dalcin     char fname[PETSC_MAX_PATH_LEN];
46805c7dedfSBarry Smith 
4699566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
4709566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
4718c0b561eSLisandro Dalcin 
472e5c89e4eSSatish Balay     fd = fopen(fname, "r");
4739566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname, 'r', &isdir));
47408401ef6SPierre Jolivet     PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
475ad38b122SPatrick Sanan     if (fd && !isdir) {
4763a018368SJed Brown       PetscSegBuffer vseg, aseg;
4779566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4789566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4793a018368SJed Brown 
4809b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4819566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
482e24ecc5dSJed Brown 
4835fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4844704e885SBarry Smith         /* eliminate comments from each line */
4859566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
48690f79514SSatish Balay         if (cmatch) *cmatch = 0;
4879566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4885981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
489e5c89e4eSSatish Balay         for (i = 0; i < len; i++) {
490ad540459SPierre Jolivet           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
491e5c89e4eSSatish Balay         }
4929566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4939566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4947fb43599SVaclav Hapla         if (!tokens[0]) {
49502b0d46eSSatish Balay           goto destroy;
4967fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
4979566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
49890f79514SSatish Balay         }
49948a46eb9SPierre Jolivet         for (i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
5007fb43599SVaclav Hapla         if (!tokens[0]) {
5012662f744SSatish Balay           goto destroy;
5027fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
5039566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
50428b400f6SJacob 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]);
5059566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
5069566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
5079566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
508e24ecc5dSJed Brown           vstring[len] = ' ';
5097fb43599SVaclav Hapla           if (tokens[1]) {
5109566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
51128b400f6SJacob 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]);
5129566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5139566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
514e24ecc5dSJed Brown             vstring[0] = '"';
5159566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
516e24ecc5dSJed Brown             vstring[len + 1] = '"';
517e24ecc5dSJed Brown             vstring[len + 2] = ' ';
51809192fe3SBarry Smith           }
51990f79514SSatish Balay         } else {
5209566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
5219210b8eaSVaclav Hapla           if (alias) {
5229566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
52328b400f6SJacob 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]);
52408401ef6SPierre 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]);
5259566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
52628b400f6SJacob 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]);
5279566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5289566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5299566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
530e24ecc5dSJed Brown             astring[len] = ' ';
531e24ecc5dSJed Brown 
5329566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5339566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5349566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
535e24ecc5dSJed Brown             astring[len] = ' ';
53698921bdaSJacob 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]);
5379210b8eaSVaclav Hapla         }
5389210b8eaSVaclav Hapla         {
5399210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
54028b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
541e5c89e4eSSatish Balay         }
54202b0d46eSSatish Balay       destroy:
5434b40f50bSBarry Smith         free(string);
5449566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5459210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5469210b8eaSVaclav Hapla         line++;
547e5c89e4eSSatish Balay       }
548ed9cf6e9SBarry Smith       err = fclose(fd);
54928b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5509566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5519566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5529566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
553e24ecc5dSJed Brown       astring[0] = 0;
5549566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5559566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5569566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
557e24ecc5dSJed Brown       vstring[0] = 0;
5589566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5599566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5609566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5619566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5629566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
56328b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5649b754dc9SBarry Smith   }
56505c7dedfSBarry Smith 
5663a018368SJed Brown   counts[0] = acnt;
5673a018368SJed Brown   counts[1] = cnt;
5684201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
56928b400f6SJacob 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/");
5703a018368SJed Brown   acnt = counts[0];
5713a018368SJed Brown   cnt  = counts[1];
57248a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5733a018368SJed Brown   if (acnt || cnt) {
5749566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5753a018368SJed Brown     astring = packed;
5763a018368SJed Brown     vstring = packed + acnt + 1;
5773a018368SJed Brown   }
5783a018368SJed Brown 
5799b754dc9SBarry Smith   if (acnt) {
5809566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5819566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5827fb43599SVaclav Hapla     while (tokens[0]) {
5839566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5849566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5859566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5869b754dc9SBarry Smith     }
5879566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5889b754dc9SBarry Smith   }
5899b754dc9SBarry Smith 
5909355ec05SMatthew G. Knepley   if (cnt) PetscCall(PetscOptionsInsertString_Private(options, vstring, PETSC_OPT_FILE));
5919566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
5923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
593e5c89e4eSSatish Balay }
594e5c89e4eSSatish Balay 
595d06005cbSLisandro Dalcin /*@C
596be10d61cSLisandro Dalcin   PetscOptionsInsertFile - Inserts options into the database from a file.
597be10d61cSLisandro Dalcin 
598be10d61cSLisandro Dalcin   Collective
599be10d61cSLisandro Dalcin 
600d8d19677SJose E. Roman   Input Parameters:
601811af0c4SBarry Smith + comm    - the processes that will share the options (usually `PETSC_COMM_WORLD`)
60220f4b53cSBarry Smith . options - options database, use `NULL` for default global database
603be10d61cSLisandro Dalcin . file    - name of file,
604be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
605be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
606811af0c4SBarry Smith - require - if `PETSC_TRUE` will generate an error if the file does not exist
607be10d61cSLisandro Dalcin 
60820f4b53cSBarry Smith   Level: developer
60920f4b53cSBarry Smith 
610be10d61cSLisandro Dalcin   Notes:
611be10d61cSLisandro Dalcin   Use  # for lines that are comments and which should be ignored.
612811af0c4SBarry Smith   Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
61321532e8aSBarry 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
61421532e8aSBarry Smith   calls to `XXXSetFromOptions()`, it should not be used for options listed under PetscInitialize().
61521532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes in comm will
61621532e8aSBarry Smith   have the effect of these options. If some processes that create objects call this routine and others do
617be10d61cSLisandro Dalcin   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
618be10d61cSLisandro Dalcin   on different ranks.
619be10d61cSLisandro Dalcin 
620db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
621db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
622db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
623c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
624db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
625db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
626be10d61cSLisandro Dalcin @*/
627d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
628d71ae5a4SJacob Faibussowitsch {
629be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
630be10d61cSLisandro Dalcin   PetscBool yaml;
631be10d61cSLisandro Dalcin 
632be10d61cSLisandro Dalcin   PetscFunctionBegin;
6339566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
634be10d61cSLisandro Dalcin   if (yaml) {
6359566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
636be10d61cSLisandro Dalcin   } else {
6379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
638be10d61cSLisandro Dalcin   }
6393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
640be10d61cSLisandro Dalcin }
641be10d61cSLisandro Dalcin 
642be10d61cSLisandro Dalcin /*@C
643d06005cbSLisandro Dalcin   PetscOptionsInsertArgs - Inserts options into the database from a array of strings
644d06005cbSLisandro Dalcin 
645d06005cbSLisandro Dalcin   Logically Collective
646d06005cbSLisandro Dalcin 
647d8d19677SJose E. Roman   Input Parameters:
648d06005cbSLisandro Dalcin + options - options object
6496aad120cSJose E. Roman . argc    - the array length
650d06005cbSLisandro Dalcin - args    - the string array
651d06005cbSLisandro Dalcin 
652d06005cbSLisandro Dalcin   Level: intermediate
653d06005cbSLisandro Dalcin 
654db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
655d06005cbSLisandro Dalcin @*/
656d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, char *args[])
657d71ae5a4SJacob Faibussowitsch {
658d06005cbSLisandro Dalcin   MPI_Comm     comm  = PETSC_COMM_WORLD;
659d06005cbSLisandro Dalcin   int          left  = PetscMax(argc, 0);
660d06005cbSLisandro Dalcin   char *const *eargs = args;
66185079163SJed Brown 
66285079163SJed Brown   PetscFunctionBegin;
66385079163SJed Brown   while (left) {
664d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6659566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6669566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6679566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6689566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6699566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6709566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
671093de6efSBarry Smith     if (!key) {
6729371c9d4SSatish Balay       eargs++;
6739371c9d4SSatish Balay       left--;
674d06005cbSLisandro Dalcin     } else if (isfile) {
675cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6769566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6779371c9d4SSatish Balay       eargs += 2;
6789371c9d4SSatish Balay       left -= 2;
679d06005cbSLisandro Dalcin     } else if (isfileyaml) {
680cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6819566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6829371c9d4SSatish Balay       eargs += 2;
6839371c9d4SSatish Balay       left -= 2;
684d06005cbSLisandro Dalcin     } else if (isstringyaml) {
685cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6869355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
6879371c9d4SSatish Balay       eargs += 2;
6889371c9d4SSatish Balay       left -= 2;
689d06005cbSLisandro Dalcin     } else if (ispush) {
69008401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
691cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6929566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6939371c9d4SSatish Balay       eargs += 2;
6949371c9d4SSatish Balay       left -= 2;
695d06005cbSLisandro Dalcin     } else if (ispop) {
6969566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
6979371c9d4SSatish Balay       eargs++;
6989371c9d4SSatish Balay       left--;
6997935c3d8SJed Brown     } else {
7007935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
7019566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
70298b6bf53SJed Brown       if (left < 2 || nextiskey) {
7039355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
7049371c9d4SSatish Balay         eargs++;
7059371c9d4SSatish Balay         left--;
70685079163SJed Brown       } else {
7079355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
7089371c9d4SSatish Balay         eargs += 2;
7099371c9d4SSatish Balay         left -= 2;
71085079163SJed Brown       }
71185079163SJed Brown     }
7127935c3d8SJed Brown   }
7133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71485079163SJed Brown }
71585079163SJed Brown 
71610c654e6SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], const PetscBool set[], PetscBool *flg)
717d71ae5a4SJacob Faibussowitsch {
718c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
719c5b5d8d5SVaclav Hapla   if (set[opt]) {
7209566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
721c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
7223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
723c5b5d8d5SVaclav Hapla }
724c5b5d8d5SVaclav Hapla 
725660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
726d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
727d71ae5a4SJacob Faibussowitsch {
728c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
729c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
730c5b5d8d5SVaclav Hapla   size_t             o;
731c5b5d8d5SVaclav Hapla   int                a;
732c5b5d8d5SVaclav Hapla   const char       **val;
7330c99d500SBarry Smith   char             **cval;
734660278c0SBarry Smith   PetscBool         *set, unneeded;
735c5b5d8d5SVaclav Hapla 
736c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7370c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7380c99d500SBarry Smith   val = (const char **)cval;
739c5b5d8d5SVaclav Hapla 
740c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
74148a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
742c5b5d8d5SVaclav Hapla 
743a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
744c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
745c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
746c5b5d8d5SVaclav Hapla 
7479566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
748c5b5d8d5SVaclav Hapla     if (!valid) continue;
749c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7509566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
751c5b5d8d5SVaclav Hapla       if (eq) {
752c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
753c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
754c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
755c5b5d8d5SVaclav Hapla         break;
756c5b5d8d5SVaclav Hapla       }
757c5b5d8d5SVaclav Hapla     }
758c5b5d8d5SVaclav Hapla   }
759c5b5d8d5SVaclav Hapla 
760c5b5d8d5SVaclav Hapla   /* Process flags */
7619566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
762d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7639566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
764660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
765660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
7669355ec05SMatthew G. Knepley   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
7679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7699566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
770c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
771c5b5d8d5SVaclav Hapla 
772c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
773660278c0SBarry Smith   for (o = 1; o < n; o++) {
774c5b5d8d5SVaclav Hapla     if (set[o]) {
7759355ec05SMatthew G. Knepley       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
776d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
777c5b5d8d5SVaclav Hapla     }
778c5b5d8d5SVaclav Hapla   }
7790c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
780c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
7813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
782c5b5d8d5SVaclav Hapla }
783c5b5d8d5SVaclav Hapla 
784d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
785d71ae5a4SJacob Faibussowitsch {
78639a651e2SJacob Faibussowitsch   PetscFunctionBegin;
78739a651e2SJacob Faibussowitsch   PetscValidBoolPointer(flg, 3);
788c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
789c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
79039a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
791c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
792c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7939566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
794c5b5d8d5SVaclav Hapla         if (*flg) break;
795c5b5d8d5SVaclav Hapla       }
796c5b5d8d5SVaclav Hapla     }
797c5b5d8d5SVaclav Hapla   }
7983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
799c5b5d8d5SVaclav Hapla }
80085079163SJed Brown 
801e5c89e4eSSatish Balay /*@C
802e5c89e4eSSatish Balay   PetscOptionsInsert - Inserts into the options database from the command line,
803e5c89e4eSSatish Balay   the environmental variable and a file.
804e5c89e4eSSatish Balay 
805811af0c4SBarry Smith   Collective on `PETSC_COMM_WORLD`
8061c9f3c13SBarry Smith 
807e5c89e4eSSatish Balay   Input Parameters:
80820f4b53cSBarry Smith + options - options database or `NULL` for the default global database
809c5929fdfSBarry Smith . argc    - count of number of command line arguments
810e5c89e4eSSatish Balay . args    - the command line arguments
811be10d61cSLisandro Dalcin - file    - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
81220f4b53cSBarry Smith           Use `NULL` or empty string to not check for code specific file.
813be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
814c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
815e5c89e4eSSatish Balay 
816081c24baSBoyana Norris   Options Database Keys:
817d06005cbSLisandro Dalcin + -options_file <filename>      - read options from a file
818d06005cbSLisandro Dalcin - -options_file_yaml <filename> - read options from a YAML file
819c5b5d8d5SVaclav Hapla 
82020f4b53cSBarry Smith   Level: advanced
82120f4b53cSBarry Smith 
822811af0c4SBarry Smith   Notes:
82320f4b53cSBarry Smith   Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
824811af0c4SBarry Smith   the user does not typically need to call this routine. `PetscOptionsInsert()`
825811af0c4SBarry Smith   can be called several times, adding additional entries into the database.
826811af0c4SBarry Smith 
827811af0c4SBarry Smith   See `PetscInitialize()` for options related to option database monitoring.
828081c24baSBoyana Norris 
829db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
830db781477SPatrick Sanan           `PetscInitialize()`
831e5c89e4eSSatish Balay @*/
832d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[])
833d71ae5a4SJacob Faibussowitsch {
834d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
835e5c89e4eSSatish Balay   PetscMPIInt rank;
836c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
837c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
838e5c89e4eSSatish Balay 
839e5c89e4eSSatish Balay   PetscFunctionBegin;
84008401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8419566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
842e5c89e4eSSatish Balay 
843c5b5d8d5SVaclav Hapla   if (!options) {
8449566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
845c5b5d8d5SVaclav Hapla     options = defaultoptions;
846c5b5d8d5SVaclav Hapla   }
847c5b5d8d5SVaclav Hapla   if (hasArgs) {
848c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8499566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
850660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
851c5b5d8d5SVaclav Hapla   }
8524b09e917SBarry Smith   if (file && file[0]) {
8539566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
854c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8559566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
856321366bcSBarry Smith   }
857c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
858be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8599566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8609566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
861c6a7a370SJeremy L Thompson     if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
8629566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8639566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8649566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
865e5c89e4eSSatish Balay   }
866e5c89e4eSSatish Balay 
8672d747510SLisandro Dalcin   /* insert environment options */
868e5c89e4eSSatish Balay   {
8692d747510SLisandro Dalcin     char  *eoptions = NULL;
870e5c89e4eSSatish Balay     size_t len      = 0;
871dd400576SPatrick Sanan     if (rank == 0) {
872e5c89e4eSSatish Balay       eoptions = (char *)getenv("PETSC_OPTIONS");
8739566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
874e5c89e4eSSatish Balay     }
8759566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
876e5c89e4eSSatish Balay     if (len) {
8779566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8789566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
87996fc60bcSBarry Smith       if (rank) eoptions[len] = 0;
8809355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8819566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
882e5c89e4eSSatish Balay     }
883e5c89e4eSSatish Balay   }
884e5c89e4eSSatish Balay 
885d06005cbSLisandro Dalcin   /* insert YAML environment options */
88656a31166SBarry Smith   {
8879fc438c3SToby Isaac     char  *eoptions = NULL;
8889fc438c3SToby Isaac     size_t len      = 0;
889dd400576SPatrick Sanan     if (rank == 0) {
8909fc438c3SToby Isaac       eoptions = (char *)getenv("PETSC_OPTIONS_YAML");
8919566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
8929fc438c3SToby Isaac     }
8939566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8949fc438c3SToby Isaac     if (len) {
8959566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8969566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
8979fc438c3SToby Isaac       if (rank) eoptions[len] = 0;
8989355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8999566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
9009fc438c3SToby Isaac     }
9019fc438c3SToby Isaac   }
9023bcbd388SSean Farley 
903c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
9049566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, *args + 1));
905660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
9063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
907e5c89e4eSSatish Balay }
908e5c89e4eSSatish Balay 
909660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
910660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
911e9a33e21SBarry Smith static const char *PetscCIOptions[] = {"malloc_debug", "malloc_dump", "malloc_test", "malloc", "nox", "nox_warning", "display", "saws_port_auto_select", "saws_port_auto_select_silent", "vecscatter_mpi1", "check_pointer_intensity", "cuda_initialize", "error_output_stdout", "use_gpu_aware_mpi", "checkfunctionlist", "fp_trap", "petsc_ci", "petsc_ci_portable_error_output", "options_left"};
912660278c0SBarry Smith 
913d71ae5a4SJacob Faibussowitsch static PetscBool PetscCIOption(const char *name)
914d71ae5a4SJacob Faibussowitsch {
915660278c0SBarry Smith   PetscInt  idx;
916660278c0SBarry Smith   PetscBool found;
917660278c0SBarry Smith 
918660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
9193ba16761SJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
920660278c0SBarry Smith   return found;
921660278c0SBarry Smith }
922660278c0SBarry Smith 
923e5c89e4eSSatish Balay /*@C
92488c29154SBarry Smith   PetscOptionsView - Prints the options that have been loaded. This is
925e5c89e4eSSatish Balay   useful for debugging purposes.
926e5c89e4eSSatish Balay 
927c3339decSBarry Smith   Logically Collective
928e5c89e4eSSatish Balay 
929d8d19677SJose E. Roman   Input Parameters:
93020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
931811af0c4SBarry Smith - viewer  - must be an `PETSCVIEWERASCII` viewer
932e5c89e4eSSatish Balay 
933e5c89e4eSSatish Balay   Options Database Key:
934811af0c4SBarry Smith . -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
935e5c89e4eSSatish Balay 
93620f4b53cSBarry Smith   Level: advanced
93720f4b53cSBarry Smith 
938811af0c4SBarry Smith   Note:
93921532e8aSBarry Smith   Only the MPI rank 0 of the `MPI_Comm` used to create view prints the option values. Other processes
9401c9f3c13SBarry Smith   may have different values but they are not printed.
9411c9f3c13SBarry Smith 
942db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
943e5c89e4eSSatish Balay @*/
944d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
945d71ae5a4SJacob Faibussowitsch {
946660278c0SBarry Smith   PetscInt  i, N = 0;
94788c29154SBarry Smith   PetscBool isascii;
948e5c89e4eSSatish Balay 
949e5c89e4eSSatish Balay   PetscFunctionBegin;
9502d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
951c5929fdfSBarry Smith   options = options ? options : defaultoptions;
95288c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9539566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
95428b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
95588c29154SBarry Smith 
956660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
957660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
958660278c0SBarry Smith     N++;
959660278c0SBarry Smith   }
960660278c0SBarry Smith 
961660278c0SBarry Smith   if (!N) {
9629566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9633ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
96430694fe9SBarry Smith   }
9652d747510SLisandro Dalcin 
9669566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
967e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
968660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
969e5c89e4eSSatish Balay     if (options->values[i]) {
9709355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
971e5c89e4eSSatish Balay     } else {
9729355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
973e5c89e4eSSatish Balay     }
9749355ec05SMatthew G. Knepley     PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
975e5c89e4eSSatish Balay   }
9769566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
9773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
978e5c89e4eSSatish Balay }
979e5c89e4eSSatish Balay 
980e11779c2SBarry Smith /*
981e11779c2SBarry Smith    Called by error handlers to print options used in run
982e11779c2SBarry Smith */
983d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftError(void)
984d71ae5a4SJacob Faibussowitsch {
985f4bc716fSBarry Smith   PetscInt i, nopt = 0;
986f4bc716fSBarry Smith 
987f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
988f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
989f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
990f4bc716fSBarry Smith       nopt++;
991f4bc716fSBarry Smith     }
992f4bc716fSBarry Smith   }
993f4bc716fSBarry Smith   if (nopt) {
9947d44c3adSBarry Smith     PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
995f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
996f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
997f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
9983ba16761SJacob Faibussowitsch         if (defaultoptions->values[i]) PetscCall((*PetscErrorPrintf)("  Option left: name:-%s value: %s source: %s\n", defaultoptions->names[i], defaultoptions->values[i], PetscOptionSources[defaultoptions->source[i]]));
9993ba16761SJacob Faibussowitsch         else PetscCall((*PetscErrorPrintf)("  Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
1000f4bc716fSBarry Smith       }
1001f4bc716fSBarry Smith     }
1002f4bc716fSBarry Smith   }
10033ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1004f4bc716fSBarry Smith }
1005f4bc716fSBarry Smith 
1006d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1007d71ae5a4SJacob Faibussowitsch {
1008660278c0SBarry Smith   PetscInt     i, N = 0;
10094416b707SBarry Smith   PetscOptions options = defaultoptions;
1010e11779c2SBarry Smith 
1011660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
1012660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1013660278c0SBarry Smith     N++;
1014660278c0SBarry Smith   }
1015660278c0SBarry Smith 
1016660278c0SBarry Smith   if (N) {
10173ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1018e11779c2SBarry Smith   } else {
10193ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1020e11779c2SBarry Smith   }
1021e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1022660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1023e11779c2SBarry Smith     if (options->values[i]) {
10243ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1025e11779c2SBarry Smith     } else {
10263ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1027e11779c2SBarry Smith     }
1028e11779c2SBarry Smith   }
10293ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1030e11779c2SBarry Smith }
1031e11779c2SBarry Smith 
1032e5c89e4eSSatish Balay /*@C
103374e0666dSJed Brown   PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
103474e0666dSJed Brown 
10351c9f3c13SBarry Smith   Logically Collective
103674e0666dSJed Brown 
1037d8d19677SJose E. Roman   Input Parameters:
103820f4b53cSBarry Smith + options - options database, or `NULL` for the default global database
1039c5929fdfSBarry Smith - prefix  - The string to append to the existing prefix
10409db968c8SJed Brown 
10419db968c8SJed Brown   Options Database Keys:
10429db968c8SJed Brown + -prefix_push <some_prefix_> - push the given prefix
10439db968c8SJed Brown - -prefix_pop                 - pop the last prefix
10449db968c8SJed Brown 
104520f4b53cSBarry Smith   Level: advanced
104620f4b53cSBarry Smith 
10479db968c8SJed Brown   Notes:
104821532e8aSBarry Smith   It is common to use this in conjunction with `-options_file` as in
10499db968c8SJed Brown 
10509db968c8SJed Brown $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10519db968c8SJed Brown 
105221532e8aSBarry Smith   where the files no longer require all options to be prefixed with `-system2_`.
105374e0666dSJed Brown 
105421532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
10551c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
10561c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10571c9f3c13SBarry Smith   on different ranks.
10581c9f3c13SBarry Smith 
1059db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
106074e0666dSJed Brown @*/
1061d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1062d71ae5a4SJacob Faibussowitsch {
106374e0666dSJed Brown   size_t    n;
106474e0666dSJed Brown   PetscInt  start;
10659355ec05SMatthew G. Knepley   char      key[PETSC_MAX_OPTION_NAME + 1];
10662d747510SLisandro Dalcin   PetscBool valid;
106774e0666dSJed Brown 
106874e0666dSJed Brown   PetscFunctionBegin;
1069064a246eSJacob Faibussowitsch   PetscValidCharPointer(prefix, 2);
1070c5929fdfSBarry Smith   options = options ? options : defaultoptions;
107108401ef6SPierre Jolivet   PetscCheck(options->prefixind < MAXPREFIXES, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum depth of prefix stack %d exceeded, recompile \n src/sys/objects/options.c with larger value for MAXPREFIXES", MAXPREFIXES);
10722d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10739566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10758bf569ecSLisandro Dalcin   if (!valid && options->prefixind > 0 && isdigit((int)prefix[0])) valid = PETSC_TRUE; /* If the prefix stack is not empty, make numbers a valid prefix */
107628b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_USER, "Given prefix \"%s\" not valid (the first character must be a letter%s, do not include leading '-')", prefix, options->prefixind ? " or digit" : "");
107774e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10789566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
107908401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10809566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
108174e0666dSJed Brown   options->prefixstack[options->prefixind++] = start + n;
10823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108374e0666dSJed Brown }
108474e0666dSJed Brown 
1085c5929fdfSBarry Smith /*@C
1086811af0c4SBarry Smith   PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
108774e0666dSJed Brown 
1088811af0c4SBarry Smith   Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
108974e0666dSJed Brown 
1090811af0c4SBarry Smith   Input Parameter:
109120f4b53cSBarry Smith . options - options database, or `NULL` for the default global database
1092c5929fdfSBarry Smith 
109374e0666dSJed Brown   Level: advanced
109474e0666dSJed Brown 
1095db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
109674e0666dSJed Brown @*/
1097d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1098d71ae5a4SJacob Faibussowitsch {
109974e0666dSJed Brown   PetscInt offset;
110074e0666dSJed Brown 
110174e0666dSJed Brown   PetscFunctionBegin;
1102c5929fdfSBarry Smith   options = options ? options : defaultoptions;
110308401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
110474e0666dSJed Brown   options->prefixind--;
110574e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
110674e0666dSJed Brown   options->prefix[offset] = 0;
11073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
110874e0666dSJed Brown }
110974e0666dSJed Brown 
1110a542b6e8SBarry Smith /*@C
1111a542b6e8SBarry Smith   PetscOptionsClear - Removes all options form the database leaving it empty.
1112a542b6e8SBarry Smith 
11131c9f3c13SBarry Smith   Logically Collective
11141c9f3c13SBarry Smith 
1115811af0c4SBarry Smith   Input Parameter:
111620f4b53cSBarry Smith . options - options database, use `NULL` for the default global database
1117c5929fdfSBarry Smith 
111820f4b53cSBarry Smith   Level: developer
111920f4b53cSBarry Smith 
112020f4b53cSBarry Smith   Note:
112121532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11221c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11231c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11241c9f3c13SBarry Smith   on different ranks.
11251c9f3c13SBarry Smith 
1126db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1127a542b6e8SBarry Smith @*/
1128d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClear(PetscOptions options)
1129d71ae5a4SJacob Faibussowitsch {
1130a542b6e8SBarry Smith   PetscInt i;
1131a542b6e8SBarry Smith 
113239a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1133c5929fdfSBarry Smith   options = options ? options : defaultoptions;
11343ba16761SJacob Faibussowitsch   if (!options) PetscFunctionReturn(PETSC_SUCCESS);
11352d747510SLisandro Dalcin 
1136a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1137a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1138a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1139a542b6e8SBarry Smith   }
11402d747510SLisandro Dalcin   options->N = 0;
11419355ec05SMatthew G. Knepley   free(options->names);
11429355ec05SMatthew G. Knepley   free(options->values);
11439355ec05SMatthew G. Knepley   free(options->used);
11449355ec05SMatthew G. Knepley   free(options->source);
11459355ec05SMatthew G. Knepley   options->names  = NULL;
11469355ec05SMatthew G. Knepley   options->values = NULL;
11479355ec05SMatthew G. Knepley   options->used   = NULL;
11489355ec05SMatthew G. Knepley   options->source = NULL;
11499355ec05SMatthew G. Knepley   options->Nalloc = 0;
11502d747510SLisandro Dalcin 
11519355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
1152a542b6e8SBarry Smith     free(options->aliases1[i]);
1153a542b6e8SBarry Smith     free(options->aliases2[i]);
1154a542b6e8SBarry Smith   }
11559355ec05SMatthew G. Knepley   options->Na = 0;
11569355ec05SMatthew G. Knepley   free(options->aliases1);
11579355ec05SMatthew G. Knepley   free(options->aliases2);
11589355ec05SMatthew G. Knepley   options->aliases1 = options->aliases2 = NULL;
11599355ec05SMatthew G. Knepley   options->Naalloc                      = 0;
1160a542b6e8SBarry Smith 
11612d747510SLisandro Dalcin   /* destroy hash table */
11622d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11632d747510SLisandro Dalcin   options->ht = NULL;
11640eb63584SBarry Smith 
11652d747510SLisandro Dalcin   options->prefixind  = 0;
11662d747510SLisandro Dalcin   options->prefix[0]  = 0;
11672d747510SLisandro Dalcin   options->help       = PETSC_FALSE;
11689355ec05SMatthew G. Knepley   options->help_intro = PETSC_FALSE;
11693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11704416b707SBarry Smith }
11714416b707SBarry Smith 
11722d747510SLisandro Dalcin /*@C
11732d747510SLisandro Dalcin   PetscOptionsSetAlias - Makes a key and alias for another key
11742d747510SLisandro Dalcin 
11751c9f3c13SBarry Smith   Logically Collective
11762d747510SLisandro Dalcin 
11772d747510SLisandro Dalcin   Input Parameters:
117820f4b53cSBarry Smith + options - options database, or `NULL` for default global database
11792d747510SLisandro Dalcin . newname - the alias
11802d747510SLisandro Dalcin - oldname - the name that alias will refer to
11812d747510SLisandro Dalcin 
11822d747510SLisandro Dalcin   Level: advanced
11832d747510SLisandro Dalcin 
118420f4b53cSBarry Smith   Note:
118521532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11861c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11871c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11881c9f3c13SBarry Smith   on different ranks.
11891c9f3c13SBarry Smith 
1190c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1191c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1192db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1193c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1194db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1195db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
11962d747510SLisandro Dalcin @*/
1197d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1198d71ae5a4SJacob Faibussowitsch {
11992d747510SLisandro Dalcin   size_t    len;
12009210b8eaSVaclav Hapla   PetscBool valid;
12012d747510SLisandro Dalcin 
12022d747510SLisandro Dalcin   PetscFunctionBegin;
12032d747510SLisandro Dalcin   PetscValidCharPointer(newname, 2);
12042d747510SLisandro Dalcin   PetscValidCharPointer(oldname, 3);
12052d747510SLisandro Dalcin   options = options ? options : defaultoptions;
12069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
120728b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
12089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
120928b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
12102d747510SLisandro Dalcin 
12119355ec05SMatthew G. Knepley   if (options->Na == options->Naalloc) {
12129355ec05SMatthew G. Knepley     char **tmpA1, **tmpA2;
12132d747510SLisandro Dalcin 
12149355ec05SMatthew G. Knepley     options->Naalloc = PetscMax(4, options->Naalloc * 2);
12159355ec05SMatthew G. Knepley     tmpA1            = (char **)malloc(options->Naalloc * sizeof(char *));
12169355ec05SMatthew G. Knepley     tmpA2            = (char **)malloc(options->Naalloc * sizeof(char *));
12179355ec05SMatthew G. Knepley     for (int i = 0; i < options->Na; ++i) {
12189355ec05SMatthew G. Knepley       tmpA1[i] = options->aliases1[i];
12199355ec05SMatthew G. Knepley       tmpA2[i] = options->aliases2[i];
12209355ec05SMatthew G. Knepley     }
12219355ec05SMatthew G. Knepley     free(options->aliases1);
12229355ec05SMatthew G. Knepley     free(options->aliases2);
12239355ec05SMatthew G. Knepley     options->aliases1 = tmpA1;
12249355ec05SMatthew G. Knepley     options->aliases2 = tmpA2;
12259355ec05SMatthew G. Knepley   }
12269371c9d4SSatish Balay   newname++;
12279371c9d4SSatish Balay   oldname++;
12289566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
12299355ec05SMatthew G. Knepley   options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1230c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
12319566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
12329355ec05SMatthew G. Knepley   options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1233c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
12349355ec05SMatthew G. Knepley   ++options->Na;
12353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12362d747510SLisandro Dalcin }
12374416b707SBarry Smith 
1238e5c89e4eSSatish Balay /*@C
1239e5c89e4eSSatish Balay   PetscOptionsSetValue - Sets an option name-value pair in the options
1240e5c89e4eSSatish Balay   database, overriding whatever is already present.
1241e5c89e4eSSatish Balay 
12421c9f3c13SBarry Smith   Logically Collective
1243e5c89e4eSSatish Balay 
1244e5c89e4eSSatish Balay   Input Parameters:
124520f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1246c5929fdfSBarry Smith . name    - name of option, this SHOULD have the - prepended
124720f4b53cSBarry Smith - value   - the option value (not used for all options, so can be `NULL`)
1248e5c89e4eSSatish Balay 
1249e5c89e4eSSatish Balay   Level: intermediate
1250e5c89e4eSSatish Balay 
1251e5c89e4eSSatish Balay   Note:
1252811af0c4SBarry Smith   This function can be called BEFORE `PetscInitialize()`
1253d49172ceSBarry Smith 
125421532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
12551c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
12561c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12571c9f3c13SBarry Smith   on different ranks.
12581c9f3c13SBarry Smith 
1259*aec76313SJacob Faibussowitsch   Developer Notes:
126020f4b53cSBarry Smith   Uses malloc() directly because PETSc may not be initialized yet.
1261b0250c70SBarry Smith 
1262db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1263e5c89e4eSSatish Balay @*/
1264d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1265d71ae5a4SJacob Faibussowitsch {
126639a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12679355ec05SMatthew G. Knepley   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
12683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1269c5b5d8d5SVaclav Hapla }
1270c5b5d8d5SVaclav Hapla 
12719355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1272d71ae5a4SJacob Faibussowitsch {
1273e5c89e4eSSatish Balay   size_t    len;
12749355ec05SMatthew G. Knepley   int       n, i;
1275e5c89e4eSSatish Balay   char    **names;
12769355ec05SMatthew G. Knepley   char      fullname[PETSC_MAX_OPTION_NAME] = "";
1277c5b5d8d5SVaclav Hapla   PetscBool flg;
1278e5c89e4eSSatish Balay 
127939a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12807272c0d2SVaclav Hapla   if (!options) {
12819566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12827272c0d2SVaclav Hapla     options = defaultoptions;
1283c5929fdfSBarry Smith   }
128439a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
12852d747510SLisandro Dalcin 
12869566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
12873ba16761SJacob Faibussowitsch   if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1288e5c89e4eSSatish Balay 
12892d747510SLisandro Dalcin   name++; /* skip starting dash */
12902d747510SLisandro Dalcin 
129174e0666dSJed Brown   if (options->prefixind > 0) {
1292d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
12932d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
129489ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
12952d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
129674e0666dSJed Brown     name                           = fullname;
129774e0666dSJed Brown   }
129874e0666dSJed Brown 
129974e0666dSJed Brown   /* check against aliases */
13009355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
13012d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
13029371c9d4SSatish Balay     if (!result) {
13039371c9d4SSatish Balay       name = options->aliases2[i];
13049371c9d4SSatish Balay       break;
13059371c9d4SSatish Balay     }
1306e5c89e4eSSatish Balay   }
1307e5c89e4eSSatish Balay 
13082d747510SLisandro Dalcin   /* slow search */
13099355ec05SMatthew G. Knepley   n     = options->N;
1310e5c89e4eSSatish Balay   names = options->names;
13119355ec05SMatthew G. Knepley   for (i = 0; i < options->N; i++) {
13122d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13132d747510SLisandro Dalcin     if (!result) {
13149371c9d4SSatish Balay       n = i;
13159371c9d4SSatish Balay       goto setvalue;
13162d747510SLisandro Dalcin     } else if (result > 0) {
13179371c9d4SSatish Balay       n = i;
13189371c9d4SSatish Balay       break;
1319e5c89e4eSSatish Balay     }
1320e5c89e4eSSatish Balay   }
13219355ec05SMatthew G. Knepley   if (options->N == options->Nalloc) {
13229355ec05SMatthew G. Knepley     char             **names, **values;
13239355ec05SMatthew G. Knepley     PetscBool         *used;
13249355ec05SMatthew G. Knepley     PetscOptionSource *source;
13259355ec05SMatthew G. Knepley 
13269355ec05SMatthew G. Knepley     options->Nalloc = PetscMax(10, options->Nalloc * 2);
13279355ec05SMatthew G. Knepley     names           = (char **)malloc(options->Nalloc * sizeof(char *));
13289355ec05SMatthew G. Knepley     values          = (char **)malloc(options->Nalloc * sizeof(char *));
13299355ec05SMatthew G. Knepley     used            = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
13309355ec05SMatthew G. Knepley     source          = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
13319355ec05SMatthew G. Knepley     for (int i = 0; i < options->N; ++i) {
13329355ec05SMatthew G. Knepley       names[i]  = options->names[i];
13339355ec05SMatthew G. Knepley       values[i] = options->values[i];
13349355ec05SMatthew G. Knepley       used[i]   = options->used[i];
13359355ec05SMatthew G. Knepley       source[i] = options->source[i];
13369355ec05SMatthew G. Knepley     }
13379355ec05SMatthew G. Knepley     free(options->names);
13389355ec05SMatthew G. Knepley     free(options->values);
13399355ec05SMatthew G. Knepley     free(options->used);
13409355ec05SMatthew G. Knepley     free(options->source);
13419355ec05SMatthew G. Knepley     options->names  = names;
13429355ec05SMatthew G. Knepley     options->values = values;
13439355ec05SMatthew G. Knepley     options->used   = used;
13449355ec05SMatthew G. Knepley     options->source = source;
13459355ec05SMatthew G. Knepley   }
134639a651e2SJacob Faibussowitsch 
13472d747510SLisandro Dalcin   /* shift remaining values up 1 */
13489355ec05SMatthew G. Knepley   for (i = options->N; i > n; i--) {
13495e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1350e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1351e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
13529355ec05SMatthew G. Knepley     options->source[i] = options->source[i - 1];
1353e5c89e4eSSatish Balay   }
13542d747510SLisandro Dalcin   options->names[n]  = NULL;
13552d747510SLisandro Dalcin   options->values[n] = NULL;
13562d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
13579355ec05SMatthew G. Knepley   options->source[n] = PETSC_OPT_CODE;
13582d747510SLisandro Dalcin   options->N++;
13592d747510SLisandro Dalcin 
13602d747510SLisandro Dalcin   /* destroy hash table */
13612d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13622d747510SLisandro Dalcin   options->ht = NULL;
13632d747510SLisandro Dalcin 
13642d747510SLisandro Dalcin   /* set new name */
136570d8d27cSBarry Smith   len               = strlen(name);
13665e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
136739a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1368d49172ceSBarry Smith   strcpy(options->names[n], name);
13692d747510SLisandro Dalcin 
13702d747510SLisandro Dalcin setvalue:
13712d747510SLisandro Dalcin   /* set new value */
13722d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1373d49172ceSBarry Smith   len = value ? strlen(value) : 0;
13745e8c5e88SLisandro Dalcin   if (len) {
1375e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1376d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1377d49172ceSBarry Smith     strcpy(options->values[n], value);
13782d747510SLisandro Dalcin   } else {
13792d747510SLisandro Dalcin     options->values[n] = NULL;
13802d747510SLisandro Dalcin   }
13819355ec05SMatthew G. Knepley   options->source[n] = source;
13822d747510SLisandro Dalcin 
138391ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
138491ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
138591ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1386d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
138791ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
138891ad3481SVaclav Hapla   }
138991ad3481SVaclav Hapla 
13909355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, value, source));
1391c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
13923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1393e5c89e4eSSatish Balay }
1394e5c89e4eSSatish Balay 
1395e5c89e4eSSatish Balay /*@C
1396e5c89e4eSSatish Balay   PetscOptionsClearValue - Clears an option name-value pair in the options
1397e5c89e4eSSatish Balay   database, overriding whatever is already present.
1398e5c89e4eSSatish Balay 
13991c9f3c13SBarry Smith   Logically Collective
1400e5c89e4eSSatish Balay 
1401d8d19677SJose E. Roman   Input Parameters:
140220f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1403a2b725a8SWilliam Gropp - name    - name of option, this SHOULD have the - prepended
1404e5c89e4eSSatish Balay 
1405e5c89e4eSSatish Balay   Level: intermediate
1406e5c89e4eSSatish Balay 
1407811af0c4SBarry Smith   Note:
140821532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
14091c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
14101c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
14111c9f3c13SBarry Smith   on different ranks.
14121c9f3c13SBarry Smith 
1413db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1414e5c89e4eSSatish Balay @*/
1415d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1416d71ae5a4SJacob Faibussowitsch {
14172d747510SLisandro Dalcin   int    N, n, i;
14182d747510SLisandro Dalcin   char **names;
1419e5c89e4eSSatish Balay 
1420e5c89e4eSSatish Balay   PetscFunctionBegin;
1421c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1422cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1423c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
14242d747510SLisandro Dalcin 
14252d747510SLisandro Dalcin   name++; /* skip starting dash */
14262d747510SLisandro Dalcin 
14272d747510SLisandro Dalcin   /* slow search */
14282d747510SLisandro Dalcin   N = n = options->N;
1429e5c89e4eSSatish Balay   names = options->names;
1430e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
14312d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
14322d747510SLisandro Dalcin     if (!result) {
14339371c9d4SSatish Balay       n = i;
14349371c9d4SSatish Balay       break;
14352d747510SLisandro Dalcin     } else if (result > 0) {
14369371c9d4SSatish Balay       n = N;
14379371c9d4SSatish Balay       break;
1438e5c89e4eSSatish Balay     }
14392d747510SLisandro Dalcin   }
14403ba16761SJacob Faibussowitsch   if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1441e5c89e4eSSatish Balay 
14422d747510SLisandro Dalcin   /* remove name and value */
14432d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
14442d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1445e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1446e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
14475e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1448e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1449e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
14509355ec05SMatthew G. Knepley     options->source[i] = options->source[i + 1];
1451e5c89e4eSSatish Balay   }
1452e5c89e4eSSatish Balay   options->N--;
14532d747510SLisandro Dalcin 
14542d747510SLisandro Dalcin   /* destroy hash table */
14552d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
14562d747510SLisandro Dalcin   options->ht = NULL;
14572d747510SLisandro Dalcin 
14589355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
14593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1460e5c89e4eSSatish Balay }
1461e5c89e4eSSatish Balay 
1462e5c89e4eSSatish Balay /*@C
14632d747510SLisandro Dalcin   PetscOptionsFindPair - Gets an option name-value pair from the options database.
1464e5c89e4eSSatish Balay 
14652d747510SLisandro Dalcin   Not Collective
1466e5c89e4eSSatish Balay 
1467e5c89e4eSSatish Balay   Input Parameters:
146820f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
146920f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
14702d747510SLisandro Dalcin - name    - name of option, this SHOULD have the "-" prepended
1471e5c89e4eSSatish Balay 
14722d747510SLisandro Dalcin   Output Parameters:
14732d747510SLisandro Dalcin + value - the option value (optional, not used for all options)
14742d747510SLisandro Dalcin - set   - whether the option is set (optional)
1475e5c89e4eSSatish Balay 
147620f4b53cSBarry Smith   Level: developer
147720f4b53cSBarry Smith 
1478811af0c4SBarry Smith   Note:
14799666a313SBarry Smith   Each process may find different values or no value depending on how options were inserted into the database
14801c9f3c13SBarry Smith 
1481db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1482e5c89e4eSSatish Balay @*/
1483d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1484d71ae5a4SJacob Faibussowitsch {
14859355ec05SMatthew G. Knepley   char      buf[PETSC_MAX_OPTION_NAME];
1486daabea38SBarry Smith   PetscBool usehashtable = PETSC_TRUE;
14872d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1488e5c89e4eSSatish Balay 
1489e5c89e4eSSatish Balay   PetscFunctionBegin;
1490c5929fdfSBarry Smith   options = options ? options : defaultoptions;
149108401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1492cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1493e5c89e4eSSatish Balay 
14942d747510SLisandro Dalcin   name++; /* skip starting dash */
1495e5c89e4eSSatish Balay 
14967cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
14972d747510SLisandro Dalcin   if (pre && pre[0]) {
14982d747510SLisandro Dalcin     char *ptr = buf;
14999371c9d4SSatish Balay     if (name[0] == '-') {
15009371c9d4SSatish Balay       *ptr++ = '-';
15019371c9d4SSatish Balay       name++;
15029371c9d4SSatish Balay     }
15039566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
15049566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
15052d747510SLisandro Dalcin     name = buf;
15067cd08cecSJed Brown   }
15072d747510SLisandro Dalcin 
150876bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
15092f828895SJed Brown     PetscBool valid;
15109355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
15119566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
15129566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
151328b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
15142f828895SJed Brown   }
1515e5c89e4eSSatish Balay 
15162d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
15172d747510SLisandro Dalcin     int          i, ret;
15182d747510SLisandro Dalcin     khiter_t     it;
15192d747510SLisandro Dalcin     khash_t(HO) *ht;
15202d747510SLisandro Dalcin     ht = kh_init(HO);
152128b400f6SJacob Faibussowitsch     PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15222d747510SLisandro Dalcin     ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
152328b400f6SJacob Faibussowitsch     PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15242d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
15252d747510SLisandro Dalcin       it = kh_put(HO, ht, options->names[i], &ret);
152608401ef6SPierre Jolivet       PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15272d747510SLisandro Dalcin       kh_val(ht, it) = i;
15282d747510SLisandro Dalcin     }
15292d747510SLisandro Dalcin     options->ht = ht;
15302d747510SLisandro Dalcin   }
15312d747510SLisandro Dalcin 
15329371c9d4SSatish Balay   if (usehashtable) { /* fast search */
15332d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
15342d747510SLisandro Dalcin     khiter_t     it = kh_get(HO, ht, name);
15352d747510SLisandro Dalcin     if (it != kh_end(ht)) {
15362d747510SLisandro Dalcin       int i            = kh_val(ht, it);
1537e5c89e4eSSatish Balay       options->used[i] = PETSC_TRUE;
15382d747510SLisandro Dalcin       if (value) *value = options->values[i];
15392d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
15403ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
15412d747510SLisandro Dalcin     }
15429371c9d4SSatish Balay   } else { /* slow search */
15432d747510SLisandro Dalcin     int i, N = options->N;
15442d747510SLisandro Dalcin     for (i = 0; i < N; i++) {
1545daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i], name);
15462d747510SLisandro Dalcin       if (!result) {
15472d747510SLisandro Dalcin         options->used[i] = PETSC_TRUE;
15482d747510SLisandro Dalcin         if (value) *value = options->values[i];
15492d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
15503ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15512d747510SLisandro Dalcin       } else if (result > 0) {
1552e5c89e4eSSatish Balay         break;
1553e5c89e4eSSatish Balay       }
1554e5c89e4eSSatish Balay     }
15552d747510SLisandro Dalcin   }
15562d747510SLisandro Dalcin 
15572d747510SLisandro Dalcin   /*
15582d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
15592d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
15602d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
15612d747510SLisandro Dalcin    */
15622d747510SLisandro Dalcin   if (matchnumbers) {
15632d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1564e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
15652d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
15662d747510SLisandro Dalcin       if (name[i] == '_') {
15672d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
15682d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
15692d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1570e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1571e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1572e5c89e4eSSatish Balay           }
15732d747510SLisandro Dalcin           i = j - 1;
1574e5c89e4eSSatish Balay           break;
1575e5c89e4eSSatish Balay         }
1576e5c89e4eSSatish Balay       }
1577e5c89e4eSSatish Balay     }
1578e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
15792d747510SLisandro Dalcin       PetscBool found;
15809355ec05SMatthew G. Knepley       char      opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
15819566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
15829566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15839566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
15849566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
15859371c9d4SSatish Balay       if (found) {
15869371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
15873ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15889371c9d4SSatish Balay       }
1589e5c89e4eSSatish Balay     }
1590e5c89e4eSSatish Balay   }
15912d747510SLisandro Dalcin 
15922d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
15933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1594e5c89e4eSSatish Balay }
1595e5c89e4eSSatish Balay 
1596d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
1597d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1598d71ae5a4SJacob Faibussowitsch {
15999355ec05SMatthew G. Knepley   char buf[PETSC_MAX_OPTION_NAME];
1600d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1601514bf10dSMatthew G Knepley 
1602514bf10dSMatthew G Knepley   PetscFunctionBegin;
1603c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1604cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1605cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1606514bf10dSMatthew G Knepley 
16072d747510SLisandro Dalcin   name++; /* skip starting dash */
1608514bf10dSMatthew G Knepley 
1609514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
16102d747510SLisandro Dalcin   if (pre && pre[0]) {
16112d747510SLisandro Dalcin     char *ptr = buf;
16129371c9d4SSatish Balay     if (name[0] == '-') {
16139371c9d4SSatish Balay       *ptr++ = '-';
16149371c9d4SSatish Balay       name++;
16159371c9d4SSatish Balay     }
16169b15cf9aSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
16179566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
16182d747510SLisandro Dalcin     name = buf;
1619514bf10dSMatthew G Knepley   }
16202d747510SLisandro Dalcin 
162176bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1622514bf10dSMatthew G Knepley     PetscBool valid;
16239355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
16249566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
16259566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
162628b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1627514bf10dSMatthew G Knepley   }
1628514bf10dSMatthew G Knepley 
1629d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1630d6ced9c0SMatthew G. Knepley   {
1631d6ced9c0SMatthew G. Knepley     int i, j;
1632d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1633d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1634d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1635d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1636d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1637d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1638d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1639d6ced9c0SMatthew G. Knepley           }
1640d6ced9c0SMatthew G. Knepley           i = j - 1;
1641d6ced9c0SMatthew G. Knepley           break;
1642d6ced9c0SMatthew G. Knepley         }
1643d6ced9c0SMatthew G. Knepley       }
1644d6ced9c0SMatthew G. Knepley     }
1645d6ced9c0SMatthew G. Knepley   }
1646d6ced9c0SMatthew G. Knepley 
1647363da2dcSJacob Faibussowitsch   /* slow search */
1648363da2dcSJacob Faibussowitsch   for (int c = -1; c < numCnt; ++c) {
1649363da2dcSJacob Faibussowitsch     char   opt[PETSC_MAX_OPTION_NAME + 2] = "";
16502d747510SLisandro Dalcin     size_t len;
1651d6ced9c0SMatthew G. Knepley 
1652d6ced9c0SMatthew G. Knepley     if (c < 0) {
1653c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1654d6ced9c0SMatthew G. Knepley     } else {
1655363da2dcSJacob Faibussowitsch       PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1656363da2dcSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1657d6ced9c0SMatthew G. Knepley     }
16589566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(opt, &len));
1659363da2dcSJacob Faibussowitsch     for (int i = 0; i < options->N; i++) {
1660363da2dcSJacob Faibussowitsch       PetscBool match;
1661363da2dcSJacob Faibussowitsch 
16629566063dSJacob Faibussowitsch       PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1663514bf10dSMatthew G Knepley       if (match) {
1664514bf10dSMatthew G Knepley         options->used[i] = PETSC_TRUE;
16652d747510SLisandro Dalcin         if (value) *value = options->values[i];
16662d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
16673ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
1668514bf10dSMatthew G Knepley       }
1669514bf10dSMatthew G Knepley     }
16702d747510SLisandro Dalcin   }
16712d747510SLisandro Dalcin 
16722d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1674514bf10dSMatthew G Knepley }
1675514bf10dSMatthew G Knepley 
1676e5c89e4eSSatish Balay /*@C
1677e5c89e4eSSatish Balay   PetscOptionsReject - Generates an error if a certain option is given.
1678e5c89e4eSSatish Balay 
16791c9f3c13SBarry Smith   Not Collective
1680e5c89e4eSSatish Balay 
1681e5c89e4eSSatish Balay   Input Parameters:
168220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
168320f4b53cSBarry Smith . pre     - the option prefix (may be `NULL`)
16842d747510SLisandro Dalcin . name    - the option name one is seeking
168520f4b53cSBarry Smith - mess    - error message (may be `NULL`)
1686e5c89e4eSSatish Balay 
1687e5c89e4eSSatish Balay   Level: advanced
1688e5c89e4eSSatish Balay 
1689c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1690db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1691db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1692c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1693db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1694db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1695e5c89e4eSSatish Balay @*/
1696d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1697d71ae5a4SJacob Faibussowitsch {
1698ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1699e5c89e4eSSatish Balay 
1700e5c89e4eSSatish Balay   PetscFunctionBegin;
17019566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1702e5c89e4eSSatish Balay   if (flag) {
170308401ef6SPierre 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);
1704f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1705e5c89e4eSSatish Balay   }
17063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1707e5c89e4eSSatish Balay }
1708e5c89e4eSSatish Balay 
1709e5c89e4eSSatish Balay /*@C
17102d747510SLisandro Dalcin   PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
17112d747510SLisandro Dalcin 
17122d747510SLisandro Dalcin   Not Collective
17132d747510SLisandro Dalcin 
1714811af0c4SBarry Smith   Input Parameter:
171520f4b53cSBarry Smith . options - options database, use `NULL` for default global database
17162d747510SLisandro Dalcin 
1717811af0c4SBarry Smith   Output Parameter:
1718811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
17192d747510SLisandro Dalcin 
17202d747510SLisandro Dalcin   Level: advanced
17212d747510SLisandro Dalcin 
1722db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
17232d747510SLisandro Dalcin @*/
1724d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1725d71ae5a4SJacob Faibussowitsch {
17262d747510SLisandro Dalcin   PetscFunctionBegin;
1727dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
17282d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17292d747510SLisandro Dalcin   *set    = options->help;
17303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17312d747510SLisandro Dalcin }
17322d747510SLisandro Dalcin 
1733d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1734d71ae5a4SJacob Faibussowitsch {
1735d314f959SVaclav Hapla   PetscFunctionBegin;
1736dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set, 2);
1737d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1738d314f959SVaclav Hapla   *set    = options->help_intro;
17393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1740d314f959SVaclav Hapla }
1741d314f959SVaclav Hapla 
17422d747510SLisandro Dalcin /*@C
1743e24fcbf7SPierre 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
1744e24fcbf7SPierre Jolivet   if its value is set to false.
1745e5c89e4eSSatish Balay 
1746e5c89e4eSSatish Balay   Not Collective
1747e5c89e4eSSatish Balay 
1748e5c89e4eSSatish Balay   Input Parameters:
174920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
175020f4b53cSBarry Smith . pre     - string to prepend to the name or `NULL`
17513de71b31SHong Zhang - name    - the option one is seeking
1752e5c89e4eSSatish Balay 
1753811af0c4SBarry Smith   Output Parameter:
1754811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1755e5c89e4eSSatish Balay 
1756e5c89e4eSSatish Balay   Level: beginner
1757e5c89e4eSSatish Balay 
1758811af0c4SBarry Smith   Note:
1759811af0c4SBarry Smith   In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
176090d69ab7SBarry Smith 
1761db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1762db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1763db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1764c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1765db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1766db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1767e5c89e4eSSatish Balay @*/
1768d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1769d71ae5a4SJacob Faibussowitsch {
17702d747510SLisandro Dalcin   const char *value;
1771ace3abfcSBarry Smith   PetscBool   flag;
1772e5c89e4eSSatish Balay 
1773e5c89e4eSSatish Balay   PetscFunctionBegin;
17749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
177596ef3cdfSSatish Balay   if (set) *set = flag;
17763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1777e5c89e4eSSatish Balay }
1778e5c89e4eSSatish Balay 
1779e5c89e4eSSatish Balay /*@C
17802d747510SLisandro Dalcin   PetscOptionsGetAll - Lists all the options the program was run with in a single string.
17812d747510SLisandro Dalcin 
17822d747510SLisandro Dalcin   Not Collective
17832d747510SLisandro Dalcin 
1784fd292e60Sprj-   Input Parameter:
178520f4b53cSBarry Smith . options - the options database, use `NULL` for the default global database
17862d747510SLisandro Dalcin 
17872d747510SLisandro Dalcin   Output Parameter:
17882d747510SLisandro Dalcin . copts - pointer where string pointer is stored
17892d747510SLisandro Dalcin 
179020f4b53cSBarry Smith   Level: advanced
179120f4b53cSBarry Smith 
17922d747510SLisandro Dalcin   Notes:
1793811af0c4SBarry Smith   The array and each entry in the array should be freed with `PetscFree()`
1794811af0c4SBarry Smith 
17951c9f3c13SBarry Smith   Each process may have different values depending on how the options were inserted into the database
17962d747510SLisandro Dalcin 
1797db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
17982d747510SLisandro Dalcin @*/
1799d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[])
1800d71ae5a4SJacob Faibussowitsch {
18012d747510SLisandro Dalcin   PetscInt i;
18022d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
18032d747510SLisandro Dalcin   char    *coptions = NULL;
18042d747510SLisandro Dalcin 
18052d747510SLisandro Dalcin   PetscFunctionBegin;
18062d747510SLisandro Dalcin   PetscValidPointer(copts, 2);
18072d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18082d747510SLisandro Dalcin   /* count the length of the required string */
18092d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18109566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
18112d747510SLisandro Dalcin     len += 2 + lent;
18122d747510SLisandro Dalcin     if (options->values[i]) {
18139566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
18142d747510SLisandro Dalcin       len += 1 + lent;
18152d747510SLisandro Dalcin     }
18162d747510SLisandro Dalcin   }
18179566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
18182d747510SLisandro Dalcin   coptions[0] = 0;
18192d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1820c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, "-", len));
1821c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, options->names[i], len));
1822c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, " ", len));
18232d747510SLisandro Dalcin     if (options->values[i]) {
1824c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, options->values[i], len));
1825c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, " ", len));
18262d747510SLisandro Dalcin     }
18272d747510SLisandro Dalcin   }
18282d747510SLisandro Dalcin   *copts = coptions;
18293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18302d747510SLisandro Dalcin }
18312d747510SLisandro Dalcin 
18322d747510SLisandro Dalcin /*@C
18332d747510SLisandro Dalcin   PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
18342d747510SLisandro Dalcin 
18352d747510SLisandro Dalcin   Not Collective
18362d747510SLisandro Dalcin 
1837d8d19677SJose E. Roman   Input Parameters:
183820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
18392d747510SLisandro Dalcin - name    - string name of option
18402d747510SLisandro Dalcin 
18412d747510SLisandro Dalcin   Output Parameter:
1842811af0c4SBarry Smith . used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
18432d747510SLisandro Dalcin 
18442d747510SLisandro Dalcin   Level: advanced
18452d747510SLisandro Dalcin 
1846811af0c4SBarry Smith   Note:
18479666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18481c9f3c13SBarry Smith   on the given process
18491c9f3c13SBarry Smith 
1850db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
18512d747510SLisandro Dalcin @*/
1852d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1853d71ae5a4SJacob Faibussowitsch {
18542d747510SLisandro Dalcin   PetscInt i;
18552d747510SLisandro Dalcin 
18562d747510SLisandro Dalcin   PetscFunctionBegin;
18572d747510SLisandro Dalcin   PetscValidCharPointer(name, 2);
1858dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(used, 3);
18592d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18602d747510SLisandro Dalcin   *used   = PETSC_FALSE;
18612d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18629566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
18632d747510SLisandro Dalcin     if (*used) {
18642d747510SLisandro Dalcin       *used = options->used[i];
18652d747510SLisandro Dalcin       break;
18662d747510SLisandro Dalcin     }
18672d747510SLisandro Dalcin   }
18683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18692d747510SLisandro Dalcin }
18702d747510SLisandro Dalcin 
1871487a658cSBarry Smith /*@
18722d747510SLisandro Dalcin   PetscOptionsAllUsed - Returns a count of the number of options in the
18732d747510SLisandro Dalcin   database that have never been selected.
18742d747510SLisandro Dalcin 
18752d747510SLisandro Dalcin   Not Collective
18762d747510SLisandro Dalcin 
18772d747510SLisandro Dalcin   Input Parameter:
187820f4b53cSBarry Smith . options - options database, use `NULL` for default global database
18792d747510SLisandro Dalcin 
18802d747510SLisandro Dalcin   Output Parameter:
18812d747510SLisandro Dalcin . N - count of options not used
18822d747510SLisandro Dalcin 
18832d747510SLisandro Dalcin   Level: advanced
18842d747510SLisandro Dalcin 
1885811af0c4SBarry Smith   Note:
18869666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18871c9f3c13SBarry Smith   on the given process
18881c9f3c13SBarry Smith 
1889db781477SPatrick Sanan .seealso: `PetscOptionsView()`
18902d747510SLisandro Dalcin @*/
1891d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1892d71ae5a4SJacob Faibussowitsch {
18932d747510SLisandro Dalcin   PetscInt i, n = 0;
18942d747510SLisandro Dalcin 
18952d747510SLisandro Dalcin   PetscFunctionBegin;
18962d747510SLisandro Dalcin   PetscValidIntPointer(N, 2);
18972d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18982d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18992d747510SLisandro Dalcin     if (!options->used[i]) n++;
19002d747510SLisandro Dalcin   }
19012d747510SLisandro Dalcin   *N = n;
19023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19032d747510SLisandro Dalcin }
19042d747510SLisandro Dalcin 
1905487a658cSBarry Smith /*@
19062d747510SLisandro Dalcin   PetscOptionsLeft - Prints to screen any options that were set and never used.
19072d747510SLisandro Dalcin 
19082d747510SLisandro Dalcin   Not Collective
19092d747510SLisandro Dalcin 
19102d747510SLisandro Dalcin   Input Parameter:
191120f4b53cSBarry Smith . options - options database; use `NULL` for default global database
19122d747510SLisandro Dalcin 
19132d747510SLisandro Dalcin   Options Database Key:
1914811af0c4SBarry Smith . -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
19152d747510SLisandro Dalcin 
191620f4b53cSBarry Smith   Level: advanced
191720f4b53cSBarry Smith 
19183de2bfdfSBarry Smith   Notes:
1919811af0c4SBarry Smith   This is rarely used directly, it is called by `PetscFinalize()` in debug more or if -options_left
19201c9f3c13SBarry Smith   is passed otherwise to help users determine possible mistakes in their usage of options. This
1921811af0c4SBarry Smith   only prints values on process zero of `PETSC_COMM_WORLD`.
1922811af0c4SBarry Smith 
1923811af0c4SBarry Smith   Other processes depending the objects
19241c9f3c13SBarry Smith   used may have different options that are left unused.
19253de2bfdfSBarry Smith 
1926db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
19272d747510SLisandro Dalcin @*/
1928d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeft(PetscOptions options)
1929d71ae5a4SJacob Faibussowitsch {
19302d747510SLisandro Dalcin   PetscInt     i;
19313de2bfdfSBarry Smith   PetscInt     cnt = 0;
19323de2bfdfSBarry Smith   PetscOptions toptions;
19332d747510SLisandro Dalcin 
19342d747510SLisandro Dalcin   PetscFunctionBegin;
19353de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
19363de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
19373de2bfdfSBarry Smith     if (!toptions->used[i]) {
1938660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
19393de2bfdfSBarry Smith       if (toptions->values[i]) {
19409355ec05SMatthew 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]]));
19412d747510SLisandro Dalcin       } else {
19429355ec05SMatthew G. Knepley         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
19432d747510SLisandro Dalcin       }
19442d747510SLisandro Dalcin     }
19452d747510SLisandro Dalcin   }
19463de2bfdfSBarry Smith   if (!options) {
19473de2bfdfSBarry Smith     toptions = defaultoptions;
19483de2bfdfSBarry Smith     while (toptions->previous) {
19493de2bfdfSBarry Smith       cnt++;
19503de2bfdfSBarry Smith       toptions = toptions->previous;
19513de2bfdfSBarry Smith     }
195248a46eb9SPierre 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));
19533de2bfdfSBarry Smith   }
19543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19552d747510SLisandro Dalcin }
19562d747510SLisandro Dalcin 
19572d747510SLisandro Dalcin /*@C
19582d747510SLisandro Dalcin   PetscOptionsLeftGet - Returns all options that were set and never used.
19592d747510SLisandro Dalcin 
19602d747510SLisandro Dalcin   Not Collective
19612d747510SLisandro Dalcin 
19622d747510SLisandro Dalcin   Input Parameter:
196320f4b53cSBarry Smith . options - options database, use `NULL` for default global database
19642d747510SLisandro Dalcin 
1965d8d19677SJose E. Roman   Output Parameters:
1966a2b725a8SWilliam Gropp + N      - count of options not used
19672d747510SLisandro Dalcin . names  - names of options not used
1968a2b725a8SWilliam Gropp - values - values of options not used
19692d747510SLisandro Dalcin 
19702d747510SLisandro Dalcin   Level: advanced
19712d747510SLisandro Dalcin 
19722d747510SLisandro Dalcin   Notes:
1973811af0c4SBarry Smith   Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1974811af0c4SBarry Smith 
1975811af0c4SBarry Smith   The value returned may be different on each process and depends on which options have been processed
19761c9f3c13SBarry Smith   on the given process
19772d747510SLisandro Dalcin 
1978db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
19792d747510SLisandro Dalcin @*/
1980d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
1981d71ae5a4SJacob Faibussowitsch {
19822d747510SLisandro Dalcin   PetscInt i, n;
19832d747510SLisandro Dalcin 
19842d747510SLisandro Dalcin   PetscFunctionBegin;
19852d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
19862d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
19872d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
19882d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19892d747510SLisandro Dalcin 
19902d747510SLisandro Dalcin   /* The number of unused PETSc options */
19912d747510SLisandro Dalcin   n = 0;
19922d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1993660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
19942d747510SLisandro Dalcin     if (!options->used[i]) n++;
19952d747510SLisandro Dalcin   }
1996ad540459SPierre Jolivet   if (N) *N = n;
19979566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
19989566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
19992d747510SLisandro Dalcin 
20002d747510SLisandro Dalcin   n = 0;
20012d747510SLisandro Dalcin   if (names || values) {
20022d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
20032d747510SLisandro Dalcin       if (!options->used[i]) {
2004660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
20052d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
20062d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
20072d747510SLisandro Dalcin         n++;
20082d747510SLisandro Dalcin       }
20092d747510SLisandro Dalcin     }
20102d747510SLisandro Dalcin   }
20113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20122d747510SLisandro Dalcin }
20132d747510SLisandro Dalcin 
20142d747510SLisandro Dalcin /*@C
2015811af0c4SBarry Smith   PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
20162d747510SLisandro Dalcin 
20172d747510SLisandro Dalcin   Not Collective
20182d747510SLisandro Dalcin 
2019d8d19677SJose E. Roman   Input Parameters:
202020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
20212d747510SLisandro Dalcin . names   - names of options not used
2022a2b725a8SWilliam Gropp - values  - values of options not used
20232d747510SLisandro Dalcin 
20242d747510SLisandro Dalcin   Level: advanced
20252d747510SLisandro Dalcin 
2026db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
20272d747510SLisandro Dalcin @*/
2028d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2029d71ae5a4SJacob Faibussowitsch {
20302d747510SLisandro Dalcin   PetscFunctionBegin;
20312d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N, 2);
20322d747510SLisandro Dalcin   if (names) PetscValidPointer(names, 3);
20332d747510SLisandro Dalcin   if (values) PetscValidPointer(values, 4);
2034ad540459SPierre Jolivet   if (N) *N = 0;
20359566063dSJacob Faibussowitsch   if (names) PetscCall(PetscFree(*names));
20369566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
20373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20382d747510SLisandro Dalcin }
20392d747510SLisandro Dalcin 
20402d747510SLisandro Dalcin /*@C
2041811af0c4SBarry Smith   PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
20422d747510SLisandro Dalcin 
2043c3339decSBarry Smith   Logically Collective
20442d747510SLisandro Dalcin 
20452d747510SLisandro Dalcin   Input Parameters:
20462d747510SLisandro Dalcin + name   - option name string
20472d747510SLisandro Dalcin . value  - option value string
20489355ec05SMatthew G. Knepley . source - The source for the option
204920f4b53cSBarry Smith - ctx    - a `PETSCVIEWERASCII` or `NULL`
20502d747510SLisandro Dalcin 
20512d747510SLisandro Dalcin   Level: intermediate
20522d747510SLisandro Dalcin 
20539666a313SBarry Smith   Notes:
205420f4b53cSBarry Smith   If ctx is `NULL`, `PetscPrintf()` is used.
2055811af0c4SBarry Smith   The first MPI rank in the `PetscViewer` viewer actually prints the values, other
20561c9f3c13SBarry Smith   processes may have different values set
20571c9f3c13SBarry Smith 
2058811af0c4SBarry Smith   If `PetscCIEnabled` then do not print the test harness options
2059660278c0SBarry Smith 
2060db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
20612d747510SLisandro Dalcin @*/
20629355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], PetscOptionSource source, void *ctx)
2063d71ae5a4SJacob Faibussowitsch {
20642d747510SLisandro Dalcin   PetscFunctionBegin;
20653ba16761SJacob Faibussowitsch   if (PetscCIOption(name)) PetscFunctionReturn(PETSC_SUCCESS);
2066660278c0SBarry Smith 
20679060e2f9SVaclav Hapla   if (ctx) {
20689060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
20692d747510SLisandro Dalcin     if (!value) {
20709566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
20712d747510SLisandro Dalcin     } else if (!value[0]) {
20729355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20732d747510SLisandro Dalcin     } else {
20749355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20752d747510SLisandro Dalcin     }
20769060e2f9SVaclav Hapla   } else {
20779060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
20789060e2f9SVaclav Hapla     if (!value) {
20799566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
20809060e2f9SVaclav Hapla     } else if (!value[0]) {
20819355ec05SMatthew G. Knepley       PetscCall(PetscPrintf(comm, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20829060e2f9SVaclav Hapla     } else {
2083aaa8cc7dSPierre Jolivet       PetscCall(PetscPrintf(comm, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20849060e2f9SVaclav Hapla     }
20859060e2f9SVaclav Hapla   }
20863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20872d747510SLisandro Dalcin }
20882d747510SLisandro Dalcin 
20892d747510SLisandro Dalcin /*@C
20902d747510SLisandro Dalcin   PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
20912d747510SLisandro Dalcin   modified the PETSc options database.
20922d747510SLisandro Dalcin 
20932d747510SLisandro Dalcin   Not Collective
20942d747510SLisandro Dalcin 
20952d747510SLisandro Dalcin   Input Parameters:
209620f4b53cSBarry Smith + monitor        - pointer to function (if this is `NULL`, it turns off monitoring
20972d747510SLisandro Dalcin . mctx           - [optional] context for private data for the
209820f4b53cSBarry Smith              monitor routine (use `NULL` if no context is desired)
20992d747510SLisandro Dalcin - monitordestroy - [optional] routine that frees monitor context
210020f4b53cSBarry Smith           (may be `NULL`)
21012d747510SLisandro Dalcin 
2102*aec76313SJacob Faibussowitsch   Calling sequence:
210320f4b53cSBarry Smith $   PetscErrorCode monitor(const char name[], const char value[], void *mctx)
21042d747510SLisandro Dalcin + name  - option name string
21052d747510SLisandro Dalcin . value - option value string
21069355ec05SMatthew G. Knepley . source - option source
2107811af0c4SBarry Smith - mctx  - optional monitoring context, as set by `PetscOptionsMonitorSet()`
21082d747510SLisandro Dalcin 
210920f4b53cSBarry Smith   Calling Sequence of `monitordestroy`:
211020f4b53cSBarry Smith $  PetscErrorCode monitordestroy(void *cctx)
211120f4b53cSBarry Smith 
211220f4b53cSBarry Smith   Options Database Key:
2113811af0c4SBarry Smith    See `PetscInitialize()` for options related to option database monitoring.
21142d747510SLisandro Dalcin 
211520f4b53cSBarry Smith   Level: intermediate
211620f4b53cSBarry Smith 
21172d747510SLisandro Dalcin   Notes:
21182d747510SLisandro Dalcin   The default is to do nothing.  To print the name and value of options
2119811af0c4SBarry Smith   being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
21202d747510SLisandro Dalcin   with a null monitoring context.
21212d747510SLisandro Dalcin 
21222d747510SLisandro Dalcin   Several different monitoring routines may be set by calling
2123811af0c4SBarry Smith   `PetscOptionsMonitorSet()` multiple times; all will be called in the
21242d747510SLisandro Dalcin   order in which they were set.
21252d747510SLisandro Dalcin 
2126db781477SPatrick Sanan .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
21272d747510SLisandro Dalcin @*/
21289355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **))
2129d71ae5a4SJacob Faibussowitsch {
21302d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
21312d747510SLisandro Dalcin 
21322d747510SLisandro Dalcin   PetscFunctionBegin;
21333ba16761SJacob Faibussowitsch   if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
213408401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
21352d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
21362d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
21372d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void *)mctx;
21383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21392d747510SLisandro Dalcin }
21402d747510SLisandro Dalcin 
21412d747510SLisandro Dalcin /*
21422d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
214363fe8743SVaclav Hapla      Empty string is considered as true.
21442d747510SLisandro Dalcin */
2145d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2146d71ae5a4SJacob Faibussowitsch {
21472d747510SLisandro Dalcin   PetscBool istrue, isfalse;
21482d747510SLisandro Dalcin   size_t    len;
21492d747510SLisandro Dalcin 
21502d747510SLisandro Dalcin   PetscFunctionBegin;
215163fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
21529566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
21539371c9d4SSatish Balay   if (!len) {
21549371c9d4SSatish Balay     *a = PETSC_TRUE;
21553ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21569371c9d4SSatish Balay   }
21579566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
21589371c9d4SSatish Balay   if (istrue) {
21599371c9d4SSatish Balay     *a = PETSC_TRUE;
21603ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21619371c9d4SSatish Balay   }
21629566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
21639371c9d4SSatish Balay   if (istrue) {
21649371c9d4SSatish Balay     *a = PETSC_TRUE;
21653ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21669371c9d4SSatish Balay   }
21679566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
21689371c9d4SSatish Balay   if (istrue) {
21699371c9d4SSatish Balay     *a = PETSC_TRUE;
21703ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21719371c9d4SSatish Balay   }
21729566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
21739371c9d4SSatish Balay   if (istrue) {
21749371c9d4SSatish Balay     *a = PETSC_TRUE;
21753ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21769371c9d4SSatish Balay   }
21779566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
21789371c9d4SSatish Balay   if (isfalse) {
21799371c9d4SSatish Balay     *a = PETSC_FALSE;
21803ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21819371c9d4SSatish Balay   }
21829566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
21839371c9d4SSatish Balay   if (isfalse) {
21849371c9d4SSatish Balay     *a = PETSC_FALSE;
21853ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21869371c9d4SSatish Balay   }
21879566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
21889371c9d4SSatish Balay   if (isfalse) {
21899371c9d4SSatish Balay     *a = PETSC_FALSE;
21903ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21919371c9d4SSatish Balay   }
21929566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
21939371c9d4SSatish Balay   if (isfalse) {
21949371c9d4SSatish Balay     *a = PETSC_FALSE;
21953ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21969371c9d4SSatish Balay   }
219798921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
21982d747510SLisandro Dalcin }
21992d747510SLisandro Dalcin 
22002d747510SLisandro Dalcin /*
22012d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
22022d747510SLisandro Dalcin */
2203d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2204d71ae5a4SJacob Faibussowitsch {
22052d747510SLisandro Dalcin   size_t    len;
22062d747510SLisandro Dalcin   PetscBool decide, tdefault, mouse;
22072d747510SLisandro Dalcin 
22082d747510SLisandro Dalcin   PetscFunctionBegin;
22099566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
22105f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22112d747510SLisandro Dalcin 
22129566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
221348a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
22149566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
221548a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
22169566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
22172d747510SLisandro Dalcin 
22182d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
22192d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
22202d747510SLisandro Dalcin   else if (mouse) *a = -1;
22212d747510SLisandro Dalcin   else {
22222d747510SLisandro Dalcin     char *endptr;
22232d747510SLisandro Dalcin     long  strtolval;
22242d747510SLisandro Dalcin 
22252d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2226cc73adaaSBarry 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);
22272d747510SLisandro Dalcin 
22282d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
22292d747510SLisandro Dalcin     (void)strtolval;
22302d747510SLisandro Dalcin     *a = atoll(name);
22312d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
22322d747510SLisandro Dalcin     (void)strtolval;
22332d747510SLisandro Dalcin     *a = _atoi64(name);
22342d747510SLisandro Dalcin #else
22352d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
22362d747510SLisandro Dalcin #endif
22372d747510SLisandro Dalcin   }
22383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22392d747510SLisandro Dalcin }
22402d747510SLisandro Dalcin 
22412d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22422d747510SLisandro Dalcin   #include <quadmath.h>
22432d747510SLisandro Dalcin #endif
22442d747510SLisandro Dalcin 
2245d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2246d71ae5a4SJacob Faibussowitsch {
22472d747510SLisandro Dalcin   PetscFunctionBegin;
22482d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22492d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
22502d747510SLisandro Dalcin #else
22512d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
22522d747510SLisandro Dalcin #endif
22533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22542d747510SLisandro Dalcin }
22552d747510SLisandro Dalcin 
2256d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2257d71ae5a4SJacob Faibussowitsch {
22582d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
22592d747510SLisandro Dalcin   char     *ptr;
22602d747510SLisandro Dalcin   PetscReal strtoval;
22612d747510SLisandro Dalcin 
22622d747510SLisandro Dalcin   PetscFunctionBegin;
22639566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
22642d747510SLisandro Dalcin   if (ptr == name) {
22652d747510SLisandro Dalcin     strtoval = 1.;
22662d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
22672d747510SLisandro Dalcin     if (name[0] == 'i') {
22682d747510SLisandro Dalcin       ptr++;
22692d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
22702d747510SLisandro Dalcin       ptr += 2;
22712d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
22722d747510SLisandro Dalcin       strtoval = -1.;
22732d747510SLisandro Dalcin       ptr += 2;
22742d747510SLisandro Dalcin     }
22752d747510SLisandro Dalcin   } else if (*ptr == 'i') {
22762d747510SLisandro Dalcin     hasi = PETSC_TRUE;
22772d747510SLisandro Dalcin     ptr++;
22782d747510SLisandro Dalcin   }
22792d747510SLisandro Dalcin   *endptr      = ptr;
22802d747510SLisandro Dalcin   *isImaginary = hasi;
22812d747510SLisandro Dalcin   if (hasi) {
22822d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
228398921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
22842d747510SLisandro Dalcin #else
22852d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
22862d747510SLisandro Dalcin #endif
22872d747510SLisandro Dalcin   } else {
22882d747510SLisandro Dalcin     *a = strtoval;
22892d747510SLisandro Dalcin   }
22903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22912d747510SLisandro Dalcin }
22922d747510SLisandro Dalcin 
22932d747510SLisandro Dalcin /*
22942d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
22952d747510SLisandro Dalcin */
2296d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2297d71ae5a4SJacob Faibussowitsch {
22982d747510SLisandro Dalcin   size_t    len;
22992d747510SLisandro Dalcin   PetscBool match;
23002d747510SLisandro Dalcin   char     *endptr;
23012d747510SLisandro Dalcin 
23022d747510SLisandro Dalcin   PetscFunctionBegin;
23039566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
230428b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
23052d747510SLisandro Dalcin 
23069566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
23079566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
23089371c9d4SSatish Balay   if (match) {
23099371c9d4SSatish Balay     *a = PETSC_DEFAULT;
23103ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23119371c9d4SSatish Balay   }
23122d747510SLisandro Dalcin 
23139566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
23149566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
23159371c9d4SSatish Balay   if (match) {
23169371c9d4SSatish Balay     *a = PETSC_DECIDE;
23173ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23189371c9d4SSatish Balay   }
23192d747510SLisandro Dalcin 
23209566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
232139a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
23223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23232d747510SLisandro Dalcin }
23242d747510SLisandro Dalcin 
2325d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2326d71ae5a4SJacob Faibussowitsch {
23272d747510SLisandro Dalcin   PetscBool   imag1;
23282d747510SLisandro Dalcin   size_t      len;
23292d747510SLisandro Dalcin   PetscScalar val = 0.;
23302d747510SLisandro Dalcin   char       *ptr = NULL;
23312d747510SLisandro Dalcin 
23322d747510SLisandro Dalcin   PetscFunctionBegin;
23339566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
233428b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
23359566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
23362d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
23372d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
23382d747510SLisandro Dalcin     PetscBool   imag2;
23392d747510SLisandro Dalcin     PetscScalar val2;
23402d747510SLisandro Dalcin 
23419566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
234239a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
23432d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
23442d747510SLisandro Dalcin   }
23452d747510SLisandro Dalcin #endif
234639a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
23472d747510SLisandro Dalcin   *a = val;
23483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23492d747510SLisandro Dalcin }
23502d747510SLisandro Dalcin 
23512d747510SLisandro Dalcin /*@C
23522d747510SLisandro Dalcin   PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
23532d747510SLisandro Dalcin   option in the database.
2354e5c89e4eSSatish Balay 
2355e5c89e4eSSatish Balay   Not Collective
2356e5c89e4eSSatish Balay 
2357e5c89e4eSSatish Balay   Input Parameters:
235820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
235920f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2360e5c89e4eSSatish Balay - name    - the option one is seeking
2361e5c89e4eSSatish Balay 
2362d8d19677SJose E. Roman   Output Parameters:
23632d747510SLisandro Dalcin + ivalue - the logical value to return
2364811af0c4SBarry Smith - set    - `PETSC_TRUE`  if found, else `PETSC_FALSE`
2365e5c89e4eSSatish Balay 
2366e5c89e4eSSatish Balay   Level: beginner
2367e5c89e4eSSatish Balay 
236895452b02SPatrick Sanan   Notes:
2369811af0c4SBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`
2370811af0c4SBarry Smith   FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
23712d747510SLisandro Dalcin 
2372811af0c4SBarry 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
23732d747510SLisandro Dalcin   is equivalent to -requested_bool true
23742d747510SLisandro Dalcin 
23752d747510SLisandro Dalcin   If the user does not supply the option at all ivalue is NOT changed. Thus
23762efd9cb1SBarry Smith   you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
23772efd9cb1SBarry Smith 
2378db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2379db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2380db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2381c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2382db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2383db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2384e5c89e4eSSatish Balay @*/
2385d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2386d71ae5a4SJacob Faibussowitsch {
23872d747510SLisandro Dalcin   const char *value;
2388ace3abfcSBarry Smith   PetscBool   flag;
2389e5c89e4eSSatish Balay 
2390e5c89e4eSSatish Balay   PetscFunctionBegin;
23912d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2392064a246eSJacob Faibussowitsch   if (ivalue) PetscValidBoolPointer(ivalue, 4);
23939566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2394e5c89e4eSSatish Balay   if (flag) {
239596ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
23969566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
23972d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2398e5c89e4eSSatish Balay   } else {
239996ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2400e5c89e4eSSatish Balay   }
24013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2402e5c89e4eSSatish Balay }
2403e5c89e4eSSatish Balay 
2404e5c89e4eSSatish Balay /*@C
2405e5c89e4eSSatish Balay   PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2406e5c89e4eSSatish Balay 
2407e5c89e4eSSatish Balay   Not Collective
2408e5c89e4eSSatish Balay 
2409e5c89e4eSSatish Balay   Input Parameters:
241020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
241120f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2412e5c89e4eSSatish Balay . opt     - option name
2413a264d7a6SBarry Smith . list    - the possible choices (one of these must be selected, anything else is invalid)
2414a2b725a8SWilliam Gropp - ntext   - number of choices
2415e5c89e4eSSatish Balay 
2416d8d19677SJose E. Roman   Output Parameters:
24172efd9cb1SBarry Smith + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2418811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2419e5c89e4eSSatish Balay 
2420e5c89e4eSSatish Balay   Level: intermediate
2421e5c89e4eSSatish Balay 
242295452b02SPatrick Sanan   Notes:
242395452b02SPatrick Sanan   If the user does not supply the option value is NOT changed. Thus
24242efd9cb1SBarry Smith   you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
24252efd9cb1SBarry Smith 
2426811af0c4SBarry Smith   See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2427e5c89e4eSSatish Balay 
2428db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2429db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2430db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2431c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2432db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2433db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2434e5c89e4eSSatish Balay @*/
2435d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscInt ntext, PetscInt *value, PetscBool *set)
2436d71ae5a4SJacob Faibussowitsch {
243758b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2438e5c89e4eSSatish Balay   char     *svalue;
2439ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2440e5c89e4eSSatish Balay   PetscInt  i;
2441e5c89e4eSSatish Balay 
2442e5c89e4eSSatish Balay   PetscFunctionBegin;
24432d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
2444e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
24459566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2446e5c89e4eSSatish Balay     if (alen > len) len = alen;
244758b0ac4eSStefano Zampini     tlen += len + 1;
2448e5c89e4eSSatish Balay   }
2449e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
24509566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
24519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2452e5c89e4eSSatish Balay   if (aset) {
24539566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
245458b0ac4eSStefano Zampini     if (!flg) {
2455c6a7a370SJeremy L Thompson       char *avail;
245658b0ac4eSStefano Zampini 
24579566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
2458c6a7a370SJeremy L Thompson       avail[0] = '\0';
245958b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
2460c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, list[i], tlen));
2461c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, " ", tlen));
246258b0ac4eSStefano Zampini       }
24639566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
246498921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
246558b0ac4eSStefano Zampini     }
2466fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2467a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
24689566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
24693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2470e5c89e4eSSatish Balay }
2471e5c89e4eSSatish Balay 
2472e5c89e4eSSatish Balay /*@C
2473e5c89e4eSSatish Balay   PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2474e5c89e4eSSatish Balay 
2475e5c89e4eSSatish Balay   Not Collective
2476e5c89e4eSSatish Balay 
2477e5c89e4eSSatish Balay   Input Parameters:
247820f4b53cSBarry Smith + options - options database, use `NULL` for default global database
247920f4b53cSBarry Smith . pre     - option prefix or `NULL`
2480e5c89e4eSSatish Balay . opt     - option name
24816b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2482e5c89e4eSSatish Balay 
2483d8d19677SJose E. Roman   Output Parameters:
2484e5c89e4eSSatish Balay + value - the  value to return
2485811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2486e5c89e4eSSatish Balay 
2487e5c89e4eSSatish Balay   Level: beginner
2488e5c89e4eSSatish Balay 
248995452b02SPatrick Sanan   Notes:
249095452b02SPatrick Sanan   If the user does not supply the option value is NOT changed. Thus
24912efd9cb1SBarry Smith   you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2492e5c89e4eSSatish Balay 
2493811af0c4SBarry Smith   List is usually something like `PCASMTypes` or some other predefined list of enum names
2494e5c89e4eSSatish Balay 
2495db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2496db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2497*aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2498db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2499c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2500db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2501db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2502e5c89e4eSSatish Balay @*/
2503d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscEnum *value, PetscBool *set)
2504d71ae5a4SJacob Faibussowitsch {
250569a24498SJed Brown   PetscInt  ntext = 0, tval;
2506ace3abfcSBarry Smith   PetscBool fset;
2507e5c89e4eSSatish Balay 
2508e5c89e4eSSatish Balay   PetscFunctionBegin;
25092d747510SLisandro Dalcin   PetscValidCharPointer(opt, 3);
2510ad540459SPierre 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");
251108401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2512e5c89e4eSSatish Balay   ntext -= 3;
25139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
251469a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2515809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2516809ceb46SBarry Smith   if (set) *set = fset;
25173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2518e5c89e4eSSatish Balay }
2519e5c89e4eSSatish Balay 
2520e5c89e4eSSatish Balay /*@C
25212d747510SLisandro Dalcin   PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2522e5c89e4eSSatish Balay 
2523e5c89e4eSSatish Balay   Not Collective
2524e5c89e4eSSatish Balay 
2525e5c89e4eSSatish Balay   Input Parameters:
252620f4b53cSBarry Smith + options - options database, use `NULL` for default global database
252720f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2528e5c89e4eSSatish Balay - name    - the option one is seeking
2529e5c89e4eSSatish Balay 
2530d8d19677SJose E. Roman   Output Parameters:
25312d747510SLisandro Dalcin + ivalue - the integer value to return
2532811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2533e5c89e4eSSatish Balay 
2534e5c89e4eSSatish Balay   Level: beginner
2535e5c89e4eSSatish Balay 
2536e5c89e4eSSatish Balay   Notes:
25372d747510SLisandro Dalcin   If the user does not supply the option ivalue is NOT changed. Thus
25382efd9cb1SBarry Smith   you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
25395c07ccb8SBarry Smith 
2540db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2541db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2542*aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2543db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2544c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2545db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2546db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2547e5c89e4eSSatish Balay @*/
2548d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2549d71ae5a4SJacob Faibussowitsch {
25502d747510SLisandro Dalcin   const char *value;
25512d747510SLisandro Dalcin   PetscBool   flag;
2552e5c89e4eSSatish Balay 
2553e5c89e4eSSatish Balay   PetscFunctionBegin;
25542d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
25552d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
25569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2557e5c89e4eSSatish Balay   if (flag) {
255834a9cc2cSBarry Smith     if (!value) {
25592d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
256034a9cc2cSBarry Smith     } else {
25612d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
25629566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2563e5c89e4eSSatish Balay     }
2564e5c89e4eSSatish Balay   } else {
256596ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2566e5c89e4eSSatish Balay   }
25673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2568e5c89e4eSSatish Balay }
2569e5c89e4eSSatish Balay 
2570e2446a98SMatthew Knepley /*@C
2571e5c89e4eSSatish Balay   PetscOptionsGetReal - Gets the double precision value for a particular
2572e5c89e4eSSatish Balay   option in the database.
2573e5c89e4eSSatish Balay 
2574e5c89e4eSSatish Balay   Not Collective
2575e5c89e4eSSatish Balay 
2576e5c89e4eSSatish Balay   Input Parameters:
257720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
257820f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2579e5c89e4eSSatish Balay - name    - the option one is seeking
2580e5c89e4eSSatish Balay 
2581d8d19677SJose E. Roman   Output Parameters:
2582e5c89e4eSSatish Balay + dvalue - the double value to return
2583811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2584e5c89e4eSSatish Balay 
258520f4b53cSBarry Smith   Level: beginner
258620f4b53cSBarry Smith 
2587811af0c4SBarry Smith   Note:
258895452b02SPatrick Sanan   If the user does not supply the option dvalue is NOT changed. Thus
25892efd9cb1SBarry Smith   you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2590e4974155SBarry Smith 
2591db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2592c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2593db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2594c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2595db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2596db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2597e5c89e4eSSatish Balay @*/
2598d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2599d71ae5a4SJacob Faibussowitsch {
26002d747510SLisandro Dalcin   const char *value;
2601ace3abfcSBarry Smith   PetscBool   flag;
2602e5c89e4eSSatish Balay 
2603e5c89e4eSSatish Balay   PetscFunctionBegin;
26042d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
26052d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
26069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2607e5c89e4eSSatish Balay   if (flag) {
2608a297a907SKarl Rupp     if (!value) {
2609a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2610a297a907SKarl Rupp     } else {
2611a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
26129566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2613a297a907SKarl Rupp     }
2614e5c89e4eSSatish Balay   } else {
261596ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2616e5c89e4eSSatish Balay   }
26173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2618e5c89e4eSSatish Balay }
2619e5c89e4eSSatish Balay 
2620e5c89e4eSSatish Balay /*@C
2621e5c89e4eSSatish Balay   PetscOptionsGetScalar - Gets the scalar value for a particular
2622e5c89e4eSSatish Balay   option in the database.
2623e5c89e4eSSatish Balay 
2624e5c89e4eSSatish Balay   Not Collective
2625e5c89e4eSSatish Balay 
2626e5c89e4eSSatish Balay   Input Parameters:
262720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
262820f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2629e5c89e4eSSatish Balay - name    - the option one is seeking
2630e5c89e4eSSatish Balay 
2631d8d19677SJose E. Roman   Output Parameters:
2632e5c89e4eSSatish Balay + dvalue - the double value to return
2633811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2634e5c89e4eSSatish Balay 
2635e5c89e4eSSatish Balay   Level: beginner
2636e5c89e4eSSatish Balay 
2637e5c89e4eSSatish Balay   Usage:
2638eb4ae41dSBarry Smith   A complex number 2+3i must be specified with NO spaces
2639e5c89e4eSSatish Balay 
2640811af0c4SBarry Smith   Note:
264195452b02SPatrick Sanan   If the user does not supply the option dvalue is NOT changed. Thus
26422efd9cb1SBarry Smith   you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2643e4974155SBarry Smith 
2644db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2645db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2646db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2647c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2648db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2649db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2650e5c89e4eSSatish Balay @*/
2651d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2652d71ae5a4SJacob Faibussowitsch {
26532d747510SLisandro Dalcin   const char *value;
2654ace3abfcSBarry Smith   PetscBool   flag;
2655e5c89e4eSSatish Balay 
2656e5c89e4eSSatish Balay   PetscFunctionBegin;
26572d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
26582d747510SLisandro Dalcin   PetscValidScalarPointer(dvalue, 4);
26599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2660e5c89e4eSSatish Balay   if (flag) {
2661e5c89e4eSSatish Balay     if (!value) {
266296ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2663e5c89e4eSSatish Balay     } else {
2664e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
26659566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2666e5c89e4eSSatish Balay #else
26679566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2668e5c89e4eSSatish Balay #endif
266996ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2670e5c89e4eSSatish Balay     }
2671e5c89e4eSSatish Balay   } else { /* flag */
267296ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2673e5c89e4eSSatish Balay   }
26743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2675e5c89e4eSSatish Balay }
2676e5c89e4eSSatish Balay 
2677e5c89e4eSSatish Balay /*@C
2678e5c89e4eSSatish Balay   PetscOptionsGetString - Gets the string value for a particular option in
2679e5c89e4eSSatish Balay   the database.
2680e5c89e4eSSatish Balay 
2681e5c89e4eSSatish Balay   Not Collective
2682e5c89e4eSSatish Balay 
2683e5c89e4eSSatish Balay   Input Parameters:
268420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
268520f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
2686e5c89e4eSSatish Balay . name    - the option one is seeking
2687bcbf2dc5SJed Brown - len     - maximum length of the string including null termination
2688e5c89e4eSSatish Balay 
2689e5c89e4eSSatish Balay   Output Parameters:
2690e5c89e4eSSatish Balay + string - location to copy string
2691811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2692e5c89e4eSSatish Balay 
2693e5c89e4eSSatish Balay   Level: beginner
2694e5c89e4eSSatish Balay 
269520f4b53cSBarry Smith   Note:
269620f4b53cSBarry 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`
269720f4b53cSBarry Smith 
269820f4b53cSBarry Smith   If the user does not use the option then the string is not changed. Thus
269920f4b53cSBarry Smith   you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
270020f4b53cSBarry Smith 
270120f4b53cSBarry Smith   Even if the user provided no string (for example -optionname -someotheroption) the flag is set to PETSC_TRUE (and the string is fulled with nulls).
270220f4b53cSBarry Smith 
2703*aec76313SJacob Faibussowitsch   Fortran Notes:
2704e5c89e4eSSatish Balay   The Fortran interface is slightly different from the C/C++
2705e5c89e4eSSatish Balay   interface (len is not used).  Sample usage in Fortran follows
2706e5c89e4eSSatish Balay .vb
2707e5c89e4eSSatish Balay       character *20    string
270893e6ba5cSBarry Smith       PetscErrorCode   ierr
270993e6ba5cSBarry Smith       PetscBool        set
27101b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2711e5c89e4eSSatish Balay .ve
2712e5c89e4eSSatish Balay 
2713db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2714db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2715db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2716c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2717db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2718db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2719e5c89e4eSSatish Balay @*/
2720d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set)
2721d71ae5a4SJacob Faibussowitsch {
27222d747510SLisandro Dalcin   const char *value;
2723ace3abfcSBarry Smith   PetscBool   flag;
2724e5c89e4eSSatish Balay 
2725e5c89e4eSSatish Balay   PetscFunctionBegin;
27262d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
27272d747510SLisandro Dalcin   PetscValidCharPointer(string, 4);
27289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2729e5c89e4eSSatish Balay   if (!flag) {
273096ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2731e5c89e4eSSatish Balay   } else {
273296ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
27339566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
27349566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2735e5c89e4eSSatish Balay   }
27363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2737e5c89e4eSSatish Balay }
2738e5c89e4eSSatish Balay 
2739d71ae5a4SJacob Faibussowitsch char *PetscOptionsGetStringMatlab(PetscOptions options, const char pre[], const char name[])
2740d71ae5a4SJacob Faibussowitsch {
27412d747510SLisandro Dalcin   const char *value;
274214ce751eSBarry Smith   PetscBool   flag;
274314ce751eSBarry Smith 
274414ce751eSBarry Smith   PetscFunctionBegin;
274539a651e2SJacob Faibussowitsch   if (PetscOptionsFindPair(options, pre, name, &value, &flag)) PetscFunctionReturn(NULL);
27462d747510SLisandro Dalcin   if (flag) PetscFunctionReturn((char *)value);
274739a651e2SJacob Faibussowitsch   PetscFunctionReturn(NULL);
274814ce751eSBarry Smith }
274914ce751eSBarry Smith 
27502d747510SLisandro Dalcin /*@C
27512d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2752f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
27532d747510SLisandro Dalcin 
27542d747510SLisandro Dalcin   Not Collective
27552d747510SLisandro Dalcin 
27562d747510SLisandro Dalcin   Input Parameters:
275720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
275820f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
27596b867d5aSJose E. Roman - name    - the option one is seeking
27606b867d5aSJose E. Roman 
2761d8d19677SJose E. Roman   Output Parameters:
27622d747510SLisandro Dalcin + dvalue - the integer values to return
2763f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2764811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
27652d747510SLisandro Dalcin 
27662d747510SLisandro Dalcin   Level: beginner
27672d747510SLisandro Dalcin 
2768811af0c4SBarry Smith   Note:
276920f4b53cSBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`. FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
27702d747510SLisandro Dalcin 
2771db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2772db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2773db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2774c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2775db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2776db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
27772d747510SLisandro Dalcin @*/
2778d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2779d71ae5a4SJacob Faibussowitsch {
27802d747510SLisandro Dalcin   const char *svalue;
27812d747510SLisandro Dalcin   char       *value;
27822d747510SLisandro Dalcin   PetscInt    n = 0;
27832d747510SLisandro Dalcin   PetscBool   flag;
27842d747510SLisandro Dalcin   PetscToken  token;
27852d747510SLisandro Dalcin 
27862d747510SLisandro Dalcin   PetscFunctionBegin;
27872d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
2788064a246eSJacob Faibussowitsch   PetscValidBoolPointer(dvalue, 4);
27892d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
27902d747510SLisandro Dalcin 
27919566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
27929371c9d4SSatish Balay   if (!flag || !svalue) {
27939371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
27949371c9d4SSatish Balay     *nmax = 0;
27953ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
27969371c9d4SSatish Balay   }
27972d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
27989566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
27999566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28002d747510SLisandro Dalcin   while (value && n < *nmax) {
28019566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
28029566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
28032d747510SLisandro Dalcin     dvalue++;
28042d747510SLisandro Dalcin     n++;
28052d747510SLisandro Dalcin   }
28069566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28072d747510SLisandro Dalcin   *nmax = n;
28083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28092d747510SLisandro Dalcin }
28102d747510SLisandro Dalcin 
28112d747510SLisandro Dalcin /*@C
28122d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
28132d747510SLisandro Dalcin 
28142d747510SLisandro Dalcin   Not Collective
28152d747510SLisandro Dalcin 
28162d747510SLisandro Dalcin   Input Parameters:
281720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
281820f4b53cSBarry Smith . pre     - option prefix or `NULL`
28192d747510SLisandro Dalcin . name    - option name
28206b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
28216b867d5aSJose E. Roman 
28222d747510SLisandro Dalcin   Output Parameters:
28232d747510SLisandro Dalcin + ivalue - the  enum values to return
2824f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2825811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
28262d747510SLisandro Dalcin 
28272d747510SLisandro Dalcin   Level: beginner
28282d747510SLisandro Dalcin 
28292d747510SLisandro Dalcin   Notes:
28302d747510SLisandro Dalcin   The array must be passed as a comma separated list.
28312d747510SLisandro Dalcin 
28322d747510SLisandro Dalcin   There must be no intervening spaces between the values.
28332d747510SLisandro Dalcin 
2834811af0c4SBarry Smith   list is usually something like `PCASMTypes` or some other predefined list of enum names.
28352d747510SLisandro Dalcin 
2836db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2837db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2838*aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsName()`,
2839c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2840db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2841db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
28422d747510SLisandro Dalcin @*/
2843d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const *list, PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
2844d71ae5a4SJacob Faibussowitsch {
28452d747510SLisandro Dalcin   const char *svalue;
28462d747510SLisandro Dalcin   char       *value;
28472d747510SLisandro Dalcin   PetscInt    n = 0;
28482d747510SLisandro Dalcin   PetscEnum   evalue;
28492d747510SLisandro Dalcin   PetscBool   flag;
28502d747510SLisandro Dalcin   PetscToken  token;
28512d747510SLisandro Dalcin 
28522d747510SLisandro Dalcin   PetscFunctionBegin;
28532d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
28542d747510SLisandro Dalcin   PetscValidPointer(list, 4);
28552d747510SLisandro Dalcin   PetscValidPointer(ivalue, 5);
28562d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 6);
28572d747510SLisandro Dalcin 
28589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28599371c9d4SSatish Balay   if (!flag || !svalue) {
28609371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28619371c9d4SSatish Balay     *nmax = 0;
28623ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
28639371c9d4SSatish Balay   }
28642d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28659566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28669566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28672d747510SLisandro Dalcin   while (value && n < *nmax) {
28689566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
286928b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
28702d747510SLisandro Dalcin     ivalue[n++] = evalue;
28719566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
28722d747510SLisandro Dalcin   }
28739566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28742d747510SLisandro Dalcin   *nmax = n;
28753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28762d747510SLisandro Dalcin }
28772d747510SLisandro Dalcin 
28782d747510SLisandro Dalcin /*@C
2879f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
28802d747510SLisandro Dalcin 
28812d747510SLisandro Dalcin   Not Collective
28822d747510SLisandro Dalcin 
28832d747510SLisandro Dalcin   Input Parameters:
288420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
288520f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
28866b867d5aSJose E. Roman - name    - the option one is seeking
28876b867d5aSJose E. Roman 
2888d8d19677SJose E. Roman   Output Parameters:
28892d747510SLisandro Dalcin + ivalue - the integer values to return
2890f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2891811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
28922d747510SLisandro Dalcin 
28932d747510SLisandro Dalcin   Level: beginner
28942d747510SLisandro Dalcin 
28952d747510SLisandro Dalcin   Notes:
28962d747510SLisandro Dalcin   The array can be passed as
2897811af0c4SBarry Smith +  a comma separated list -                                 0,1,2,3,4,5,6,7
2898811af0c4SBarry Smith .  a range (start\-end+1) -                                 0-8
2899811af0c4SBarry Smith .  a range with given increment (start\-end+1:inc) -        0-7:2
2900811af0c4SBarry Smith -  a combination of values and ranges separated by commas - 0,1-8,8-15:2
29012d747510SLisandro Dalcin 
29022d747510SLisandro Dalcin   There must be no intervening spaces between the values.
29032d747510SLisandro Dalcin 
2904db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2905db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2906db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2907c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2908db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2909db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29102d747510SLisandro Dalcin @*/
2911d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
2912d71ae5a4SJacob Faibussowitsch {
29132d747510SLisandro Dalcin   const char *svalue;
29142d747510SLisandro Dalcin   char       *value;
29152d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
29162d747510SLisandro Dalcin   size_t      len;
29172d747510SLisandro Dalcin   PetscBool   flag, foundrange;
29182d747510SLisandro Dalcin   PetscToken  token;
29192d747510SLisandro Dalcin 
29202d747510SLisandro Dalcin   PetscFunctionBegin;
29212d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
29222d747510SLisandro Dalcin   PetscValidIntPointer(ivalue, 4);
29232d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
29242d747510SLisandro Dalcin 
29259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29269371c9d4SSatish Balay   if (!flag || !svalue) {
29279371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29289371c9d4SSatish Balay     *nmax = 0;
29293ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29309371c9d4SSatish Balay   }
29312d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29329566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29339566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29342d747510SLisandro Dalcin   while (value && n < *nmax) {
29352d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
29362d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
29379566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value, &len));
29382d747510SLisandro Dalcin     if (value[0] == '-') i = 2;
29392d747510SLisandro Dalcin     else i = 1;
29402d747510SLisandro Dalcin     for (; i < (int)len; i++) {
29412d747510SLisandro Dalcin       if (value[i] == '-') {
2942cc73adaaSBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
29432d747510SLisandro Dalcin         value[i] = 0;
29442d747510SLisandro Dalcin 
29459566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value, &start));
29462d747510SLisandro Dalcin         inc = 1;
29472d747510SLisandro Dalcin         j   = i + 1;
29482d747510SLisandro Dalcin         for (; j < (int)len; j++) {
29492d747510SLisandro Dalcin           if (value[j] == ':') {
29502d747510SLisandro Dalcin             value[j] = 0;
29512d747510SLisandro Dalcin 
29529566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value + j + 1, &inc));
295308401ef6SPierre 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);
29542d747510SLisandro Dalcin             break;
29552d747510SLisandro Dalcin           }
29562d747510SLisandro Dalcin         }
29579566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
295808401ef6SPierre 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);
29592d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
2960cc73adaaSBarry 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);
29612d747510SLisandro Dalcin         for (; start < end; start += inc) {
29629371c9d4SSatish Balay           *ivalue = start;
29639371c9d4SSatish Balay           ivalue++;
29649371c9d4SSatish Balay           n++;
29652d747510SLisandro Dalcin         }
29662d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
29672d747510SLisandro Dalcin         break;
29682d747510SLisandro Dalcin       }
29692d747510SLisandro Dalcin     }
29702d747510SLisandro Dalcin     if (!foundrange) {
29719566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
29722d747510SLisandro Dalcin       ivalue++;
29732d747510SLisandro Dalcin       n++;
29742d747510SLisandro Dalcin     }
29759566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29762d747510SLisandro Dalcin   }
29779566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29782d747510SLisandro Dalcin   *nmax = n;
29793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29802d747510SLisandro Dalcin }
29812d747510SLisandro Dalcin 
29822d747510SLisandro Dalcin /*@C
29832d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
2984f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
29852d747510SLisandro Dalcin 
29862d747510SLisandro Dalcin   Not Collective
29872d747510SLisandro Dalcin 
29882d747510SLisandro Dalcin   Input Parameters:
298920f4b53cSBarry Smith + options - options database, use `NULL` for default global database
299020f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
29916b867d5aSJose E. Roman - name    - the option one is seeking
29926b867d5aSJose E. Roman 
29932d747510SLisandro Dalcin   Output Parameters:
29942d747510SLisandro Dalcin + dvalue - the double values to return
2995f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2996811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
29972d747510SLisandro Dalcin 
29982d747510SLisandro Dalcin   Level: beginner
29992d747510SLisandro Dalcin 
3000db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3001db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3002db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3003c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3004db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3005db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30062d747510SLisandro Dalcin @*/
3007d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
3008d71ae5a4SJacob Faibussowitsch {
30092d747510SLisandro Dalcin   const char *svalue;
30102d747510SLisandro Dalcin   char       *value;
30112d747510SLisandro Dalcin   PetscInt    n = 0;
30122d747510SLisandro Dalcin   PetscBool   flag;
30132d747510SLisandro Dalcin   PetscToken  token;
30142d747510SLisandro Dalcin 
30152d747510SLisandro Dalcin   PetscFunctionBegin;
30162d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
30172d747510SLisandro Dalcin   PetscValidRealPointer(dvalue, 4);
30182d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
30192d747510SLisandro Dalcin 
30209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30219371c9d4SSatish Balay   if (!flag || !svalue) {
30229371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30239371c9d4SSatish Balay     *nmax = 0;
30243ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
30259371c9d4SSatish Balay   }
30262d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30279566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30289566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30292d747510SLisandro Dalcin   while (value && n < *nmax) {
30309566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
30319566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30322d747510SLisandro Dalcin     n++;
30332d747510SLisandro Dalcin   }
30349566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30352d747510SLisandro Dalcin   *nmax = n;
30363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30372d747510SLisandro Dalcin }
30382d747510SLisandro Dalcin 
30392d747510SLisandro Dalcin /*@C
30402d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
3041f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
30422d747510SLisandro Dalcin 
30432d747510SLisandro Dalcin   Not Collective
30442d747510SLisandro Dalcin 
30452d747510SLisandro Dalcin   Input Parameters:
304620f4b53cSBarry Smith + options - options database, use `NULL` for default global database
304720f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
30486b867d5aSJose E. Roman - name    - the option one is seeking
30496b867d5aSJose E. Roman 
30502d747510SLisandro Dalcin   Output Parameters:
30512d747510SLisandro Dalcin + dvalue - the scalar values to return
3052f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3053811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
30542d747510SLisandro Dalcin 
30552d747510SLisandro Dalcin   Level: beginner
30562d747510SLisandro Dalcin 
3057db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3058db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3059db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3060c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3061db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3062db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30632d747510SLisandro Dalcin @*/
3064d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3065d71ae5a4SJacob Faibussowitsch {
30662d747510SLisandro Dalcin   const char *svalue;
30672d747510SLisandro Dalcin   char       *value;
30682d747510SLisandro Dalcin   PetscInt    n = 0;
30692d747510SLisandro Dalcin   PetscBool   flag;
30702d747510SLisandro Dalcin   PetscToken  token;
30712d747510SLisandro Dalcin 
30722d747510SLisandro Dalcin   PetscFunctionBegin;
30732d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
3074064a246eSJacob Faibussowitsch   PetscValidScalarPointer(dvalue, 4);
30752d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
30762d747510SLisandro Dalcin 
30779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30789371c9d4SSatish Balay   if (!flag || !svalue) {
30799371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30809371c9d4SSatish Balay     *nmax = 0;
30813ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
30829371c9d4SSatish Balay   }
30832d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30849566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30859566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30862d747510SLisandro Dalcin   while (value && n < *nmax) {
30879566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value, dvalue++));
30889566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30892d747510SLisandro Dalcin     n++;
30902d747510SLisandro Dalcin   }
30919566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30922d747510SLisandro Dalcin   *nmax = n;
30933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30942d747510SLisandro Dalcin }
309514ce751eSBarry Smith 
3096e5c89e4eSSatish Balay /*@C
3097e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
3098f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
3099e5c89e4eSSatish Balay 
3100cf53795eSBarry Smith   Not Collective; No Fortran Support
3101e5c89e4eSSatish Balay 
3102e5c89e4eSSatish Balay   Input Parameters:
310320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
310420f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
31056b867d5aSJose E. Roman - name    - the option one is seeking
31066b867d5aSJose E. Roman 
3107e7b76fa7SPatrick Sanan   Output Parameters:
3108e5c89e4eSSatish Balay + strings - location to copy strings
3109f1a722f8SMatthew G. Knepley . nmax    - On input maximum number of strings, on output the actual number of strings found
3110811af0c4SBarry Smith - set     - `PETSC_TRUE` if found, else `PETSC_FALSE`
3111e5c89e4eSSatish Balay 
3112e5c89e4eSSatish Balay   Level: beginner
3113e5c89e4eSSatish Balay 
3114e5c89e4eSSatish Balay   Notes:
3115e7b76fa7SPatrick Sanan   The nmax parameter is used for both input and output.
3116e7b76fa7SPatrick Sanan 
3117e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
3118e5c89e4eSSatish Balay   strings returned by this function.
3119e5c89e4eSSatish Balay 
3120e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3121cf53795eSBarry Smith   returned.
3122e5c89e4eSSatish Balay 
3123db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3124db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3125db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3126c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3127db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3128db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3129e5c89e4eSSatish Balay @*/
3130d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set)
3131d71ae5a4SJacob Faibussowitsch {
31322d747510SLisandro Dalcin   const char *svalue;
3133e5c89e4eSSatish Balay   char       *value;
31342d747510SLisandro Dalcin   PetscInt    n = 0;
3135ace3abfcSBarry Smith   PetscBool   flag;
31369c9d3cfdSBarry Smith   PetscToken  token;
3137e5c89e4eSSatish Balay 
3138e5c89e4eSSatish Balay   PetscFunctionBegin;
31392d747510SLisandro Dalcin   PetscValidCharPointer(name, 3);
31402d747510SLisandro Dalcin   PetscValidPointer(strings, 4);
31412d747510SLisandro Dalcin   PetscValidIntPointer(nmax, 5);
3142e5c89e4eSSatish Balay 
31439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
31449371c9d4SSatish Balay   if (!flag || !svalue) {
31459371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
31469371c9d4SSatish Balay     *nmax = 0;
31473ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
31489371c9d4SSatish Balay   }
31492d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31509566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31519566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31522d747510SLisandro Dalcin   while (value && n < *nmax) {
31539566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
31549566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3155e5c89e4eSSatish Balay     n++;
3156e5c89e4eSSatish Balay   }
31579566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3158e5c89e4eSSatish Balay   *nmax = n;
31593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3160e5c89e4eSSatish Balay }
316106824ed3SPatrick Sanan 
316206824ed3SPatrick Sanan /*@C
3163*aec76313SJacob Faibussowitsch   PetscOptionsDeprecated_Private - mark an option as deprecated, optionally replacing it with `newname`
316406824ed3SPatrick Sanan 
316506824ed3SPatrick Sanan   Prints a deprecation warning, unless an option is supplied to suppress.
316606824ed3SPatrick Sanan 
31671c9f3c13SBarry Smith   Logically Collective
316806824ed3SPatrick Sanan 
316906824ed3SPatrick Sanan   Input Parameters:
3170*aec76313SJacob Faibussowitsch + PetscOptionsObject - string to prepend to name or `NULL`
317106824ed3SPatrick Sanan . oldname            - the old, deprecated option
317220f4b53cSBarry Smith . newname            - the new option, or `NULL` if option is purely removed
31739f3a6782SPatrick Sanan . version            - a string describing the version of first deprecation, e.g. "3.9"
317420f4b53cSBarry Smith - info               - additional information string, or `NULL`.
317506824ed3SPatrick Sanan 
3176811af0c4SBarry Smith   Options Database Key:
317706824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
317806824ed3SPatrick Sanan 
317920f4b53cSBarry Smith   Level: developer
318020f4b53cSBarry Smith 
318106824ed3SPatrick Sanan   Notes:
31824ead3382SBarry Smith   If `newname` is provided then the options database will automatically check the database for `oldname`.
31834ead3382SBarry Smith 
31844ead3382SBarry Smith   The old call `PetscOptionsXXX`(`oldname`) should be removed from the source code when both (1) the call to `PetscOptionsDeprecated()` occurs before the
31854ead3382SBarry Smith   new call to `PetscOptionsXXX`(`newname`) and (2) the argument handling of the new call to `PetscOptionsXXX`(`newname`) is identical to the previous call.
31864ead3382SBarry Smith   See `PTScotch_PartGraph_Seq()` for an example of when (1) fails and `SNESTestJacobian()` where an example of (2) fails.
31874ead3382SBarry Smith 
3188811af0c4SBarry Smith   Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
318935cb6cd3SPierre Jolivet   Only the process of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3190811af0c4SBarry Smith   `PetscObjectOptionsBegin()` prints the information
3191b40114eaSPatrick Sanan   If newname is provided, the old option is replaced. Otherwise, it remains
3192b40114eaSPatrick Sanan   in the options database.
31939f3a6782SPatrick Sanan   If an option is not replaced, the info argument should be used to advise the user
31949f3a6782SPatrick Sanan   on how to proceed.
31959f3a6782SPatrick Sanan   There is a limit on the length of the warning printed, so very long strings
31969f3a6782SPatrick Sanan   provided as info may be truncated.
319706824ed3SPatrick Sanan 
3198db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
319906824ed3SPatrick Sanan @*/
3200d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3201d71ae5a4SJacob Faibussowitsch {
320206824ed3SPatrick Sanan   PetscBool         found, quiet;
320306824ed3SPatrick Sanan   const char       *value;
320406824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
32059f3a6782SPatrick Sanan   char              msg[4096];
3206b0bdc838SStefano Zampini   char             *prefix  = NULL;
3207b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3208b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
320906824ed3SPatrick Sanan 
321006824ed3SPatrick Sanan   PetscFunctionBegin;
321106824ed3SPatrick Sanan   PetscValidCharPointer(oldname, 2);
321206824ed3SPatrick Sanan   PetscValidCharPointer(version, 4);
3213b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3214b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3215b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3216b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3217b0bdc838SStefano Zampini   }
32189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
321906824ed3SPatrick Sanan   if (found) {
322006824ed3SPatrick Sanan     if (newname) {
32211baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
32229566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options, newname, value));
32231baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
32249566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3225b40114eaSPatrick Sanan     }
322606824ed3SPatrick Sanan     quiet = PETSC_FALSE;
32279566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
322806824ed3SPatrick Sanan     if (!quiet) {
3229c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option ", sizeof(msg)));
3230c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, oldname, sizeof(msg)));
3231c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3232c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
32334bd3d7f8SBarry Smith       PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
323406824ed3SPatrick Sanan       if (newname) {
32354bd3d7f8SBarry Smith         PetscCall(PetscStrlcat(msg, "   Use the option ", sizeof(msg)));
3236c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, newname, sizeof(msg)));
3237c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
323806824ed3SPatrick Sanan       }
32399f3a6782SPatrick Sanan       if (info) {
3240c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3241c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
32429f3a6782SPatrick Sanan       }
3243c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3244c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3245c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
32469566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
324706824ed3SPatrick Sanan     }
324806824ed3SPatrick Sanan   }
32493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
325006824ed3SPatrick Sanan }
3251