xref: /petsc/src/sys/objects/options.c (revision ffeef943c8ee50edff320d8a3135bb0c94853e4c)
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;
1564f572ea9SToby Isaac   PetscAssertPointer(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 
172aec76313SJacob Faibussowitsch .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsSetValue()`
1732d747510SLisandro Dalcin @*/
174d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
175d71ae5a4SJacob Faibussowitsch {
176362febeeSStefano Zampini   PetscFunctionBegin;
1774f572ea9SToby Isaac   PetscAssertPointer(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 
216aec76313SJacob 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 
23742747ad1SJacob Faibussowitsch .seealso: `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 
269cc4c1da9SBarry Smith /*@
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
28110450e9eSJacob Faibussowitsch 
28210450e9eSJacob Faibussowitsch .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`
2833fc1eb6aSBarry Smith @*/
284d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid)
285d71ae5a4SJacob Faibussowitsch {
286f603b5e9SToby Isaac   char               *ptr;
28727304958SStefano Zampini   PETSC_UNUSED double d;
2887c5db45bSBarry Smith 
28996fc60bcSBarry Smith   PetscFunctionBegin;
2904f572ea9SToby Isaac   if (key) PetscAssertPointer(key, 1);
2914f572ea9SToby Isaac   PetscAssertPointer(valid, 2);
2922d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2933ba16761SJacob Faibussowitsch   if (!key) PetscFunctionReturn(PETSC_SUCCESS);
2943ba16761SJacob Faibussowitsch   if (key[0] != '-') PetscFunctionReturn(PETSC_SUCCESS);
2952d747510SLisandro Dalcin   if (key[1] == '-') key++;
2963ba16761SJacob Faibussowitsch   if (!isalpha((int)key[1])) PetscFunctionReturn(PETSC_SUCCESS);
29727304958SStefano Zampini   d = strtod(key, &ptr);
2983ba16761SJacob Faibussowitsch   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(PETSC_SUCCESS);
2992d747510SLisandro Dalcin   *valid = PETSC_TRUE;
3003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30196fc60bcSBarry Smith }
30296fc60bcSBarry Smith 
30310c654e6SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertString_Private(PetscOptions options, const char in_str[], PetscOptionSource source)
304d71ae5a4SJacob Faibussowitsch {
305d06005cbSLisandro Dalcin   char      *first, *second;
3069c9d3cfdSBarry Smith   PetscToken token;
307e5c89e4eSSatish Balay 
308e5c89e4eSSatish Balay   PetscFunctionBegin;
3099566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(in_str, ' ', &token));
3109566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &first));
31196fc60bcSBarry Smith   while (first) {
312d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
31310c654e6SJacob Faibussowitsch 
3149566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
3159566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
3169566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
3179566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
3189566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
3199566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(first, &key));
320d06005cbSLisandro Dalcin     if (!key) {
3219566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
322d06005cbSLisandro Dalcin     } else if (isfile) {
3239566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
32410c654e6SJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(PETSC_COMM_SELF, options, second, PETSC_TRUE));
3259566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
326d06005cbSLisandro Dalcin     } else if (isfileyaml) {
3279566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
32810c654e6SJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(PETSC_COMM_SELF, options, second, PETSC_TRUE));
3299566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
330d06005cbSLisandro Dalcin     } else if (isstringyaml) {
3319566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3329355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, second, source));
3339566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
334d06005cbSLisandro Dalcin     } else if (ispush) {
3359566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3369566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, second));
3379566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
3389db968c8SJed Brown     } else if (ispop) {
3399566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
3409566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &first));
341d06005cbSLisandro Dalcin     } else {
3429566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &second));
3439566063dSJacob Faibussowitsch       PetscCall(PetscOptionsValidKey(second, &key));
34496fc60bcSBarry Smith       if (!key) {
3459355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, second, NULL, source));
3469566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &first));
34796fc60bcSBarry Smith       } else {
3489355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, first, NULL, NULL, source));
34996fc60bcSBarry Smith         first = second;
35096fc60bcSBarry Smith       }
351e5c89e4eSSatish Balay     }
352e5c89e4eSSatish Balay   }
3539566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
355e5c89e4eSSatish Balay }
356e5c89e4eSSatish Balay 
3579355ec05SMatthew G. Knepley /*@C
3589355ec05SMatthew G. Knepley   PetscOptionsInsertString - Inserts options into the database from a string
3599355ec05SMatthew G. Knepley 
3609355ec05SMatthew G. Knepley   Logically Collective
3619355ec05SMatthew G. Knepley 
3629355ec05SMatthew G. Knepley   Input Parameters:
3639355ec05SMatthew G. Knepley + options - options object
3649355ec05SMatthew G. Knepley - in_str  - string that contains options separated by blanks
3659355ec05SMatthew G. Knepley 
3669355ec05SMatthew G. Knepley   Level: intermediate
3679355ec05SMatthew G. Knepley 
36820f4b53cSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
3699355ec05SMatthew G. Knepley   have the affect of these options. If some processes that create objects call this routine and others do
3709355ec05SMatthew G. Knepley   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
3719355ec05SMatthew G. Knepley   on different ranks.
3729355ec05SMatthew G. Knepley 
3739355ec05SMatthew G. Knepley    Contributed by Boyana Norris
3749355ec05SMatthew G. Knepley 
3759355ec05SMatthew G. Knepley .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
3769355ec05SMatthew G. Knepley           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3779355ec05SMatthew G. Knepley           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3789355ec05SMatthew G. Knepley           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3799355ec05SMatthew G. Knepley           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3809355ec05SMatthew G. Knepley           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
3819355ec05SMatthew G. Knepley @*/
3829355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[])
3839355ec05SMatthew G. Knepley {
3849355ec05SMatthew G. Knepley   PetscFunctionBegin;
3859355ec05SMatthew G. Knepley   PetscCall(PetscOptionsInsertString_Private(options, in_str, PETSC_OPT_CODE));
3863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3879355ec05SMatthew G. Knepley }
3889355ec05SMatthew G. Knepley 
3893fc1eb6aSBarry Smith /*
3903fc1eb6aSBarry Smith     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
3913fc1eb6aSBarry Smith */
392d71ae5a4SJacob Faibussowitsch static char *Petscgetline(FILE *f)
393d71ae5a4SJacob Faibussowitsch {
3945fa91da5SBarry Smith   size_t size = 0;
3955fa91da5SBarry Smith   size_t len  = 0;
3965fa91da5SBarry Smith   size_t last = 0;
3970298fd71SBarry Smith   char  *buf  = NULL;
3985fa91da5SBarry Smith 
39902c9f0b5SLisandro Dalcin   if (feof(f)) return NULL;
4005fa91da5SBarry Smith   do {
4015fa91da5SBarry Smith     size += 1024;                             /* BUFSIZ is defined as "the optimal read size for this platform" */
4026e0c8459SSatish Balay     buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
4035fa91da5SBarry Smith     /* Actually do the read. Note that fgets puts a terminal '\0' on the
4045fa91da5SBarry Smith     end of the string, so we make sure we overwrite this */
405e86f3e45SDave May     if (!fgets(buf + len, 1024, f)) buf[len] = 0;
4063ba16761SJacob Faibussowitsch     PetscCallAbort(PETSC_COMM_SELF, PetscStrlen(buf, &len));
4075fa91da5SBarry Smith     last = len - 1;
4085fa91da5SBarry Smith   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
40908ac41f7SSatish Balay   if (len) return buf;
4105fa91da5SBarry Smith   free(buf);
41102c9f0b5SLisandro Dalcin   return NULL;
4125fa91da5SBarry Smith }
4135fa91da5SBarry Smith 
414d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml)
415d71ae5a4SJacob Faibussowitsch {
416be10d61cSLisandro Dalcin   char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
417e5c89e4eSSatish Balay 
418be10d61cSLisandro Dalcin   PetscFunctionBegin;
419362febeeSStefano Zampini   *yaml = PETSC_FALSE;
4209566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
4219566063dSJacob Faibussowitsch   PetscCall(PetscFixFilename(fname, path));
4229566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(path, ":yaml", yaml));
423be10d61cSLisandro Dalcin   if (*yaml) {
4249566063dSJacob Faibussowitsch     PetscCall(PetscStrrchr(path, ':', &tail));
425be10d61cSLisandro Dalcin     tail[-1] = 0; /* remove ":yaml" suffix from path */
426be10d61cSLisandro Dalcin   }
4279566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
428a1d2f846SLisandro Dalcin   /* check for standard YAML and JSON filename extensions */
4299566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
4309566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
4319566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
432a1d2f846SLisandro Dalcin   if (!*yaml) { /* check file contents */
433a1d2f846SLisandro Dalcin     PetscMPIInt rank;
4349566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
435dd400576SPatrick Sanan     if (rank == 0) {
436a1d2f846SLisandro Dalcin       FILE *fh = fopen(filename, "r");
437a1d2f846SLisandro Dalcin       if (fh) {
438a1d2f846SLisandro Dalcin         char buf[6] = "";
439a1d2f846SLisandro Dalcin         if (fread(buf, 1, 6, fh) > 0) {
4409566063dSJacob Faibussowitsch           PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml));          /* check for '%YAML' tag */
4419566063dSJacob Faibussowitsch           if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
442a1d2f846SLisandro Dalcin         }
443a1d2f846SLisandro Dalcin         (void)fclose(fh);
444a1d2f846SLisandro Dalcin       }
445a1d2f846SLisandro Dalcin     }
4469566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(yaml, 1, MPIU_BOOL, 0, comm));
447a1d2f846SLisandro Dalcin   }
4483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
449be10d61cSLisandro Dalcin }
450e5c89e4eSSatish Balay 
451d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
452d71ae5a4SJacob Faibussowitsch {
4538c0b561eSLisandro Dalcin   char       *string, *vstring = NULL, *astring = NULL, *packed = NULL;
4547fb43599SVaclav Hapla   char       *tokens[4];
45513e3f751SJed Brown   size_t      i, len, bytes;
456e5c89e4eSSatish Balay   FILE       *fd;
4577fb43599SVaclav Hapla   PetscToken  token = NULL;
458ed9cf6e9SBarry Smith   int         err;
459bbcf679cSJacob Faibussowitsch   char       *cmatch = NULL;
460581bbe83SVaclav Hapla   const char  cmt    = '#';
4619210b8eaSVaclav Hapla   PetscInt    line   = 1;
4623a018368SJed Brown   PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
4639210b8eaSVaclav Hapla   PetscBool   isdir, alias = PETSC_FALSE, valid;
464e5c89e4eSSatish Balay 
465e5c89e4eSSatish Balay   PetscFunctionBegin;
4669566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tokens, sizeof(tokens)));
4679566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
468dd400576SPatrick Sanan   if (rank == 0) {
4698c0b561eSLisandro Dalcin     char fpath[PETSC_MAX_PATH_LEN];
4708c0b561eSLisandro Dalcin     char fname[PETSC_MAX_PATH_LEN];
47105c7dedfSBarry Smith 
4729566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
4739566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
4748c0b561eSLisandro Dalcin 
475e5c89e4eSSatish Balay     fd = fopen(fname, "r");
4769566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname, 'r', &isdir));
47708401ef6SPierre Jolivet     PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
478ad38b122SPatrick Sanan     if (fd && !isdir) {
4793a018368SJed Brown       PetscSegBuffer vseg, aseg;
4809566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
4819566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
4823a018368SJed Brown 
4839b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4849566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
485e24ecc5dSJed Brown 
4865fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4874704e885SBarry Smith         /* eliminate comments from each line */
4889566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string, cmt, &cmatch));
48990f79514SSatish Balay         if (cmatch) *cmatch = 0;
4909566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string, &len));
4915981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
492e5c89e4eSSatish Balay         for (i = 0; i < len; i++) {
493ad540459SPierre Jolivet           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
494e5c89e4eSSatish Balay         }
4959566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string, ' ', &token));
4969566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token, &tokens[0]));
4977fb43599SVaclav Hapla         if (!tokens[0]) {
49802b0d46eSSatish Balay           goto destroy;
4997fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
5009566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token, &tokens[0]));
50190f79514SSatish Balay         }
50248a46eb9SPierre Jolivet         for (i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
5037fb43599SVaclav Hapla         if (!tokens[0]) {
5042662f744SSatish Balay           goto destroy;
5057fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
5069566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0], &valid));
50728b400f6SJacob Faibussowitsch           PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": invalid option %s", fname, line, tokens[0]);
5089566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0], &len));
5099566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
5109566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring, tokens[0], len));
511e24ecc5dSJed Brown           vstring[len] = ' ';
5127fb43599SVaclav Hapla           if (tokens[1]) {
5139566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
51428b400f6SJacob Faibussowitsch             PetscCheck(!valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": cannot specify two options per line (%s %s)", fname, line, tokens[0], tokens[1]);
5159566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5169566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
517e24ecc5dSJed Brown             vstring[0] = '"';
5189566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
519e24ecc5dSJed Brown             vstring[len + 1] = '"';
520e24ecc5dSJed Brown             vstring[len + 2] = ' ';
52109192fe3SBarry Smith           }
52290f79514SSatish Balay         } else {
5239566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
5249210b8eaSVaclav Hapla           if (alias) {
5259566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1], &valid));
52628b400f6SJacob Faibussowitsch             PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": invalid aliased option %s", fname, line, tokens[1]);
52708401ef6SPierre Jolivet             PetscCheck(tokens[2], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": alias missing for %s", fname, line, tokens[1]);
5289566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2], &valid));
52928b400f6SJacob Faibussowitsch             PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": invalid aliasee option %s", fname, line, tokens[2]);
5309566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1], &len));
5319566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5329566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[1], len));
533e24ecc5dSJed Brown             astring[len] = ' ';
534e24ecc5dSJed Brown 
5359566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2], &len));
5369566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
5379566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring, tokens[2], len));
538e24ecc5dSJed Brown             astring[len] = ' ';
53998921bdaSJacob Faibussowitsch           } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown first token in options file %s line %" PetscInt_FMT ": %s", fname, line, tokens[0]);
5409210b8eaSVaclav Hapla         }
5419210b8eaSVaclav Hapla         {
5429210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
54328b400f6SJacob Faibussowitsch           PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
544e5c89e4eSSatish Balay         }
54502b0d46eSSatish Balay       destroy:
5464b40f50bSBarry Smith         free(string);
5479566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5489210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5499210b8eaSVaclav Hapla         line++;
550e5c89e4eSSatish Balay       }
551ed9cf6e9SBarry Smith       err = fclose(fd);
55228b400f6SJacob Faibussowitsch       PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
5539566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
5549566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &acnt));
5559566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg, 1, &astring));
556e24ecc5dSJed Brown       astring[0] = 0;
5579566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
5589566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes, &cnt));
5599566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
560e24ecc5dSJed Brown       vstring[0] = 0;
5619566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5629566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg, packed));
5639566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
5649566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5659566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
56628b400f6SJacob Faibussowitsch     } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
5679b754dc9SBarry Smith   }
56805c7dedfSBarry Smith 
5693a018368SJed Brown   counts[0] = acnt;
5703a018368SJed Brown   counts[1] = cnt;
5714201f521SBarry Smith   err       = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
57228b400f6SJacob Faibussowitsch   PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in first MPI collective call, could be caused by using an incorrect mpiexec or a network problem, it can be caused by having VPN running: see https://petsc.org/release/faq/");
5733a018368SJed Brown   acnt = counts[0];
5743a018368SJed Brown   cnt  = counts[1];
57548a46eb9SPierre Jolivet   if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
5763a018368SJed Brown   if (acnt || cnt) {
5779566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
5783a018368SJed Brown     astring = packed;
5793a018368SJed Brown     vstring = packed + acnt + 1;
5803a018368SJed Brown   }
5813a018368SJed Brown 
5829b754dc9SBarry Smith   if (acnt) {
5839566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring, ' ', &token));
5849566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &tokens[0]));
5857fb43599SVaclav Hapla     while (tokens[0]) {
5869566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[1]));
5879566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
5889566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token, &tokens[0]));
5899b754dc9SBarry Smith     }
5909566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5919b754dc9SBarry Smith   }
5929b754dc9SBarry Smith 
5939355ec05SMatthew G. Knepley   if (cnt) PetscCall(PetscOptionsInsertString_Private(options, vstring, PETSC_OPT_FILE));
5949566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
5953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
596e5c89e4eSSatish Balay }
597e5c89e4eSSatish Balay 
598d06005cbSLisandro Dalcin /*@C
599be10d61cSLisandro Dalcin   PetscOptionsInsertFile - Inserts options into the database from a file.
600be10d61cSLisandro Dalcin 
601be10d61cSLisandro Dalcin   Collective
602be10d61cSLisandro Dalcin 
603d8d19677SJose E. Roman   Input Parameters:
604811af0c4SBarry Smith + comm    - the processes that will share the options (usually `PETSC_COMM_WORLD`)
60520f4b53cSBarry Smith . options - options database, use `NULL` for default global database
606be10d61cSLisandro Dalcin . file    - name of file,
607be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
608be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
609811af0c4SBarry Smith - require - if `PETSC_TRUE` will generate an error if the file does not exist
610be10d61cSLisandro Dalcin 
61120f4b53cSBarry Smith   Level: developer
61220f4b53cSBarry Smith 
613be10d61cSLisandro Dalcin   Notes:
614be10d61cSLisandro Dalcin   Use  # for lines that are comments and which should be ignored.
615811af0c4SBarry Smith   Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
61621532e8aSBarry Smith   such as `-log_view` or `-malloc_debug` are processed properly. This routine only sets options into the options database that will be processed by later
61721532e8aSBarry Smith   calls to `XXXSetFromOptions()`, it should not be used for options listed under PetscInitialize().
61821532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes in comm will
61921532e8aSBarry Smith   have the effect of these options. If some processes that create objects call this routine and others do
620be10d61cSLisandro Dalcin   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
621be10d61cSLisandro Dalcin   on different ranks.
622be10d61cSLisandro Dalcin 
623db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
624db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
625db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
626c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
627db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
628db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
629be10d61cSLisandro Dalcin @*/
630d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
631d71ae5a4SJacob Faibussowitsch {
632be10d61cSLisandro Dalcin   char      filename[PETSC_MAX_PATH_LEN];
633be10d61cSLisandro Dalcin   PetscBool yaml;
634be10d61cSLisandro Dalcin 
635be10d61cSLisandro Dalcin   PetscFunctionBegin;
6369566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
637be10d61cSLisandro Dalcin   if (yaml) {
6389566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
639be10d61cSLisandro Dalcin   } else {
6409566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
641be10d61cSLisandro Dalcin   }
6423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
643be10d61cSLisandro Dalcin }
644be10d61cSLisandro Dalcin 
645be10d61cSLisandro Dalcin /*@C
646d06005cbSLisandro Dalcin   PetscOptionsInsertArgs - Inserts options into the database from a array of strings
647d06005cbSLisandro Dalcin 
648d06005cbSLisandro Dalcin   Logically Collective
649d06005cbSLisandro Dalcin 
650d8d19677SJose E. Roman   Input Parameters:
651d06005cbSLisandro Dalcin + options - options object
6526aad120cSJose E. Roman . argc    - the array length
653d06005cbSLisandro Dalcin - args    - the string array
654d06005cbSLisandro Dalcin 
655d06005cbSLisandro Dalcin   Level: intermediate
656d06005cbSLisandro Dalcin 
657db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
658d06005cbSLisandro Dalcin @*/
659d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, char *args[])
660d71ae5a4SJacob Faibussowitsch {
661d06005cbSLisandro Dalcin   MPI_Comm     comm  = PETSC_COMM_WORLD;
662d06005cbSLisandro Dalcin   int          left  = PetscMax(argc, 0);
663d06005cbSLisandro Dalcin   char *const *eargs = args;
66485079163SJed Brown 
66585079163SJed Brown   PetscFunctionBegin;
66685079163SJed Brown   while (left) {
667d06005cbSLisandro Dalcin     PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
6689566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
6699566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
6709566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
6719566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
6729566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
6739566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0], &key));
674093de6efSBarry Smith     if (!key) {
6759371c9d4SSatish Balay       eargs++;
6769371c9d4SSatish Balay       left--;
677d06005cbSLisandro Dalcin     } else if (isfile) {
678cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
6799566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
6809371c9d4SSatish Balay       eargs += 2;
6819371c9d4SSatish Balay       left -= 2;
682d06005cbSLisandro Dalcin     } else if (isfileyaml) {
683cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
6849566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
6859371c9d4SSatish Balay       eargs += 2;
6869371c9d4SSatish Balay       left -= 2;
687d06005cbSLisandro Dalcin     } else if (isstringyaml) {
688cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
6899355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
6909371c9d4SSatish Balay       eargs += 2;
6919371c9d4SSatish Balay       left -= 2;
692d06005cbSLisandro Dalcin     } else if (ispush) {
69308401ef6SPierre Jolivet       PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
694cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6959566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
6969371c9d4SSatish Balay       eargs += 2;
6979371c9d4SSatish Balay       left -= 2;
698d06005cbSLisandro Dalcin     } else if (ispop) {
6999566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
7009371c9d4SSatish Balay       eargs++;
7019371c9d4SSatish Balay       left--;
7027935c3d8SJed Brown     } else {
7037935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
7049566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
70598b6bf53SJed Brown       if (left < 2 || nextiskey) {
7069355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
7079371c9d4SSatish Balay         eargs++;
7089371c9d4SSatish Balay         left--;
70985079163SJed Brown       } else {
7109355ec05SMatthew G. Knepley         PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
7119371c9d4SSatish Balay         eargs += 2;
7129371c9d4SSatish Balay         left -= 2;
71385079163SJed Brown       }
71485079163SJed Brown     }
7157935c3d8SJed Brown   }
7163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71785079163SJed Brown }
71885079163SJed Brown 
71910c654e6SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], const PetscBool set[], PetscBool *flg)
720d71ae5a4SJacob Faibussowitsch {
721c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
722c5b5d8d5SVaclav Hapla   if (set[opt]) {
7239566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt], flg));
724c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
7253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
726c5b5d8d5SVaclav Hapla }
727c5b5d8d5SVaclav Hapla 
728660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
729d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
730d71ae5a4SJacob Faibussowitsch {
731c5b5d8d5SVaclav Hapla   const char *const *opt = precedentOptions;
732c5b5d8d5SVaclav Hapla   const size_t       n   = PO_NUM;
733c5b5d8d5SVaclav Hapla   size_t             o;
734c5b5d8d5SVaclav Hapla   int                a;
735c5b5d8d5SVaclav Hapla   const char       **val;
7360c99d500SBarry Smith   char             **cval;
737660278c0SBarry Smith   PetscBool         *set, unneeded;
738c5b5d8d5SVaclav Hapla 
739c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7400c99d500SBarry Smith   PetscCall(PetscCalloc2(n, &cval, n, &set));
7410c99d500SBarry Smith   val = (const char **)cval;
742c5b5d8d5SVaclav Hapla 
743c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
74448a46eb9SPierre Jolivet   for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
745c5b5d8d5SVaclav Hapla 
746a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
747c5b5d8d5SVaclav Hapla   for (a = 1; a < argc; a++) {
748c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
749c5b5d8d5SVaclav Hapla 
7509566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a], &valid));
751c5b5d8d5SVaclav Hapla     if (!valid) continue;
752c5b5d8d5SVaclav Hapla     for (o = 0; o < n; o++) {
7539566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
754c5b5d8d5SVaclav Hapla       if (eq) {
755c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
756c5b5d8d5SVaclav Hapla         if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
757c5b5d8d5SVaclav Hapla         else val[o] = args[a + 1];
758c5b5d8d5SVaclav Hapla         break;
759c5b5d8d5SVaclav Hapla       }
760c5b5d8d5SVaclav Hapla     }
761c5b5d8d5SVaclav Hapla   }
762c5b5d8d5SVaclav Hapla 
763c5b5d8d5SVaclav Hapla   /* Process flags */
7649566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
765d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7669566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
767660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
768660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
7699355ec05SMatthew G. Knepley   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
7709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
7719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
7729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
773c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
774c5b5d8d5SVaclav Hapla 
775c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
776660278c0SBarry Smith   for (o = 1; o < n; o++) {
777c5b5d8d5SVaclav Hapla     if (set[o]) {
7789355ec05SMatthew G. Knepley       PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
779d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
780c5b5d8d5SVaclav Hapla     }
781c5b5d8d5SVaclav Hapla   }
7820c99d500SBarry Smith   PetscCall(PetscFree2(cval, set));
783c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
7843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
785c5b5d8d5SVaclav Hapla }
786c5b5d8d5SVaclav Hapla 
787d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
788d71ae5a4SJacob Faibussowitsch {
78939a651e2SJacob Faibussowitsch   PetscFunctionBegin;
7904f572ea9SToby Isaac   PetscAssertPointer(flg, 3);
791c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
792c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
79339a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
794c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i], name)) {
795c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7969566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
797c5b5d8d5SVaclav Hapla         if (*flg) break;
798c5b5d8d5SVaclav Hapla       }
799c5b5d8d5SVaclav Hapla     }
800c5b5d8d5SVaclav Hapla   }
8013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
802c5b5d8d5SVaclav Hapla }
80385079163SJed Brown 
804e5c89e4eSSatish Balay /*@C
805e5c89e4eSSatish Balay   PetscOptionsInsert - Inserts into the options database from the command line,
806e5c89e4eSSatish Balay   the environmental variable and a file.
807e5c89e4eSSatish Balay 
808811af0c4SBarry Smith   Collective on `PETSC_COMM_WORLD`
8091c9f3c13SBarry Smith 
810e5c89e4eSSatish Balay   Input Parameters:
81120f4b53cSBarry Smith + options - options database or `NULL` for the default global database
812c5929fdfSBarry Smith . argc    - count of number of command line arguments
813e5c89e4eSSatish Balay . args    - the command line arguments
814be10d61cSLisandro Dalcin - file    - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
81520f4b53cSBarry Smith           Use `NULL` or empty string to not check for code specific file.
816be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
817c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
818e5c89e4eSSatish Balay 
819081c24baSBoyana Norris   Options Database Keys:
820d06005cbSLisandro Dalcin + -options_file <filename>      - read options from a file
821d06005cbSLisandro Dalcin - -options_file_yaml <filename> - read options from a YAML file
822c5b5d8d5SVaclav Hapla 
82320f4b53cSBarry Smith   Level: advanced
82420f4b53cSBarry Smith 
825811af0c4SBarry Smith   Notes:
82620f4b53cSBarry Smith   Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
827811af0c4SBarry Smith   the user does not typically need to call this routine. `PetscOptionsInsert()`
828811af0c4SBarry Smith   can be called several times, adding additional entries into the database.
829811af0c4SBarry Smith 
830811af0c4SBarry Smith   See `PetscInitialize()` for options related to option database monitoring.
831081c24baSBoyana Norris 
832db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
833db781477SPatrick Sanan           `PetscInitialize()`
834e5c89e4eSSatish Balay @*/
835d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[])
836d71ae5a4SJacob Faibussowitsch {
837d06005cbSLisandro Dalcin   MPI_Comm    comm = PETSC_COMM_WORLD;
838e5c89e4eSSatish Balay   PetscMPIInt rank;
839c5b5d8d5SVaclav Hapla   PetscBool   hasArgs     = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
840c5b5d8d5SVaclav Hapla   PetscBool   skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
841e5c89e4eSSatish Balay 
842e5c89e4eSSatish Balay   PetscFunctionBegin;
84308401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
8449566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
845e5c89e4eSSatish Balay 
846c5b5d8d5SVaclav Hapla   if (!options) {
8479566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
848c5b5d8d5SVaclav Hapla     options = defaultoptions;
849c5b5d8d5SVaclav Hapla   }
850c5b5d8d5SVaclav Hapla   if (hasArgs) {
851c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8529566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
853660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
854c5b5d8d5SVaclav Hapla   }
8554b09e917SBarry Smith   if (file && file[0]) {
8569566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
857c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8589566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
859321366bcSBarry Smith   }
860c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
861be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8629566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
8639566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
864c6a7a370SJeremy L Thompson     if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
8659566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
8669566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
8679566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
868e5c89e4eSSatish Balay   }
869e5c89e4eSSatish Balay 
8702d747510SLisandro Dalcin   /* insert environment options */
871e5c89e4eSSatish Balay   {
8722d747510SLisandro Dalcin     char  *eoptions = NULL;
873e5c89e4eSSatish Balay     size_t len      = 0;
874dd400576SPatrick Sanan     if (rank == 0) {
875e5c89e4eSSatish Balay       eoptions = (char *)getenv("PETSC_OPTIONS");
8769566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
877e5c89e4eSSatish Balay     }
8789566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
879e5c89e4eSSatish Balay     if (len) {
8809566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8819566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
88296fc60bcSBarry Smith       if (rank) eoptions[len] = 0;
8839355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
8849566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
885e5c89e4eSSatish Balay     }
886e5c89e4eSSatish Balay   }
887e5c89e4eSSatish Balay 
888d06005cbSLisandro Dalcin   /* insert YAML environment options */
88956a31166SBarry Smith   {
8909fc438c3SToby Isaac     char  *eoptions = NULL;
8919fc438c3SToby Isaac     size_t len      = 0;
892dd400576SPatrick Sanan     if (rank == 0) {
8939fc438c3SToby Isaac       eoptions = (char *)getenv("PETSC_OPTIONS_YAML");
8949566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions, &len));
8959fc438c3SToby Isaac     }
8969566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
8979fc438c3SToby Isaac     if (len) {
8989566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
8999566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions, len, MPI_CHAR, 0, comm));
9009fc438c3SToby Isaac       if (rank) eoptions[len] = 0;
9019355ec05SMatthew G. Knepley       PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
9029566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
9039fc438c3SToby Isaac     }
9049fc438c3SToby Isaac   }
9053bcbd388SSean Farley 
906c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
9079566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, *args + 1));
908660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
9093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
910e5c89e4eSSatish Balay }
911e5c89e4eSSatish Balay 
912660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
913660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
914e9a33e21SBarry 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"};
915660278c0SBarry Smith 
916d71ae5a4SJacob Faibussowitsch static PetscBool PetscCIOption(const char *name)
917d71ae5a4SJacob Faibussowitsch {
918660278c0SBarry Smith   PetscInt  idx;
919660278c0SBarry Smith   PetscBool found;
920660278c0SBarry Smith 
921660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
9223ba16761SJacob Faibussowitsch   PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
923660278c0SBarry Smith   return found;
924660278c0SBarry Smith }
925660278c0SBarry Smith 
926e5c89e4eSSatish Balay /*@C
92788c29154SBarry Smith   PetscOptionsView - Prints the options that have been loaded. This is
928e5c89e4eSSatish Balay   useful for debugging purposes.
929e5c89e4eSSatish Balay 
930*ffeef943SBarry Smith   Logically Collective, No Fortran Support
931e5c89e4eSSatish Balay 
932d8d19677SJose E. Roman   Input Parameters:
93320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
934811af0c4SBarry Smith - viewer  - must be an `PETSCVIEWERASCII` viewer
935e5c89e4eSSatish Balay 
936e5c89e4eSSatish Balay   Options Database Key:
937811af0c4SBarry Smith . -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
938e5c89e4eSSatish Balay 
93920f4b53cSBarry Smith   Level: advanced
94020f4b53cSBarry Smith 
941811af0c4SBarry Smith   Note:
94221532e8aSBarry Smith   Only the MPI rank 0 of the `MPI_Comm` used to create view prints the option values. Other processes
9431c9f3c13SBarry Smith   may have different values but they are not printed.
9441c9f3c13SBarry Smith 
945db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
946e5c89e4eSSatish Balay @*/
947d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
948d71ae5a4SJacob Faibussowitsch {
949660278c0SBarry Smith   PetscInt  i, N = 0;
95088c29154SBarry Smith   PetscBool isascii;
951e5c89e4eSSatish Balay 
952e5c89e4eSSatish Balay   PetscFunctionBegin;
9532d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
954c5929fdfSBarry Smith   options = options ? options : defaultoptions;
95588c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
95728b400f6SJacob Faibussowitsch   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
95888c29154SBarry Smith 
959660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
960660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
961660278c0SBarry Smith     N++;
962660278c0SBarry Smith   }
963660278c0SBarry Smith 
964660278c0SBarry Smith   if (!N) {
9659566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
9663ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
96730694fe9SBarry Smith   }
9682d747510SLisandro Dalcin 
9699566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
970e5c89e4eSSatish Balay   for (i = 0; i < options->N; i++) {
971660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
972e5c89e4eSSatish Balay     if (options->values[i]) {
9739355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
974e5c89e4eSSatish Balay     } else {
9759355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
976e5c89e4eSSatish Balay     }
9779355ec05SMatthew G. Knepley     PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
978e5c89e4eSSatish Balay   }
9799566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
9803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
981e5c89e4eSSatish Balay }
982e5c89e4eSSatish Balay 
983e11779c2SBarry Smith /*
984e11779c2SBarry Smith    Called by error handlers to print options used in run
985e11779c2SBarry Smith */
986d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftError(void)
987d71ae5a4SJacob Faibussowitsch {
988f4bc716fSBarry Smith   PetscInt i, nopt = 0;
989f4bc716fSBarry Smith 
990f4bc716fSBarry Smith   for (i = 0; i < defaultoptions->N; i++) {
991f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
992f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
993f4bc716fSBarry Smith       nopt++;
994f4bc716fSBarry Smith     }
995f4bc716fSBarry Smith   }
996f4bc716fSBarry Smith   if (nopt) {
9977d44c3adSBarry Smith     PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
998f4bc716fSBarry Smith     for (i = 0; i < defaultoptions->N; i++) {
999f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
1000f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
10013ba16761SJacob 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]]));
10023ba16761SJacob Faibussowitsch         else PetscCall((*PetscErrorPrintf)("  Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
1003f4bc716fSBarry Smith       }
1004f4bc716fSBarry Smith     }
1005f4bc716fSBarry Smith   }
10063ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1007f4bc716fSBarry Smith }
1008f4bc716fSBarry Smith 
1009d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1010d71ae5a4SJacob Faibussowitsch {
1011660278c0SBarry Smith   PetscInt     i, N = 0;
10124416b707SBarry Smith   PetscOptions options = defaultoptions;
1013e11779c2SBarry Smith 
1014660278c0SBarry Smith   for (i = 0; i < options->N; i++) {
1015660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1016660278c0SBarry Smith     N++;
1017660278c0SBarry Smith   }
1018660278c0SBarry Smith 
1019660278c0SBarry Smith   if (N) {
10203ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1021e11779c2SBarry Smith   } else {
10223ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1023e11779c2SBarry Smith   }
1024e11779c2SBarry Smith   for (i = 0; i < options->N; i++) {
1025660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1026e11779c2SBarry Smith     if (options->values[i]) {
10273ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1028e11779c2SBarry Smith     } else {
10293ba16761SJacob Faibussowitsch       PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1030e11779c2SBarry Smith     }
1031e11779c2SBarry Smith   }
10323ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1033e11779c2SBarry Smith }
1034e11779c2SBarry Smith 
1035e5c89e4eSSatish Balay /*@C
103674e0666dSJed Brown   PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
103774e0666dSJed Brown 
10381c9f3c13SBarry Smith   Logically Collective
103974e0666dSJed Brown 
1040d8d19677SJose E. Roman   Input Parameters:
104120f4b53cSBarry Smith + options - options database, or `NULL` for the default global database
1042c5929fdfSBarry Smith - prefix  - The string to append to the existing prefix
10439db968c8SJed Brown 
10449db968c8SJed Brown   Options Database Keys:
10459db968c8SJed Brown + -prefix_push <some_prefix_> - push the given prefix
10469db968c8SJed Brown - -prefix_pop                 - pop the last prefix
10479db968c8SJed Brown 
104820f4b53cSBarry Smith   Level: advanced
104920f4b53cSBarry Smith 
10509db968c8SJed Brown   Notes:
105121532e8aSBarry Smith   It is common to use this in conjunction with `-options_file` as in
10529314d9b7SBarry Smith .vb
10539314d9b7SBarry Smith  -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10549314d9b7SBarry Smith .ve
105521532e8aSBarry Smith   where the files no longer require all options to be prefixed with `-system2_`.
105674e0666dSJed Brown 
105721532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
10581c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
10591c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10601c9f3c13SBarry Smith   on different ranks.
10611c9f3c13SBarry Smith 
1062db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
106374e0666dSJed Brown @*/
1064d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1065d71ae5a4SJacob Faibussowitsch {
106674e0666dSJed Brown   size_t    n;
106774e0666dSJed Brown   PetscInt  start;
10689355ec05SMatthew G. Knepley   char      key[PETSC_MAX_OPTION_NAME + 1];
10692d747510SLisandro Dalcin   PetscBool valid;
107074e0666dSJed Brown 
107174e0666dSJed Brown   PetscFunctionBegin;
10724f572ea9SToby Isaac   PetscAssertPointer(prefix, 2);
1073c5929fdfSBarry Smith   options = options ? options : defaultoptions;
107400045ab3SPierre Jolivet   PetscCheck(options->prefixind < MAXPREFIXES, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum depth of prefix stack %d exceeded, recompile src/sys/objects/options.c with larger value for MAXPREFIXES", MAXPREFIXES);
10752d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10769566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
10779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key, &valid));
10788bf569ecSLisandro 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 */
107928b400f6SJacob 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" : "");
108074e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
10819566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix, &n));
108208401ef6SPierre Jolivet   PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
10839566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
108474e0666dSJed Brown   options->prefixstack[options->prefixind++] = start + n;
10853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108674e0666dSJed Brown }
108774e0666dSJed Brown 
1088c5929fdfSBarry Smith /*@C
1089811af0c4SBarry Smith   PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
109074e0666dSJed Brown 
1091811af0c4SBarry Smith   Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
109274e0666dSJed Brown 
1093811af0c4SBarry Smith   Input Parameter:
109420f4b53cSBarry Smith . options - options database, or `NULL` for the default global database
1095c5929fdfSBarry Smith 
109674e0666dSJed Brown   Level: advanced
109774e0666dSJed Brown 
1098db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
109974e0666dSJed Brown @*/
1100d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1101d71ae5a4SJacob Faibussowitsch {
110274e0666dSJed Brown   PetscInt offset;
110374e0666dSJed Brown 
110474e0666dSJed Brown   PetscFunctionBegin;
1105c5929fdfSBarry Smith   options = options ? options : defaultoptions;
110608401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
110774e0666dSJed Brown   options->prefixind--;
110874e0666dSJed Brown   offset                  = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
110974e0666dSJed Brown   options->prefix[offset] = 0;
11103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
111174e0666dSJed Brown }
111274e0666dSJed Brown 
1113a542b6e8SBarry Smith /*@C
1114a542b6e8SBarry Smith   PetscOptionsClear - Removes all options form the database leaving it empty.
1115a542b6e8SBarry Smith 
11161c9f3c13SBarry Smith   Logically Collective
11171c9f3c13SBarry Smith 
1118811af0c4SBarry Smith   Input Parameter:
111920f4b53cSBarry Smith . options - options database, use `NULL` for the default global database
1120c5929fdfSBarry Smith 
112120f4b53cSBarry Smith   Level: developer
112220f4b53cSBarry Smith 
112320f4b53cSBarry Smith   Note:
112421532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11251c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11261c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11271c9f3c13SBarry Smith   on different ranks.
11281c9f3c13SBarry Smith 
1129db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1130a542b6e8SBarry Smith @*/
1131d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClear(PetscOptions options)
1132d71ae5a4SJacob Faibussowitsch {
1133a542b6e8SBarry Smith   PetscInt i;
1134a542b6e8SBarry Smith 
113539a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1136c5929fdfSBarry Smith   options = options ? options : defaultoptions;
11373ba16761SJacob Faibussowitsch   if (!options) PetscFunctionReturn(PETSC_SUCCESS);
11382d747510SLisandro Dalcin 
1139a542b6e8SBarry Smith   for (i = 0; i < options->N; i++) {
1140a542b6e8SBarry Smith     if (options->names[i]) free(options->names[i]);
1141a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1142a542b6e8SBarry Smith   }
11432d747510SLisandro Dalcin   options->N = 0;
11449355ec05SMatthew G. Knepley   free(options->names);
11459355ec05SMatthew G. Knepley   free(options->values);
11469355ec05SMatthew G. Knepley   free(options->used);
11479355ec05SMatthew G. Knepley   free(options->source);
11489355ec05SMatthew G. Knepley   options->names  = NULL;
11499355ec05SMatthew G. Knepley   options->values = NULL;
11509355ec05SMatthew G. Knepley   options->used   = NULL;
11519355ec05SMatthew G. Knepley   options->source = NULL;
11529355ec05SMatthew G. Knepley   options->Nalloc = 0;
11532d747510SLisandro Dalcin 
11549355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
1155a542b6e8SBarry Smith     free(options->aliases1[i]);
1156a542b6e8SBarry Smith     free(options->aliases2[i]);
1157a542b6e8SBarry Smith   }
11589355ec05SMatthew G. Knepley   options->Na = 0;
11599355ec05SMatthew G. Knepley   free(options->aliases1);
11609355ec05SMatthew G. Knepley   free(options->aliases2);
11619355ec05SMatthew G. Knepley   options->aliases1 = options->aliases2 = NULL;
11629355ec05SMatthew G. Knepley   options->Naalloc                      = 0;
1163a542b6e8SBarry Smith 
11642d747510SLisandro Dalcin   /* destroy hash table */
11652d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
11662d747510SLisandro Dalcin   options->ht = NULL;
11670eb63584SBarry Smith 
11682d747510SLisandro Dalcin   options->prefixind  = 0;
11692d747510SLisandro Dalcin   options->prefix[0]  = 0;
11702d747510SLisandro Dalcin   options->help       = PETSC_FALSE;
11719355ec05SMatthew G. Knepley   options->help_intro = PETSC_FALSE;
11723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11734416b707SBarry Smith }
11744416b707SBarry Smith 
11752d747510SLisandro Dalcin /*@C
11762d747510SLisandro Dalcin   PetscOptionsSetAlias - Makes a key and alias for another key
11772d747510SLisandro Dalcin 
11781c9f3c13SBarry Smith   Logically Collective
11792d747510SLisandro Dalcin 
11802d747510SLisandro Dalcin   Input Parameters:
118120f4b53cSBarry Smith + options - options database, or `NULL` for default global database
11822d747510SLisandro Dalcin . newname - the alias
11832d747510SLisandro Dalcin - oldname - the name that alias will refer to
11842d747510SLisandro Dalcin 
11852d747510SLisandro Dalcin   Level: advanced
11862d747510SLisandro Dalcin 
118720f4b53cSBarry Smith   Note:
118821532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
11891c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
11901c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11911c9f3c13SBarry Smith   on different ranks.
11921c9f3c13SBarry Smith 
1193c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1194c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1195db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1196c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1197db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1198db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
11992d747510SLisandro Dalcin @*/
1200d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1201d71ae5a4SJacob Faibussowitsch {
12022d747510SLisandro Dalcin   size_t    len;
12039210b8eaSVaclav Hapla   PetscBool valid;
12042d747510SLisandro Dalcin 
12052d747510SLisandro Dalcin   PetscFunctionBegin;
12064f572ea9SToby Isaac   PetscAssertPointer(newname, 2);
12074f572ea9SToby Isaac   PetscAssertPointer(oldname, 3);
12082d747510SLisandro Dalcin   options = options ? options : defaultoptions;
12099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname, &valid));
121028b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
12119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname, &valid));
121228b400f6SJacob Faibussowitsch   PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
12132d747510SLisandro Dalcin 
12149355ec05SMatthew G. Knepley   if (options->Na == options->Naalloc) {
12159355ec05SMatthew G. Knepley     char **tmpA1, **tmpA2;
12162d747510SLisandro Dalcin 
12179355ec05SMatthew G. Knepley     options->Naalloc = PetscMax(4, options->Naalloc * 2);
12189355ec05SMatthew G. Knepley     tmpA1            = (char **)malloc(options->Naalloc * sizeof(char *));
12199355ec05SMatthew G. Knepley     tmpA2            = (char **)malloc(options->Naalloc * sizeof(char *));
12209355ec05SMatthew G. Knepley     for (int i = 0; i < options->Na; ++i) {
12219355ec05SMatthew G. Knepley       tmpA1[i] = options->aliases1[i];
12229355ec05SMatthew G. Knepley       tmpA2[i] = options->aliases2[i];
12239355ec05SMatthew G. Knepley     }
12249355ec05SMatthew G. Knepley     free(options->aliases1);
12259355ec05SMatthew G. Knepley     free(options->aliases2);
12269355ec05SMatthew G. Knepley     options->aliases1 = tmpA1;
12279355ec05SMatthew G. Knepley     options->aliases2 = tmpA2;
12289355ec05SMatthew G. Knepley   }
12299371c9d4SSatish Balay   newname++;
12309371c9d4SSatish Balay   oldname++;
12319566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname, &len));
12329355ec05SMatthew G. Knepley   options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1233c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
12349566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname, &len));
12359355ec05SMatthew G. Knepley   options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1236c6a7a370SJeremy L Thompson   PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
12379355ec05SMatthew G. Knepley   ++options->Na;
12383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12392d747510SLisandro Dalcin }
12404416b707SBarry Smith 
1241e5c89e4eSSatish Balay /*@C
1242e5c89e4eSSatish Balay   PetscOptionsSetValue - Sets an option name-value pair in the options
1243e5c89e4eSSatish Balay   database, overriding whatever is already present.
1244e5c89e4eSSatish Balay 
12451c9f3c13SBarry Smith   Logically Collective
1246e5c89e4eSSatish Balay 
1247e5c89e4eSSatish Balay   Input Parameters:
124820f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1249c5929fdfSBarry Smith . name    - name of option, this SHOULD have the - prepended
125020f4b53cSBarry Smith - value   - the option value (not used for all options, so can be `NULL`)
1251e5c89e4eSSatish Balay 
1252e5c89e4eSSatish Balay   Level: intermediate
1253e5c89e4eSSatish Balay 
1254e5c89e4eSSatish Balay   Note:
1255811af0c4SBarry Smith   This function can be called BEFORE `PetscInitialize()`
1256d49172ceSBarry Smith 
125721532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
12581c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
12591c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12601c9f3c13SBarry Smith   on different ranks.
12611c9f3c13SBarry Smith 
1262aec76313SJacob Faibussowitsch   Developer Notes:
126320f4b53cSBarry Smith   Uses malloc() directly because PETSc may not be initialized yet.
1264b0250c70SBarry Smith 
1265db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1266e5c89e4eSSatish Balay @*/
1267d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1268d71ae5a4SJacob Faibussowitsch {
126939a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12709355ec05SMatthew G. Knepley   PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
12713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1272c5b5d8d5SVaclav Hapla }
1273c5b5d8d5SVaclav Hapla 
12749355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1275d71ae5a4SJacob Faibussowitsch {
1276e5c89e4eSSatish Balay   size_t    len;
12779355ec05SMatthew G. Knepley   int       n, i;
1278e5c89e4eSSatish Balay   char    **names;
12799355ec05SMatthew G. Knepley   char      fullname[PETSC_MAX_OPTION_NAME] = "";
1280c5b5d8d5SVaclav Hapla   PetscBool flg;
1281e5c89e4eSSatish Balay 
128239a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12837272c0d2SVaclav Hapla   if (!options) {
12849566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12857272c0d2SVaclav Hapla     options = defaultoptions;
1286c5929fdfSBarry Smith   }
128739a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
12882d747510SLisandro Dalcin 
12899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
12903ba16761SJacob Faibussowitsch   if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1291e5c89e4eSSatish Balay 
12922d747510SLisandro Dalcin   name++; /* skip starting dash */
12932d747510SLisandro Dalcin 
129474e0666dSJed Brown   if (options->prefixind > 0) {
1295d49172ceSBarry Smith     strncpy(fullname, options->prefix, sizeof(fullname));
12962d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
129789ae1891SBarry Smith     strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
12982d747510SLisandro Dalcin     fullname[sizeof(fullname) - 1] = 0;
129974e0666dSJed Brown     name                           = fullname;
130074e0666dSJed Brown   }
130174e0666dSJed Brown 
130274e0666dSJed Brown   /* check against aliases */
13039355ec05SMatthew G. Knepley   for (i = 0; i < options->Na; i++) {
13042d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i], name);
13059371c9d4SSatish Balay     if (!result) {
13069371c9d4SSatish Balay       name = options->aliases2[i];
13079371c9d4SSatish Balay       break;
13089371c9d4SSatish Balay     }
1309e5c89e4eSSatish Balay   }
1310e5c89e4eSSatish Balay 
13112d747510SLisandro Dalcin   /* slow search */
13129355ec05SMatthew G. Knepley   n     = options->N;
1313e5c89e4eSSatish Balay   names = options->names;
13149355ec05SMatthew G. Knepley   for (i = 0; i < options->N; i++) {
13152d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
13162d747510SLisandro Dalcin     if (!result) {
13179371c9d4SSatish Balay       n = i;
13189371c9d4SSatish Balay       goto setvalue;
13192d747510SLisandro Dalcin     } else if (result > 0) {
13209371c9d4SSatish Balay       n = i;
13219371c9d4SSatish Balay       break;
1322e5c89e4eSSatish Balay     }
1323e5c89e4eSSatish Balay   }
13249355ec05SMatthew G. Knepley   if (options->N == options->Nalloc) {
13259355ec05SMatthew G. Knepley     char             **names, **values;
13269355ec05SMatthew G. Knepley     PetscBool         *used;
13279355ec05SMatthew G. Knepley     PetscOptionSource *source;
13289355ec05SMatthew G. Knepley 
13299355ec05SMatthew G. Knepley     options->Nalloc = PetscMax(10, options->Nalloc * 2);
13309355ec05SMatthew G. Knepley     names           = (char **)malloc(options->Nalloc * sizeof(char *));
13319355ec05SMatthew G. Knepley     values          = (char **)malloc(options->Nalloc * sizeof(char *));
13329355ec05SMatthew G. Knepley     used            = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
13339355ec05SMatthew G. Knepley     source          = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
13349355ec05SMatthew G. Knepley     for (int i = 0; i < options->N; ++i) {
13359355ec05SMatthew G. Knepley       names[i]  = options->names[i];
13369355ec05SMatthew G. Knepley       values[i] = options->values[i];
13379355ec05SMatthew G. Knepley       used[i]   = options->used[i];
13389355ec05SMatthew G. Knepley       source[i] = options->source[i];
13399355ec05SMatthew G. Knepley     }
13409355ec05SMatthew G. Knepley     free(options->names);
13419355ec05SMatthew G. Knepley     free(options->values);
13429355ec05SMatthew G. Knepley     free(options->used);
13439355ec05SMatthew G. Knepley     free(options->source);
13449355ec05SMatthew G. Knepley     options->names  = names;
13459355ec05SMatthew G. Knepley     options->values = values;
13469355ec05SMatthew G. Knepley     options->used   = used;
13479355ec05SMatthew G. Knepley     options->source = source;
13489355ec05SMatthew G. Knepley   }
134939a651e2SJacob Faibussowitsch 
13502d747510SLisandro Dalcin   /* shift remaining values up 1 */
13519355ec05SMatthew G. Knepley   for (i = options->N; i > n; i--) {
13525e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i - 1];
1353e5c89e4eSSatish Balay     options->values[i] = options->values[i - 1];
1354e5c89e4eSSatish Balay     options->used[i]   = options->used[i - 1];
13559355ec05SMatthew G. Knepley     options->source[i] = options->source[i - 1];
1356e5c89e4eSSatish Balay   }
13572d747510SLisandro Dalcin   options->names[n]  = NULL;
13582d747510SLisandro Dalcin   options->values[n] = NULL;
13592d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
13609355ec05SMatthew G. Knepley   options->source[n] = PETSC_OPT_CODE;
13612d747510SLisandro Dalcin   options->N++;
13622d747510SLisandro Dalcin 
13632d747510SLisandro Dalcin   /* destroy hash table */
13642d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
13652d747510SLisandro Dalcin   options->ht = NULL;
13662d747510SLisandro Dalcin 
13672d747510SLisandro Dalcin   /* set new name */
136870d8d27cSBarry Smith   len               = strlen(name);
13695e8c5e88SLisandro Dalcin   options->names[n] = (char *)malloc((len + 1) * sizeof(char));
137039a651e2SJacob Faibussowitsch   PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1371d49172ceSBarry Smith   strcpy(options->names[n], name);
13722d747510SLisandro Dalcin 
13732d747510SLisandro Dalcin setvalue:
13742d747510SLisandro Dalcin   /* set new value */
13752d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1376d49172ceSBarry Smith   len = value ? strlen(value) : 0;
13775e8c5e88SLisandro Dalcin   if (len) {
1378e5c89e4eSSatish Balay     options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1379d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1380d49172ceSBarry Smith     strcpy(options->values[n], value);
13812d747510SLisandro Dalcin   } else {
13822d747510SLisandro Dalcin     options->values[n] = NULL;
13832d747510SLisandro Dalcin   }
13849355ec05SMatthew G. Knepley   options->source[n] = source;
13852d747510SLisandro Dalcin 
138691ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
138791ad3481SVaclav Hapla   if (!PetscOptNameCmp(name, "help")) {
138891ad3481SVaclav Hapla     options->help       = PETSC_TRUE;
1389d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
139091ad3481SVaclav Hapla     options->used[n]    = PETSC_TRUE;
139191ad3481SVaclav Hapla   }
139291ad3481SVaclav Hapla 
13939355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, value, source));
1394c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
13953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1396e5c89e4eSSatish Balay }
1397e5c89e4eSSatish Balay 
1398e5c89e4eSSatish Balay /*@C
1399e5c89e4eSSatish Balay   PetscOptionsClearValue - Clears an option name-value pair in the options
1400e5c89e4eSSatish Balay   database, overriding whatever is already present.
1401e5c89e4eSSatish Balay 
14021c9f3c13SBarry Smith   Logically Collective
1403e5c89e4eSSatish Balay 
1404d8d19677SJose E. Roman   Input Parameters:
140520f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
1406a2b725a8SWilliam Gropp - name    - name of option, this SHOULD have the - prepended
1407e5c89e4eSSatish Balay 
1408e5c89e4eSSatish Balay   Level: intermediate
1409e5c89e4eSSatish Balay 
1410811af0c4SBarry Smith   Note:
141121532e8aSBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
14121c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
14131c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
14141c9f3c13SBarry Smith   on different ranks.
14151c9f3c13SBarry Smith 
1416db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1417e5c89e4eSSatish Balay @*/
1418d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1419d71ae5a4SJacob Faibussowitsch {
14202d747510SLisandro Dalcin   int    N, n, i;
14212d747510SLisandro Dalcin   char **names;
1422e5c89e4eSSatish Balay 
1423e5c89e4eSSatish Balay   PetscFunctionBegin;
1424c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1425cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1426c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
14272d747510SLisandro Dalcin 
14282d747510SLisandro Dalcin   name++; /* skip starting dash */
14292d747510SLisandro Dalcin 
14302d747510SLisandro Dalcin   /* slow search */
14312d747510SLisandro Dalcin   N = n = options->N;
1432e5c89e4eSSatish Balay   names = options->names;
1433e5c89e4eSSatish Balay   for (i = 0; i < N; i++) {
14342d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i], name);
14352d747510SLisandro Dalcin     if (!result) {
14369371c9d4SSatish Balay       n = i;
14379371c9d4SSatish Balay       break;
14382d747510SLisandro Dalcin     } else if (result > 0) {
14399371c9d4SSatish Balay       n = N;
14409371c9d4SSatish Balay       break;
1441e5c89e4eSSatish Balay     }
14422d747510SLisandro Dalcin   }
14433ba16761SJacob Faibussowitsch   if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1444e5c89e4eSSatish Balay 
14452d747510SLisandro Dalcin   /* remove name and value */
14462d747510SLisandro Dalcin   if (options->names[n]) free(options->names[n]);
14472d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1448e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1449e5c89e4eSSatish Balay   for (i = n; i < N - 1; i++) {
14505e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i + 1];
1451e5c89e4eSSatish Balay     options->values[i] = options->values[i + 1];
1452e5c89e4eSSatish Balay     options->used[i]   = options->used[i + 1];
14539355ec05SMatthew G. Knepley     options->source[i] = options->source[i + 1];
1454e5c89e4eSSatish Balay   }
1455e5c89e4eSSatish Balay   options->N--;
14562d747510SLisandro Dalcin 
14572d747510SLisandro Dalcin   /* destroy hash table */
14582d747510SLisandro Dalcin   kh_destroy(HO, options->ht);
14592d747510SLisandro Dalcin   options->ht = NULL;
14602d747510SLisandro Dalcin 
14619355ec05SMatthew G. Knepley   PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
14623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1463e5c89e4eSSatish Balay }
1464e5c89e4eSSatish Balay 
1465e5c89e4eSSatish Balay /*@C
14662d747510SLisandro Dalcin   PetscOptionsFindPair - Gets an option name-value pair from the options database.
1467e5c89e4eSSatish Balay 
14682d747510SLisandro Dalcin   Not Collective
1469e5c89e4eSSatish Balay 
1470e5c89e4eSSatish Balay   Input Parameters:
147120f4b53cSBarry Smith + options - options database, use `NULL` for the default global database
147220f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
14732d747510SLisandro Dalcin - name    - name of option, this SHOULD have the "-" prepended
1474e5c89e4eSSatish Balay 
14752d747510SLisandro Dalcin   Output Parameters:
14762d747510SLisandro Dalcin + value - the option value (optional, not used for all options)
14772d747510SLisandro Dalcin - set   - whether the option is set (optional)
1478e5c89e4eSSatish Balay 
147920f4b53cSBarry Smith   Level: developer
148020f4b53cSBarry Smith 
1481811af0c4SBarry Smith   Note:
14829666a313SBarry Smith   Each process may find different values or no value depending on how options were inserted into the database
14831c9f3c13SBarry Smith 
1484db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1485e5c89e4eSSatish Balay @*/
1486d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1487d71ae5a4SJacob Faibussowitsch {
14889355ec05SMatthew G. Knepley   char      buf[PETSC_MAX_OPTION_NAME];
1489daabea38SBarry Smith   PetscBool usehashtable = PETSC_TRUE;
14902d747510SLisandro Dalcin   PetscBool matchnumbers = PETSC_TRUE;
1491e5c89e4eSSatish Balay 
1492e5c89e4eSSatish Balay   PetscFunctionBegin;
1493c5929fdfSBarry Smith   options = options ? options : defaultoptions;
149408401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1495cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1496e5c89e4eSSatish Balay 
14972d747510SLisandro Dalcin   name++; /* skip starting dash */
1498e5c89e4eSSatish Balay 
14997cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
15002d747510SLisandro Dalcin   if (pre && pre[0]) {
15012d747510SLisandro Dalcin     char *ptr = buf;
15029371c9d4SSatish Balay     if (name[0] == '-') {
15039371c9d4SSatish Balay       *ptr++ = '-';
15049371c9d4SSatish Balay       name++;
15059371c9d4SSatish Balay     }
15069566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
15079566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
15082d747510SLisandro Dalcin     name = buf;
15097cd08cecSJed Brown   }
15102d747510SLisandro Dalcin 
151176bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
15122f828895SJed Brown     PetscBool valid;
15139355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
15149566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
15159566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
151628b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
15172f828895SJed Brown   }
1518e5c89e4eSSatish Balay 
15192d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
15202d747510SLisandro Dalcin     int          i, ret;
15212d747510SLisandro Dalcin     khiter_t     it;
15222d747510SLisandro Dalcin     khash_t(HO) *ht;
15232d747510SLisandro Dalcin     ht = kh_init(HO);
152428b400f6SJacob Faibussowitsch     PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15252d747510SLisandro Dalcin     ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
152628b400f6SJacob Faibussowitsch     PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15272d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
15282d747510SLisandro Dalcin       it = kh_put(HO, ht, options->names[i], &ret);
152908401ef6SPierre Jolivet       PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
15302d747510SLisandro Dalcin       kh_val(ht, it) = i;
15312d747510SLisandro Dalcin     }
15322d747510SLisandro Dalcin     options->ht = ht;
15332d747510SLisandro Dalcin   }
15342d747510SLisandro Dalcin 
15359371c9d4SSatish Balay   if (usehashtable) { /* fast search */
15362d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
15372d747510SLisandro Dalcin     khiter_t     it = kh_get(HO, ht, name);
15382d747510SLisandro Dalcin     if (it != kh_end(ht)) {
15392d747510SLisandro Dalcin       int i            = kh_val(ht, it);
1540e5c89e4eSSatish Balay       options->used[i] = PETSC_TRUE;
15412d747510SLisandro Dalcin       if (value) *value = options->values[i];
15422d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
15433ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
15442d747510SLisandro Dalcin     }
15459371c9d4SSatish Balay   } else { /* slow search */
15462d747510SLisandro Dalcin     int i, N = options->N;
15472d747510SLisandro Dalcin     for (i = 0; i < N; i++) {
1548daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i], name);
15492d747510SLisandro Dalcin       if (!result) {
15502d747510SLisandro Dalcin         options->used[i] = PETSC_TRUE;
15512d747510SLisandro Dalcin         if (value) *value = options->values[i];
15522d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
15533ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15542d747510SLisandro Dalcin       } else if (result > 0) {
1555e5c89e4eSSatish Balay         break;
1556e5c89e4eSSatish Balay       }
1557e5c89e4eSSatish Balay     }
15582d747510SLisandro Dalcin   }
15592d747510SLisandro Dalcin 
15602d747510SLisandro Dalcin   /*
15612d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
15622d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
15632d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
15642d747510SLisandro Dalcin    */
15652d747510SLisandro Dalcin   if (matchnumbers) {
15662d747510SLisandro Dalcin     int i, j, cnt = 0, locs[16], loce[16];
1567e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
15682d747510SLisandro Dalcin     for (i = 0; name[i]; i++) {
15692d747510SLisandro Dalcin       if (name[i] == '_') {
15702d747510SLisandro Dalcin         for (j = i + 1; name[j]; j++) {
15712d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
15722d747510SLisandro Dalcin           if (name[j] == '_' && j > i + 1) { /* found a number */
1573e5c89e4eSSatish Balay             locs[cnt]   = i + 1;
1574e5c89e4eSSatish Balay             loce[cnt++] = j + 1;
1575e5c89e4eSSatish Balay           }
15762d747510SLisandro Dalcin           i = j - 1;
1577e5c89e4eSSatish Balay           break;
1578e5c89e4eSSatish Balay         }
1579e5c89e4eSSatish Balay       }
1580e5c89e4eSSatish Balay     }
1581e5c89e4eSSatish Balay     for (i = 0; i < cnt; i++) {
15822d747510SLisandro Dalcin       PetscBool found;
15839355ec05SMatthew G. Knepley       char      opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
15849566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
15859566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
15869566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
15879566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
15889371c9d4SSatish Balay       if (found) {
15899371c9d4SSatish Balay         if (set) *set = PETSC_TRUE;
15903ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
15919371c9d4SSatish Balay       }
1592e5c89e4eSSatish Balay     }
1593e5c89e4eSSatish Balay   }
15942d747510SLisandro Dalcin 
15952d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
15963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1597e5c89e4eSSatish Balay }
1598e5c89e4eSSatish Balay 
1599d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
160054a546c1SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *option[], const char *value[], PetscBool *set)
1601d71ae5a4SJacob Faibussowitsch {
16029355ec05SMatthew G. Knepley   char buf[PETSC_MAX_OPTION_NAME];
1603d6ced9c0SMatthew G. Knepley   int  numCnt = 0, locs[16], loce[16];
1604514bf10dSMatthew G Knepley 
1605514bf10dSMatthew G Knepley   PetscFunctionBegin;
1606c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1607cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1608cc73adaaSBarry Smith   PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1609514bf10dSMatthew G Knepley 
16102d747510SLisandro Dalcin   name++; /* skip starting dash */
1611514bf10dSMatthew G Knepley 
1612514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
16132d747510SLisandro Dalcin   if (pre && pre[0]) {
16142d747510SLisandro Dalcin     char *ptr = buf;
16159371c9d4SSatish Balay     if (name[0] == '-') {
16169371c9d4SSatish Balay       *ptr++ = '-';
16179371c9d4SSatish Balay       name++;
16189371c9d4SSatish Balay     }
16199b15cf9aSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
16209566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
16212d747510SLisandro Dalcin     name = buf;
1622514bf10dSMatthew G Knepley   }
16232d747510SLisandro Dalcin 
162476bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1625514bf10dSMatthew G Knepley     PetscBool valid;
16269355ec05SMatthew G. Knepley     char      key[PETSC_MAX_OPTION_NAME + 1] = "-";
16279566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
16289566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key, &valid));
162928b400f6SJacob Faibussowitsch     PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1630514bf10dSMatthew G Knepley   }
1631514bf10dSMatthew G Knepley 
1632d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1633d6ced9c0SMatthew G. Knepley   {
1634d6ced9c0SMatthew G. Knepley     int i, j;
1635d6ced9c0SMatthew G. Knepley     for (i = 0; name[i]; i++) {
1636d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1637d6ced9c0SMatthew G. Knepley         for (j = i + 1; name[j]; j++) {
1638d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1639d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i + 1) { /* found a number */
1640d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i + 1;
1641d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j + 1;
1642d6ced9c0SMatthew G. Knepley           }
1643d6ced9c0SMatthew G. Knepley           i = j - 1;
1644d6ced9c0SMatthew G. Knepley           break;
1645d6ced9c0SMatthew G. Knepley         }
1646d6ced9c0SMatthew G. Knepley       }
1647d6ced9c0SMatthew G. Knepley     }
1648d6ced9c0SMatthew G. Knepley   }
1649d6ced9c0SMatthew G. Knepley 
1650363da2dcSJacob Faibussowitsch   /* slow search */
1651363da2dcSJacob Faibussowitsch   for (int c = -1; c < numCnt; ++c) {
1652363da2dcSJacob Faibussowitsch     char   opt[PETSC_MAX_OPTION_NAME + 2] = "";
16532d747510SLisandro Dalcin     size_t len;
1654d6ced9c0SMatthew G. Knepley 
1655d6ced9c0SMatthew G. Knepley     if (c < 0) {
1656c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1657d6ced9c0SMatthew G. Knepley     } else {
1658363da2dcSJacob Faibussowitsch       PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1659363da2dcSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1660d6ced9c0SMatthew G. Knepley     }
16619566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(opt, &len));
1662363da2dcSJacob Faibussowitsch     for (int i = 0; i < options->N; i++) {
1663363da2dcSJacob Faibussowitsch       PetscBool match;
1664363da2dcSJacob Faibussowitsch 
16659566063dSJacob Faibussowitsch       PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1666514bf10dSMatthew G Knepley       if (match) {
1667514bf10dSMatthew G Knepley         options->used[i] = PETSC_TRUE;
166854a546c1SMatthew G. Knepley         if (option) *option = options->names[i];
16692d747510SLisandro Dalcin         if (value) *value = options->values[i];
16702d747510SLisandro Dalcin         if (set) *set = PETSC_TRUE;
16713ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
1672514bf10dSMatthew G Knepley       }
1673514bf10dSMatthew G Knepley     }
16742d747510SLisandro Dalcin   }
16752d747510SLisandro Dalcin 
16762d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
16773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1678514bf10dSMatthew G Knepley }
1679514bf10dSMatthew G Knepley 
1680e5c89e4eSSatish Balay /*@C
1681e5c89e4eSSatish Balay   PetscOptionsReject - Generates an error if a certain option is given.
1682e5c89e4eSSatish Balay 
16831c9f3c13SBarry Smith   Not Collective
1684e5c89e4eSSatish Balay 
1685e5c89e4eSSatish Balay   Input Parameters:
168620f4b53cSBarry Smith + options - options database, use `NULL` for default global database
168720f4b53cSBarry Smith . pre     - the option prefix (may be `NULL`)
16882d747510SLisandro Dalcin . name    - the option name one is seeking
168920f4b53cSBarry Smith - mess    - error message (may be `NULL`)
1690e5c89e4eSSatish Balay 
1691e5c89e4eSSatish Balay   Level: advanced
1692e5c89e4eSSatish Balay 
1693c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1694db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1695db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1696c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1697db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1698db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1699e5c89e4eSSatish Balay @*/
1700d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1701d71ae5a4SJacob Faibussowitsch {
1702ace3abfcSBarry Smith   PetscBool flag = PETSC_FALSE;
1703e5c89e4eSSatish Balay 
1704e5c89e4eSSatish Balay   PetscFunctionBegin;
17059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1706e5c89e4eSSatish Balay   if (flag) {
170708401ef6SPierre 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);
1708f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1709e5c89e4eSSatish Balay   }
17103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1711e5c89e4eSSatish Balay }
1712e5c89e4eSSatish Balay 
1713e5c89e4eSSatish Balay /*@C
17142d747510SLisandro Dalcin   PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
17152d747510SLisandro Dalcin 
17162d747510SLisandro Dalcin   Not Collective
17172d747510SLisandro Dalcin 
1718811af0c4SBarry Smith   Input Parameter:
171920f4b53cSBarry Smith . options - options database, use `NULL` for default global database
17202d747510SLisandro Dalcin 
1721811af0c4SBarry Smith   Output Parameter:
1722811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
17232d747510SLisandro Dalcin 
17242d747510SLisandro Dalcin   Level: advanced
17252d747510SLisandro Dalcin 
1726db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
17272d747510SLisandro Dalcin @*/
1728d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1729d71ae5a4SJacob Faibussowitsch {
17302d747510SLisandro Dalcin   PetscFunctionBegin;
17314f572ea9SToby Isaac   PetscAssertPointer(set, 2);
17322d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17332d747510SLisandro Dalcin   *set    = options->help;
17343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17352d747510SLisandro Dalcin }
17362d747510SLisandro Dalcin 
1737d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1738d71ae5a4SJacob Faibussowitsch {
1739d314f959SVaclav Hapla   PetscFunctionBegin;
17404f572ea9SToby Isaac   PetscAssertPointer(set, 2);
1741d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1742d314f959SVaclav Hapla   *set    = options->help_intro;
17433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1744d314f959SVaclav Hapla }
1745d314f959SVaclav Hapla 
17462d747510SLisandro Dalcin /*@C
1747e24fcbf7SPierre 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
1748e24fcbf7SPierre Jolivet   if its value is set to false.
1749e5c89e4eSSatish Balay 
1750e5c89e4eSSatish Balay   Not Collective
1751e5c89e4eSSatish Balay 
1752e5c89e4eSSatish Balay   Input Parameters:
175320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
175420f4b53cSBarry Smith . pre     - string to prepend to the name or `NULL`
17553de71b31SHong Zhang - name    - the option one is seeking
1756e5c89e4eSSatish Balay 
1757811af0c4SBarry Smith   Output Parameter:
1758811af0c4SBarry Smith . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1759e5c89e4eSSatish Balay 
1760e5c89e4eSSatish Balay   Level: beginner
1761e5c89e4eSSatish Balay 
1762811af0c4SBarry Smith   Note:
1763811af0c4SBarry Smith   In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
176490d69ab7SBarry Smith 
1765db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1766db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1767db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1768c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1769db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1770db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1771e5c89e4eSSatish Balay @*/
1772d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1773d71ae5a4SJacob Faibussowitsch {
17742d747510SLisandro Dalcin   const char *value;
1775ace3abfcSBarry Smith   PetscBool   flag;
1776e5c89e4eSSatish Balay 
1777e5c89e4eSSatish Balay   PetscFunctionBegin;
17789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
177996ef3cdfSSatish Balay   if (set) *set = flag;
17803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1781e5c89e4eSSatish Balay }
1782e5c89e4eSSatish Balay 
1783e5c89e4eSSatish Balay /*@C
17842d747510SLisandro Dalcin   PetscOptionsGetAll - Lists all the options the program was run with in a single string.
17852d747510SLisandro Dalcin 
17862d747510SLisandro Dalcin   Not Collective
17872d747510SLisandro Dalcin 
1788fd292e60Sprj-   Input Parameter:
178920f4b53cSBarry Smith . options - the options database, use `NULL` for the default global database
17902d747510SLisandro Dalcin 
17912d747510SLisandro Dalcin   Output Parameter:
17922d747510SLisandro Dalcin . copts - pointer where string pointer is stored
17932d747510SLisandro Dalcin 
179420f4b53cSBarry Smith   Level: advanced
179520f4b53cSBarry Smith 
17962d747510SLisandro Dalcin   Notes:
1797811af0c4SBarry Smith   The array and each entry in the array should be freed with `PetscFree()`
1798811af0c4SBarry Smith 
17991c9f3c13SBarry Smith   Each process may have different values depending on how the options were inserted into the database
18002d747510SLisandro Dalcin 
1801db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
18022d747510SLisandro Dalcin @*/
1803d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[])
1804d71ae5a4SJacob Faibussowitsch {
18052d747510SLisandro Dalcin   PetscInt i;
18062d747510SLisandro Dalcin   size_t   len = 1, lent = 0;
18072d747510SLisandro Dalcin   char    *coptions = NULL;
18082d747510SLisandro Dalcin 
18092d747510SLisandro Dalcin   PetscFunctionBegin;
18104f572ea9SToby Isaac   PetscAssertPointer(copts, 2);
18112d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18122d747510SLisandro Dalcin   /* count the length of the required string */
18132d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18149566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i], &lent));
18152d747510SLisandro Dalcin     len += 2 + lent;
18162d747510SLisandro Dalcin     if (options->values[i]) {
18179566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i], &lent));
18182d747510SLisandro Dalcin       len += 1 + lent;
18192d747510SLisandro Dalcin     }
18202d747510SLisandro Dalcin   }
18219566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &coptions));
18222d747510SLisandro Dalcin   coptions[0] = 0;
18232d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1824c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, "-", len));
1825c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, options->names[i], len));
1826c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(coptions, " ", len));
18272d747510SLisandro Dalcin     if (options->values[i]) {
1828c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, options->values[i], len));
1829c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(coptions, " ", len));
18302d747510SLisandro Dalcin     }
18312d747510SLisandro Dalcin   }
18322d747510SLisandro Dalcin   *copts = coptions;
18333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18342d747510SLisandro Dalcin }
18352d747510SLisandro Dalcin 
18362d747510SLisandro Dalcin /*@C
18372d747510SLisandro Dalcin   PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
18382d747510SLisandro Dalcin 
18392d747510SLisandro Dalcin   Not Collective
18402d747510SLisandro Dalcin 
1841d8d19677SJose E. Roman   Input Parameters:
184220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
18432d747510SLisandro Dalcin - name    - string name of option
18442d747510SLisandro Dalcin 
18452d747510SLisandro Dalcin   Output Parameter:
1846811af0c4SBarry Smith . used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
18472d747510SLisandro Dalcin 
18482d747510SLisandro Dalcin   Level: advanced
18492d747510SLisandro Dalcin 
1850811af0c4SBarry Smith   Note:
18519666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18521c9f3c13SBarry Smith   on the given process
18531c9f3c13SBarry Smith 
1854db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
18552d747510SLisandro Dalcin @*/
1856d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1857d71ae5a4SJacob Faibussowitsch {
18582d747510SLisandro Dalcin   PetscInt i;
18592d747510SLisandro Dalcin 
18602d747510SLisandro Dalcin   PetscFunctionBegin;
18614f572ea9SToby Isaac   PetscAssertPointer(name, 2);
18624f572ea9SToby Isaac   PetscAssertPointer(used, 3);
18632d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18642d747510SLisandro Dalcin   *used   = PETSC_FALSE;
18652d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
18669566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i], name, used));
18672d747510SLisandro Dalcin     if (*used) {
18682d747510SLisandro Dalcin       *used = options->used[i];
18692d747510SLisandro Dalcin       break;
18702d747510SLisandro Dalcin     }
18712d747510SLisandro Dalcin   }
18723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18732d747510SLisandro Dalcin }
18742d747510SLisandro Dalcin 
1875487a658cSBarry Smith /*@
18762d747510SLisandro Dalcin   PetscOptionsAllUsed - Returns a count of the number of options in the
18772d747510SLisandro Dalcin   database that have never been selected.
18782d747510SLisandro Dalcin 
18792d747510SLisandro Dalcin   Not Collective
18802d747510SLisandro Dalcin 
18812d747510SLisandro Dalcin   Input Parameter:
188220f4b53cSBarry Smith . options - options database, use `NULL` for default global database
18832d747510SLisandro Dalcin 
18842d747510SLisandro Dalcin   Output Parameter:
18852d747510SLisandro Dalcin . N - count of options not used
18862d747510SLisandro Dalcin 
18872d747510SLisandro Dalcin   Level: advanced
18882d747510SLisandro Dalcin 
1889811af0c4SBarry Smith   Note:
18909666a313SBarry Smith   The value returned may be different on each process and depends on which options have been processed
18911c9f3c13SBarry Smith   on the given process
18921c9f3c13SBarry Smith 
1893db781477SPatrick Sanan .seealso: `PetscOptionsView()`
18942d747510SLisandro Dalcin @*/
1895d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1896d71ae5a4SJacob Faibussowitsch {
18972d747510SLisandro Dalcin   PetscInt i, n = 0;
18982d747510SLisandro Dalcin 
18992d747510SLisandro Dalcin   PetscFunctionBegin;
19004f572ea9SToby Isaac   PetscAssertPointer(N, 2);
19012d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19022d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
19032d747510SLisandro Dalcin     if (!options->used[i]) n++;
19042d747510SLisandro Dalcin   }
19052d747510SLisandro Dalcin   *N = n;
19063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19072d747510SLisandro Dalcin }
19082d747510SLisandro Dalcin 
1909487a658cSBarry Smith /*@
19102d747510SLisandro Dalcin   PetscOptionsLeft - Prints to screen any options that were set and never used.
19112d747510SLisandro Dalcin 
19122d747510SLisandro Dalcin   Not Collective
19132d747510SLisandro Dalcin 
19142d747510SLisandro Dalcin   Input Parameter:
191520f4b53cSBarry Smith . options - options database; use `NULL` for default global database
19162d747510SLisandro Dalcin 
19172d747510SLisandro Dalcin   Options Database Key:
1918811af0c4SBarry Smith . -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
19192d747510SLisandro Dalcin 
192020f4b53cSBarry Smith   Level: advanced
192120f4b53cSBarry Smith 
19223de2bfdfSBarry Smith   Notes:
1923811af0c4SBarry Smith   This is rarely used directly, it is called by `PetscFinalize()` in debug more or if -options_left
19241c9f3c13SBarry Smith   is passed otherwise to help users determine possible mistakes in their usage of options. This
1925811af0c4SBarry Smith   only prints values on process zero of `PETSC_COMM_WORLD`.
1926811af0c4SBarry Smith 
1927811af0c4SBarry Smith   Other processes depending the objects
19281c9f3c13SBarry Smith   used may have different options that are left unused.
19293de2bfdfSBarry Smith 
1930db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
19312d747510SLisandro Dalcin @*/
1932d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeft(PetscOptions options)
1933d71ae5a4SJacob Faibussowitsch {
19342d747510SLisandro Dalcin   PetscInt     i;
19353de2bfdfSBarry Smith   PetscInt     cnt = 0;
19363de2bfdfSBarry Smith   PetscOptions toptions;
19372d747510SLisandro Dalcin 
19382d747510SLisandro Dalcin   PetscFunctionBegin;
19393de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
19403de2bfdfSBarry Smith   for (i = 0; i < toptions->N; i++) {
19413de2bfdfSBarry Smith     if (!toptions->used[i]) {
1942660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
19433de2bfdfSBarry Smith       if (toptions->values[i]) {
19449355ec05SMatthew 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]]));
19452d747510SLisandro Dalcin       } else {
19469355ec05SMatthew G. Knepley         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
19472d747510SLisandro Dalcin       }
19482d747510SLisandro Dalcin     }
19492d747510SLisandro Dalcin   }
19503de2bfdfSBarry Smith   if (!options) {
19513de2bfdfSBarry Smith     toptions = defaultoptions;
19523de2bfdfSBarry Smith     while (toptions->previous) {
19533de2bfdfSBarry Smith       cnt++;
19543de2bfdfSBarry Smith       toptions = toptions->previous;
19553de2bfdfSBarry Smith     }
195648a46eb9SPierre 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));
19573de2bfdfSBarry Smith   }
19583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19592d747510SLisandro Dalcin }
19602d747510SLisandro Dalcin 
19612d747510SLisandro Dalcin /*@C
19622d747510SLisandro Dalcin   PetscOptionsLeftGet - Returns all options that were set and never used.
19632d747510SLisandro Dalcin 
19642d747510SLisandro Dalcin   Not Collective
19652d747510SLisandro Dalcin 
19662d747510SLisandro Dalcin   Input Parameter:
196720f4b53cSBarry Smith . options - options database, use `NULL` for default global database
19682d747510SLisandro Dalcin 
1969d8d19677SJose E. Roman   Output Parameters:
1970a2b725a8SWilliam Gropp + N      - count of options not used
19712d747510SLisandro Dalcin . names  - names of options not used
1972a2b725a8SWilliam Gropp - values - values of options not used
19732d747510SLisandro Dalcin 
19742d747510SLisandro Dalcin   Level: advanced
19752d747510SLisandro Dalcin 
19762d747510SLisandro Dalcin   Notes:
1977811af0c4SBarry Smith   Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1978811af0c4SBarry Smith 
1979811af0c4SBarry Smith   The value returned may be different on each process and depends on which options have been processed
19801c9f3c13SBarry Smith   on the given process
19812d747510SLisandro Dalcin 
1982db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
19832d747510SLisandro Dalcin @*/
1984d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
1985d71ae5a4SJacob Faibussowitsch {
19862d747510SLisandro Dalcin   PetscInt i, n;
19872d747510SLisandro Dalcin 
19882d747510SLisandro Dalcin   PetscFunctionBegin;
19894f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
19904f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
19914f572ea9SToby Isaac   if (values) PetscAssertPointer(values, 4);
19922d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19932d747510SLisandro Dalcin 
19942d747510SLisandro Dalcin   /* The number of unused PETSc options */
19952d747510SLisandro Dalcin   n = 0;
19962d747510SLisandro Dalcin   for (i = 0; i < options->N; i++) {
1997660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
19982d747510SLisandro Dalcin     if (!options->used[i]) n++;
19992d747510SLisandro Dalcin   }
2000ad540459SPierre Jolivet   if (N) *N = n;
20019566063dSJacob Faibussowitsch   if (names) PetscCall(PetscMalloc1(n, names));
20029566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n, values));
20032d747510SLisandro Dalcin 
20042d747510SLisandro Dalcin   n = 0;
20052d747510SLisandro Dalcin   if (names || values) {
20062d747510SLisandro Dalcin     for (i = 0; i < options->N; i++) {
20072d747510SLisandro Dalcin       if (!options->used[i]) {
2008660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
20092d747510SLisandro Dalcin         if (names) (*names)[n] = options->names[i];
20102d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
20112d747510SLisandro Dalcin         n++;
20122d747510SLisandro Dalcin       }
20132d747510SLisandro Dalcin     }
20142d747510SLisandro Dalcin   }
20153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20162d747510SLisandro Dalcin }
20172d747510SLisandro Dalcin 
20182d747510SLisandro Dalcin /*@C
2019811af0c4SBarry Smith   PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
20202d747510SLisandro Dalcin 
20212d747510SLisandro Dalcin   Not Collective
20222d747510SLisandro Dalcin 
2023d8d19677SJose E. Roman   Input Parameters:
202420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
202510450e9eSJacob Faibussowitsch . N       - count of options not used
20262d747510SLisandro Dalcin . names   - names of options not used
2027a2b725a8SWilliam Gropp - values  - values of options not used
20282d747510SLisandro Dalcin 
20292d747510SLisandro Dalcin   Level: advanced
20302d747510SLisandro Dalcin 
203110450e9eSJacob Faibussowitsch   Notes:
203210450e9eSJacob Faibussowitsch   The user should pass the same pointer to `N` as they did when calling `PetscOptionsLeftGet()`
203310450e9eSJacob Faibussowitsch 
2034db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
20352d747510SLisandro Dalcin @*/
2036d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2037d71ae5a4SJacob Faibussowitsch {
20382d747510SLisandro Dalcin   PetscFunctionBegin;
203910450e9eSJacob Faibussowitsch   (void)options;
20404f572ea9SToby Isaac   if (N) PetscAssertPointer(N, 2);
20414f572ea9SToby Isaac   if (names) PetscAssertPointer(names, 3);
20424f572ea9SToby Isaac   if (values) PetscAssertPointer(values, 4);
2043ad540459SPierre Jolivet   if (N) *N = 0;
20449566063dSJacob Faibussowitsch   if (names) PetscCall(PetscFree(*names));
20459566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
20463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20472d747510SLisandro Dalcin }
20482d747510SLisandro Dalcin 
20492d747510SLisandro Dalcin /*@C
2050811af0c4SBarry Smith   PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
20512d747510SLisandro Dalcin 
2052c3339decSBarry Smith   Logically Collective
20532d747510SLisandro Dalcin 
20542d747510SLisandro Dalcin   Input Parameters:
20552d747510SLisandro Dalcin + name   - option name string
20562d747510SLisandro Dalcin . value  - option value string
20579355ec05SMatthew G. Knepley . source - The source for the option
205820f4b53cSBarry Smith - ctx    - a `PETSCVIEWERASCII` or `NULL`
20592d747510SLisandro Dalcin 
20602d747510SLisandro Dalcin   Level: intermediate
20612d747510SLisandro Dalcin 
20629666a313SBarry Smith   Notes:
206320f4b53cSBarry Smith   If ctx is `NULL`, `PetscPrintf()` is used.
20649314d9b7SBarry Smith   The first MPI process in the `PetscViewer` viewer actually prints the values, other
20651c9f3c13SBarry Smith   processes may have different values set
20661c9f3c13SBarry Smith 
2067811af0c4SBarry Smith   If `PetscCIEnabled` then do not print the test harness options
2068660278c0SBarry Smith 
2069db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
20702d747510SLisandro Dalcin @*/
20719355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], PetscOptionSource source, void *ctx)
2072d71ae5a4SJacob Faibussowitsch {
20732d747510SLisandro Dalcin   PetscFunctionBegin;
20743ba16761SJacob Faibussowitsch   if (PetscCIOption(name)) PetscFunctionReturn(PETSC_SUCCESS);
2075660278c0SBarry Smith 
20769060e2f9SVaclav Hapla   if (ctx) {
20779060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
20782d747510SLisandro Dalcin     if (!value) {
20799566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
20802d747510SLisandro Dalcin     } else if (!value[0]) {
20819355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20822d747510SLisandro Dalcin     } else {
20839355ec05SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20842d747510SLisandro Dalcin     }
20859060e2f9SVaclav Hapla   } else {
20869060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
20879060e2f9SVaclav Hapla     if (!value) {
20889566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
20899060e2f9SVaclav Hapla     } else if (!value[0]) {
20909355ec05SMatthew G. Knepley       PetscCall(PetscPrintf(comm, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
20919060e2f9SVaclav Hapla     } else {
2092aaa8cc7dSPierre Jolivet       PetscCall(PetscPrintf(comm, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
20939060e2f9SVaclav Hapla     }
20949060e2f9SVaclav Hapla   }
20953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20962d747510SLisandro Dalcin }
20972d747510SLisandro Dalcin 
20982d747510SLisandro Dalcin /*@C
20992d747510SLisandro Dalcin   PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
21002d747510SLisandro Dalcin   modified the PETSc options database.
21012d747510SLisandro Dalcin 
21022d747510SLisandro Dalcin   Not Collective
21032d747510SLisandro Dalcin 
21042d747510SLisandro Dalcin   Input Parameters:
210520f4b53cSBarry Smith + monitor        - pointer to function (if this is `NULL`, it turns off monitoring
210610450e9eSJacob Faibussowitsch . mctx           - [optional] context for private data for the monitor routine (use `NULL` if
210710450e9eSJacob Faibussowitsch                    no context is desired)
210810450e9eSJacob Faibussowitsch - monitordestroy - [optional] routine that frees monitor context (may be `NULL`)
21092d747510SLisandro Dalcin 
211010450e9eSJacob Faibussowitsch   Calling sequence of `monitor`:
21112d747510SLisandro Dalcin + name   - option name string
21122d747510SLisandro Dalcin . value  - option value string
21139355ec05SMatthew G. Knepley . source - option source
2114811af0c4SBarry Smith - mctx   - optional monitoring context, as set by `PetscOptionsMonitorSet()`
21152d747510SLisandro Dalcin 
211610450e9eSJacob Faibussowitsch   Calling sequence of `monitordestroy`:
211710450e9eSJacob Faibussowitsch . mctx - [optional] pointer to context to destroy with
21182d747510SLisandro Dalcin 
211920f4b53cSBarry Smith   Level: intermediate
212020f4b53cSBarry Smith 
21212d747510SLisandro Dalcin   Notes:
212210450e9eSJacob Faibussowitsch   See `PetscInitialize()` for options related to option database monitoring.
212310450e9eSJacob Faibussowitsch 
21242d747510SLisandro Dalcin   The default is to do nothing.  To print the name and value of options
2125811af0c4SBarry Smith   being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
21262d747510SLisandro Dalcin   with a null monitoring context.
21272d747510SLisandro Dalcin 
21282d747510SLisandro Dalcin   Several different monitoring routines may be set by calling
2129811af0c4SBarry Smith   `PetscOptionsMonitorSet()` multiple times; all will be called in the
21302d747510SLisandro Dalcin   order in which they were set.
21312d747510SLisandro Dalcin 
2132db781477SPatrick Sanan .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
21332d747510SLisandro Dalcin @*/
213410450e9eSJacob Faibussowitsch PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource source, void *mctx), void *mctx, PetscErrorCode (*monitordestroy)(void **mctx))
2135d71ae5a4SJacob Faibussowitsch {
21362d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
21372d747510SLisandro Dalcin 
21382d747510SLisandro Dalcin   PetscFunctionBegin;
21393ba16761SJacob Faibussowitsch   if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
214008401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
21412d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
21422d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
21432d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void *)mctx;
21443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21452d747510SLisandro Dalcin }
21462d747510SLisandro Dalcin 
21472d747510SLisandro Dalcin /*
21482d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
214963fe8743SVaclav Hapla      Empty string is considered as true.
21502d747510SLisandro Dalcin */
2151d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2152d71ae5a4SJacob Faibussowitsch {
21532d747510SLisandro Dalcin   PetscBool istrue, isfalse;
21542d747510SLisandro Dalcin   size_t    len;
21552d747510SLisandro Dalcin 
21562d747510SLisandro Dalcin   PetscFunctionBegin;
215763fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
21589566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value, &len));
21599371c9d4SSatish Balay   if (!len) {
21609371c9d4SSatish Balay     *a = PETSC_TRUE;
21613ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21629371c9d4SSatish Balay   }
21639566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
21649371c9d4SSatish Balay   if (istrue) {
21659371c9d4SSatish Balay     *a = PETSC_TRUE;
21663ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21679371c9d4SSatish Balay   }
21689566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "YES", &istrue));
21699371c9d4SSatish Balay   if (istrue) {
21709371c9d4SSatish Balay     *a = PETSC_TRUE;
21713ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21729371c9d4SSatish Balay   }
21739566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "1", &istrue));
21749371c9d4SSatish Balay   if (istrue) {
21759371c9d4SSatish Balay     *a = PETSC_TRUE;
21763ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21779371c9d4SSatish Balay   }
21789566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "on", &istrue));
21799371c9d4SSatish Balay   if (istrue) {
21809371c9d4SSatish Balay     *a = PETSC_TRUE;
21813ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21829371c9d4SSatish Balay   }
21839566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
21849371c9d4SSatish Balay   if (isfalse) {
21859371c9d4SSatish Balay     *a = PETSC_FALSE;
21863ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21879371c9d4SSatish Balay   }
21889566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
21899371c9d4SSatish Balay   if (isfalse) {
21909371c9d4SSatish Balay     *a = PETSC_FALSE;
21913ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21929371c9d4SSatish Balay   }
21939566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "0", &isfalse));
21949371c9d4SSatish Balay   if (isfalse) {
21959371c9d4SSatish Balay     *a = PETSC_FALSE;
21963ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
21979371c9d4SSatish Balay   }
21989566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value, "off", &isfalse));
21999371c9d4SSatish Balay   if (isfalse) {
22009371c9d4SSatish Balay     *a = PETSC_FALSE;
22013ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
22029371c9d4SSatish Balay   }
220398921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
22042d747510SLisandro Dalcin }
22052d747510SLisandro Dalcin 
22062d747510SLisandro Dalcin /*
22072d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
22082d747510SLisandro Dalcin */
2209d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2210d71ae5a4SJacob Faibussowitsch {
22112d747510SLisandro Dalcin   size_t    len;
22122d747510SLisandro Dalcin   PetscBool decide, tdefault, mouse;
22132d747510SLisandro Dalcin 
22142d747510SLisandro Dalcin   PetscFunctionBegin;
22159566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
22165f80ce2aSJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
22172d747510SLisandro Dalcin 
22189566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
221948a46eb9SPierre Jolivet   if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
22209566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
222148a46eb9SPierre Jolivet   if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
22229566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
22232d747510SLisandro Dalcin 
22242d747510SLisandro Dalcin   if (tdefault) *a = PETSC_DEFAULT;
22252d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
22262d747510SLisandro Dalcin   else if (mouse) *a = -1;
22272d747510SLisandro Dalcin   else {
22282d747510SLisandro Dalcin     char *endptr;
22292d747510SLisandro Dalcin     long  strtolval;
22302d747510SLisandro Dalcin 
22312d747510SLisandro Dalcin     strtolval = strtol(name, &endptr, 10);
2232cc73adaaSBarry 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);
22332d747510SLisandro Dalcin 
22342d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
22352d747510SLisandro Dalcin     (void)strtolval;
22362d747510SLisandro Dalcin     *a = atoll(name);
22372d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
22382d747510SLisandro Dalcin     (void)strtolval;
22392d747510SLisandro Dalcin     *a = _atoi64(name);
22402d747510SLisandro Dalcin #else
22412d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
22422d747510SLisandro Dalcin #endif
22432d747510SLisandro Dalcin   }
22443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22452d747510SLisandro Dalcin }
22462d747510SLisandro Dalcin 
22472d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22482d747510SLisandro Dalcin   #include <quadmath.h>
22492d747510SLisandro Dalcin #endif
22502d747510SLisandro Dalcin 
2251d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2252d71ae5a4SJacob Faibussowitsch {
22532d747510SLisandro Dalcin   PetscFunctionBegin;
22542d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
22552d747510SLisandro Dalcin   *a = strtoflt128(name, endptr);
22562d747510SLisandro Dalcin #else
22572d747510SLisandro Dalcin   *a = (PetscReal)strtod(name, endptr);
22582d747510SLisandro Dalcin #endif
22593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22602d747510SLisandro Dalcin }
22612d747510SLisandro Dalcin 
2262d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2263d71ae5a4SJacob Faibussowitsch {
22642d747510SLisandro Dalcin   PetscBool hasi = PETSC_FALSE;
22652d747510SLisandro Dalcin   char     *ptr;
22662d747510SLisandro Dalcin   PetscReal strtoval;
22672d747510SLisandro Dalcin 
22682d747510SLisandro Dalcin   PetscFunctionBegin;
22699566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, &strtoval, &ptr));
22702d747510SLisandro Dalcin   if (ptr == name) {
22712d747510SLisandro Dalcin     strtoval = 1.;
22722d747510SLisandro Dalcin     hasi     = PETSC_TRUE;
22732d747510SLisandro Dalcin     if (name[0] == 'i') {
22742d747510SLisandro Dalcin       ptr++;
22752d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
22762d747510SLisandro Dalcin       ptr += 2;
22772d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
22782d747510SLisandro Dalcin       strtoval = -1.;
22792d747510SLisandro Dalcin       ptr += 2;
22802d747510SLisandro Dalcin     }
22812d747510SLisandro Dalcin   } else if (*ptr == 'i') {
22822d747510SLisandro Dalcin     hasi = PETSC_TRUE;
22832d747510SLisandro Dalcin     ptr++;
22842d747510SLisandro Dalcin   }
22852d747510SLisandro Dalcin   *endptr      = ptr;
22862d747510SLisandro Dalcin   *isImaginary = hasi;
22872d747510SLisandro Dalcin   if (hasi) {
22882d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
228998921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
22902d747510SLisandro Dalcin #else
22912d747510SLisandro Dalcin     *a = PetscCMPLX(0., strtoval);
22922d747510SLisandro Dalcin #endif
22932d747510SLisandro Dalcin   } else {
22942d747510SLisandro Dalcin     *a = strtoval;
22952d747510SLisandro Dalcin   }
22963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22972d747510SLisandro Dalcin }
22982d747510SLisandro Dalcin 
22992d747510SLisandro Dalcin /*
23002d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
23012d747510SLisandro Dalcin */
2302d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2303d71ae5a4SJacob Faibussowitsch {
23042d747510SLisandro Dalcin   size_t    len;
23052d747510SLisandro Dalcin   PetscBool match;
23062d747510SLisandro Dalcin   char     *endptr;
23072d747510SLisandro Dalcin 
23082d747510SLisandro Dalcin   PetscFunctionBegin;
23099566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
231028b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
23112d747510SLisandro Dalcin 
23129566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
23139566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
23149371c9d4SSatish Balay   if (match) {
23159371c9d4SSatish Balay     *a = PETSC_DEFAULT;
23163ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23179371c9d4SSatish Balay   }
23182d747510SLisandro Dalcin 
23199566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
23209566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
23219371c9d4SSatish Balay   if (match) {
23229371c9d4SSatish Balay     *a = PETSC_DECIDE;
23233ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
23249371c9d4SSatish Balay   }
23252d747510SLisandro Dalcin 
23269566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name, a, &endptr));
232739a651e2SJacob Faibussowitsch   PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
23283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23292d747510SLisandro Dalcin }
23302d747510SLisandro Dalcin 
2331d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2332d71ae5a4SJacob Faibussowitsch {
23332d747510SLisandro Dalcin   PetscBool   imag1;
23342d747510SLisandro Dalcin   size_t      len;
23352d747510SLisandro Dalcin   PetscScalar val = 0.;
23362d747510SLisandro Dalcin   char       *ptr = NULL;
23372d747510SLisandro Dalcin 
23382d747510SLisandro Dalcin   PetscFunctionBegin;
23399566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name, &len));
234028b400f6SJacob Faibussowitsch   PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
23419566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
23422d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
23432d747510SLisandro Dalcin   if ((size_t)(ptr - name) < len) {
23442d747510SLisandro Dalcin     PetscBool   imag2;
23452d747510SLisandro Dalcin     PetscScalar val2;
23462d747510SLisandro Dalcin 
23479566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
234839a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
23492d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
23502d747510SLisandro Dalcin   }
23512d747510SLisandro Dalcin #endif
235239a651e2SJacob Faibussowitsch   PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
23532d747510SLisandro Dalcin   *a = val;
23543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23552d747510SLisandro Dalcin }
23562d747510SLisandro Dalcin 
23572d747510SLisandro Dalcin /*@C
23582d747510SLisandro Dalcin   PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
23592d747510SLisandro Dalcin   option in the database.
2360e5c89e4eSSatish Balay 
2361e5c89e4eSSatish Balay   Not Collective
2362e5c89e4eSSatish Balay 
2363e5c89e4eSSatish Balay   Input Parameters:
236420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
236520f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2366e5c89e4eSSatish Balay - name    - the option one is seeking
2367e5c89e4eSSatish Balay 
2368d8d19677SJose E. Roman   Output Parameters:
23692d747510SLisandro Dalcin + ivalue - the logical value to return
2370811af0c4SBarry Smith - set    - `PETSC_TRUE`  if found, else `PETSC_FALSE`
2371e5c89e4eSSatish Balay 
2372e5c89e4eSSatish Balay   Level: beginner
2373e5c89e4eSSatish Balay 
237495452b02SPatrick Sanan   Notes:
2375811af0c4SBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`
2376811af0c4SBarry Smith   FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
23772d747510SLisandro Dalcin 
23789314d9b7SBarry 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`
23799314d9b7SBarry Smith   is equivalent to `-requested_bool true`
23802d747510SLisandro Dalcin 
23819314d9b7SBarry Smith   If the user does not supply the option at all `ivalue` is NOT changed. Thus
23829314d9b7SBarry Smith   you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
23832efd9cb1SBarry Smith 
2384db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2385db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2386db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2387c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2388db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2389db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2390e5c89e4eSSatish Balay @*/
2391d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2392d71ae5a4SJacob Faibussowitsch {
23932d747510SLisandro Dalcin   const char *value;
2394ace3abfcSBarry Smith   PetscBool   flag;
2395e5c89e4eSSatish Balay 
2396e5c89e4eSSatish Balay   PetscFunctionBegin;
23974f572ea9SToby Isaac   PetscAssertPointer(name, 3);
23984f572ea9SToby Isaac   if (ivalue) PetscAssertPointer(ivalue, 4);
23999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2400e5c89e4eSSatish Balay   if (flag) {
240196ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
24029566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
24032d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2404e5c89e4eSSatish Balay   } else {
240596ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2406e5c89e4eSSatish Balay   }
24073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2408e5c89e4eSSatish Balay }
2409e5c89e4eSSatish Balay 
2410e5c89e4eSSatish Balay /*@C
2411e5c89e4eSSatish Balay   PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2412e5c89e4eSSatish Balay 
2413e5c89e4eSSatish Balay   Not Collective
2414e5c89e4eSSatish Balay 
2415e5c89e4eSSatish Balay   Input Parameters:
241620f4b53cSBarry Smith + options - options database, use `NULL` for default global database
241720f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2418e5c89e4eSSatish Balay . opt     - option name
2419a264d7a6SBarry Smith . list    - the possible choices (one of these must be selected, anything else is invalid)
2420a2b725a8SWilliam Gropp - ntext   - number of choices
2421e5c89e4eSSatish Balay 
2422d8d19677SJose E. Roman   Output Parameters:
24232efd9cb1SBarry Smith + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2424811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2425e5c89e4eSSatish Balay 
2426e5c89e4eSSatish Balay   Level: intermediate
2427e5c89e4eSSatish Balay 
242895452b02SPatrick Sanan   Notes:
24299314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
24309314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
24312efd9cb1SBarry Smith 
2432811af0c4SBarry Smith   See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2433e5c89e4eSSatish Balay 
2434db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2435db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2436db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2437c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2438db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2439db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2440e5c89e4eSSatish Balay @*/
2441d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscInt ntext, PetscInt *value, PetscBool *set)
2442d71ae5a4SJacob Faibussowitsch {
244358b0ac4eSStefano Zampini   size_t    alen, len = 0, tlen = 0;
2444e5c89e4eSSatish Balay   char     *svalue;
2445ace3abfcSBarry Smith   PetscBool aset, flg = PETSC_FALSE;
2446e5c89e4eSSatish Balay   PetscInt  i;
2447e5c89e4eSSatish Balay 
2448e5c89e4eSSatish Balay   PetscFunctionBegin;
24494f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2450e5c89e4eSSatish Balay   for (i = 0; i < ntext; i++) {
24519566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i], &alen));
2452e5c89e4eSSatish Balay     if (alen > len) len = alen;
245358b0ac4eSStefano Zampini     tlen += len + 1;
2454e5c89e4eSSatish Balay   }
2455e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
24569566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len, &svalue));
24579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2458e5c89e4eSSatish Balay   if (aset) {
24599566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
246058b0ac4eSStefano Zampini     if (!flg) {
2461c6a7a370SJeremy L Thompson       char *avail;
246258b0ac4eSStefano Zampini 
24639566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen, &avail));
2464c6a7a370SJeremy L Thompson       avail[0] = '\0';
246558b0ac4eSStefano Zampini       for (i = 0; i < ntext; i++) {
2466c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, list[i], tlen));
2467c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(avail, " ", tlen));
246858b0ac4eSStefano Zampini       }
24699566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
247098921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option %s for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
247158b0ac4eSStefano Zampini     }
2472fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2473a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
24749566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
24753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2476e5c89e4eSSatish Balay }
2477e5c89e4eSSatish Balay 
2478e5c89e4eSSatish Balay /*@C
2479e5c89e4eSSatish Balay   PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2480e5c89e4eSSatish Balay 
2481e5c89e4eSSatish Balay   Not Collective
2482e5c89e4eSSatish Balay 
2483e5c89e4eSSatish Balay   Input Parameters:
248420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
248520f4b53cSBarry Smith . pre     - option prefix or `NULL`
2486e5c89e4eSSatish Balay . opt     - option name
24876b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2488e5c89e4eSSatish Balay 
2489d8d19677SJose E. Roman   Output Parameters:
2490e5c89e4eSSatish Balay + value - the value to return
2491811af0c4SBarry Smith - set   - `PETSC_TRUE` if found, else `PETSC_FALSE`
2492e5c89e4eSSatish Balay 
2493e5c89e4eSSatish Balay   Level: beginner
2494e5c89e4eSSatish Balay 
249595452b02SPatrick Sanan   Notes:
24969314d9b7SBarry Smith   If the user does not supply the option `value` is NOT changed. Thus
24979314d9b7SBarry Smith   you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2498e5c89e4eSSatish Balay 
24999314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names
2500e5c89e4eSSatish Balay 
2501db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2502db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2503aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2504db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2505c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2506db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2507db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2508e5c89e4eSSatish Balay @*/
2509d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const *list, PetscEnum *value, PetscBool *set)
2510d71ae5a4SJacob Faibussowitsch {
251169a24498SJed Brown   PetscInt  ntext = 0, tval;
2512ace3abfcSBarry Smith   PetscBool fset;
2513e5c89e4eSSatish Balay 
2514e5c89e4eSSatish Balay   PetscFunctionBegin;
25154f572ea9SToby Isaac   PetscAssertPointer(opt, 3);
2516ad540459SPierre 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");
251708401ef6SPierre Jolivet   PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2518e5c89e4eSSatish Balay   ntext -= 3;
25199566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
252069a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2521809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2522809ceb46SBarry Smith   if (set) *set = fset;
25233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2524e5c89e4eSSatish Balay }
2525e5c89e4eSSatish Balay 
2526e5c89e4eSSatish Balay /*@C
25272d747510SLisandro Dalcin   PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2528e5c89e4eSSatish Balay 
2529e5c89e4eSSatish Balay   Not Collective
2530e5c89e4eSSatish Balay 
2531e5c89e4eSSatish Balay   Input Parameters:
253220f4b53cSBarry Smith + options - options database, use `NULL` for default global database
253320f4b53cSBarry Smith . pre     - the string to prepend to the name or `NULL`
2534e5c89e4eSSatish Balay - name    - the option one is seeking
2535e5c89e4eSSatish Balay 
2536d8d19677SJose E. Roman   Output Parameters:
25372d747510SLisandro Dalcin + ivalue - the integer value to return
2538811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2539e5c89e4eSSatish Balay 
2540e5c89e4eSSatish Balay   Level: beginner
2541e5c89e4eSSatish Balay 
2542e5c89e4eSSatish Balay   Notes:
25439314d9b7SBarry Smith   If the user does not supply the option `ivalue` is NOT changed. Thus
25449314d9b7SBarry Smith   you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
25455c07ccb8SBarry Smith 
2546db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2547db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2548aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2549db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2550c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2551db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2552db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2553e5c89e4eSSatish Balay @*/
2554d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2555d71ae5a4SJacob Faibussowitsch {
25562d747510SLisandro Dalcin   const char *value;
25572d747510SLisandro Dalcin   PetscBool   flag;
2558e5c89e4eSSatish Balay 
2559e5c89e4eSSatish Balay   PetscFunctionBegin;
25604f572ea9SToby Isaac   PetscAssertPointer(name, 3);
25614f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
25629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2563e5c89e4eSSatish Balay   if (flag) {
256434a9cc2cSBarry Smith     if (!value) {
25652d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
256634a9cc2cSBarry Smith     } else {
25672d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
25689566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
2569e5c89e4eSSatish Balay     }
2570e5c89e4eSSatish Balay   } else {
257196ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2572e5c89e4eSSatish Balay   }
25733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2574e5c89e4eSSatish Balay }
2575e5c89e4eSSatish Balay 
2576e2446a98SMatthew Knepley /*@C
2577e5c89e4eSSatish Balay   PetscOptionsGetReal - Gets the double precision value for a particular
2578e5c89e4eSSatish Balay   option in the database.
2579e5c89e4eSSatish Balay 
2580e5c89e4eSSatish Balay   Not Collective
2581e5c89e4eSSatish Balay 
2582e5c89e4eSSatish Balay   Input Parameters:
258320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
258420f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2585e5c89e4eSSatish Balay - name    - the option one is seeking
2586e5c89e4eSSatish Balay 
2587d8d19677SJose E. Roman   Output Parameters:
2588e5c89e4eSSatish Balay + dvalue - the double value to return
2589811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2590e5c89e4eSSatish Balay 
259120f4b53cSBarry Smith   Level: beginner
259220f4b53cSBarry Smith 
2593811af0c4SBarry Smith   Note:
25949314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
25959314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking that the `set` flag is true.
2596e4974155SBarry Smith 
2597db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2598c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2599db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2600c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2601db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2602db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2603e5c89e4eSSatish Balay @*/
2604d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2605d71ae5a4SJacob Faibussowitsch {
26062d747510SLisandro Dalcin   const char *value;
2607ace3abfcSBarry Smith   PetscBool   flag;
2608e5c89e4eSSatish Balay 
2609e5c89e4eSSatish Balay   PetscFunctionBegin;
26104f572ea9SToby Isaac   PetscAssertPointer(name, 3);
26114f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
26129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2613e5c89e4eSSatish Balay   if (flag) {
2614a297a907SKarl Rupp     if (!value) {
2615a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2616a297a907SKarl Rupp     } else {
2617a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
26189566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2619a297a907SKarl Rupp     }
2620e5c89e4eSSatish Balay   } else {
262196ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2622e5c89e4eSSatish Balay   }
26233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2624e5c89e4eSSatish Balay }
2625e5c89e4eSSatish Balay 
2626e5c89e4eSSatish Balay /*@C
2627e5c89e4eSSatish Balay   PetscOptionsGetScalar - Gets the scalar value for a particular
2628e5c89e4eSSatish Balay   option in the database.
2629e5c89e4eSSatish Balay 
2630e5c89e4eSSatish Balay   Not Collective
2631e5c89e4eSSatish Balay 
2632e5c89e4eSSatish Balay   Input Parameters:
263320f4b53cSBarry Smith + options - options database, use `NULL` for default global database
263420f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
2635e5c89e4eSSatish Balay - name    - the option one is seeking
2636e5c89e4eSSatish Balay 
2637d8d19677SJose E. Roman   Output Parameters:
26389314d9b7SBarry Smith + dvalue - the scalar value to return
2639811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2640e5c89e4eSSatish Balay 
2641e5c89e4eSSatish Balay   Level: beginner
2642e5c89e4eSSatish Balay 
264310450e9eSJacob Faibussowitsch   Example Usage:
2644eb4ae41dSBarry Smith   A complex number 2+3i must be specified with NO spaces
2645e5c89e4eSSatish Balay 
2646811af0c4SBarry Smith   Note:
26479314d9b7SBarry Smith   If the user does not supply the option `dvalue` is NOT changed. Thus
26489314d9b7SBarry Smith   you should ALWAYS initialize `dvalue` if you access it without first checking if the `set` flag is true.
2649e4974155SBarry Smith 
2650db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2651db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2652db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2653c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2654db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2655db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2656e5c89e4eSSatish Balay @*/
2657d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2658d71ae5a4SJacob Faibussowitsch {
26592d747510SLisandro Dalcin   const char *value;
2660ace3abfcSBarry Smith   PetscBool   flag;
2661e5c89e4eSSatish Balay 
2662e5c89e4eSSatish Balay   PetscFunctionBegin;
26634f572ea9SToby Isaac   PetscAssertPointer(name, 3);
26644f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
26659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2666e5c89e4eSSatish Balay   if (flag) {
2667e5c89e4eSSatish Balay     if (!value) {
266896ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2669e5c89e4eSSatish Balay     } else {
2670e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
26719566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value, dvalue));
2672e5c89e4eSSatish Balay #else
26739566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value, dvalue));
2674e5c89e4eSSatish Balay #endif
267596ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2676e5c89e4eSSatish Balay     }
2677e5c89e4eSSatish Balay   } else { /* flag */
267896ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2679e5c89e4eSSatish Balay   }
26803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2681e5c89e4eSSatish Balay }
2682e5c89e4eSSatish Balay 
2683e5c89e4eSSatish Balay /*@C
2684e5c89e4eSSatish Balay   PetscOptionsGetString - Gets the string value for a particular option in
2685e5c89e4eSSatish Balay   the database.
2686e5c89e4eSSatish Balay 
2687e5c89e4eSSatish Balay   Not Collective
2688e5c89e4eSSatish Balay 
2689e5c89e4eSSatish Balay   Input Parameters:
269020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
269120f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
2692e5c89e4eSSatish Balay . name    - the option one is seeking
2693bcbf2dc5SJed Brown - len     - maximum length of the string including null termination
2694e5c89e4eSSatish Balay 
2695e5c89e4eSSatish Balay   Output Parameters:
2696e5c89e4eSSatish Balay + string - location to copy string
2697811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
2698e5c89e4eSSatish Balay 
2699e5c89e4eSSatish Balay   Level: beginner
2700e5c89e4eSSatish Balay 
270120f4b53cSBarry Smith   Note:
27029314d9b7SBarry 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`
270320f4b53cSBarry Smith 
27049314d9b7SBarry Smith   If the user does not use the option then `string` is not changed. Thus
27059314d9b7SBarry Smith   you should ALWAYS initialize `string` if you access it without first checking that the `set` flag is true.
270620f4b53cSBarry Smith 
2707aec76313SJacob Faibussowitsch   Fortran Notes:
2708e5c89e4eSSatish Balay   The Fortran interface is slightly different from the C/C++
2709e5c89e4eSSatish Balay   interface (len is not used).  Sample usage in Fortran follows
2710e5c89e4eSSatish Balay .vb
2711e5c89e4eSSatish Balay       character *20    string
271293e6ba5cSBarry Smith       PetscErrorCode   ierr
271393e6ba5cSBarry Smith       PetscBool        set
27141b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2715e5c89e4eSSatish Balay .ve
2716e5c89e4eSSatish Balay 
2717db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2718db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2719db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2720c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2721db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2722db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2723e5c89e4eSSatish Balay @*/
2724d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set)
2725d71ae5a4SJacob Faibussowitsch {
27262d747510SLisandro Dalcin   const char *value;
2727ace3abfcSBarry Smith   PetscBool   flag;
2728e5c89e4eSSatish Balay 
2729e5c89e4eSSatish Balay   PetscFunctionBegin;
27304f572ea9SToby Isaac   PetscAssertPointer(name, 3);
27314f572ea9SToby Isaac   PetscAssertPointer(string, 4);
27329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2733e5c89e4eSSatish Balay   if (!flag) {
273496ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2735e5c89e4eSSatish Balay   } else {
273696ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
27379566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string, value, len));
27389566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string, len));
2739e5c89e4eSSatish Balay   }
27403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2741e5c89e4eSSatish Balay }
2742e5c89e4eSSatish Balay 
27432d747510SLisandro Dalcin /*@C
27442d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2745f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
27462d747510SLisandro Dalcin 
27472d747510SLisandro Dalcin   Not Collective
27482d747510SLisandro Dalcin 
27492d747510SLisandro Dalcin   Input Parameters:
275020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
275120f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
27526b867d5aSJose E. Roman - name    - the option one is seeking
27536b867d5aSJose E. Roman 
2754d8d19677SJose E. Roman   Output Parameters:
27559314d9b7SBarry Smith + dvalue - the Boolean values to return
2756f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2757811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
27582d747510SLisandro Dalcin 
27592d747510SLisandro Dalcin   Level: beginner
27602d747510SLisandro Dalcin 
2761811af0c4SBarry Smith   Note:
276220f4b53cSBarry Smith   TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`. FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
27632d747510SLisandro Dalcin 
2764db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2765db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2766db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2767c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2768db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2769db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
27702d747510SLisandro Dalcin @*/
2771d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2772d71ae5a4SJacob Faibussowitsch {
27732d747510SLisandro Dalcin   const char *svalue;
27742d747510SLisandro Dalcin   char       *value;
27752d747510SLisandro Dalcin   PetscInt    n = 0;
27762d747510SLisandro Dalcin   PetscBool   flag;
27772d747510SLisandro Dalcin   PetscToken  token;
27782d747510SLisandro Dalcin 
27792d747510SLisandro Dalcin   PetscFunctionBegin;
27804f572ea9SToby Isaac   PetscAssertPointer(name, 3);
27814f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
27824f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
27832d747510SLisandro Dalcin 
27849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
27859371c9d4SSatish Balay   if (!flag || !svalue) {
27869371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
27879371c9d4SSatish Balay     *nmax = 0;
27883ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
27899371c9d4SSatish Balay   }
27902d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
27919566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
27929566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
27932d747510SLisandro Dalcin   while (value && n < *nmax) {
27949566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, dvalue));
27959566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
27962d747510SLisandro Dalcin     dvalue++;
27972d747510SLisandro Dalcin     n++;
27982d747510SLisandro Dalcin   }
27999566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28002d747510SLisandro Dalcin   *nmax = n;
28013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28022d747510SLisandro Dalcin }
28032d747510SLisandro Dalcin 
28042d747510SLisandro Dalcin /*@C
28052d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
28062d747510SLisandro Dalcin 
28072d747510SLisandro Dalcin   Not Collective
28082d747510SLisandro Dalcin 
28092d747510SLisandro Dalcin   Input Parameters:
281020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
281120f4b53cSBarry Smith . pre     - option prefix or `NULL`
28122d747510SLisandro Dalcin . name    - option name
28136b867d5aSJose E. Roman - list    - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
28146b867d5aSJose E. Roman 
28152d747510SLisandro Dalcin   Output Parameters:
28162d747510SLisandro Dalcin + ivalue - the  enum values to return
2817f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2818811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
28192d747510SLisandro Dalcin 
28202d747510SLisandro Dalcin   Level: beginner
28212d747510SLisandro Dalcin 
28222d747510SLisandro Dalcin   Notes:
28239314d9b7SBarry Smith   The array must be passed as a comma separated list with no spaces between the items.
28242d747510SLisandro Dalcin 
28259314d9b7SBarry Smith   `list` is usually something like `PCASMTypes` or some other predefined list of enum names.
28262d747510SLisandro Dalcin 
2827db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2828db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2829aec76313SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsName()`,
2830c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2831db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2832db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
28332d747510SLisandro Dalcin @*/
2834d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const *list, PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
2835d71ae5a4SJacob Faibussowitsch {
28362d747510SLisandro Dalcin   const char *svalue;
28372d747510SLisandro Dalcin   char       *value;
28382d747510SLisandro Dalcin   PetscInt    n = 0;
28392d747510SLisandro Dalcin   PetscEnum   evalue;
28402d747510SLisandro Dalcin   PetscBool   flag;
28412d747510SLisandro Dalcin   PetscToken  token;
28422d747510SLisandro Dalcin 
28432d747510SLisandro Dalcin   PetscFunctionBegin;
28444f572ea9SToby Isaac   PetscAssertPointer(name, 3);
28454f572ea9SToby Isaac   PetscAssertPointer(list, 4);
28464f572ea9SToby Isaac   PetscAssertPointer(ivalue, 5);
28474f572ea9SToby Isaac   PetscAssertPointer(nmax, 6);
28482d747510SLisandro Dalcin 
28499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
28509371c9d4SSatish Balay   if (!flag || !svalue) {
28519371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
28529371c9d4SSatish Balay     *nmax = 0;
28533ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
28549371c9d4SSatish Balay   }
28552d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28569566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
28579566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
28582d747510SLisandro Dalcin   while (value && n < *nmax) {
28599566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list, value, &evalue, &flag));
286028b400f6SJacob Faibussowitsch     PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
28612d747510SLisandro Dalcin     ivalue[n++] = evalue;
28629566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
28632d747510SLisandro Dalcin   }
28649566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28652d747510SLisandro Dalcin   *nmax = n;
28663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28672d747510SLisandro Dalcin }
28682d747510SLisandro Dalcin 
28692d747510SLisandro Dalcin /*@C
2870f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
28712d747510SLisandro Dalcin 
28722d747510SLisandro Dalcin   Not Collective
28732d747510SLisandro Dalcin 
28742d747510SLisandro Dalcin   Input Parameters:
287520f4b53cSBarry Smith + options - options database, use `NULL` for default global database
287620f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
28776b867d5aSJose E. Roman - name    - the option one is seeking
28786b867d5aSJose E. Roman 
2879d8d19677SJose E. Roman   Output Parameters:
28802d747510SLisandro Dalcin + ivalue - the integer values to return
2881f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2882811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
28832d747510SLisandro Dalcin 
28842d747510SLisandro Dalcin   Level: beginner
28852d747510SLisandro Dalcin 
28862d747510SLisandro Dalcin   Notes:
28872d747510SLisandro Dalcin   The array can be passed as
2888811af0c4SBarry Smith +  a comma separated list -                                 0,1,2,3,4,5,6,7
2889811af0c4SBarry Smith .  a range (start\-end+1) -                                 0-8
2890811af0c4SBarry Smith .  a range with given increment (start\-end+1:inc) -        0-7:2
2891811af0c4SBarry Smith -  a combination of values and ranges separated by commas - 0,1-8,8-15:2
28922d747510SLisandro Dalcin 
28932d747510SLisandro Dalcin   There must be no intervening spaces between the values.
28942d747510SLisandro Dalcin 
2895db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2896db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2897db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2898c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2899db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2900db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29012d747510SLisandro Dalcin @*/
2902d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
2903d71ae5a4SJacob Faibussowitsch {
29042d747510SLisandro Dalcin   const char *svalue;
29052d747510SLisandro Dalcin   char       *value;
29062d747510SLisandro Dalcin   PetscInt    n = 0, i, j, start, end, inc, nvalues;
29072d747510SLisandro Dalcin   size_t      len;
29082d747510SLisandro Dalcin   PetscBool   flag, foundrange;
29092d747510SLisandro Dalcin   PetscToken  token;
29102d747510SLisandro Dalcin 
29112d747510SLisandro Dalcin   PetscFunctionBegin;
29124f572ea9SToby Isaac   PetscAssertPointer(name, 3);
29134f572ea9SToby Isaac   PetscAssertPointer(ivalue, 4);
29144f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
29152d747510SLisandro Dalcin 
29169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
29179371c9d4SSatish Balay   if (!flag || !svalue) {
29189371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
29199371c9d4SSatish Balay     *nmax = 0;
29203ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
29219371c9d4SSatish Balay   }
29222d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29239566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
29249566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
29252d747510SLisandro Dalcin   while (value && n < *nmax) {
29262d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
29272d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
29289566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value, &len));
29292d747510SLisandro Dalcin     if (value[0] == '-') i = 2;
29302d747510SLisandro Dalcin     else i = 1;
29312d747510SLisandro Dalcin     for (; i < (int)len; i++) {
29322d747510SLisandro Dalcin       if (value[i] == '-') {
2933cc73adaaSBarry Smith         PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value);
29342d747510SLisandro Dalcin         value[i] = 0;
29352d747510SLisandro Dalcin 
29369566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value, &start));
29372d747510SLisandro Dalcin         inc = 1;
29382d747510SLisandro Dalcin         j   = i + 1;
29392d747510SLisandro Dalcin         for (; j < (int)len; j++) {
29402d747510SLisandro Dalcin           if (value[j] == ':') {
29412d747510SLisandro Dalcin             value[j] = 0;
29422d747510SLisandro Dalcin 
29439566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value + j + 1, &inc));
294408401ef6SPierre 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);
29452d747510SLisandro Dalcin             break;
29462d747510SLisandro Dalcin           }
29472d747510SLisandro Dalcin         }
29489566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value + i + 1, &end));
294908401ef6SPierre 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);
29502d747510SLisandro Dalcin         nvalues = (end - start) / inc + (end - start) % inc;
2951cc73adaaSBarry 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);
29522d747510SLisandro Dalcin         for (; start < end; start += inc) {
29539371c9d4SSatish Balay           *ivalue = start;
29549371c9d4SSatish Balay           ivalue++;
29559371c9d4SSatish Balay           n++;
29562d747510SLisandro Dalcin         }
29572d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
29582d747510SLisandro Dalcin         break;
29592d747510SLisandro Dalcin       }
29602d747510SLisandro Dalcin     }
29612d747510SLisandro Dalcin     if (!foundrange) {
29629566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value, ivalue));
29632d747510SLisandro Dalcin       ivalue++;
29642d747510SLisandro Dalcin       n++;
29652d747510SLisandro Dalcin     }
29669566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
29672d747510SLisandro Dalcin   }
29689566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29692d747510SLisandro Dalcin   *nmax = n;
29703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29712d747510SLisandro Dalcin }
29722d747510SLisandro Dalcin 
29732d747510SLisandro Dalcin /*@C
29742d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
2975f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
29762d747510SLisandro Dalcin 
29772d747510SLisandro Dalcin   Not Collective
29782d747510SLisandro Dalcin 
29792d747510SLisandro Dalcin   Input Parameters:
298020f4b53cSBarry Smith + options - options database, use `NULL` for default global database
298120f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
29826b867d5aSJose E. Roman - name    - the option one is seeking
29836b867d5aSJose E. Roman 
29842d747510SLisandro Dalcin   Output Parameters:
29852d747510SLisandro Dalcin + dvalue - the double values to return
2986f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
2987811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
29882d747510SLisandro Dalcin 
29892d747510SLisandro Dalcin   Level: beginner
29902d747510SLisandro Dalcin 
2991db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2992db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2993db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2994c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2995db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2996db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29972d747510SLisandro Dalcin @*/
2998d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
2999d71ae5a4SJacob Faibussowitsch {
30002d747510SLisandro Dalcin   const char *svalue;
30012d747510SLisandro Dalcin   char       *value;
30022d747510SLisandro Dalcin   PetscInt    n = 0;
30032d747510SLisandro Dalcin   PetscBool   flag;
30042d747510SLisandro Dalcin   PetscToken  token;
30052d747510SLisandro Dalcin 
30062d747510SLisandro Dalcin   PetscFunctionBegin;
30074f572ea9SToby Isaac   PetscAssertPointer(name, 3);
30084f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
30094f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
30102d747510SLisandro Dalcin 
30119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30129371c9d4SSatish Balay   if (!flag || !svalue) {
30139371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30149371c9d4SSatish Balay     *nmax = 0;
30153ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
30169371c9d4SSatish Balay   }
30172d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30189566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30199566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30202d747510SLisandro Dalcin   while (value && n < *nmax) {
30219566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value, dvalue++));
30229566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30232d747510SLisandro Dalcin     n++;
30242d747510SLisandro Dalcin   }
30259566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30262d747510SLisandro Dalcin   *nmax = n;
30273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30282d747510SLisandro Dalcin }
30292d747510SLisandro Dalcin 
30302d747510SLisandro Dalcin /*@C
30312d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
3032f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
30332d747510SLisandro Dalcin 
30342d747510SLisandro Dalcin   Not Collective
30352d747510SLisandro Dalcin 
30362d747510SLisandro Dalcin   Input Parameters:
303720f4b53cSBarry Smith + options - options database, use `NULL` for default global database
303820f4b53cSBarry Smith . pre     - string to prepend to each name or `NULL`
30396b867d5aSJose E. Roman - name    - the option one is seeking
30406b867d5aSJose E. Roman 
30412d747510SLisandro Dalcin   Output Parameters:
30422d747510SLisandro Dalcin + dvalue - the scalar values to return
3043f1a722f8SMatthew G. Knepley . nmax   - On input maximum number of values to retrieve, on output the actual number of values retrieved
3044811af0c4SBarry Smith - set    - `PETSC_TRUE` if found, else `PETSC_FALSE`
30452d747510SLisandro Dalcin 
30462d747510SLisandro Dalcin   Level: beginner
30472d747510SLisandro Dalcin 
3048db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3049db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3050db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3051c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3052db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3053db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
30542d747510SLisandro Dalcin @*/
3055d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3056d71ae5a4SJacob Faibussowitsch {
30572d747510SLisandro Dalcin   const char *svalue;
30582d747510SLisandro Dalcin   char       *value;
30592d747510SLisandro Dalcin   PetscInt    n = 0;
30602d747510SLisandro Dalcin   PetscBool   flag;
30612d747510SLisandro Dalcin   PetscToken  token;
30622d747510SLisandro Dalcin 
30632d747510SLisandro Dalcin   PetscFunctionBegin;
30644f572ea9SToby Isaac   PetscAssertPointer(name, 3);
30654f572ea9SToby Isaac   PetscAssertPointer(dvalue, 4);
30664f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
30672d747510SLisandro Dalcin 
30689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
30699371c9d4SSatish Balay   if (!flag || !svalue) {
30709371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
30719371c9d4SSatish Balay     *nmax = 0;
30723ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
30739371c9d4SSatish Balay   }
30742d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30759566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
30769566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
30772d747510SLisandro Dalcin   while (value && n < *nmax) {
30789566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value, dvalue++));
30799566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
30802d747510SLisandro Dalcin     n++;
30812d747510SLisandro Dalcin   }
30829566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
30832d747510SLisandro Dalcin   *nmax = n;
30843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30852d747510SLisandro Dalcin }
308614ce751eSBarry Smith 
3087e5c89e4eSSatish Balay /*@C
3088e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
3089f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
3090e5c89e4eSSatish Balay 
3091cf53795eSBarry Smith   Not Collective; No Fortran Support
3092e5c89e4eSSatish Balay 
3093e5c89e4eSSatish Balay   Input Parameters:
309420f4b53cSBarry Smith + options - options database, use `NULL` for default global database
309520f4b53cSBarry Smith . pre     - string to prepend to name or `NULL`
30966b867d5aSJose E. Roman - name    - the option one is seeking
30976b867d5aSJose E. Roman 
3098e7b76fa7SPatrick Sanan   Output Parameters:
3099e5c89e4eSSatish Balay + strings - location to copy strings
3100f1a722f8SMatthew G. Knepley . nmax    - On input maximum number of strings, on output the actual number of strings found
3101811af0c4SBarry Smith - set     - `PETSC_TRUE` if found, else `PETSC_FALSE`
3102e5c89e4eSSatish Balay 
3103e5c89e4eSSatish Balay   Level: beginner
3104e5c89e4eSSatish Balay 
3105e5c89e4eSSatish Balay   Notes:
31069314d9b7SBarry Smith   The `nmax` parameter is used for both input and output.
3107e7b76fa7SPatrick Sanan 
3108e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
3109e5c89e4eSSatish Balay   strings returned by this function.
3110e5c89e4eSSatish Balay 
3111e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3112cf53795eSBarry Smith   returned.
3113e5c89e4eSSatish Balay 
3114db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3115db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3116db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3117c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3118db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3119db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3120e5c89e4eSSatish Balay @*/
3121d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set)
3122d71ae5a4SJacob Faibussowitsch {
31232d747510SLisandro Dalcin   const char *svalue;
3124e5c89e4eSSatish Balay   char       *value;
31252d747510SLisandro Dalcin   PetscInt    n = 0;
3126ace3abfcSBarry Smith   PetscBool   flag;
31279c9d3cfdSBarry Smith   PetscToken  token;
3128e5c89e4eSSatish Balay 
3129e5c89e4eSSatish Balay   PetscFunctionBegin;
31304f572ea9SToby Isaac   PetscAssertPointer(name, 3);
31314f572ea9SToby Isaac   PetscAssertPointer(strings, 4);
31324f572ea9SToby Isaac   PetscAssertPointer(nmax, 5);
3133e5c89e4eSSatish Balay 
31349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
31359371c9d4SSatish Balay   if (!flag || !svalue) {
31369371c9d4SSatish Balay     if (set) *set = PETSC_FALSE;
31379371c9d4SSatish Balay     *nmax = 0;
31383ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
31399371c9d4SSatish Balay   }
31402d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
31419566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue, ',', &token));
31429566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token, &value));
31432d747510SLisandro Dalcin   while (value && n < *nmax) {
31449566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value, &strings[n]));
31459566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token, &value));
3146e5c89e4eSSatish Balay     n++;
3147e5c89e4eSSatish Balay   }
31489566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3149e5c89e4eSSatish Balay   *nmax = n;
31503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3151e5c89e4eSSatish Balay }
315206824ed3SPatrick Sanan 
315306824ed3SPatrick Sanan /*@C
3154aec76313SJacob Faibussowitsch   PetscOptionsDeprecated_Private - mark an option as deprecated, optionally replacing it with `newname`
315506824ed3SPatrick Sanan 
315606824ed3SPatrick Sanan   Prints a deprecation warning, unless an option is supplied to suppress.
315706824ed3SPatrick Sanan 
31581c9f3c13SBarry Smith   Logically Collective
315906824ed3SPatrick Sanan 
316006824ed3SPatrick Sanan   Input Parameters:
3161aec76313SJacob Faibussowitsch + PetscOptionsObject - string to prepend to name or `NULL`
316206824ed3SPatrick Sanan . oldname            - the old, deprecated option
316320f4b53cSBarry Smith . newname            - the new option, or `NULL` if option is purely removed
31649f3a6782SPatrick Sanan . version            - a string describing the version of first deprecation, e.g. "3.9"
316520f4b53cSBarry Smith - info               - additional information string, or `NULL`.
316606824ed3SPatrick Sanan 
3167811af0c4SBarry Smith   Options Database Key:
316806824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
316906824ed3SPatrick Sanan 
317020f4b53cSBarry Smith   Level: developer
317120f4b53cSBarry Smith 
317206824ed3SPatrick Sanan   Notes:
31734ead3382SBarry Smith   If `newname` is provided then the options database will automatically check the database for `oldname`.
31744ead3382SBarry Smith 
31754ead3382SBarry Smith   The old call `PetscOptionsXXX`(`oldname`) should be removed from the source code when both (1) the call to `PetscOptionsDeprecated()` occurs before the
31764ead3382SBarry Smith   new call to `PetscOptionsXXX`(`newname`) and (2) the argument handling of the new call to `PetscOptionsXXX`(`newname`) is identical to the previous call.
31774ead3382SBarry Smith   See `PTScotch_PartGraph_Seq()` for an example of when (1) fails and `SNESTestJacobian()` where an example of (2) fails.
31784ead3382SBarry Smith 
3179811af0c4SBarry Smith   Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
318035cb6cd3SPierre Jolivet   Only the process of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3181811af0c4SBarry Smith   `PetscObjectOptionsBegin()` prints the information
3182b40114eaSPatrick Sanan   If newname is provided, the old option is replaced. Otherwise, it remains
3183b40114eaSPatrick Sanan   in the options database.
31849f3a6782SPatrick Sanan   If an option is not replaced, the info argument should be used to advise the user
31859f3a6782SPatrick Sanan   on how to proceed.
31869f3a6782SPatrick Sanan   There is a limit on the length of the warning printed, so very long strings
31879f3a6782SPatrick Sanan   provided as info may be truncated.
318806824ed3SPatrick Sanan 
3189db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
319006824ed3SPatrick Sanan @*/
3191d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3192d71ae5a4SJacob Faibussowitsch {
319306824ed3SPatrick Sanan   PetscBool         found, quiet;
319406824ed3SPatrick Sanan   const char       *value;
319506824ed3SPatrick Sanan   const char *const quietopt = "-options_suppress_deprecated_warnings";
31969f3a6782SPatrick Sanan   char              msg[4096];
3197b0bdc838SStefano Zampini   char             *prefix  = NULL;
3198b0bdc838SStefano Zampini   PetscOptions      options = NULL;
3199b0bdc838SStefano Zampini   MPI_Comm          comm    = PETSC_COMM_SELF;
320006824ed3SPatrick Sanan 
320106824ed3SPatrick Sanan   PetscFunctionBegin;
32024f572ea9SToby Isaac   PetscAssertPointer(oldname, 2);
32034f572ea9SToby Isaac   PetscAssertPointer(version, 4);
3204b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3205b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3206b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3207b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3208b0bdc838SStefano Zampini   }
32099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
321006824ed3SPatrick Sanan   if (found) {
321106824ed3SPatrick Sanan     if (newname) {
32121baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
32139566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options, newname, value));
32141baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
32159566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options, oldname));
3216b40114eaSPatrick Sanan     }
321706824ed3SPatrick Sanan     quiet = PETSC_FALSE;
32189566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
321906824ed3SPatrick Sanan     if (!quiet) {
3220c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option ", sizeof(msg)));
3221c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, oldname, sizeof(msg)));
3222c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3223c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
32244bd3d7f8SBarry Smith       PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
322506824ed3SPatrick Sanan       if (newname) {
32264bd3d7f8SBarry Smith         PetscCall(PetscStrlcat(msg, "   Use the option ", sizeof(msg)));
3227c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, newname, sizeof(msg)));
3228c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
322906824ed3SPatrick Sanan       }
32309f3a6782SPatrick Sanan       if (info) {
3231c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3232c6a7a370SJeremy L Thompson         PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
32339f3a6782SPatrick Sanan       }
3234c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3235c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3236c6a7a370SJeremy L Thompson       PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
32379566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm, "%s", msg));
323806824ed3SPatrick Sanan     }
323906824ed3SPatrick Sanan   }
32403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
324106824ed3SPatrick Sanan }
3242