xref: /petsc/src/sys/objects/options.c (revision f4bc716f397fd5489d603233454e5da12ee644d0)
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   */
349fbee547SJacob Faibussowitsch static inline int PetscToLower(int c)
352d747510SLisandro Dalcin {
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) */
409fbee547SJacob Faibussowitsch static inline unsigned int PetscOptHash(const char key[])
412d747510SLisandro Dalcin {
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 
549fbee547SJacob Faibussowitsch static inline int PetscOptEqual(const char a[],const char b[])
552d747510SLisandro Dalcin {
562d747510SLisandro Dalcin   return !PetscOptNameCmp(a,b);
572d747510SLisandro Dalcin }
582d747510SLisandro Dalcin 
592d747510SLisandro Dalcin KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
602d747510SLisandro Dalcin 
61e5c89e4eSSatish Balay /*
623fc1eb6aSBarry Smith     This table holds all the options set by the user. For simplicity, we use a static size database
63e5c89e4eSSatish Balay */
64c5c1f447SLisandro Dalcin #define MAXOPTNAME PETSC_MAX_OPTION_NAME
65e5c89e4eSSatish Balay #define MAXOPTIONS 512
66e5c89e4eSSatish Balay #define MAXALIASES  25
6774e0666dSJed Brown #define MAXPREFIXES 25
682d747510SLisandro Dalcin #define MAXOPTIONSMONITORS 5
69e5c89e4eSSatish Balay 
704416b707SBarry Smith struct  _n_PetscOptions {
713de2bfdfSBarry Smith   PetscOptions   previous;
722d747510SLisandro Dalcin   int            N;                    /* number of options */
732d747510SLisandro Dalcin   char           *names[MAXOPTIONS];   /* option names */
742d747510SLisandro Dalcin   char           *values[MAXOPTIONS];  /* option values */
752d747510SLisandro Dalcin   PetscBool      used[MAXOPTIONS];     /* flag option use */
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];
842d747510SLisandro Dalcin   char           prefix[MAXOPTNAME];
852d747510SLisandro Dalcin 
862d747510SLisandro Dalcin   /* Aliases */
872d747510SLisandro Dalcin   int            Naliases;                   /* number or aliases */
882d747510SLisandro Dalcin   char           *aliases1[MAXALIASES];      /* aliased */
892d747510SLisandro Dalcin   char           *aliases2[MAXALIASES];      /* aliasee */
902d747510SLisandro Dalcin 
912d747510SLisandro Dalcin   /* Help */
922d747510SLisandro Dalcin   PetscBool      help;       /* flag whether "-help" is in the database */
93d314f959SVaclav Hapla   PetscBool      help_intro; /* flag whether "-help intro" is in the database */
942d747510SLisandro Dalcin 
952d747510SLisandro Dalcin   /* Monitors */
96c5b5d8d5SVaclav Hapla   PetscBool      monitorFromOptions, monitorCancel;
97081c24baSBoyana Norris   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[],const char[],void*); /* returns control to user after */
98c2efdce3SBarry Smith   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void**);         /* */
99081c24baSBoyana Norris   void           *monitorcontext[MAXOPTIONSMONITORS];                  /* to pass arbitrary user data into monitor */
100081c24baSBoyana Norris   PetscInt       numbermonitors;                                       /* to, for instance, detect options being set */
1014416b707SBarry Smith };
102e5c89e4eSSatish Balay 
103b4205f0bSBarry Smith static PetscOptions defaultoptions = NULL;  /* the options database routines query this object for options */
1042d747510SLisandro Dalcin 
105c5b5d8d5SVaclav Hapla /* list of options which preceed others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
106660278c0SBarry Smith /* these options can only take boolean values, the code will crash if given a non-boolean value */
107660278c0SBarry Smith static const char *precedentOptions[] = {"-petsc_ci","-options_monitor","-options_monitor_cancel","-help","-skip_petscrc"};
108660278c0SBarry Smith enum PetscPrecedentOption {PO_CI_ENABLE,PO_OPTIONS_MONITOR,PO_OPTIONS_MONITOR_CANCEL,PO_HELP,PO_SKIP_PETSCRC,PO_NUM};
109c5b5d8d5SVaclav Hapla 
110c5b5d8d5SVaclav Hapla static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions,const char[],const char[],int*);
111c5b5d8d5SVaclav Hapla 
112081c24baSBoyana Norris /*
113081c24baSBoyana Norris     Options events monitor
114081c24baSBoyana Norris */
1152d747510SLisandro Dalcin static PetscErrorCode PetscOptionsMonitor(PetscOptions options,const char name[],const char value[])
116e5c89e4eSSatish Balay {
117e5c89e4eSSatish Balay   PetscFunctionBegin;
118c5b5d8d5SVaclav Hapla   if (!value) value = "";
1199566063dSJacob Faibussowitsch   if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name,value,NULL));
1209566063dSJacob Faibussowitsch   for (PetscInt i=0; i<options->numbermonitors; i++) PetscCall((*options->monitor[i])(name,value,options->monitorcontext[i]));
121e5c89e4eSSatish Balay   PetscFunctionReturn(0);
122e5c89e4eSSatish Balay }
123e5c89e4eSSatish Balay 
1242d747510SLisandro Dalcin /*@
1252d747510SLisandro Dalcin    PetscOptionsCreate - Creates an empty options database.
126e5c89e4eSSatish Balay 
1271c9f3c13SBarry Smith    Logically collective
1281c9f3c13SBarry Smith 
129e5c89e4eSSatish Balay    Output Parameter:
1302d747510SLisandro Dalcin .  options - Options database object
131e5c89e4eSSatish Balay 
132e5c89e4eSSatish Balay    Level: advanced
133e5c89e4eSSatish Balay 
1341c9f3c13SBarry Smith    Developer Note: We may want eventually to pass a MPI_Comm to determine the ownership of the object
1351c9f3c13SBarry Smith 
136db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
137e5c89e4eSSatish Balay @*/
1382d747510SLisandro Dalcin PetscErrorCode PetscOptionsCreate(PetscOptions *options)
1392d747510SLisandro Dalcin {
14039a651e2SJacob Faibussowitsch   PetscFunctionBegin;
14139a651e2SJacob Faibussowitsch   PetscValidPointer(options,1);
1422d747510SLisandro Dalcin   *options = (PetscOptions)calloc(1,sizeof(**options));
14339a651e2SJacob Faibussowitsch   PetscCheck(*options,PETSC_COMM_SELF,PETSC_ERR_MEM,"Failed to allocate the options database");
14439a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1452d747510SLisandro Dalcin }
1462d747510SLisandro Dalcin 
1472d747510SLisandro Dalcin /*@
1482d747510SLisandro Dalcin     PetscOptionsDestroy - Destroys an option database.
1492d747510SLisandro Dalcin 
1501c9f3c13SBarry Smith     Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
1511c9f3c13SBarry Smith 
1522d747510SLisandro Dalcin   Input Parameter:
1532d747510SLisandro Dalcin .  options - the PetscOptions object
1542d747510SLisandro Dalcin 
1553de2bfdfSBarry Smith    Level: advanced
1562d747510SLisandro Dalcin 
157db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
1582d747510SLisandro Dalcin @*/
1592d747510SLisandro Dalcin PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
160e5c89e4eSSatish Balay {
161362febeeSStefano Zampini   PetscFunctionBegin;
16239a651e2SJacob Faibussowitsch   if (!*options) PetscFunctionReturn(0);
1635f80ce2aSJacob 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()");
1649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsClear(*options));
1652d747510SLisandro Dalcin   /* XXX what about monitors ? */
1662800570dSLisandro Dalcin   free(*options);
1672d747510SLisandro Dalcin   *options = NULL;
168e5c89e4eSSatish Balay   PetscFunctionReturn(0);
169e5c89e4eSSatish Balay }
170e5c89e4eSSatish Balay 
1712d747510SLisandro Dalcin /*
1722d747510SLisandro Dalcin     PetscOptionsCreateDefault - Creates the default global options database
1732d747510SLisandro Dalcin */
1742d747510SLisandro Dalcin PetscErrorCode PetscOptionsCreateDefault(void)
175e5c89e4eSSatish Balay {
17639a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1779566063dSJacob Faibussowitsch   if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
17839a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1792d747510SLisandro Dalcin }
1802d747510SLisandro Dalcin 
181b4205f0bSBarry Smith /*@
182b4205f0bSBarry Smith       PetscOptionsPush - Push a new PetscOptions object as the default provider of options
1831c9f3c13SBarry Smith                          Allows using different parts of a code to use different options databases
184b4205f0bSBarry Smith 
185b4205f0bSBarry Smith   Logically Collective
186b4205f0bSBarry Smith 
187b4205f0bSBarry Smith   Input Parameter:
188b4205f0bSBarry Smith .   opt - the options obtained with PetscOptionsCreate()
189b4205f0bSBarry Smith 
190b4205f0bSBarry Smith   Notes:
191b4205f0bSBarry Smith   Use PetscOptionsPop() to return to the previous default options database
1921c9f3c13SBarry Smith 
1939666a313SBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
1941c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
1951c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1961c9f3c13SBarry Smith   on different ranks.
197b4205f0bSBarry Smith 
1983de2bfdfSBarry Smith    Level: advanced
1993de2bfdfSBarry Smith 
200db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
201b4205f0bSBarry Smith 
202b4205f0bSBarry Smith @*/
203b4205f0bSBarry Smith PetscErrorCode PetscOptionsPush(PetscOptions opt)
204b4205f0bSBarry Smith {
205b4205f0bSBarry Smith   PetscFunctionBegin;
2069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsCreateDefault());
207b4205f0bSBarry Smith   opt->previous  = defaultoptions;
208b4205f0bSBarry Smith   defaultoptions = opt;
209b4205f0bSBarry Smith   PetscFunctionReturn(0);
210b4205f0bSBarry Smith }
211b4205f0bSBarry Smith 
212b4205f0bSBarry Smith /*@
213b4205f0bSBarry Smith       PetscOptionsPop - Pop the most recent PetscOptionsPush() to return to the previous default options
214b4205f0bSBarry Smith 
2151c9f3c13SBarry Smith       Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
216b4205f0bSBarry Smith 
217b4205f0bSBarry Smith   Notes:
218b4205f0bSBarry Smith   Use PetscOptionsPop() to return to the previous default options database
219b4205f0bSBarry Smith   Allows using different parts of a code to use different options databases
220b4205f0bSBarry Smith 
2213de2bfdfSBarry Smith    Level: advanced
2223de2bfdfSBarry Smith 
223db781477SPatrick Sanan .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
224b4205f0bSBarry Smith 
225b4205f0bSBarry Smith @*/
226b4205f0bSBarry Smith PetscErrorCode PetscOptionsPop(void)
227b4205f0bSBarry Smith {
2283de2bfdfSBarry Smith   PetscOptions current = defaultoptions;
2293de2bfdfSBarry Smith 
230b4205f0bSBarry Smith   PetscFunctionBegin;
23128b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing default options");
23228b400f6SJacob Faibussowitsch   PetscCheck(defaultoptions->previous,PETSC_COMM_SELF,PETSC_ERR_PLIB,"PetscOptionsPop() called too many times");
233b4205f0bSBarry Smith   defaultoptions    = defaultoptions->previous;
2343de2bfdfSBarry Smith   current->previous = NULL;
235b4205f0bSBarry Smith   PetscFunctionReturn(0);
236b4205f0bSBarry Smith }
237b4205f0bSBarry Smith 
2382d747510SLisandro Dalcin /*
2392d747510SLisandro Dalcin     PetscOptionsDestroyDefault - Destroys the default global options database
2402d747510SLisandro Dalcin */
2412d747510SLisandro Dalcin PetscErrorCode PetscOptionsDestroyDefault(void)
2422d747510SLisandro Dalcin {
24339a651e2SJacob Faibussowitsch   PetscFunctionBegin;
24439a651e2SJacob Faibussowitsch   if (!defaultoptions) PetscFunctionReturn(0);
2453de2bfdfSBarry Smith   /* Destroy any options that the user forgot to pop */
2463de2bfdfSBarry Smith   while (defaultoptions->previous) {
24739a651e2SJacob Faibussowitsch     PetscOptions tmp = defaultoptions;
24839a651e2SJacob Faibussowitsch 
2499566063dSJacob Faibussowitsch     PetscCall(PetscOptionsPop());
2509566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDestroy(&tmp));
2513de2bfdfSBarry Smith   }
2529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDestroy(&defaultoptions));
25339a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
254e5c89e4eSSatish Balay }
255e5c89e4eSSatish Balay 
25694ef8ddeSSatish Balay /*@C
2577cd08cecSJed Brown    PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
2583fc1eb6aSBarry Smith 
259447722d5SBarry Smith    Not collective
2601c9f3c13SBarry Smith 
2613fc1eb6aSBarry Smith    Input Parameter:
2622d747510SLisandro Dalcin .  key - string to check if valid
2633fc1eb6aSBarry Smith 
2643fc1eb6aSBarry Smith    Output Parameter:
2652d747510SLisandro Dalcin .  valid - PETSC_TRUE if a valid key
2663fc1eb6aSBarry Smith 
267f6680f47SSatish Balay    Level: intermediate
2683fc1eb6aSBarry Smith @*/
2692d747510SLisandro Dalcin PetscErrorCode PetscOptionsValidKey(const char key[],PetscBool *valid)
27096fc60bcSBarry Smith {
271f603b5e9SToby Isaac   char *ptr;
2727c5db45bSBarry Smith 
27396fc60bcSBarry Smith   PetscFunctionBegin;
2742d747510SLisandro Dalcin   if (key) PetscValidCharPointer(key,1);
275dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(valid,2);
2762d747510SLisandro Dalcin   *valid = PETSC_FALSE;
2772d747510SLisandro Dalcin   if (!key) PetscFunctionReturn(0);
2782d747510SLisandro Dalcin   if (key[0] != '-') PetscFunctionReturn(0);
2792d747510SLisandro Dalcin   if (key[1] == '-') key++;
280c850d057SPierre Jolivet   if (!isalpha((int)key[1])) PetscFunctionReturn(0);
2812d747510SLisandro Dalcin   (void) strtod(key,&ptr);
282c850d057SPierre Jolivet   if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(0);
2832d747510SLisandro Dalcin   *valid = PETSC_TRUE;
28496fc60bcSBarry Smith   PetscFunctionReturn(0);
28596fc60bcSBarry Smith }
28696fc60bcSBarry Smith 
287e5c89e4eSSatish Balay /*@C
288e5c89e4eSSatish Balay    PetscOptionsInsertString - Inserts options into the database from a string
289e5c89e4eSSatish Balay 
2901c9f3c13SBarry Smith    Logically Collective
291e5c89e4eSSatish Balay 
292d8d19677SJose E. Roman    Input Parameters:
293080f0011SToby Isaac +  options - options object
294080f0011SToby Isaac -  in_str - string that contains options separated by blanks
295e5c89e4eSSatish Balay 
296e5c89e4eSSatish Balay    Level: intermediate
297e5c89e4eSSatish Balay 
2989666a313SBarry Smith   The collectivity of this routine is complex; only the MPI processes that call this routine will
2991c9f3c13SBarry Smith   have the affect of these options. If some processes that create objects call this routine and others do
3001c9f3c13SBarry Smith   not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
3011c9f3c13SBarry Smith   on different ranks.
3021c9f3c13SBarry Smith 
303e5c89e4eSSatish Balay    Contributed by Boyana Norris
304e5c89e4eSSatish Balay 
305db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
306db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
307db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
308c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
309db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
310db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
311e5c89e4eSSatish Balay @*/
312c5929fdfSBarry Smith PetscErrorCode PetscOptionsInsertString(PetscOptions options,const char in_str[])
313e5c89e4eSSatish Balay {
314d06005cbSLisandro Dalcin   MPI_Comm       comm = PETSC_COMM_SELF;
315d06005cbSLisandro Dalcin   char           *first,*second;
3169c9d3cfdSBarry Smith   PetscToken     token;
317e5c89e4eSSatish Balay 
318e5c89e4eSSatish Balay   PetscFunctionBegin;
3199566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(in_str,' ',&token));
3209566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token,&first));
32196fc60bcSBarry Smith   while (first) {
322d06005cbSLisandro Dalcin     PetscBool isfile,isfileyaml,isstringyaml,ispush,ispop,key;
3239566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first,"-options_file",&isfile));
3249566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first,"-options_file_yaml",&isfileyaml));
3259566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first,"-options_string_yaml",&isstringyaml));
3269566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first,"-prefix_push",&ispush));
3279566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(first,"-prefix_pop",&ispop));
3289566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(first,&key));
329d06005cbSLisandro Dalcin     if (!key) {
3309566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&first));
331d06005cbSLisandro Dalcin     } else if (isfile) {
3329566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&second));
3339566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm,options,second,PETSC_TRUE));
3349566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&first));
335d06005cbSLisandro Dalcin     } else if (isfileyaml) {
3369566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&second));
3379566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm,options,second,PETSC_TRUE));
3389566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&first));
339d06005cbSLisandro Dalcin     } else if (isstringyaml) {
3409566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&second));
3419566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options,second));
3429566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&first));
343d06005cbSLisandro Dalcin     } else if (ispush) {
3449566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&second));
3459566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options,second));
3469566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&first));
3479db968c8SJed Brown     } else if (ispop) {
3489566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
3499566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&first));
350d06005cbSLisandro Dalcin     } else {
3519566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&second));
3529566063dSJacob Faibussowitsch       PetscCall(PetscOptionsValidKey(second,&key));
35396fc60bcSBarry Smith       if (!key) {
3549566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options,first,second));
3559566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token,&first));
35696fc60bcSBarry Smith       } else {
3579566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options,first,NULL));
35896fc60bcSBarry Smith         first = second;
35996fc60bcSBarry Smith       }
360e5c89e4eSSatish Balay     }
361e5c89e4eSSatish Balay   }
3629566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
363e5c89e4eSSatish Balay   PetscFunctionReturn(0);
364e5c89e4eSSatish Balay }
365e5c89e4eSSatish Balay 
3663fc1eb6aSBarry Smith /*
3673fc1eb6aSBarry Smith     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
3683fc1eb6aSBarry Smith */
3695fa91da5SBarry Smith static char *Petscgetline(FILE * f)
3705fa91da5SBarry Smith {
3715fa91da5SBarry Smith   size_t size  = 0;
3725fa91da5SBarry Smith   size_t len   = 0;
3735fa91da5SBarry Smith   size_t last  = 0;
3740298fd71SBarry Smith   char   *buf  = NULL;
3755fa91da5SBarry Smith 
37602c9f0b5SLisandro Dalcin   if (feof(f)) return NULL;
3775fa91da5SBarry Smith   do {
3785fa91da5SBarry Smith     size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
3796e0c8459SSatish Balay     buf   = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
3805fa91da5SBarry Smith     /* Actually do the read. Note that fgets puts a terminal '\0' on the
3815fa91da5SBarry Smith     end of the string, so we make sure we overwrite this */
382e86f3e45SDave May     if (!fgets(buf+len,1024,f)) buf[len]=0;
3835fa91da5SBarry Smith     PetscStrlen(buf,&len);
3845fa91da5SBarry Smith     last = len - 1;
3855fa91da5SBarry Smith   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
38608ac41f7SSatish Balay   if (len) return buf;
3875fa91da5SBarry Smith   free(buf);
38802c9f0b5SLisandro Dalcin   return NULL;
3895fa91da5SBarry Smith }
3905fa91da5SBarry Smith 
391be10d61cSLisandro Dalcin static PetscErrorCode PetscOptionsFilename(MPI_Comm comm,const char file[],char filename[PETSC_MAX_PATH_LEN],PetscBool *yaml)
392be10d61cSLisandro Dalcin {
393be10d61cSLisandro Dalcin   char           fname[PETSC_MAX_PATH_LEN+8],path[PETSC_MAX_PATH_LEN+8],*tail;
394e5c89e4eSSatish Balay 
395be10d61cSLisandro Dalcin   PetscFunctionBegin;
396362febeeSStefano Zampini   *yaml = PETSC_FALSE;
3979566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(comm,file,fname,sizeof(fname)));
3989566063dSJacob Faibussowitsch   PetscCall(PetscFixFilename(fname,path));
3999566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(path,":yaml",yaml));
400be10d61cSLisandro Dalcin   if (*yaml) {
4019566063dSJacob Faibussowitsch     PetscCall(PetscStrrchr(path,':',&tail));
402be10d61cSLisandro Dalcin     tail[-1] = 0; /* remove ":yaml" suffix from path */
403be10d61cSLisandro Dalcin   }
4049566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(filename,path,PETSC_MAX_PATH_LEN));
405a1d2f846SLisandro Dalcin   /* check for standard YAML and JSON filename extensions */
4069566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename,".yaml",yaml));
4079566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename,".yml", yaml));
4089566063dSJacob Faibussowitsch   if (!*yaml) PetscCall(PetscStrendswith(filename,".json",yaml));
409a1d2f846SLisandro Dalcin   if (!*yaml) { /* check file contents */
410a1d2f846SLisandro Dalcin     PetscMPIInt rank;
4119566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm,&rank));
412dd400576SPatrick Sanan     if (rank == 0) {
413a1d2f846SLisandro Dalcin       FILE *fh = fopen(filename,"r");
414a1d2f846SLisandro Dalcin       if (fh) {
415a1d2f846SLisandro Dalcin         char buf[6] = "";
416a1d2f846SLisandro Dalcin         if (fread(buf,1,6,fh) > 0) {
4179566063dSJacob Faibussowitsch           PetscCall(PetscStrncmp(buf,"%YAML ",6,yaml));  /* check for '%YAML' tag */
4189566063dSJacob Faibussowitsch           if (!*yaml) PetscCall(PetscStrncmp(buf,"---",3,yaml));  /* check for document start */
419a1d2f846SLisandro Dalcin         }
420a1d2f846SLisandro Dalcin         (void)fclose(fh);
421a1d2f846SLisandro Dalcin       }
422a1d2f846SLisandro Dalcin     }
4239566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(yaml,1,MPIU_BOOL,0,comm));
424a1d2f846SLisandro Dalcin   }
425be10d61cSLisandro Dalcin   PetscFunctionReturn(0);
426be10d61cSLisandro Dalcin }
427e5c89e4eSSatish Balay 
428be10d61cSLisandro Dalcin static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
429e5c89e4eSSatish Balay {
4308c0b561eSLisandro Dalcin   char           *string,*vstring = NULL,*astring = NULL,*packed = NULL;
4317fb43599SVaclav Hapla   char           *tokens[4];
43213e3f751SJed Brown   size_t         i,len,bytes;
433e5c89e4eSSatish Balay   FILE           *fd;
4347fb43599SVaclav Hapla   PetscToken     token=NULL;
435ed9cf6e9SBarry Smith   int            err;
436581bbe83SVaclav Hapla   char           *cmatch;
437581bbe83SVaclav Hapla   const char     cmt='#';
4389210b8eaSVaclav Hapla   PetscInt       line=1;
4393a018368SJed Brown   PetscMPIInt    rank,cnt=0,acnt=0,counts[2];
4409210b8eaSVaclav Hapla   PetscBool      isdir,alias=PETSC_FALSE,valid;
441e5c89e4eSSatish Balay 
442e5c89e4eSSatish Balay   PetscFunctionBegin;
4439566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tokens,sizeof(tokens)));
4449566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
445dd400576SPatrick Sanan   if (rank == 0) {
4468c0b561eSLisandro Dalcin     char fpath[PETSC_MAX_PATH_LEN];
4478c0b561eSLisandro Dalcin     char fname[PETSC_MAX_PATH_LEN];
44805c7dedfSBarry Smith 
4499566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF,file,fpath,sizeof(fpath)));
4509566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath,fname));
4518c0b561eSLisandro Dalcin 
452e5c89e4eSSatish Balay     fd   = fopen(fname,"r");
4539566063dSJacob Faibussowitsch     PetscCall(PetscTestDirectory(fname,'r',&isdir));
45408401ef6SPierre Jolivet     PetscCheck(!isdir || !require,PETSC_COMM_SELF,PETSC_ERR_USER,"Specified options file %s is a directory",fname);
455ad38b122SPatrick Sanan     if (fd && !isdir) {
4563a018368SJed Brown       PetscSegBuffer vseg,aseg;
4579566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1,4000,&vseg));
4589566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(1,2000,&aseg));
4593a018368SJed Brown 
4609b754dc9SBarry Smith       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
4619566063dSJacob Faibussowitsch       PetscCall(PetscInfo(NULL,"Opened options file %s\n",file));
462e24ecc5dSJed Brown 
4635fa91da5SBarry Smith       while ((string = Petscgetline(fd))) {
4644704e885SBarry Smith         /* eliminate comments from each line */
4659566063dSJacob Faibussowitsch         PetscCall(PetscStrchr(string,cmt,&cmatch));
46690f79514SSatish Balay         if (cmatch) *cmatch = 0;
4679566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(string,&len));
4685981331cSSatish Balay         /* replace tabs, ^M, \n with " " */
469e5c89e4eSSatish Balay         for (i=0; i<len; i++) {
4705981331cSSatish Balay           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
471e5c89e4eSSatish Balay             string[i] = ' ';
472e5c89e4eSSatish Balay           }
473e5c89e4eSSatish Balay         }
4749566063dSJacob Faibussowitsch         PetscCall(PetscTokenCreate(string,' ',&token));
4759566063dSJacob Faibussowitsch         PetscCall(PetscTokenFind(token,&tokens[0]));
4767fb43599SVaclav Hapla         if (!tokens[0]) {
47702b0d46eSSatish Balay           goto destroy;
4787fb43599SVaclav Hapla         } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
4799566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token,&tokens[0]));
48090f79514SSatish Balay         }
4817fb43599SVaclav Hapla         for (i=1; i<4; i++) {
4829566063dSJacob Faibussowitsch           PetscCall(PetscTokenFind(token,&tokens[i]));
4837fb43599SVaclav Hapla         }
4847fb43599SVaclav Hapla         if (!tokens[0]) {
4852662f744SSatish Balay           goto destroy;
4867fb43599SVaclav Hapla         } else if (tokens[0][0] == '-') {
4879566063dSJacob Faibussowitsch           PetscCall(PetscOptionsValidKey(tokens[0],&valid));
48828b400f6SJacob 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]);
4899566063dSJacob Faibussowitsch           PetscCall(PetscStrlen(tokens[0],&len));
4909566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(vseg,len+1,&vstring));
4919566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(vstring,tokens[0],len));
492e24ecc5dSJed Brown           vstring[len] = ' ';
4937fb43599SVaclav Hapla           if (tokens[1]) {
4949566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1],&valid));
49528b400f6SJacob 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]);
4969566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1],&len));
4979566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(vseg,len+3,&vstring));
498e24ecc5dSJed Brown             vstring[0] = '"';
4999566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(vstring+1,tokens[1],len));
500e24ecc5dSJed Brown             vstring[len+1] = '"';
501e24ecc5dSJed Brown             vstring[len+2] = ' ';
50209192fe3SBarry Smith           }
50390f79514SSatish Balay         } else {
5049566063dSJacob Faibussowitsch           PetscCall(PetscStrcasecmp(tokens[0],"alias",&alias));
5059210b8eaSVaclav Hapla           if (alias) {
5069566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[1],&valid));
50728b400f6SJacob 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]);
50808401ef6SPierre 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]);
5099566063dSJacob Faibussowitsch             PetscCall(PetscOptionsValidKey(tokens[2],&valid));
51028b400f6SJacob 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]);
5119566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[1],&len));
5129566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg,len+1,&astring));
5139566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring,tokens[1],len));
514e24ecc5dSJed Brown             astring[len] = ' ';
515e24ecc5dSJed Brown 
5169566063dSJacob Faibussowitsch             PetscCall(PetscStrlen(tokens[2],&len));
5179566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(aseg,len+1,&astring));
5189566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(astring,tokens[2],len));
519e24ecc5dSJed Brown             astring[len] = ' ';
52098921bdaSJacob 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]);
5219210b8eaSVaclav Hapla         }
5229210b8eaSVaclav Hapla         {
5239210b8eaSVaclav Hapla           const char *extraToken = alias ? tokens[3] : tokens[2];
52428b400f6SJacob Faibussowitsch           PetscCheck(!extraToken,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %" PetscInt_FMT ": extra token %s",fname,line,extraToken);
525e5c89e4eSSatish Balay         }
52602b0d46eSSatish Balay destroy:
5274b40f50bSBarry Smith         free(string);
5289566063dSJacob Faibussowitsch         PetscCall(PetscTokenDestroy(&token));
5299210b8eaSVaclav Hapla         alias = PETSC_FALSE;
5309210b8eaSVaclav Hapla         line++;
531e5c89e4eSSatish Balay       }
532ed9cf6e9SBarry Smith       err = fclose(fd);
53328b400f6SJacob Faibussowitsch       PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file %s",fname);
5349566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(aseg,&bytes)); /* size without null termination */
5359566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes,&acnt));
5369566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(aseg,1,&astring));
537e24ecc5dSJed Brown       astring[0] = 0;
5389566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGetSize(vseg,&bytes)); /* size without null termination */
5399566063dSJacob Faibussowitsch       PetscCall(PetscMPIIntCast(bytes,&cnt));
5409566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(vseg,1,&vstring));
541e24ecc5dSJed Brown       vstring[0] = 0;
5429566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(2+acnt+cnt,&packed));
5439566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(aseg,packed));
5449566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractTo(vseg,packed+acnt+1));
5459566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&aseg));
5469566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&vseg));
54728b400f6SJacob Faibussowitsch     } else PetscCheck(!require,PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open options file %s",fname);
5489b754dc9SBarry Smith   }
54905c7dedfSBarry Smith 
5503a018368SJed Brown   counts[0] = acnt;
5513a018368SJed Brown   counts[1] = cnt;
5524201f521SBarry Smith   err = MPI_Bcast(counts,2,MPI_INT,0,comm);
55328b400f6SJacob 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/");
5543a018368SJed Brown   acnt = counts[0];
5553a018368SJed Brown   cnt = counts[1];
5563a018368SJed Brown   if (rank) {
5579566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(2+acnt+cnt,&packed));
5583a018368SJed Brown   }
5593a018368SJed Brown   if (acnt || cnt) {
5609566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm));
5613a018368SJed Brown     astring = packed;
5623a018368SJed Brown     vstring = packed + acnt + 1;
5633a018368SJed Brown   }
5643a018368SJed Brown 
5659b754dc9SBarry Smith   if (acnt) {
5669566063dSJacob Faibussowitsch     PetscCall(PetscTokenCreate(astring,' ',&token));
5679566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token,&tokens[0]));
5687fb43599SVaclav Hapla     while (tokens[0]) {
5699566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&tokens[1]));
5709566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetAlias(options,tokens[0],tokens[1]));
5719566063dSJacob Faibussowitsch       PetscCall(PetscTokenFind(token,&tokens[0]));
5729b754dc9SBarry Smith     }
5739566063dSJacob Faibussowitsch     PetscCall(PetscTokenDestroy(&token));
5749b754dc9SBarry Smith   }
5759b754dc9SBarry Smith 
5761baa6e33SBarry Smith   if (cnt) PetscCall(PetscOptionsInsertString(options,vstring));
5779566063dSJacob Faibussowitsch   PetscCall(PetscFree(packed));
578e5c89e4eSSatish Balay   PetscFunctionReturn(0);
579e5c89e4eSSatish Balay }
580e5c89e4eSSatish Balay 
581d06005cbSLisandro Dalcin /*@C
582be10d61cSLisandro Dalcin      PetscOptionsInsertFile - Inserts options into the database from a file.
583be10d61cSLisandro Dalcin 
584be10d61cSLisandro Dalcin      Collective
585be10d61cSLisandro Dalcin 
586d8d19677SJose E. Roman   Input Parameters:
587be10d61cSLisandro Dalcin +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
588be10d61cSLisandro Dalcin .   options - options database, use NULL for default global database
589be10d61cSLisandro Dalcin .   file - name of file,
590be10d61cSLisandro Dalcin            ".yml" and ".yaml" filename extensions are inserted as YAML options,
591be10d61cSLisandro Dalcin            append ":yaml" to filename to force YAML options.
592be10d61cSLisandro Dalcin -   require - if PETSC_TRUE will generate an error if the file does not exist
593be10d61cSLisandro Dalcin 
594be10d61cSLisandro Dalcin   Notes:
595be10d61cSLisandro Dalcin    Use  # for lines that are comments and which should be ignored.
596be10d61cSLisandro Dalcin    Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
597be10d61cSLisandro Dalcin    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
598be10d61cSLisandro Dalcin    calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().
599be10d61cSLisandro Dalcin    The collectivity of this routine is complex; only the MPI processes in comm will
600be10d61cSLisandro Dalcin    have the affect of these options. If some processes that create objects call this routine and others do
601be10d61cSLisandro Dalcin    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
602be10d61cSLisandro Dalcin    on different ranks.
603be10d61cSLisandro Dalcin 
604be10d61cSLisandro Dalcin   Level: developer
605be10d61cSLisandro Dalcin 
606db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
607db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
608db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
609c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
610db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
611db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
612be10d61cSLisandro Dalcin 
613be10d61cSLisandro Dalcin @*/
614be10d61cSLisandro Dalcin PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
615be10d61cSLisandro Dalcin {
616be10d61cSLisandro Dalcin   char           filename[PETSC_MAX_PATH_LEN];
617be10d61cSLisandro Dalcin   PetscBool      yaml;
618be10d61cSLisandro Dalcin 
619be10d61cSLisandro Dalcin   PetscFunctionBegin;
6209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFilename(comm,file,filename,&yaml));
621be10d61cSLisandro Dalcin   if (yaml) {
6229566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFileYAML(comm,options,filename,require));
623be10d61cSLisandro Dalcin   } else {
6249566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFilePetsc(comm,options,filename,require));
625be10d61cSLisandro Dalcin   }
626be10d61cSLisandro Dalcin   PetscFunctionReturn(0);
627be10d61cSLisandro Dalcin }
628be10d61cSLisandro Dalcin 
629be10d61cSLisandro Dalcin /*@C
630d06005cbSLisandro Dalcin    PetscOptionsInsertArgs - Inserts options into the database from a array of strings
631d06005cbSLisandro Dalcin 
632d06005cbSLisandro Dalcin    Logically Collective
633d06005cbSLisandro Dalcin 
634d8d19677SJose E. Roman    Input Parameters:
635d06005cbSLisandro Dalcin +  options - options object
6366aad120cSJose E. Roman .  argc - the array length
637d06005cbSLisandro Dalcin -  args - the string array
638d06005cbSLisandro Dalcin 
639d06005cbSLisandro Dalcin    Level: intermediate
640d06005cbSLisandro Dalcin 
641db781477SPatrick Sanan .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
642d06005cbSLisandro Dalcin @*/
643d06005cbSLisandro Dalcin PetscErrorCode PetscOptionsInsertArgs(PetscOptions options,int argc,char *args[])
64485079163SJed Brown {
645d06005cbSLisandro Dalcin   MPI_Comm       comm = PETSC_COMM_WORLD;
646d06005cbSLisandro Dalcin   int            left          = PetscMax(argc,0);
647d06005cbSLisandro Dalcin   char           *const *eargs = args;
64885079163SJed Brown 
64985079163SJed Brown   PetscFunctionBegin;
65085079163SJed Brown   while (left) {
651d06005cbSLisandro Dalcin     PetscBool isfile,isfileyaml,isstringyaml,ispush,ispop,key;
6529566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0],"-options_file",&isfile));
6539566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0],"-options_file_yaml",&isfileyaml));
6549566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0],"-options_string_yaml",&isstringyaml));
6559566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0],"-prefix_push",&ispush));
6569566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(eargs[0],"-prefix_pop",&ispop));
6579566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(eargs[0],&key));
658093de6efSBarry Smith     if (!key) {
65985079163SJed Brown       eargs++; left--;
660d06005cbSLisandro Dalcin     } else if (isfile) {
661cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-',PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
6629566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFile(comm,options,eargs[1],PETSC_TRUE));
66385079163SJed Brown       eargs += 2; left -= 2;
664d06005cbSLisandro Dalcin     } else if (isfileyaml) {
665cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-',PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file_yaml filename option");
6669566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertFileYAML(comm,options,eargs[1],PETSC_TRUE));
667d06005cbSLisandro Dalcin       eargs += 2; left -= 2;
668d06005cbSLisandro Dalcin     } else if (isstringyaml) {
669cc73adaaSBarry Smith       PetscCheck(left > 1 && eargs[1][0] != '-',PETSC_COMM_SELF,PETSC_ERR_USER,"Missing string for -options_string_yaml string option");
6709566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options,eargs[1]));
671d06005cbSLisandro Dalcin       eargs += 2; left -= 2;
672d06005cbSLisandro Dalcin     } else if (ispush) {
67308401ef6SPierre Jolivet       PetscCheck(left > 1,PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
674cc73adaaSBarry Smith       PetscCheck(eargs[1][0] != '-',PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
6759566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options,eargs[1]));
6769db968c8SJed Brown       eargs += 2; left -= 2;
677d06005cbSLisandro Dalcin     } else if (ispop) {
6789566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
6799db968c8SJed Brown       eargs++; left--;
6807935c3d8SJed Brown     } else {
6817935c3d8SJed Brown       PetscBool nextiskey = PETSC_FALSE;
6829566063dSJacob Faibussowitsch       if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1],&nextiskey));
68398b6bf53SJed Brown       if (left < 2 || nextiskey) {
6849566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options,eargs[0],NULL));
68585079163SJed Brown         eargs++; left--;
68685079163SJed Brown       } else {
6879566063dSJacob Faibussowitsch         PetscCall(PetscOptionsSetValue(options,eargs[0],eargs[1]));
68885079163SJed Brown         eargs += 2; left -= 2;
68985079163SJed Brown       }
69085079163SJed Brown     }
6917935c3d8SJed Brown   }
69285079163SJed Brown   PetscFunctionReturn(0);
69385079163SJed Brown }
69485079163SJed Brown 
6959fbee547SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt,const char *val[],PetscBool set[],PetscBool *flg)
696c5b5d8d5SVaclav Hapla {
697c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
698c5b5d8d5SVaclav Hapla   if (set[opt]) {
6999566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(val[opt],flg));
700c5b5d8d5SVaclav Hapla   } else *flg = PETSC_FALSE;
701c5b5d8d5SVaclav Hapla   PetscFunctionReturn(0);
702c5b5d8d5SVaclav Hapla }
703c5b5d8d5SVaclav Hapla 
704660278c0SBarry Smith /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
705c5b5d8d5SVaclav Hapla static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options,int argc,char *args[],PetscBool *skip_petscrc,PetscBool *skip_petscrc_set)
706c5b5d8d5SVaclav Hapla {
707c5b5d8d5SVaclav Hapla   const char* const *opt = precedentOptions;
708c5b5d8d5SVaclav Hapla   const size_t      n = PO_NUM;
709c5b5d8d5SVaclav Hapla   size_t            o;
710c5b5d8d5SVaclav Hapla   int               a;
711c5b5d8d5SVaclav Hapla   const char        **val;
7120c99d500SBarry Smith   char              **cval;
713660278c0SBarry Smith   PetscBool         *set,unneeded;
714c5b5d8d5SVaclav Hapla 
715c5b5d8d5SVaclav Hapla   PetscFunctionBegin;
7160c99d500SBarry Smith   PetscCall(PetscCalloc2(n,&cval,n,&set));
7170c99d500SBarry Smith   val = (const char**) cval;
718c5b5d8d5SVaclav Hapla 
719c5b5d8d5SVaclav Hapla   /* Look for options possibly set using PetscOptionsSetValue beforehand */
720c5b5d8d5SVaclav Hapla   for (o=0; o<n; o++) {
7219566063dSJacob Faibussowitsch     PetscCall(PetscOptionsFindPair(options,NULL,opt[o],&val[o],&set[o]));
722c5b5d8d5SVaclav Hapla   }
723c5b5d8d5SVaclav Hapla 
724a5b23f4aSJose E. Roman   /* Loop through all args to collect last occurring value of each option */
725c5b5d8d5SVaclav Hapla   for (a=1; a<argc; a++) {
726c5b5d8d5SVaclav Hapla     PetscBool valid, eq;
727c5b5d8d5SVaclav Hapla 
7289566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(args[a],&valid));
729c5b5d8d5SVaclav Hapla     if (!valid) continue;
730c5b5d8d5SVaclav Hapla     for (o=0; o<n; o++) {
7319566063dSJacob Faibussowitsch       PetscCall(PetscStrcasecmp(args[a],opt[o],&eq));
732c5b5d8d5SVaclav Hapla       if (eq) {
733c5b5d8d5SVaclav Hapla         set[o] = PETSC_TRUE;
734c5b5d8d5SVaclav Hapla         if (a == argc-1 || !args[a+1] || !args[a+1][0] || args[a+1][0] == '-') val[o] = NULL;
735c5b5d8d5SVaclav Hapla         else val[o] = args[a+1];
736c5b5d8d5SVaclav Hapla         break;
737c5b5d8d5SVaclav Hapla       }
738c5b5d8d5SVaclav Hapla     }
739c5b5d8d5SVaclav Hapla   }
740c5b5d8d5SVaclav Hapla 
741c5b5d8d5SVaclav Hapla   /* Process flags */
7429566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
743d314f959SVaclav Hapla   if (options->help_intro) options->help = PETSC_TRUE;
7449566063dSJacob Faibussowitsch   else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP,             val,set,&options->help));
745660278c0SBarry Smith   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE,             val,set,&unneeded));
746660278c0SBarry Smith   /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
747660278c0SBarry Smith   if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options,opt[PO_CI_ENABLE],val[PO_CI_ENABLE],&a));
7489566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL,val,set,&options->monitorCancel));
7499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR,       val,set,&options->monitorFromOptions));
7509566063dSJacob Faibussowitsch   PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC,          val,set,skip_petscrc));
751c5b5d8d5SVaclav Hapla   *skip_petscrc_set = set[PO_SKIP_PETSCRC];
752c5b5d8d5SVaclav Hapla 
753c5b5d8d5SVaclav Hapla   /* Store precedent options in database and mark them as used */
754660278c0SBarry Smith   for (o=1; o<n; o++) {
755c5b5d8d5SVaclav Hapla     if (set[o]) {
7569566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue_Private(options,opt[o],val[o],&a));
757d06005cbSLisandro Dalcin       options->used[a] = PETSC_TRUE;
758c5b5d8d5SVaclav Hapla     }
759c5b5d8d5SVaclav Hapla   }
7600c99d500SBarry Smith   PetscCall(PetscFree2(cval,set));
761c5b5d8d5SVaclav Hapla   options->precedentProcessed = PETSC_TRUE;
762c5b5d8d5SVaclav Hapla   PetscFunctionReturn(0);
763c5b5d8d5SVaclav Hapla }
764c5b5d8d5SVaclav Hapla 
7659fbee547SJacob Faibussowitsch static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options,const char name[],PetscBool *flg)
766c5b5d8d5SVaclav Hapla {
76739a651e2SJacob Faibussowitsch   PetscFunctionBegin;
76839a651e2SJacob Faibussowitsch   PetscValidBoolPointer(flg,3);
769c5b5d8d5SVaclav Hapla   *flg = PETSC_FALSE;
770c5b5d8d5SVaclav Hapla   if (options->precedentProcessed) {
77139a651e2SJacob Faibussowitsch     for (int i = 0; i < PO_NUM; ++i) {
772c5b5d8d5SVaclav Hapla       if (!PetscOptNameCmp(precedentOptions[i],name)) {
773c5b5d8d5SVaclav Hapla         /* check if precedent option has been set already */
7749566063dSJacob Faibussowitsch         PetscCall(PetscOptionsFindPair(options,NULL,name,NULL,flg));
775c5b5d8d5SVaclav Hapla         if (*flg) break;
776c5b5d8d5SVaclav Hapla       }
777c5b5d8d5SVaclav Hapla     }
778c5b5d8d5SVaclav Hapla   }
77939a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
780c5b5d8d5SVaclav Hapla }
78185079163SJed Brown 
782e5c89e4eSSatish Balay /*@C
783e5c89e4eSSatish Balay    PetscOptionsInsert - Inserts into the options database from the command line,
784e5c89e4eSSatish Balay                         the environmental variable and a file.
785e5c89e4eSSatish Balay 
7861c9f3c13SBarry Smith    Collective on PETSC_COMM_WORLD
7871c9f3c13SBarry Smith 
788e5c89e4eSSatish Balay    Input Parameters:
789c5929fdfSBarry Smith +  options - options database or NULL for the default global database
790c5929fdfSBarry Smith .  argc - count of number of command line arguments
791e5c89e4eSSatish Balay .  args - the command line arguments
792be10d61cSLisandro Dalcin -  file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
793be10d61cSLisandro Dalcin           Use NULL or empty string to not check for code specific file.
794be10d61cSLisandro Dalcin           Also checks ~/.petscrc, .petscrc and petscrc.
795c5b5d8d5SVaclav Hapla           Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
796e5c89e4eSSatish Balay 
797e5c89e4eSSatish Balay    Note:
798e5c89e4eSSatish Balay    Since PetscOptionsInsert() is automatically called by PetscInitialize(),
799e5c89e4eSSatish Balay    the user does not typically need to call this routine. PetscOptionsInsert()
800e5c89e4eSSatish Balay    can be called several times, adding additional entries into the database.
801e5c89e4eSSatish Balay 
802081c24baSBoyana Norris    Options Database Keys:
803d06005cbSLisandro Dalcin +   -options_file <filename> - read options from a file
804d06005cbSLisandro Dalcin -   -options_file_yaml <filename> - read options from a YAML file
805c5b5d8d5SVaclav Hapla 
806c5b5d8d5SVaclav Hapla    See PetscInitialize() for options related to option database monitoring.
807081c24baSBoyana Norris 
808e5c89e4eSSatish Balay    Level: advanced
809e5c89e4eSSatish Balay 
810db781477SPatrick Sanan .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
811db781477SPatrick Sanan           `PetscInitialize()`
812e5c89e4eSSatish Balay @*/
813c5929fdfSBarry Smith PetscErrorCode PetscOptionsInsert(PetscOptions options,int *argc,char ***args,const char file[])
814e5c89e4eSSatish Balay {
815d06005cbSLisandro Dalcin   MPI_Comm       comm = PETSC_COMM_WORLD;
816e5c89e4eSSatish Balay   PetscMPIInt    rank;
817c5b5d8d5SVaclav Hapla   PetscBool      hasArgs = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
818c5b5d8d5SVaclav Hapla   PetscBool      skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
819e5c89e4eSSatish Balay 
820e5c89e4eSSatish Balay   PetscFunctionBegin;
82108401ef6SPierre Jolivet   PetscCheck(!hasArgs || (args && *args),comm,PETSC_ERR_ARG_NULL,"*argc > 1 but *args not given");
8229566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
823e5c89e4eSSatish Balay 
824c5b5d8d5SVaclav Hapla   if (!options) {
8259566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
826c5b5d8d5SVaclav Hapla     options = defaultoptions;
827c5b5d8d5SVaclav Hapla   }
828c5b5d8d5SVaclav Hapla   if (hasArgs) {
829c5b5d8d5SVaclav Hapla     /* process options with absolute precedence */
8309566063dSJacob Faibussowitsch     PetscCall(PetscOptionsProcessPrecedentFlags(options,*argc,*args,&skipPetscrc,&skipPetscrcSet));
831660278c0SBarry Smith     PetscCall(PetscOptionsGetBool(NULL,NULL,"-petsc_ci",&PetscCIEnabled,NULL));
832c5b5d8d5SVaclav Hapla   }
8334b09e917SBarry Smith   if (file && file[0]) {
8349566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm,options,file,PETSC_TRUE));
835c5b5d8d5SVaclav Hapla     /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
8369566063dSJacob Faibussowitsch     if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options,NULL,"-skip_petscrc",&skipPetscrc,NULL));
837321366bcSBarry Smith   }
838c5b5d8d5SVaclav Hapla   if (!skipPetscrc) {
839be10d61cSLisandro Dalcin     char filename[PETSC_MAX_PATH_LEN];
8409566063dSJacob Faibussowitsch     PetscCall(PetscGetHomeDirectory(filename,sizeof(filename)));
8419566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(filename,(int)sizeof(filename),MPI_CHAR,0,comm));
8429566063dSJacob Faibussowitsch     if (filename[0]) PetscCall(PetscStrcat(filename,"/.petscrc"));
8439566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm,options,filename,PETSC_FALSE));
8449566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm,options,".petscrc",PETSC_FALSE));
8459566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInsertFile(comm,options,"petscrc",PETSC_FALSE));
846e5c89e4eSSatish Balay   }
847e5c89e4eSSatish Balay 
8482d747510SLisandro Dalcin   /* insert environment options */
849e5c89e4eSSatish Balay   {
8502d747510SLisandro Dalcin     char   *eoptions = NULL;
851e5c89e4eSSatish Balay     size_t len       = 0;
852dd400576SPatrick Sanan     if (rank == 0) {
853e5c89e4eSSatish Balay       eoptions = (char*)getenv("PETSC_OPTIONS");
8549566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions,&len));
855e5c89e4eSSatish Balay     }
8569566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len,1,MPIU_SIZE_T,0,comm));
857e5c89e4eSSatish Balay     if (len) {
8589566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len+1,&eoptions));
8599566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions,len,MPI_CHAR,0,comm));
86096fc60bcSBarry Smith       if (rank) eoptions[len] = 0;
8619566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertString(options,eoptions));
8629566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
863e5c89e4eSSatish Balay     }
864e5c89e4eSSatish Balay   }
865e5c89e4eSSatish Balay 
866d06005cbSLisandro Dalcin   /* insert YAML environment options */
86756a31166SBarry Smith   {
8689fc438c3SToby Isaac     char   *eoptions = NULL;
8699fc438c3SToby Isaac     size_t len       = 0;
870dd400576SPatrick Sanan     if (rank == 0) {
8719fc438c3SToby Isaac       eoptions = (char*)getenv("PETSC_OPTIONS_YAML");
8729566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(eoptions,&len));
8739fc438c3SToby Isaac     }
8749566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Bcast(&len,1,MPIU_SIZE_T,0,comm));
8759fc438c3SToby Isaac     if (len) {
8769566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscMalloc1(len+1,&eoptions));
8779566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Bcast(eoptions,len,MPI_CHAR,0,comm));
8789fc438c3SToby Isaac       if (rank) eoptions[len] = 0;
8799566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInsertStringYAML(options,eoptions));
8809566063dSJacob Faibussowitsch       if (rank) PetscCall(PetscFree(eoptions));
8819fc438c3SToby Isaac     }
8829fc438c3SToby Isaac   }
8833bcbd388SSean Farley 
884c5b5d8d5SVaclav Hapla   /* insert command line options here because they take precedence over arguments in petscrc/environment */
8859566063dSJacob Faibussowitsch   if (hasArgs) PetscCall(PetscOptionsInsertArgs(options,*argc-1,*args+1));
886660278c0SBarry Smith   PetscCall(PetscOptionsGetBool(NULL,NULL,"-petsc_ci_portable_error_output",&PetscCIEnabledPortableErrorOutput,NULL));
887e5c89e4eSSatish Balay   PetscFunctionReturn(0);
888e5c89e4eSSatish Balay }
889e5c89e4eSSatish Balay 
890660278c0SBarry Smith /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
891660278c0SBarry Smith /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
892660278c0SBarry Smith static const char *PetscCIOptions[] = {"malloc_debug",
893660278c0SBarry Smith                                        "malloc_dump",
894660278c0SBarry Smith                                        "malloc_test",
895660278c0SBarry Smith                                        "nox",
896660278c0SBarry Smith                                        "nox_warning",
897660278c0SBarry Smith                                        "display",
898660278c0SBarry Smith                                        "saws_port_auto_select",
899660278c0SBarry Smith                                        "saws_port_auto_select_silent",
900660278c0SBarry Smith                                        "vecscatter_mpi1",
901660278c0SBarry Smith                                        "check_pointer_intensity",
902660278c0SBarry Smith                                        "cuda_initialize",
903660278c0SBarry Smith                                        "error_output_stdout",
904660278c0SBarry Smith                                        "use_gpu_aware_mpi",
905660278c0SBarry Smith                                        "checkfunctionlist",
906660278c0SBarry Smith                                        "petsc_ci",
907660278c0SBarry Smith                                        "petsc_ci_portable_error_output",
908660278c0SBarry Smith                                       };
909660278c0SBarry Smith 
910660278c0SBarry Smith static PetscBool PetscCIOption(const char *name)
911660278c0SBarry Smith {
912660278c0SBarry Smith   PetscInt  idx;
913660278c0SBarry Smith   PetscBool found;
914660278c0SBarry Smith 
915660278c0SBarry Smith   if (!PetscCIEnabled) return PETSC_FALSE;
916660278c0SBarry Smith   PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions),PetscCIOptions,name,&idx,&found);
917660278c0SBarry Smith   return found;
918660278c0SBarry Smith }
919660278c0SBarry Smith 
920e5c89e4eSSatish Balay /*@C
92188c29154SBarry Smith    PetscOptionsView - Prints the options that have been loaded. This is
922e5c89e4eSSatish Balay    useful for debugging purposes.
923e5c89e4eSSatish Balay 
924c139c21fSBarry Smith    Logically Collective on PetscViewer
925e5c89e4eSSatish Balay 
926d8d19677SJose E. Roman    Input Parameters:
927a2b725a8SWilliam Gropp +  options - options database, use NULL for default global database
928a2b725a8SWilliam Gropp -  viewer - must be an PETSCVIEWERASCII viewer
929e5c89e4eSSatish Balay 
930e5c89e4eSSatish Balay    Options Database Key:
93126a7e8d4SBarry Smith .  -options_view - Activates PetscOptionsView() within PetscFinalize()
932e5c89e4eSSatish Balay 
9339666a313SBarry Smith    Notes:
9349666a313SBarry Smith    Only the rank zero process of MPI_Comm used to create view prints the option values. Other processes
9351c9f3c13SBarry Smith    may have different values but they are not printed.
9361c9f3c13SBarry Smith 
937e5c89e4eSSatish Balay    Level: advanced
938e5c89e4eSSatish Balay 
939db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
940e5c89e4eSSatish Balay @*/
941c5929fdfSBarry Smith PetscErrorCode PetscOptionsView(PetscOptions options,PetscViewer viewer)
942e5c89e4eSSatish Balay {
943660278c0SBarry Smith   PetscInt       i, N = 0;
94488c29154SBarry Smith   PetscBool      isascii;
945e5c89e4eSSatish Balay 
946e5c89e4eSSatish Balay   PetscFunctionBegin;
9472d747510SLisandro Dalcin   if (viewer) PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
948c5929fdfSBarry Smith   options = options ? options : defaultoptions;
94988c29154SBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
9509566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
95128b400f6SJacob Faibussowitsch   PetscCheck(isascii,PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
95288c29154SBarry Smith 
953660278c0SBarry Smith   for (i=0; i<options->N; i++) {
954660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
955660278c0SBarry Smith     N++;
956660278c0SBarry Smith   }
957660278c0SBarry Smith 
958660278c0SBarry Smith   if (!N) {
9599566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n"));
9602d747510SLisandro Dalcin     PetscFunctionReturn(0);
96130694fe9SBarry Smith   }
9622d747510SLisandro Dalcin 
9639566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n"));
964e5c89e4eSSatish Balay   for (i=0; i<options->N; i++) {
965660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
966e5c89e4eSSatish Balay     if (options->values[i]) {
9679566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]));
968e5c89e4eSSatish Balay     } else {
9699566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]));
970e5c89e4eSSatish Balay     }
971e5c89e4eSSatish Balay   }
9729566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n"));
973e5c89e4eSSatish Balay   PetscFunctionReturn(0);
974e5c89e4eSSatish Balay }
975e5c89e4eSSatish Balay 
976e11779c2SBarry Smith /*
977e11779c2SBarry Smith    Called by error handlers to print options used in run
978e11779c2SBarry Smith */
979*f4bc716fSBarry Smith PetscErrorCode PetscOptionsLeftError(void)
980*f4bc716fSBarry Smith {
981*f4bc716fSBarry Smith   PetscInt i, nopt = 0;
982*f4bc716fSBarry Smith 
983*f4bc716fSBarry Smith   for (i=0; i<defaultoptions->N; i++) {
984*f4bc716fSBarry Smith     if (!defaultoptions->used[i]) {
985*f4bc716fSBarry Smith       if (PetscCIOption(defaultoptions->names[i])) continue;
986*f4bc716fSBarry Smith       nopt++;
987*f4bc716fSBarry Smith     }
988*f4bc716fSBarry Smith   }
989*f4bc716fSBarry Smith   if (nopt) {
990*f4bc716fSBarry Smith     (*PetscErrorPrintf)("WARNING! There are option(s) set that were not used! Could be the program crashed before they were used or a spelling mistake, etc!\n");
991*f4bc716fSBarry Smith     for (i=0; i<defaultoptions->N; i++) {
992*f4bc716fSBarry Smith       if (!defaultoptions->used[i]) {
993*f4bc716fSBarry Smith         if (PetscCIOption(defaultoptions->names[i])) continue;
994*f4bc716fSBarry Smith         if (defaultoptions->values[i]) (*PetscErrorPrintf)("Option left: name:-%s value: %s\n",defaultoptions->names[i],defaultoptions->values[i]);
995*f4bc716fSBarry Smith         else (*PetscErrorPrintf)("Option left: name:-%s (no value)\n",defaultoptions->names[i]);
996*f4bc716fSBarry Smith       }
997*f4bc716fSBarry Smith     }
998*f4bc716fSBarry Smith   }
999*f4bc716fSBarry Smith   return 0;
1000*f4bc716fSBarry Smith }
1001*f4bc716fSBarry Smith 
100295c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1003e11779c2SBarry Smith {
1004660278c0SBarry Smith   PetscInt     i, N = 0;
10054416b707SBarry Smith   PetscOptions options = defaultoptions;
1006e11779c2SBarry Smith 
1007660278c0SBarry Smith   for (i=0; i<options->N; i++) {
1008660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1009660278c0SBarry Smith     N++;
1010660278c0SBarry Smith   }
1011660278c0SBarry Smith 
1012660278c0SBarry Smith   if (N) {
1013e11779c2SBarry Smith     (*PetscErrorPrintf)("PETSc Option Table entries:\n");
1014e11779c2SBarry Smith   } else {
1015e11779c2SBarry Smith     (*PetscErrorPrintf)("No PETSc Option Table entries\n");
1016e11779c2SBarry Smith   }
1017e11779c2SBarry Smith   for (i=0; i<options->N; i++) {
1018660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
1019e11779c2SBarry Smith     if (options->values[i]) {
1020e11779c2SBarry Smith       (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]);
1021e11779c2SBarry Smith     } else {
1022e11779c2SBarry Smith       (*PetscErrorPrintf)("-%s\n",options->names[i]);
1023e11779c2SBarry Smith     }
1024e11779c2SBarry Smith   }
1025*f4bc716fSBarry Smith   return 0;
1026e11779c2SBarry Smith }
1027e11779c2SBarry Smith 
1028e5c89e4eSSatish Balay /*@C
102974e0666dSJed Brown    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
103074e0666dSJed Brown 
10311c9f3c13SBarry Smith    Logically Collective
103274e0666dSJed Brown 
1033d8d19677SJose E. Roman    Input Parameters:
1034c5929fdfSBarry Smith +  options - options database, or NULL for the default global database
1035c5929fdfSBarry Smith -  prefix - The string to append to the existing prefix
10369db968c8SJed Brown 
10379db968c8SJed Brown    Options Database Keys:
10389db968c8SJed Brown +   -prefix_push <some_prefix_> - push the given prefix
10399db968c8SJed Brown -   -prefix_pop - pop the last prefix
10409db968c8SJed Brown 
10419db968c8SJed Brown    Notes:
10429db968c8SJed Brown    It is common to use this in conjunction with -options_file as in
10439db968c8SJed Brown 
10449db968c8SJed Brown $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
10459db968c8SJed Brown 
10469db968c8SJed Brown    where the files no longer require all options to be prefixed with -system2_.
104774e0666dSJed Brown 
10489666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
10491c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
10501c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
10511c9f3c13SBarry Smith    on different ranks.
10521c9f3c13SBarry Smith 
105374e0666dSJed Brown Level: advanced
105474e0666dSJed Brown 
1055db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
105674e0666dSJed Brown @*/
1057c5929fdfSBarry Smith PetscErrorCode PetscOptionsPrefixPush(PetscOptions options,const char prefix[])
105874e0666dSJed Brown {
105974e0666dSJed Brown   size_t         n;
106074e0666dSJed Brown   PetscInt       start;
10612d747510SLisandro Dalcin   char           key[MAXOPTNAME+1];
10622d747510SLisandro Dalcin   PetscBool      valid;
106374e0666dSJed Brown 
106474e0666dSJed Brown   PetscFunctionBegin;
1065064a246eSJacob Faibussowitsch   PetscValidCharPointer(prefix,2);
1066c5929fdfSBarry Smith   options = options ? options : defaultoptions;
106708401ef6SPierre Jolivet   PetscCheck(options->prefixind < MAXPREFIXES,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum depth of prefix stack %d exceeded, recompile \n src/sys/objects/options.c with larger value for MAXPREFIXES",MAXPREFIXES);
10682d747510SLisandro Dalcin   key[0] = '-'; /* keys must start with '-' */
10699566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(key+1,prefix,sizeof(key)-1));
10709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(key,&valid));
10718bf569ecSLisandro 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 */
107228b400f6SJacob 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":"");
107374e0666dSJed Brown   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
10749566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(prefix,&n));
107508401ef6SPierre Jolivet   PetscCheck(n+1 <= sizeof(options->prefix)-start,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %zu exceeded",sizeof(options->prefix));
10769566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(options->prefix+start,prefix,n+1));
107774e0666dSJed Brown   options->prefixstack[options->prefixind++] = start+n;
107874e0666dSJed Brown   PetscFunctionReturn(0);
107974e0666dSJed Brown }
108074e0666dSJed Brown 
1081c5929fdfSBarry Smith /*@C
108274e0666dSJed Brown    PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details
108374e0666dSJed Brown 
10841c9f3c13SBarry Smith    Logically Collective on the MPI_Comm that called PetscOptionsPrefixPush()
108574e0666dSJed Brown 
1086c5929fdfSBarry Smith   Input Parameters:
1087c5929fdfSBarry Smith .  options - options database, or NULL for the default global database
1088c5929fdfSBarry Smith 
108974e0666dSJed Brown    Level: advanced
109074e0666dSJed Brown 
1091db781477SPatrick Sanan .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
109274e0666dSJed Brown @*/
1093c5929fdfSBarry Smith PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
109474e0666dSJed Brown {
109574e0666dSJed Brown   PetscInt offset;
109674e0666dSJed Brown 
109774e0666dSJed Brown   PetscFunctionBegin;
1098c5929fdfSBarry Smith   options = options ? options : defaultoptions;
109908401ef6SPierre Jolivet   PetscCheck(options->prefixind >= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
110074e0666dSJed Brown   options->prefixind--;
110174e0666dSJed Brown   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
110274e0666dSJed Brown   options->prefix[offset] = 0;
110374e0666dSJed Brown   PetscFunctionReturn(0);
110474e0666dSJed Brown }
110574e0666dSJed Brown 
1106a542b6e8SBarry Smith /*@C
1107a542b6e8SBarry Smith     PetscOptionsClear - Removes all options form the database leaving it empty.
1108a542b6e8SBarry Smith 
11091c9f3c13SBarry Smith     Logically Collective
11101c9f3c13SBarry Smith 
1111c5929fdfSBarry Smith   Input Parameters:
1112c5929fdfSBarry Smith .  options - options database, use NULL for the default global database
1113c5929fdfSBarry Smith 
11149666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
11151c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
11161c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11171c9f3c13SBarry Smith    on different ranks.
11181c9f3c13SBarry Smith 
1119a542b6e8SBarry Smith    Level: developer
1120a542b6e8SBarry Smith 
1121db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1122a542b6e8SBarry Smith @*/
1123c5929fdfSBarry Smith PetscErrorCode PetscOptionsClear(PetscOptions options)
1124a542b6e8SBarry Smith {
1125a542b6e8SBarry Smith   PetscInt i;
1126a542b6e8SBarry Smith 
112739a651e2SJacob Faibussowitsch   PetscFunctionBegin;
1128c5929fdfSBarry Smith   options = options ? options : defaultoptions;
112939a651e2SJacob Faibussowitsch   if (!options) PetscFunctionReturn(0);
11302d747510SLisandro Dalcin 
1131a542b6e8SBarry Smith   for (i=0; i<options->N; i++) {
1132a542b6e8SBarry Smith     if (options->names[i])  free(options->names[i]);
1133a542b6e8SBarry Smith     if (options->values[i]) free(options->values[i]);
1134a542b6e8SBarry Smith   }
11352d747510SLisandro Dalcin   options->N = 0;
11362d747510SLisandro Dalcin 
1137a542b6e8SBarry Smith   for (i=0; i<options->Naliases; i++) {
1138a542b6e8SBarry Smith     free(options->aliases1[i]);
1139a542b6e8SBarry Smith     free(options->aliases2[i]);
1140a542b6e8SBarry Smith   }
1141a542b6e8SBarry Smith   options->Naliases = 0;
1142a542b6e8SBarry Smith 
11432d747510SLisandro Dalcin   /* destroy hash table */
11442d747510SLisandro Dalcin   kh_destroy(HO,options->ht);
11452d747510SLisandro Dalcin   options->ht = NULL;
11460eb63584SBarry Smith 
11472d747510SLisandro Dalcin   options->prefixind = 0;
11482d747510SLisandro Dalcin   options->prefix[0] = 0;
11492d747510SLisandro Dalcin   options->help      = PETSC_FALSE;
115039a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
11514416b707SBarry Smith }
11524416b707SBarry Smith 
11532d747510SLisandro Dalcin /*@C
11542d747510SLisandro Dalcin    PetscOptionsSetAlias - Makes a key and alias for another key
11552d747510SLisandro Dalcin 
11561c9f3c13SBarry Smith    Logically Collective
11572d747510SLisandro Dalcin 
11582d747510SLisandro Dalcin    Input Parameters:
11592d747510SLisandro Dalcin +  options - options database, or NULL for default global database
11602d747510SLisandro Dalcin .  newname - the alias
11612d747510SLisandro Dalcin -  oldname - the name that alias will refer to
11622d747510SLisandro Dalcin 
11632d747510SLisandro Dalcin    Level: advanced
11642d747510SLisandro Dalcin 
11659666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
11661c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
11671c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
11681c9f3c13SBarry Smith    on different ranks.
11691c9f3c13SBarry Smith 
1170c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1171c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1172db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1173c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1174db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1175db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
11762d747510SLisandro Dalcin @*/
11772d747510SLisandro Dalcin PetscErrorCode PetscOptionsSetAlias(PetscOptions options,const char newname[],const char oldname[])
11782d747510SLisandro Dalcin {
11792d747510SLisandro Dalcin   PetscInt       n;
11802d747510SLisandro Dalcin   size_t         len;
11819210b8eaSVaclav Hapla   PetscBool      valid;
11822d747510SLisandro Dalcin 
11832d747510SLisandro Dalcin   PetscFunctionBegin;
11842d747510SLisandro Dalcin   PetscValidCharPointer(newname,2);
11852d747510SLisandro Dalcin   PetscValidCharPointer(oldname,3);
11862d747510SLisandro Dalcin   options = options ? options : defaultoptions;
11879566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(newname,&valid));
118828b400f6SJacob Faibussowitsch   PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliased option %s",newname);
11899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsValidKey(oldname,&valid));
119028b400f6SJacob Faibussowitsch   PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliasee option %s",oldname);
11912d747510SLisandro Dalcin 
11922d747510SLisandro Dalcin   n = options->Naliases;
119308401ef6SPierre Jolivet   PetscCheck(n < MAXALIASES,PETSC_COMM_SELF,PETSC_ERR_MEM,"You have defined to many PETSc options aliases, limit %d recompile \n  src/sys/objects/options.c with larger value for MAXALIASES",MAXALIASES);
11942d747510SLisandro Dalcin 
11952d747510SLisandro Dalcin   newname++; oldname++;
11969566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(newname,&len));
11972d747510SLisandro Dalcin   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
11989566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(options->aliases1[n],newname));
11999566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(oldname,&len));
12002d747510SLisandro Dalcin   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
12019566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(options->aliases2[n],oldname));
12022d747510SLisandro Dalcin   options->Naliases++;
12032d747510SLisandro Dalcin   PetscFunctionReturn(0);
12042d747510SLisandro Dalcin }
12054416b707SBarry Smith 
1206e5c89e4eSSatish Balay /*@C
1207e5c89e4eSSatish Balay    PetscOptionsSetValue - Sets an option name-value pair in the options
1208e5c89e4eSSatish Balay    database, overriding whatever is already present.
1209e5c89e4eSSatish Balay 
12101c9f3c13SBarry Smith    Logically Collective
1211e5c89e4eSSatish Balay 
1212e5c89e4eSSatish Balay    Input Parameters:
1213c5929fdfSBarry Smith +  options - options database, use NULL for the default global database
1214c5929fdfSBarry Smith .  name - name of option, this SHOULD have the - prepended
12152d747510SLisandro Dalcin -  value - the option value (not used for all options, so can be NULL)
1216e5c89e4eSSatish Balay 
1217e5c89e4eSSatish Balay    Level: intermediate
1218e5c89e4eSSatish Balay 
1219e5c89e4eSSatish Balay    Note:
1220d49172ceSBarry Smith    This function can be called BEFORE PetscInitialize()
1221d49172ceSBarry Smith 
12229666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
12231c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
12241c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
12251c9f3c13SBarry Smith    on different ranks.
12261c9f3c13SBarry Smith 
12272d747510SLisandro Dalcin    Developers Note: Uses malloc() directly because PETSc may not be initialized yet.
1228b0250c70SBarry Smith 
1229db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1230e5c89e4eSSatish Balay @*/
12312d747510SLisandro Dalcin PetscErrorCode PetscOptionsSetValue(PetscOptions options,const char name[],const char value[])
1232e5c89e4eSSatish Balay {
123339a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSetValue_Private(options,name,value,NULL));
123539a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1236c5b5d8d5SVaclav Hapla }
1237c5b5d8d5SVaclav Hapla 
1238c5b5d8d5SVaclav Hapla static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options,const char name[],const char value[],int *pos)
1239c5b5d8d5SVaclav Hapla {
1240e5c89e4eSSatish Balay   size_t      len;
12412d747510SLisandro Dalcin   int         N,n,i;
1242e5c89e4eSSatish Balay   char      **names;
12432d747510SLisandro Dalcin   char        fullname[MAXOPTNAME] = "";
1244c5b5d8d5SVaclav Hapla   PetscBool   flg;
1245e5c89e4eSSatish Balay 
124639a651e2SJacob Faibussowitsch   PetscFunctionBegin;
12477272c0d2SVaclav Hapla   if (!options) {
12489566063dSJacob Faibussowitsch     PetscCall(PetscOptionsCreateDefault());
12497272c0d2SVaclav Hapla     options = defaultoptions;
1250c5929fdfSBarry Smith   }
125139a651e2SJacob Faibussowitsch   PetscCheck(name[0] == '-',PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"name %s must start with '-'",name);
12522d747510SLisandro Dalcin 
12539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsSkipPrecedent(options,name,&flg));
125439a651e2SJacob Faibussowitsch   if (flg) PetscFunctionReturn(0);
1255e5c89e4eSSatish Balay 
12562d747510SLisandro Dalcin   name++; /* skip starting dash */
12572d747510SLisandro Dalcin 
125874e0666dSJed Brown   if (options->prefixind > 0) {
1259d49172ceSBarry Smith     strncpy(fullname,options->prefix,sizeof(fullname));
12602d747510SLisandro Dalcin     fullname[sizeof(fullname)-1] = 0;
126189ae1891SBarry Smith     strncat(fullname,name,sizeof(fullname)-strlen(fullname)-1);
12622d747510SLisandro Dalcin     fullname[sizeof(fullname)-1] = 0;
126374e0666dSJed Brown     name = fullname;
126474e0666dSJed Brown   }
126574e0666dSJed Brown 
126674e0666dSJed Brown   /* check against aliases */
1267e5c89e4eSSatish Balay   N = options->Naliases;
1268e5c89e4eSSatish Balay   for (i=0; i<N; i++) {
12692d747510SLisandro Dalcin     int result = PetscOptNameCmp(options->aliases1[i],name);
12702d747510SLisandro Dalcin     if (!result) { name = options->aliases2[i]; break; }
1271e5c89e4eSSatish Balay   }
1272e5c89e4eSSatish Balay 
12732d747510SLisandro Dalcin   /* slow search */
12742d747510SLisandro Dalcin   N = n = options->N;
1275e5c89e4eSSatish Balay   names = options->names;
1276e5c89e4eSSatish Balay   for (i=0; i<N; i++) {
12772d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i],name);
12782d747510SLisandro Dalcin     if (!result) {
12792d747510SLisandro Dalcin       n = i; goto setvalue;
12802d747510SLisandro Dalcin     } else if (result > 0) {
12812d747510SLisandro Dalcin       n = i; break;
1282e5c89e4eSSatish Balay     }
1283e5c89e4eSSatish Balay   }
128439a651e2SJacob Faibussowitsch   PetscCheck(N < MAXOPTIONS,PETSC_COMM_SELF,PETSC_ERR_MEM,"Number of options %d < max number of options %d, can not allocate enough space",N,MAXOPTIONS);
128539a651e2SJacob Faibussowitsch 
12862d747510SLisandro Dalcin   /* shift remaining values up 1 */
1287e5c89e4eSSatish Balay   for (i=N; i>n; i--) {
12885e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i-1];
1289e5c89e4eSSatish Balay     options->values[i] = options->values[i-1];
1290e5c89e4eSSatish Balay     options->used[i]   = options->used[i-1];
1291e5c89e4eSSatish Balay   }
12922d747510SLisandro Dalcin   options->names[n]  = NULL;
12932d747510SLisandro Dalcin   options->values[n] = NULL;
12942d747510SLisandro Dalcin   options->used[n]   = PETSC_FALSE;
12952d747510SLisandro Dalcin   options->N++;
12962d747510SLisandro Dalcin 
12972d747510SLisandro Dalcin   /* destroy hash table */
12982d747510SLisandro Dalcin   kh_destroy(HO,options->ht);
12992d747510SLisandro Dalcin   options->ht = NULL;
13002d747510SLisandro Dalcin 
13012d747510SLisandro Dalcin   /* set new name */
130270d8d27cSBarry Smith   len = strlen(name);
13035e8c5e88SLisandro Dalcin   options->names[n] = (char*)malloc((len+1)*sizeof(char));
130439a651e2SJacob Faibussowitsch   PetscCheck(options->names[n],PETSC_COMM_SELF,PETSC_ERR_MEM,"Failed to allocate option name");
1305d49172ceSBarry Smith   strcpy(options->names[n],name);
13062d747510SLisandro Dalcin 
13072d747510SLisandro Dalcin setvalue:
13082d747510SLisandro Dalcin   /* set new value */
13092d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1310d49172ceSBarry Smith   len = value ? strlen(value) : 0;
13115e8c5e88SLisandro Dalcin   if (len) {
1312e5c89e4eSSatish Balay     options->values[n] = (char*)malloc((len+1)*sizeof(char));
1313d49172ceSBarry Smith     if (!options->values[n]) return PETSC_ERR_MEM;
1314d49172ceSBarry Smith     strcpy(options->values[n],value);
13152d747510SLisandro Dalcin   } else {
13162d747510SLisandro Dalcin     options->values[n] = NULL;
13172d747510SLisandro Dalcin   }
13182d747510SLisandro Dalcin 
131991ad3481SVaclav Hapla   /* handle -help so that it can be set from anywhere */
132091ad3481SVaclav Hapla   if (!PetscOptNameCmp(name,"help")) {
132191ad3481SVaclav Hapla     options->help = PETSC_TRUE;
1322d06005cbSLisandro Dalcin     options->help_intro = (value && !PetscOptNameCmp(value,"intro")) ? PETSC_TRUE : PETSC_FALSE;
132391ad3481SVaclav Hapla     options->used[n] = PETSC_TRUE;
132491ad3481SVaclav Hapla   }
132591ad3481SVaclav Hapla 
13269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsMonitor(options,name,value));
1327c5b5d8d5SVaclav Hapla   if (pos) *pos = n;
132839a651e2SJacob Faibussowitsch   PetscFunctionReturn(0);
1329e5c89e4eSSatish Balay }
1330e5c89e4eSSatish Balay 
1331e5c89e4eSSatish Balay /*@C
1332e5c89e4eSSatish Balay    PetscOptionsClearValue - Clears an option name-value pair in the options
1333e5c89e4eSSatish Balay    database, overriding whatever is already present.
1334e5c89e4eSSatish Balay 
13351c9f3c13SBarry Smith    Logically Collective
1336e5c89e4eSSatish Balay 
1337d8d19677SJose E. Roman    Input Parameters:
1338c5929fdfSBarry Smith +  options - options database, use NULL for the default global database
1339a2b725a8SWilliam Gropp -  name - name of option, this SHOULD have the - prepended
1340e5c89e4eSSatish Balay 
1341e5c89e4eSSatish Balay    Level: intermediate
1342e5c89e4eSSatish Balay 
13439666a313SBarry Smith    The collectivity of this routine is complex; only the MPI processes that call this routine will
13441c9f3c13SBarry Smith    have the affect of these options. If some processes that create objects call this routine and others do
13451c9f3c13SBarry Smith    not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
13461c9f3c13SBarry Smith    on different ranks.
13471c9f3c13SBarry Smith 
1348db781477SPatrick Sanan .seealso: `PetscOptionsInsert()`
1349e5c89e4eSSatish Balay @*/
13502d747510SLisandro Dalcin PetscErrorCode PetscOptionsClearValue(PetscOptions options,const char name[])
1351e5c89e4eSSatish Balay {
13522d747510SLisandro Dalcin   int            N,n,i;
13532d747510SLisandro Dalcin   char           **names;
1354e5c89e4eSSatish Balay 
1355e5c89e4eSSatish Balay   PetscFunctionBegin;
1356c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1357cc73adaaSBarry Smith   PetscCheck(name[0] == '-',PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1358c9dcd962SLisandro Dalcin   if (!PetscOptNameCmp(name,"-help")) options->help = options->help_intro = PETSC_FALSE;
13592d747510SLisandro Dalcin 
13602d747510SLisandro Dalcin   name++; /* skip starting dash */
13612d747510SLisandro Dalcin 
13622d747510SLisandro Dalcin   /* slow search */
13632d747510SLisandro Dalcin   N = n = options->N;
1364e5c89e4eSSatish Balay   names = options->names;
1365e5c89e4eSSatish Balay   for (i=0; i<N; i++) {
13662d747510SLisandro Dalcin     int result = PetscOptNameCmp(names[i],name);
13672d747510SLisandro Dalcin     if (!result) {
13682d747510SLisandro Dalcin       n = i; break;
13692d747510SLisandro Dalcin     } else if (result > 0) {
13702d747510SLisandro Dalcin       n = N; break;
1371e5c89e4eSSatish Balay     }
13722d747510SLisandro Dalcin   }
13732d747510SLisandro Dalcin   if (n == N) PetscFunctionReturn(0); /* it was not present */
1374e5c89e4eSSatish Balay 
13752d747510SLisandro Dalcin   /* remove name and value */
13762d747510SLisandro Dalcin   if (options->names[n])  free(options->names[n]);
13772d747510SLisandro Dalcin   if (options->values[n]) free(options->values[n]);
1378e5c89e4eSSatish Balay   /* shift remaining values down 1 */
1379e5c89e4eSSatish Balay   for (i=n; i<N-1; i++) {
13805e8c5e88SLisandro Dalcin     options->names[i]  = options->names[i+1];
1381e5c89e4eSSatish Balay     options->values[i] = options->values[i+1];
1382e5c89e4eSSatish Balay     options->used[i]   = options->used[i+1];
1383e5c89e4eSSatish Balay   }
1384e5c89e4eSSatish Balay   options->N--;
13852d747510SLisandro Dalcin 
13862d747510SLisandro Dalcin   /* destroy hash table */
13872d747510SLisandro Dalcin   kh_destroy(HO,options->ht);
13882d747510SLisandro Dalcin   options->ht = NULL;
13892d747510SLisandro Dalcin 
13909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsMonitor(options,name,NULL));
1391e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1392e5c89e4eSSatish Balay }
1393e5c89e4eSSatish Balay 
1394e5c89e4eSSatish Balay /*@C
13952d747510SLisandro Dalcin    PetscOptionsFindPair - Gets an option name-value pair from the options database.
1396e5c89e4eSSatish Balay 
13972d747510SLisandro Dalcin    Not Collective
1398e5c89e4eSSatish Balay 
1399e5c89e4eSSatish Balay    Input Parameters:
14002d747510SLisandro Dalcin +  options - options database, use NULL for the default global database
14012d747510SLisandro Dalcin .  pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
14022d747510SLisandro Dalcin -  name - name of option, this SHOULD have the "-" prepended
1403e5c89e4eSSatish Balay 
14042d747510SLisandro Dalcin    Output Parameters:
14052d747510SLisandro Dalcin +  value - the option value (optional, not used for all options)
14062d747510SLisandro Dalcin -  set - whether the option is set (optional)
1407e5c89e4eSSatish Balay 
14089666a313SBarry Smith    Notes:
14099666a313SBarry Smith    Each process may find different values or no value depending on how options were inserted into the database
14101c9f3c13SBarry Smith 
14112d747510SLisandro Dalcin    Level: developer
14122d747510SLisandro Dalcin 
1413db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1414e5c89e4eSSatish Balay @*/
14152d747510SLisandro Dalcin PetscErrorCode PetscOptionsFindPair(PetscOptions options,const char pre[],const char name[],const char *value[],PetscBool *set)
1416e5c89e4eSSatish Balay {
14172d747510SLisandro Dalcin   char           buf[MAXOPTNAME];
1418daabea38SBarry Smith   PetscBool      usehashtable = PETSC_TRUE;
14192d747510SLisandro Dalcin   PetscBool      matchnumbers = PETSC_TRUE;
1420e5c89e4eSSatish Balay 
1421e5c89e4eSSatish Balay   PetscFunctionBegin;
1422c5929fdfSBarry Smith   options = options ? options : defaultoptions;
142308401ef6SPierre Jolivet   PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'),PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1424cc73adaaSBarry Smith   PetscCheck(name[0] == '-',PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1425e5c89e4eSSatish Balay 
14262d747510SLisandro Dalcin   name++; /* skip starting dash */
1427e5c89e4eSSatish Balay 
14287cd08cecSJed Brown   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
14292d747510SLisandro Dalcin   if (pre && pre[0]) {
14302d747510SLisandro Dalcin     char *ptr = buf;
14312d747510SLisandro Dalcin     if (name[0] == '-') { *ptr++ = '-';  name++; }
14329566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr,pre,buf+sizeof(buf)-ptr));
14339566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf,name,sizeof(buf)));
14342d747510SLisandro Dalcin     name = buf;
14357cd08cecSJed Brown   }
14362d747510SLisandro Dalcin 
143776bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
14382f828895SJed Brown     PetscBool valid;
14392d747510SLisandro Dalcin     char      key[MAXOPTNAME+1] = "-";
14409566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key+1,name,sizeof(key)-1));
14419566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key,&valid));
144228b400f6SJacob Faibussowitsch     PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
14432f828895SJed Brown   }
1444e5c89e4eSSatish Balay 
14452d747510SLisandro Dalcin   if (!options->ht && usehashtable) {
14462d747510SLisandro Dalcin     int i,ret;
14472d747510SLisandro Dalcin     khiter_t it;
14482d747510SLisandro Dalcin     khash_t(HO) *ht;
14492d747510SLisandro Dalcin     ht = kh_init(HO);
145028b400f6SJacob Faibussowitsch     PetscCheck(ht,PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
14512d747510SLisandro Dalcin     ret = kh_resize(HO,ht,options->N*2); /* twice the required size to reduce risk of collisions */
145228b400f6SJacob Faibussowitsch     PetscCheck(!ret,PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
14532d747510SLisandro Dalcin     for (i=0; i<options->N; i++) {
14542d747510SLisandro Dalcin       it = kh_put(HO,ht,options->names[i],&ret);
145508401ef6SPierre Jolivet       PetscCheck(ret == 1,PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
14562d747510SLisandro Dalcin       kh_val(ht,it) = i;
14572d747510SLisandro Dalcin     }
14582d747510SLisandro Dalcin     options->ht = ht;
14592d747510SLisandro Dalcin   }
14602d747510SLisandro Dalcin 
14612d747510SLisandro Dalcin   if (usehashtable)
14622d747510SLisandro Dalcin   { /* fast search */
14632d747510SLisandro Dalcin     khash_t(HO) *ht = options->ht;
14642d747510SLisandro Dalcin     khiter_t it = kh_get(HO,ht,name);
14652d747510SLisandro Dalcin     if (it != kh_end(ht)) {
14662d747510SLisandro Dalcin       int i = kh_val(ht,it);
1467e5c89e4eSSatish Balay       options->used[i]  = PETSC_TRUE;
14682d747510SLisandro Dalcin       if (value) *value = options->values[i];
14692d747510SLisandro Dalcin       if (set)   *set   = PETSC_TRUE;
14702d747510SLisandro Dalcin       PetscFunctionReturn(0);
14712d747510SLisandro Dalcin     }
14722d747510SLisandro Dalcin   } else
14732d747510SLisandro Dalcin   { /* slow search */
14742d747510SLisandro Dalcin     int i, N = options->N;
14752d747510SLisandro Dalcin     for (i=0; i<N; i++) {
1476daabea38SBarry Smith       int result = PetscOptNameCmp(options->names[i],name);
14772d747510SLisandro Dalcin       if (!result) {
14782d747510SLisandro Dalcin         options->used[i]  = PETSC_TRUE;
14792d747510SLisandro Dalcin         if (value) *value = options->values[i];
14802d747510SLisandro Dalcin         if (set)   *set   = PETSC_TRUE;
14812d747510SLisandro Dalcin         PetscFunctionReturn(0);
14822d747510SLisandro Dalcin       } else if (result > 0) {
1483e5c89e4eSSatish Balay         break;
1484e5c89e4eSSatish Balay       }
1485e5c89e4eSSatish Balay     }
14862d747510SLisandro Dalcin   }
14872d747510SLisandro Dalcin 
14882d747510SLisandro Dalcin   /*
14892d747510SLisandro Dalcin    The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
14902d747510SLisandro Dalcin    Maybe this special lookup mode should be enabled on request with a push/pop API.
14912d747510SLisandro Dalcin    The feature of matching _%d_ used sparingly in the codebase.
14922d747510SLisandro Dalcin    */
14932d747510SLisandro Dalcin   if (matchnumbers) {
14942d747510SLisandro Dalcin     int i,j,cnt = 0,locs[16],loce[16];
1495e5c89e4eSSatish Balay     /* determine the location and number of all _%d_ in the key */
14962d747510SLisandro Dalcin     for (i=0; name[i]; i++) {
14972d747510SLisandro Dalcin       if (name[i] == '_') {
14982d747510SLisandro Dalcin         for (j=i+1; name[j]; j++) {
14992d747510SLisandro Dalcin           if (name[j] >= '0' && name[j] <= '9') continue;
15002d747510SLisandro Dalcin           if (name[j] == '_' && j > i+1) { /* found a number */
1501e5c89e4eSSatish Balay             locs[cnt]   = i+1;
1502e5c89e4eSSatish Balay             loce[cnt++] = j+1;
1503e5c89e4eSSatish Balay           }
15042d747510SLisandro Dalcin           i = j-1;
1505e5c89e4eSSatish Balay           break;
1506e5c89e4eSSatish Balay         }
1507e5c89e4eSSatish Balay       }
1508e5c89e4eSSatish Balay     }
1509e5c89e4eSSatish Balay     for (i=0; i<cnt; i++) {
15102d747510SLisandro Dalcin       PetscBool found;
15112d747510SLisandro Dalcin       char      opt[MAXOPTNAME+1] = "-", tmp[MAXOPTNAME];
15129566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(tmp,name,PetscMin((size_t)(locs[i]+1),sizeof(tmp))));
15139566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt,tmp,sizeof(opt)));
15149566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(opt,name+loce[i],sizeof(opt)));
15159566063dSJacob Faibussowitsch       PetscCall(PetscOptionsFindPair(options,NULL,opt,value,&found));
15162d747510SLisandro Dalcin       if (found) {if (set) *set = PETSC_TRUE; PetscFunctionReturn(0);}
1517e5c89e4eSSatish Balay     }
1518e5c89e4eSSatish Balay   }
15192d747510SLisandro Dalcin 
15202d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
1521e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1522e5c89e4eSSatish Balay }
1523e5c89e4eSSatish Balay 
1524d6ced9c0SMatthew G. Knepley /* Check whether any option begins with pre+name */
15252d747510SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options,const char pre[], const char name[],const char *value[],PetscBool *set)
1526514bf10dSMatthew G Knepley {
15272d747510SLisandro Dalcin   char           buf[MAXOPTNAME];
1528d6ced9c0SMatthew G. Knepley   int            numCnt = 0, locs[16],loce[16];
1529514bf10dSMatthew G Knepley 
1530514bf10dSMatthew G Knepley   PetscFunctionBegin;
1531c5929fdfSBarry Smith   options = options ? options : defaultoptions;
1532cc73adaaSBarry Smith   PetscCheck(!pre || pre[0] != '-',PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1533cc73adaaSBarry Smith   PetscCheck(name[0] == '-',PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1534514bf10dSMatthew G Knepley 
15352d747510SLisandro Dalcin   name++; /* skip starting dash */
1536514bf10dSMatthew G Knepley 
1537514bf10dSMatthew G Knepley   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
15382d747510SLisandro Dalcin   if (pre && pre[0]) {
15392d747510SLisandro Dalcin     char *ptr = buf;
15402d747510SLisandro Dalcin     if (name[0] == '-') { *ptr++ = '-';  name++; }
15419566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(ptr,pre,sizeof(buf)+(size_t)(ptr-buf)));
15429566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(buf,name,sizeof(buf)));
15432d747510SLisandro Dalcin     name = buf;
1544514bf10dSMatthew G Knepley   }
15452d747510SLisandro Dalcin 
154676bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1547514bf10dSMatthew G Knepley     PetscBool valid;
15482d747510SLisandro Dalcin     char      key[MAXOPTNAME+1] = "-";
15499566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(key+1,name,sizeof(key)-1));
15509566063dSJacob Faibussowitsch     PetscCall(PetscOptionsValidKey(key,&valid));
155128b400f6SJacob Faibussowitsch     PetscCheck(valid,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1552514bf10dSMatthew G Knepley   }
1553514bf10dSMatthew G Knepley 
1554d6ced9c0SMatthew G. Knepley   /* determine the location and number of all _%d_ in the key */
1555d6ced9c0SMatthew G. Knepley   {
1556d6ced9c0SMatthew G. Knepley     int i,j;
1557d6ced9c0SMatthew G. Knepley     for (i=0; name[i]; i++) {
1558d6ced9c0SMatthew G. Knepley       if (name[i] == '_') {
1559d6ced9c0SMatthew G. Knepley         for (j=i+1; name[j]; j++) {
1560d6ced9c0SMatthew G. Knepley           if (name[j] >= '0' && name[j] <= '9') continue;
1561d6ced9c0SMatthew G. Knepley           if (name[j] == '_' && j > i+1) { /* found a number */
1562d6ced9c0SMatthew G. Knepley             locs[numCnt]   = i+1;
1563d6ced9c0SMatthew G. Knepley             loce[numCnt++] = j+1;
1564d6ced9c0SMatthew G. Knepley           }
1565d6ced9c0SMatthew G. Knepley           i = j-1;
1566d6ced9c0SMatthew G. Knepley           break;
1567d6ced9c0SMatthew G. Knepley         }
1568d6ced9c0SMatthew G. Knepley       }
1569d6ced9c0SMatthew G. Knepley     }
1570d6ced9c0SMatthew G. Knepley   }
1571d6ced9c0SMatthew G. Knepley 
15722d747510SLisandro Dalcin   { /* slow search */
1573d6ced9c0SMatthew G. Knepley     int       c, i;
15742d747510SLisandro Dalcin     size_t    len;
15752d747510SLisandro Dalcin     PetscBool match;
1576d6ced9c0SMatthew G. Knepley 
1577d6ced9c0SMatthew G. Knepley     for (c = -1; c < numCnt; ++c) {
1578d6ced9c0SMatthew G. Knepley       char opt[MAXOPTNAME+1] = "", tmp[MAXOPTNAME];
1579d6ced9c0SMatthew G. Knepley 
1580d6ced9c0SMatthew G. Knepley       if (c < 0) {
15819566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(opt,name));
1582d6ced9c0SMatthew G. Knepley       } else {
15839566063dSJacob Faibussowitsch         PetscCall(PetscStrncpy(tmp,name,PetscMin((size_t)(locs[c]+1),sizeof(tmp))));
15849566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(opt,tmp,sizeof(opt)));
15859566063dSJacob Faibussowitsch         PetscCall(PetscStrlcat(opt,name+loce[c],sizeof(opt)));
1586d6ced9c0SMatthew G. Knepley       }
15879566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(opt,&len));
15882d747510SLisandro Dalcin       for (i=0; i<options->N; i++) {
15899566063dSJacob Faibussowitsch         PetscCall(PetscStrncmp(options->names[i],opt,len,&match));
1590514bf10dSMatthew G Knepley         if (match) {
1591514bf10dSMatthew G Knepley           options->used[i]  = PETSC_TRUE;
15922d747510SLisandro Dalcin           if (value) *value = options->values[i];
15932d747510SLisandro Dalcin           if (set)   *set   = PETSC_TRUE;
15942d747510SLisandro Dalcin           PetscFunctionReturn(0);
1595514bf10dSMatthew G Knepley         }
1596514bf10dSMatthew G Knepley       }
15972d747510SLisandro Dalcin     }
1598d6ced9c0SMatthew G. Knepley   }
15992d747510SLisandro Dalcin 
16002d747510SLisandro Dalcin   if (set) *set = PETSC_FALSE;
1601514bf10dSMatthew G Knepley   PetscFunctionReturn(0);
1602514bf10dSMatthew G Knepley }
1603514bf10dSMatthew G Knepley 
1604e5c89e4eSSatish Balay /*@C
1605e5c89e4eSSatish Balay    PetscOptionsReject - Generates an error if a certain option is given.
1606e5c89e4eSSatish Balay 
16071c9f3c13SBarry Smith    Not Collective
1608e5c89e4eSSatish Balay 
1609e5c89e4eSSatish Balay    Input Parameters:
16105c9cc608SHong Zhang +  options - options database, use NULL for default global database
16112d747510SLisandro Dalcin .  pre - the option prefix (may be NULL)
16122d747510SLisandro Dalcin .  name - the option name one is seeking
16130298fd71SBarry Smith -  mess - error message (may be NULL)
1614e5c89e4eSSatish Balay 
1615e5c89e4eSSatish Balay    Level: advanced
1616e5c89e4eSSatish Balay 
1617c2e3fba1SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `OptionsHasName()`,
1618db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1619db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1620c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1621db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1622db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1623e5c89e4eSSatish Balay @*/
16242d747510SLisandro Dalcin PetscErrorCode PetscOptionsReject(PetscOptions options,const char pre[],const char name[],const char mess[])
1625e5c89e4eSSatish Balay {
1626ace3abfcSBarry Smith   PetscBool      flag = PETSC_FALSE;
1627e5c89e4eSSatish Balay 
1628e5c89e4eSSatish Balay   PetscFunctionBegin;
16299566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(options,pre,name,&flag));
1630e5c89e4eSSatish Balay   if (flag) {
163108401ef6SPierre 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);
1632f7d195e4SLawrence Mitchell     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s",pre?pre:"",name+1);
1633e5c89e4eSSatish Balay   }
1634e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1635e5c89e4eSSatish Balay }
1636e5c89e4eSSatish Balay 
1637e5c89e4eSSatish Balay /*@C
16382d747510SLisandro Dalcin    PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
16392d747510SLisandro Dalcin 
16402d747510SLisandro Dalcin    Not Collective
16412d747510SLisandro Dalcin 
16422d747510SLisandro Dalcin    Input Parameters:
16432d747510SLisandro Dalcin .  options - options database, use NULL for default global database
16442d747510SLisandro Dalcin 
16452d747510SLisandro Dalcin    Output Parameters:
16462d747510SLisandro Dalcin .  set - PETSC_TRUE if found else PETSC_FALSE.
16472d747510SLisandro Dalcin 
16482d747510SLisandro Dalcin    Level: advanced
16492d747510SLisandro Dalcin 
1650db781477SPatrick Sanan .seealso: `PetscOptionsHasName()`
16512d747510SLisandro Dalcin @*/
16522d747510SLisandro Dalcin PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set)
16532d747510SLisandro Dalcin {
16542d747510SLisandro Dalcin   PetscFunctionBegin;
1655dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set,2);
16562d747510SLisandro Dalcin   options = options ? options : defaultoptions;
16572d747510SLisandro Dalcin   *set = options->help;
16582d747510SLisandro Dalcin   PetscFunctionReturn(0);
16592d747510SLisandro Dalcin }
16602d747510SLisandro Dalcin 
1661d314f959SVaclav Hapla PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options,PetscBool *set)
1662d314f959SVaclav Hapla {
1663d314f959SVaclav Hapla   PetscFunctionBegin;
1664dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(set,2);
1665d314f959SVaclav Hapla   options = options ? options : defaultoptions;
1666d314f959SVaclav Hapla   *set = options->help_intro;
1667d314f959SVaclav Hapla   PetscFunctionReturn(0);
1668d314f959SVaclav Hapla }
1669d314f959SVaclav Hapla 
16702d747510SLisandro Dalcin /*@C
1671e24fcbf7SPierre 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
1672e24fcbf7SPierre Jolivet                       if its value is set to false.
1673e5c89e4eSSatish Balay 
1674e5c89e4eSSatish Balay    Not Collective
1675e5c89e4eSSatish Balay 
1676e5c89e4eSSatish Balay    Input Parameters:
16775c9cc608SHong Zhang +  options - options database, use NULL for default global database
16783de71b31SHong Zhang .  pre - string to prepend to the name or NULL
16793de71b31SHong Zhang -  name - the option one is seeking
1680e5c89e4eSSatish Balay 
1681e5c89e4eSSatish Balay    Output Parameters:
168296ef3cdfSSatish Balay .  set - PETSC_TRUE if found else PETSC_FALSE.
1683e5c89e4eSSatish Balay 
1684e5c89e4eSSatish Balay    Level: beginner
1685e5c89e4eSSatish Balay 
168695452b02SPatrick Sanan    Notes:
1687acfcf0e5SJed Brown    In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.
168890d69ab7SBarry Smith 
1689db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1690db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1691db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1692c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1693db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1694db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
1695e5c89e4eSSatish Balay @*/
1696c5929fdfSBarry Smith PetscErrorCode PetscOptionsHasName(PetscOptions options,const char pre[],const char name[],PetscBool *set)
1697e5c89e4eSSatish Balay {
16982d747510SLisandro Dalcin   const char     *value;
1699ace3abfcSBarry Smith   PetscBool      flag;
1700e5c89e4eSSatish Balay 
1701e5c89e4eSSatish Balay   PetscFunctionBegin;
17029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
170396ef3cdfSSatish Balay   if (set) *set = flag;
1704e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1705e5c89e4eSSatish Balay }
1706e5c89e4eSSatish Balay 
1707e5c89e4eSSatish Balay /*@C
17082d747510SLisandro Dalcin    PetscOptionsGetAll - Lists all the options the program was run with in a single string.
17092d747510SLisandro Dalcin 
17102d747510SLisandro Dalcin    Not Collective
17112d747510SLisandro Dalcin 
1712fd292e60Sprj-    Input Parameter:
17132d747510SLisandro Dalcin .  options - the options database, use NULL for the default global database
17142d747510SLisandro Dalcin 
17152d747510SLisandro Dalcin    Output Parameter:
17162d747510SLisandro Dalcin .  copts - pointer where string pointer is stored
17172d747510SLisandro Dalcin 
17182d747510SLisandro Dalcin    Notes:
17191c9f3c13SBarry Smith     The array and each entry in the array should be freed with PetscFree()
17201c9f3c13SBarry Smith     Each process may have different values depending on how the options were inserted into the database
17212d747510SLisandro Dalcin 
17222d747510SLisandro Dalcin    Level: advanced
17232d747510SLisandro Dalcin 
1724db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`
17252d747510SLisandro Dalcin @*/
17262d747510SLisandro Dalcin PetscErrorCode PetscOptionsGetAll(PetscOptions options,char *copts[])
17272d747510SLisandro Dalcin {
17282d747510SLisandro Dalcin   PetscInt       i;
17292d747510SLisandro Dalcin   size_t         len = 1,lent = 0;
17302d747510SLisandro Dalcin   char           *coptions = NULL;
17312d747510SLisandro Dalcin 
17322d747510SLisandro Dalcin   PetscFunctionBegin;
17332d747510SLisandro Dalcin   PetscValidPointer(copts,2);
17342d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17352d747510SLisandro Dalcin   /* count the length of the required string */
17362d747510SLisandro Dalcin   for (i=0; i<options->N; i++) {
17379566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(options->names[i],&lent));
17382d747510SLisandro Dalcin     len += 2 + lent;
17392d747510SLisandro Dalcin     if (options->values[i]) {
17409566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(options->values[i],&lent));
17412d747510SLisandro Dalcin       len += 1 + lent;
17422d747510SLisandro Dalcin     }
17432d747510SLisandro Dalcin   }
17449566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len,&coptions));
17452d747510SLisandro Dalcin   coptions[0] = 0;
17462d747510SLisandro Dalcin   for (i=0; i<options->N; i++) {
17479566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions,"-"));
17489566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions,options->names[i]));
17499566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(coptions," "));
17502d747510SLisandro Dalcin     if (options->values[i]) {
17519566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(coptions,options->values[i]));
17529566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(coptions," "));
17532d747510SLisandro Dalcin     }
17542d747510SLisandro Dalcin   }
17552d747510SLisandro Dalcin   *copts = coptions;
17562d747510SLisandro Dalcin   PetscFunctionReturn(0);
17572d747510SLisandro Dalcin }
17582d747510SLisandro Dalcin 
17592d747510SLisandro Dalcin /*@C
17602d747510SLisandro Dalcin    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
17612d747510SLisandro Dalcin 
17622d747510SLisandro Dalcin    Not Collective
17632d747510SLisandro Dalcin 
1764d8d19677SJose E. Roman    Input Parameters:
17652d747510SLisandro Dalcin +  options - options database, use NULL for default global database
17662d747510SLisandro Dalcin -  name - string name of option
17672d747510SLisandro Dalcin 
17682d747510SLisandro Dalcin    Output Parameter:
17692d747510SLisandro Dalcin .  used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database
17702d747510SLisandro Dalcin 
17712d747510SLisandro Dalcin    Level: advanced
17722d747510SLisandro Dalcin 
17739666a313SBarry Smith    Notes:
17749666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
17751c9f3c13SBarry Smith    on the given process
17761c9f3c13SBarry Smith 
1777db781477SPatrick Sanan .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
17782d747510SLisandro Dalcin @*/
17792d747510SLisandro Dalcin PetscErrorCode PetscOptionsUsed(PetscOptions options,const char *name,PetscBool *used)
17802d747510SLisandro Dalcin {
17812d747510SLisandro Dalcin   PetscInt       i;
17822d747510SLisandro Dalcin 
17832d747510SLisandro Dalcin   PetscFunctionBegin;
17842d747510SLisandro Dalcin   PetscValidCharPointer(name,2);
1785dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(used,3);
17862d747510SLisandro Dalcin   options = options ? options : defaultoptions;
17872d747510SLisandro Dalcin   *used = PETSC_FALSE;
17882d747510SLisandro Dalcin   for (i=0; i<options->N; i++) {
17899566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(options->names[i],name,used));
17902d747510SLisandro Dalcin     if (*used) {
17912d747510SLisandro Dalcin       *used = options->used[i];
17922d747510SLisandro Dalcin       break;
17932d747510SLisandro Dalcin     }
17942d747510SLisandro Dalcin   }
17952d747510SLisandro Dalcin   PetscFunctionReturn(0);
17962d747510SLisandro Dalcin }
17972d747510SLisandro Dalcin 
1798487a658cSBarry Smith /*@
17992d747510SLisandro Dalcin    PetscOptionsAllUsed - Returns a count of the number of options in the
18002d747510SLisandro Dalcin    database that have never been selected.
18012d747510SLisandro Dalcin 
18022d747510SLisandro Dalcin    Not Collective
18032d747510SLisandro Dalcin 
18042d747510SLisandro Dalcin    Input Parameter:
18052d747510SLisandro Dalcin .  options - options database, use NULL for default global database
18062d747510SLisandro Dalcin 
18072d747510SLisandro Dalcin    Output Parameter:
18082d747510SLisandro Dalcin .  N - count of options not used
18092d747510SLisandro Dalcin 
18102d747510SLisandro Dalcin    Level: advanced
18112d747510SLisandro Dalcin 
18129666a313SBarry Smith    Notes:
18139666a313SBarry Smith    The value returned may be different on each process and depends on which options have been processed
18141c9f3c13SBarry Smith    on the given process
18151c9f3c13SBarry Smith 
1816db781477SPatrick Sanan .seealso: `PetscOptionsView()`
18172d747510SLisandro Dalcin @*/
18182d747510SLisandro Dalcin PetscErrorCode PetscOptionsAllUsed(PetscOptions options,PetscInt *N)
18192d747510SLisandro Dalcin {
18202d747510SLisandro Dalcin   PetscInt     i,n = 0;
18212d747510SLisandro Dalcin 
18222d747510SLisandro Dalcin   PetscFunctionBegin;
18232d747510SLisandro Dalcin   PetscValidIntPointer(N,2);
18242d747510SLisandro Dalcin   options = options ? options : defaultoptions;
18252d747510SLisandro Dalcin   for (i=0; i<options->N; i++) {
18262d747510SLisandro Dalcin     if (!options->used[i]) n++;
18272d747510SLisandro Dalcin   }
18282d747510SLisandro Dalcin   *N = n;
18292d747510SLisandro Dalcin   PetscFunctionReturn(0);
18302d747510SLisandro Dalcin }
18312d747510SLisandro Dalcin 
1832487a658cSBarry Smith /*@
18332d747510SLisandro Dalcin    PetscOptionsLeft - Prints to screen any options that were set and never used.
18342d747510SLisandro Dalcin 
18352d747510SLisandro Dalcin    Not Collective
18362d747510SLisandro Dalcin 
18372d747510SLisandro Dalcin    Input Parameter:
18382d747510SLisandro Dalcin .  options - options database; use NULL for default global database
18392d747510SLisandro Dalcin 
18402d747510SLisandro Dalcin    Options Database Key:
18413c6db4c4SPierre Jolivet .  -options_left - activates PetscOptionsAllUsed() within PetscFinalize()
18422d747510SLisandro Dalcin 
18433de2bfdfSBarry Smith    Notes:
18443de2bfdfSBarry Smith       This is rarely used directly, it is called by PetscFinalize() in debug more or if -options_left
18451c9f3c13SBarry Smith       is passed otherwise to help users determine possible mistakes in their usage of options. This
18461c9f3c13SBarry Smith       only prints values on process zero of PETSC_COMM_WORLD. Other processes depending the objects
18471c9f3c13SBarry Smith       used may have different options that are left unused.
18483de2bfdfSBarry Smith 
18492d747510SLisandro Dalcin    Level: advanced
18502d747510SLisandro Dalcin 
1851db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`
18522d747510SLisandro Dalcin @*/
18532d747510SLisandro Dalcin PetscErrorCode PetscOptionsLeft(PetscOptions options)
18542d747510SLisandro Dalcin {
18552d747510SLisandro Dalcin   PetscInt       i;
18563de2bfdfSBarry Smith   PetscInt       cnt = 0;
18573de2bfdfSBarry Smith   PetscOptions   toptions;
18582d747510SLisandro Dalcin 
18592d747510SLisandro Dalcin   PetscFunctionBegin;
18603de2bfdfSBarry Smith   toptions = options ? options : defaultoptions;
18613de2bfdfSBarry Smith   for (i=0; i<toptions->N; i++) {
18623de2bfdfSBarry Smith     if (!toptions->used[i]) {
1863660278c0SBarry Smith       if (PetscCIOption(toptions->names[i])) continue;
18643de2bfdfSBarry Smith       if (toptions->values[i]) {
18659566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",toptions->names[i],toptions->values[i]));
18662d747510SLisandro Dalcin       } else {
18679566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",toptions->names[i]));
18682d747510SLisandro Dalcin       }
18692d747510SLisandro Dalcin     }
18702d747510SLisandro Dalcin   }
18713de2bfdfSBarry Smith   if (!options) {
18723de2bfdfSBarry Smith     toptions = defaultoptions;
18733de2bfdfSBarry Smith     while (toptions->previous) {
18743de2bfdfSBarry Smith       cnt++;
18753de2bfdfSBarry Smith       toptions = toptions->previous;
18763de2bfdfSBarry Smith     }
18773de2bfdfSBarry Smith     if (cnt) {
18789566063dSJacob Faibussowitsch       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));
18793de2bfdfSBarry Smith     }
18803de2bfdfSBarry Smith   }
18812d747510SLisandro Dalcin   PetscFunctionReturn(0);
18822d747510SLisandro Dalcin }
18832d747510SLisandro Dalcin 
18842d747510SLisandro Dalcin /*@C
18852d747510SLisandro Dalcin    PetscOptionsLeftGet - Returns all options that were set and never used.
18862d747510SLisandro Dalcin 
18872d747510SLisandro Dalcin    Not Collective
18882d747510SLisandro Dalcin 
18892d747510SLisandro Dalcin    Input Parameter:
18902d747510SLisandro Dalcin .  options - options database, use NULL for default global database
18912d747510SLisandro Dalcin 
1892d8d19677SJose E. Roman    Output Parameters:
1893a2b725a8SWilliam Gropp +  N - count of options not used
18942d747510SLisandro Dalcin .  names - names of options not used
1895a2b725a8SWilliam Gropp -  values - values of options not used
18962d747510SLisandro Dalcin 
18972d747510SLisandro Dalcin    Level: advanced
18982d747510SLisandro Dalcin 
18992d747510SLisandro Dalcin    Notes:
19002d747510SLisandro Dalcin    Users should call PetscOptionsLeftRestore() to free the memory allocated in this routine
19011c9f3c13SBarry Smith    Notes: The value returned may be different on each process and depends on which options have been processed
19021c9f3c13SBarry Smith    on the given process
19032d747510SLisandro Dalcin 
1904db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
19052d747510SLisandro Dalcin @*/
19062d747510SLisandro Dalcin PetscErrorCode PetscOptionsLeftGet(PetscOptions options,PetscInt *N,char **names[],char **values[])
19072d747510SLisandro Dalcin {
19082d747510SLisandro Dalcin   PetscInt       i,n;
19092d747510SLisandro Dalcin 
19102d747510SLisandro Dalcin   PetscFunctionBegin;
19112d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N,2);
19122d747510SLisandro Dalcin   if (names) PetscValidPointer(names,3);
19132d747510SLisandro Dalcin   if (values) PetscValidPointer(values,4);
19142d747510SLisandro Dalcin   options = options ? options : defaultoptions;
19152d747510SLisandro Dalcin 
19162d747510SLisandro Dalcin   /* The number of unused PETSc options */
19172d747510SLisandro Dalcin   n = 0;
19182d747510SLisandro Dalcin   for (i=0; i<options->N; i++) {
1919660278c0SBarry Smith     if (PetscCIOption(options->names[i])) continue;
19202d747510SLisandro Dalcin     if (!options->used[i]) n++;
19212d747510SLisandro Dalcin   }
19222d747510SLisandro Dalcin   if (N) { *N = n; }
19239566063dSJacob Faibussowitsch   if (names)  PetscCall(PetscMalloc1(n,names));
19249566063dSJacob Faibussowitsch   if (values) PetscCall(PetscMalloc1(n,values));
19252d747510SLisandro Dalcin 
19262d747510SLisandro Dalcin   n = 0;
19272d747510SLisandro Dalcin   if (names || values) {
19282d747510SLisandro Dalcin     for (i=0; i<options->N; i++) {
19292d747510SLisandro Dalcin       if (!options->used[i]) {
1930660278c0SBarry Smith         if (PetscCIOption(options->names[i])) continue;
19312d747510SLisandro Dalcin         if (names)  (*names)[n]  = options->names[i];
19322d747510SLisandro Dalcin         if (values) (*values)[n] = options->values[i];
19332d747510SLisandro Dalcin         n++;
19342d747510SLisandro Dalcin       }
19352d747510SLisandro Dalcin     }
19362d747510SLisandro Dalcin   }
19372d747510SLisandro Dalcin   PetscFunctionReturn(0);
19382d747510SLisandro Dalcin }
19392d747510SLisandro Dalcin 
19402d747510SLisandro Dalcin /*@C
19412d747510SLisandro Dalcin    PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using PetscOptionsLeftGet.
19422d747510SLisandro Dalcin 
19432d747510SLisandro Dalcin    Not Collective
19442d747510SLisandro Dalcin 
1945d8d19677SJose E. Roman    Input Parameters:
1946a2b725a8SWilliam Gropp +  options - options database, use NULL for default global database
19472d747510SLisandro Dalcin .  names - names of options not used
1948a2b725a8SWilliam Gropp -  values - values of options not used
19492d747510SLisandro Dalcin 
19502d747510SLisandro Dalcin    Level: advanced
19512d747510SLisandro Dalcin 
1952db781477SPatrick Sanan .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
19532d747510SLisandro Dalcin @*/
19542d747510SLisandro Dalcin PetscErrorCode PetscOptionsLeftRestore(PetscOptions options,PetscInt *N,char **names[],char **values[])
19552d747510SLisandro Dalcin {
19562d747510SLisandro Dalcin   PetscFunctionBegin;
19572d747510SLisandro Dalcin   if (N) PetscValidIntPointer(N,2);
19582d747510SLisandro Dalcin   if (names) PetscValidPointer(names,3);
19592d747510SLisandro Dalcin   if (values) PetscValidPointer(values,4);
19602d747510SLisandro Dalcin   if (N) { *N = 0; }
19619566063dSJacob Faibussowitsch   if (names)  PetscCall(PetscFree(*names));
19629566063dSJacob Faibussowitsch   if (values) PetscCall(PetscFree(*values));
19632d747510SLisandro Dalcin   PetscFunctionReturn(0);
19642d747510SLisandro Dalcin }
19652d747510SLisandro Dalcin 
19662d747510SLisandro Dalcin /*@C
19679060e2f9SVaclav Hapla    PetscOptionsMonitorDefault - Print all options set value events using the supplied PetscViewer.
19682d747510SLisandro Dalcin 
19691c9f3c13SBarry Smith    Logically Collective on ctx
19702d747510SLisandro Dalcin 
19712d747510SLisandro Dalcin    Input Parameters:
19722d747510SLisandro Dalcin +  name  - option name string
19732d747510SLisandro Dalcin .  value - option value string
19749060e2f9SVaclav Hapla -  ctx - an ASCII viewer or NULL
19752d747510SLisandro Dalcin 
19762d747510SLisandro Dalcin    Level: intermediate
19772d747510SLisandro Dalcin 
19789666a313SBarry Smith    Notes:
19799060e2f9SVaclav Hapla      If ctx=NULL, PetscPrintf() is used.
19809666a313SBarry Smith      The first MPI rank in the PetscViewer viewer actually prints the values, other
19811c9f3c13SBarry Smith      processes may have different values set
19821c9f3c13SBarry Smith 
1983660278c0SBarry Smith      If PetscCIEnabled then do not print the test harness options
1984660278c0SBarry Smith 
1985db781477SPatrick Sanan .seealso: `PetscOptionsMonitorSet()`
19862d747510SLisandro Dalcin @*/
19872d747510SLisandro Dalcin PetscErrorCode PetscOptionsMonitorDefault(const char name[],const char value[],void *ctx)
19882d747510SLisandro Dalcin {
19892d747510SLisandro Dalcin   PetscFunctionBegin;
1990660278c0SBarry Smith   if (PetscCIOption(name)) PetscFunctionReturn(0);
1991660278c0SBarry Smith 
19929060e2f9SVaclav Hapla   if (ctx) {
19939060e2f9SVaclav Hapla     PetscViewer viewer = (PetscViewer)ctx;
19942d747510SLisandro Dalcin     if (!value) {
19959566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Removing option: %s\n",name));
19962d747510SLisandro Dalcin     } else if (!value[0]) {
19979566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Setting option: %s (no value)\n",name));
19982d747510SLisandro Dalcin     } else {
19999566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value));
20002d747510SLisandro Dalcin     }
20019060e2f9SVaclav Hapla   } else {
20029060e2f9SVaclav Hapla     MPI_Comm comm = PETSC_COMM_WORLD;
20039060e2f9SVaclav Hapla     if (!value) {
20049566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm,"Removing option: %s\n",name));
20059060e2f9SVaclav Hapla     } else if (!value[0]) {
20069566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm,"Setting option: %s (no value)\n",name));
20079060e2f9SVaclav Hapla     } else {
20089566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm,"Setting option: %s = %s\n",name,value));
20099060e2f9SVaclav Hapla     }
20109060e2f9SVaclav Hapla   }
20112d747510SLisandro Dalcin   PetscFunctionReturn(0);
20122d747510SLisandro Dalcin }
20132d747510SLisandro Dalcin 
20142d747510SLisandro Dalcin /*@C
20152d747510SLisandro Dalcin    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
20162d747510SLisandro Dalcin    modified the PETSc options database.
20172d747510SLisandro Dalcin 
20182d747510SLisandro Dalcin    Not Collective
20192d747510SLisandro Dalcin 
20202d747510SLisandro Dalcin    Input Parameters:
20212d747510SLisandro Dalcin +  monitor - pointer to function (if this is NULL, it turns off monitoring
20222d747510SLisandro Dalcin .  mctx    - [optional] context for private data for the
20232d747510SLisandro Dalcin              monitor routine (use NULL if no context is desired)
20242d747510SLisandro Dalcin -  monitordestroy - [optional] routine that frees monitor context
20252d747510SLisandro Dalcin           (may be NULL)
20262d747510SLisandro Dalcin 
20272d747510SLisandro Dalcin    Calling Sequence of monitor:
20282d747510SLisandro Dalcin $     monitor (const char name[], const char value[], void *mctx)
20292d747510SLisandro Dalcin 
20302d747510SLisandro Dalcin +  name - option name string
20312d747510SLisandro Dalcin .  value - option value string
20322d747510SLisandro Dalcin -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()
20332d747510SLisandro Dalcin 
20342d747510SLisandro Dalcin    Options Database Keys:
2035c5b5d8d5SVaclav Hapla    See PetscInitialize() for options related to option database monitoring.
20362d747510SLisandro Dalcin 
20372d747510SLisandro Dalcin    Notes:
20382d747510SLisandro Dalcin    The default is to do nothing.  To print the name and value of options
20392d747510SLisandro Dalcin    being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
20402d747510SLisandro Dalcin    with a null monitoring context.
20412d747510SLisandro Dalcin 
20422d747510SLisandro Dalcin    Several different monitoring routines may be set by calling
20432d747510SLisandro Dalcin    PetscOptionsMonitorSet() multiple times; all will be called in the
20442d747510SLisandro Dalcin    order in which they were set.
20452d747510SLisandro Dalcin 
20469060e2f9SVaclav Hapla    Level: intermediate
20472d747510SLisandro Dalcin 
2048db781477SPatrick Sanan .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`
20492d747510SLisandro Dalcin @*/
20502d747510SLisandro Dalcin PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
20512d747510SLisandro Dalcin {
20522d747510SLisandro Dalcin   PetscOptions options = defaultoptions;
20532d747510SLisandro Dalcin 
20542d747510SLisandro Dalcin   PetscFunctionBegin;
2055c5b5d8d5SVaclav Hapla   if (options->monitorCancel) PetscFunctionReturn(0);
205608401ef6SPierre Jolivet   PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
20572d747510SLisandro Dalcin   options->monitor[options->numbermonitors]          = monitor;
20582d747510SLisandro Dalcin   options->monitordestroy[options->numbermonitors]   = monitordestroy;
20592d747510SLisandro Dalcin   options->monitorcontext[options->numbermonitors++] = (void*)mctx;
20602d747510SLisandro Dalcin   PetscFunctionReturn(0);
20612d747510SLisandro Dalcin }
20622d747510SLisandro Dalcin 
20632d747510SLisandro Dalcin /*
20642d747510SLisandro Dalcin    PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
206563fe8743SVaclav Hapla      Empty string is considered as true.
20662d747510SLisandro Dalcin */
20672d747510SLisandro Dalcin PetscErrorCode PetscOptionsStringToBool(const char value[],PetscBool *a)
20682d747510SLisandro Dalcin {
20692d747510SLisandro Dalcin   PetscBool istrue,isfalse;
20702d747510SLisandro Dalcin   size_t    len;
20712d747510SLisandro Dalcin 
20722d747510SLisandro Dalcin   PetscFunctionBegin;
207363fe8743SVaclav Hapla   /* PetscStrlen() returns 0 for NULL or "" */
20749566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(value,&len));
207563fe8743SVaclav Hapla   if (!len)  {*a = PETSC_TRUE; PetscFunctionReturn(0);}
20769566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value,"TRUE",&istrue));
20772d747510SLisandro Dalcin   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
20789566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value,"YES",&istrue));
20792d747510SLisandro Dalcin   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
20809566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value,"1",&istrue));
20812d747510SLisandro Dalcin   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
20829566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value,"on",&istrue));
20832d747510SLisandro Dalcin   if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);}
20849566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value,"FALSE",&isfalse));
20852d747510SLisandro Dalcin   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
20869566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value,"NO",&isfalse));
20872d747510SLisandro Dalcin   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
20889566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value,"0",&isfalse));
20892d747510SLisandro Dalcin   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
20909566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(value,"off",&isfalse));
20912d747510SLisandro Dalcin   if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);}
209298921bdaSJacob Faibussowitsch   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value);
20932d747510SLisandro Dalcin }
20942d747510SLisandro Dalcin 
20952d747510SLisandro Dalcin /*
20962d747510SLisandro Dalcin    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
20972d747510SLisandro Dalcin */
20982d747510SLisandro Dalcin PetscErrorCode PetscOptionsStringToInt(const char name[],PetscInt *a)
20992d747510SLisandro Dalcin {
21002d747510SLisandro Dalcin   size_t    len;
21012d747510SLisandro Dalcin   PetscBool decide,tdefault,mouse;
21022d747510SLisandro Dalcin 
21032d747510SLisandro Dalcin   PetscFunctionBegin;
21049566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name,&len));
21055f80ce2aSJacob Faibussowitsch   PetscCheck(len,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
21062d747510SLisandro Dalcin 
21079566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault));
21082d747510SLisandro Dalcin   if (!tdefault) {
21099566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(name,"DEFAULT",&tdefault));
21102d747510SLisandro Dalcin   }
21119566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name,"PETSC_DECIDE",&decide));
21122d747510SLisandro Dalcin   if (!decide) {
21139566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(name,"DECIDE",&decide));
21142d747510SLisandro Dalcin   }
21159566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name,"mouse",&mouse));
21162d747510SLisandro Dalcin 
21172d747510SLisandro Dalcin   if (tdefault)    *a = PETSC_DEFAULT;
21182d747510SLisandro Dalcin   else if (decide) *a = PETSC_DECIDE;
21192d747510SLisandro Dalcin   else if (mouse)  *a = -1;
21202d747510SLisandro Dalcin   else {
21212d747510SLisandro Dalcin     char *endptr;
21222d747510SLisandro Dalcin     long strtolval;
21232d747510SLisandro Dalcin 
21242d747510SLisandro Dalcin     strtolval = strtol(name,&endptr,10);
2125cc73adaaSBarry 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);
21262d747510SLisandro Dalcin 
21272d747510SLisandro Dalcin #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
21282d747510SLisandro Dalcin     (void) strtolval;
21292d747510SLisandro Dalcin     *a = atoll(name);
21302d747510SLisandro Dalcin #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
21312d747510SLisandro Dalcin     (void) strtolval;
21322d747510SLisandro Dalcin     *a = _atoi64(name);
21332d747510SLisandro Dalcin #else
21342d747510SLisandro Dalcin     *a = (PetscInt)strtolval;
21352d747510SLisandro Dalcin #endif
21362d747510SLisandro Dalcin   }
21372d747510SLisandro Dalcin   PetscFunctionReturn(0);
21382d747510SLisandro Dalcin }
21392d747510SLisandro Dalcin 
21402d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
21412d747510SLisandro Dalcin #include <quadmath.h>
21422d747510SLisandro Dalcin #endif
21432d747510SLisandro Dalcin 
21442d747510SLisandro Dalcin static PetscErrorCode PetscStrtod(const char name[],PetscReal *a,char **endptr)
21452d747510SLisandro Dalcin {
21462d747510SLisandro Dalcin   PetscFunctionBegin;
21472d747510SLisandro Dalcin #if defined(PETSC_USE_REAL___FLOAT128)
21482d747510SLisandro Dalcin   *a = strtoflt128(name,endptr);
21492d747510SLisandro Dalcin #else
21502d747510SLisandro Dalcin   *a = (PetscReal)strtod(name,endptr);
21512d747510SLisandro Dalcin #endif
21522d747510SLisandro Dalcin   PetscFunctionReturn(0);
21532d747510SLisandro Dalcin }
21542d747510SLisandro Dalcin 
21552d747510SLisandro Dalcin static PetscErrorCode PetscStrtoz(const char name[],PetscScalar *a,char **endptr,PetscBool *isImaginary)
21562d747510SLisandro Dalcin {
21572d747510SLisandro Dalcin   PetscBool      hasi = PETSC_FALSE;
21582d747510SLisandro Dalcin   char           *ptr;
21592d747510SLisandro Dalcin   PetscReal      strtoval;
21602d747510SLisandro Dalcin 
21612d747510SLisandro Dalcin   PetscFunctionBegin;
21629566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name,&strtoval,&ptr));
21632d747510SLisandro Dalcin   if (ptr == name) {
21642d747510SLisandro Dalcin     strtoval = 1.;
21652d747510SLisandro Dalcin     hasi = PETSC_TRUE;
21662d747510SLisandro Dalcin     if (name[0] == 'i') {
21672d747510SLisandro Dalcin       ptr++;
21682d747510SLisandro Dalcin     } else if (name[0] == '+' && name[1] == 'i') {
21692d747510SLisandro Dalcin       ptr += 2;
21702d747510SLisandro Dalcin     } else if (name[0] == '-' && name[1] == 'i') {
21712d747510SLisandro Dalcin       strtoval = -1.;
21722d747510SLisandro Dalcin       ptr += 2;
21732d747510SLisandro Dalcin     }
21742d747510SLisandro Dalcin   } else if (*ptr == 'i') {
21752d747510SLisandro Dalcin     hasi = PETSC_TRUE;
21762d747510SLisandro Dalcin     ptr++;
21772d747510SLisandro Dalcin   }
21782d747510SLisandro Dalcin   *endptr = ptr;
21792d747510SLisandro Dalcin   *isImaginary = hasi;
21802d747510SLisandro Dalcin   if (hasi) {
21812d747510SLisandro Dalcin #if !defined(PETSC_USE_COMPLEX)
218298921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s contains imaginary but complex not supported ",name);
21832d747510SLisandro Dalcin #else
21842d747510SLisandro Dalcin     *a = PetscCMPLX(0.,strtoval);
21852d747510SLisandro Dalcin #endif
21862d747510SLisandro Dalcin   } else {
21872d747510SLisandro Dalcin     *a = strtoval;
21882d747510SLisandro Dalcin   }
21892d747510SLisandro Dalcin   PetscFunctionReturn(0);
21902d747510SLisandro Dalcin }
21912d747510SLisandro Dalcin 
21922d747510SLisandro Dalcin /*
21932d747510SLisandro Dalcin    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
21942d747510SLisandro Dalcin */
21952d747510SLisandro Dalcin PetscErrorCode PetscOptionsStringToReal(const char name[],PetscReal *a)
21962d747510SLisandro Dalcin {
21972d747510SLisandro Dalcin   size_t     len;
21982d747510SLisandro Dalcin   PetscBool  match;
21992d747510SLisandro Dalcin   char      *endptr;
22002d747510SLisandro Dalcin 
22012d747510SLisandro Dalcin   PetscFunctionBegin;
22029566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name,&len));
220328b400f6SJacob Faibussowitsch   PetscCheck(len,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"String of length zero has no numerical value");
22042d747510SLisandro Dalcin 
22059566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name,"PETSC_DEFAULT",&match));
22069566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name,"DEFAULT",&match));
22072d747510SLisandro Dalcin   if (match) {*a = PETSC_DEFAULT; PetscFunctionReturn(0);}
22082d747510SLisandro Dalcin 
22099566063dSJacob Faibussowitsch   PetscCall(PetscStrcasecmp(name,"PETSC_DECIDE",&match));
22109566063dSJacob Faibussowitsch   if (!match) PetscCall(PetscStrcasecmp(name,"DECIDE",&match));
22112d747510SLisandro Dalcin   if (match) {*a = PETSC_DECIDE; PetscFunctionReturn(0);}
22122d747510SLisandro Dalcin 
22139566063dSJacob Faibussowitsch   PetscCall(PetscStrtod(name,a,&endptr));
221439a651e2SJacob Faibussowitsch   PetscCheck((size_t) (endptr - name) == len,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value",name);
22152d747510SLisandro Dalcin   PetscFunctionReturn(0);
22162d747510SLisandro Dalcin }
22172d747510SLisandro Dalcin 
22182d747510SLisandro Dalcin PetscErrorCode PetscOptionsStringToScalar(const char name[],PetscScalar *a)
22192d747510SLisandro Dalcin {
22202d747510SLisandro Dalcin   PetscBool    imag1;
22212d747510SLisandro Dalcin   size_t       len;
22222d747510SLisandro Dalcin   PetscScalar  val = 0.;
22232d747510SLisandro Dalcin   char        *ptr = NULL;
22242d747510SLisandro Dalcin 
22252d747510SLisandro Dalcin   PetscFunctionBegin;
22269566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(name,&len));
222728b400f6SJacob Faibussowitsch   PetscCheck(len,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
22289566063dSJacob Faibussowitsch   PetscCall(PetscStrtoz(name,&val,&ptr,&imag1));
22292d747510SLisandro Dalcin #if defined(PETSC_USE_COMPLEX)
22302d747510SLisandro Dalcin   if ((size_t) (ptr - name) < len) {
22312d747510SLisandro Dalcin     PetscBool   imag2;
22322d747510SLisandro Dalcin     PetscScalar val2;
22332d747510SLisandro Dalcin 
22349566063dSJacob Faibussowitsch     PetscCall(PetscStrtoz(ptr,&val2,&ptr,&imag2));
223539a651e2SJacob Faibussowitsch     if (imag1) PetscCheck(imag2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s: must specify imaginary component second",name);
22362d747510SLisandro Dalcin     val = PetscCMPLX(PetscRealPart(val),PetscImaginaryPart(val2));
22372d747510SLisandro Dalcin   }
22382d747510SLisandro Dalcin #endif
223939a651e2SJacob Faibussowitsch   PetscCheck((size_t) (ptr - name) == len,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
22402d747510SLisandro Dalcin   *a = val;
22412d747510SLisandro Dalcin   PetscFunctionReturn(0);
22422d747510SLisandro Dalcin }
22432d747510SLisandro Dalcin 
22442d747510SLisandro Dalcin /*@C
22452d747510SLisandro Dalcin    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
22462d747510SLisandro Dalcin             option in the database.
2247e5c89e4eSSatish Balay 
2248e5c89e4eSSatish Balay    Not Collective
2249e5c89e4eSSatish Balay 
2250e5c89e4eSSatish Balay    Input Parameters:
22515c9cc608SHong Zhang +  options - options database, use NULL for default global database
2252c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2253e5c89e4eSSatish Balay -  name - the option one is seeking
2254e5c89e4eSSatish Balay 
2255d8d19677SJose E. Roman    Output Parameters:
22562d747510SLisandro Dalcin +  ivalue - the logical value to return
225796ef3cdfSSatish Balay -  set - PETSC_TRUE  if found, else PETSC_FALSE
2258e5c89e4eSSatish Balay 
2259e5c89e4eSSatish Balay    Level: beginner
2260e5c89e4eSSatish Balay 
226195452b02SPatrick Sanan    Notes:
22622d747510SLisandro Dalcin        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
22632d747510SLisandro Dalcin        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
22642d747510SLisandro Dalcin 
22652d747510SLisandro Dalcin       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
22662d747510SLisandro Dalcin      is equivalent to -requested_bool true
22672d747510SLisandro Dalcin 
22682d747510SLisandro Dalcin        If the user does not supply the option at all ivalue is NOT changed. Thus
22692efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
22702efd9cb1SBarry Smith 
2271db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2272db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2273db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2274c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2275db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2276db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2277e5c89e4eSSatish Balay @*/
22782d747510SLisandro Dalcin PetscErrorCode PetscOptionsGetBool(PetscOptions options,const char pre[],const char name[],PetscBool *ivalue,PetscBool *set)
2279e5c89e4eSSatish Balay {
22802d747510SLisandro Dalcin   const char     *value;
2281ace3abfcSBarry Smith   PetscBool      flag;
2282e5c89e4eSSatish Balay 
2283e5c89e4eSSatish Balay   PetscFunctionBegin;
22842d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
2285064a246eSJacob Faibussowitsch   if (ivalue) PetscValidBoolPointer(ivalue,4);
22869566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2287e5c89e4eSSatish Balay   if (flag) {
228896ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
22899566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value, &flag));
22902d747510SLisandro Dalcin     if (ivalue) *ivalue = flag;
2291e5c89e4eSSatish Balay   } else {
229296ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2293e5c89e4eSSatish Balay   }
2294e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2295e5c89e4eSSatish Balay }
2296e5c89e4eSSatish Balay 
2297e5c89e4eSSatish Balay /*@C
2298e5c89e4eSSatish Balay    PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2299e5c89e4eSSatish Balay 
2300e5c89e4eSSatish Balay    Not Collective
2301e5c89e4eSSatish Balay 
2302e5c89e4eSSatish Balay    Input Parameters:
23035c9cc608SHong Zhang +  options - options database, use NULL for default global database
2304c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2305e5c89e4eSSatish Balay .  opt - option name
2306a264d7a6SBarry Smith .  list - the possible choices (one of these must be selected, anything else is invalid)
2307a2b725a8SWilliam Gropp -  ntext - number of choices
2308e5c89e4eSSatish Balay 
2309d8d19677SJose E. Roman    Output Parameters:
23102efd9cb1SBarry Smith +  value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2311e5c89e4eSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2312e5c89e4eSSatish Balay 
2313e5c89e4eSSatish Balay    Level: intermediate
2314e5c89e4eSSatish Balay 
231595452b02SPatrick Sanan    Notes:
231695452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
23172efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
23182efd9cb1SBarry Smith 
2319a264d7a6SBarry Smith    See PetscOptionsFList() for when the choices are given in a PetscFunctionList()
2320e5c89e4eSSatish Balay 
2321db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2322db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2323db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2324c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2325db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2326db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2327e5c89e4eSSatish Balay @*/
2328c5929fdfSBarry Smith PetscErrorCode PetscOptionsGetEList(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool *set)
2329e5c89e4eSSatish Balay {
233058b0ac4eSStefano Zampini   size_t         alen,len = 0, tlen = 0;
2331e5c89e4eSSatish Balay   char           *svalue;
2332ace3abfcSBarry Smith   PetscBool      aset,flg = PETSC_FALSE;
2333e5c89e4eSSatish Balay   PetscInt       i;
2334e5c89e4eSSatish Balay 
2335e5c89e4eSSatish Balay   PetscFunctionBegin;
23362d747510SLisandro Dalcin   PetscValidCharPointer(opt,3);
2337e5c89e4eSSatish Balay   for (i=0; i<ntext; i++) {
23389566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(list[i],&alen));
2339e5c89e4eSSatish Balay     if (alen > len) len = alen;
234058b0ac4eSStefano Zampini     tlen += len + 1;
2341e5c89e4eSSatish Balay   }
2342e5c89e4eSSatish Balay   len += 5; /* a little extra space for user mistypes */
23439566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len,&svalue));
23449566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(options,pre,opt,svalue,len,&aset));
2345e5c89e4eSSatish Balay   if (aset) {
23469566063dSJacob Faibussowitsch     PetscCall(PetscEListFind(ntext,list,svalue,value,&flg));
234758b0ac4eSStefano Zampini     if (!flg) {
234858b0ac4eSStefano Zampini       char *avail,*pavl;
234958b0ac4eSStefano Zampini 
23509566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(tlen,&avail));
235158b0ac4eSStefano Zampini       pavl = avail;
235258b0ac4eSStefano Zampini       for (i=0; i<ntext; i++) {
23539566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(list[i],&alen));
23549566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(pavl,list[i]));
235558b0ac4eSStefano Zampini         pavl += alen;
23569566063dSJacob Faibussowitsch         PetscCall(PetscStrcpy(pavl," "));
235758b0ac4eSStefano Zampini         pavl += 1;
235858b0ac4eSStefano Zampini       }
23599566063dSJacob Faibussowitsch       PetscCall(PetscStrtolower(avail));
236098921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s. Available options: %s",svalue,pre ? pre : "",opt+1,avail);
236158b0ac4eSStefano Zampini     }
2362fbedd5e0SJed Brown     if (set) *set = PETSC_TRUE;
2363a297a907SKarl Rupp   } else if (set) *set = PETSC_FALSE;
23649566063dSJacob Faibussowitsch   PetscCall(PetscFree(svalue));
2365e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2366e5c89e4eSSatish Balay }
2367e5c89e4eSSatish Balay 
2368e5c89e4eSSatish Balay /*@C
2369e5c89e4eSSatish Balay    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2370e5c89e4eSSatish Balay 
2371e5c89e4eSSatish Balay    Not Collective
2372e5c89e4eSSatish Balay 
2373e5c89e4eSSatish Balay    Input Parameters:
23745c9cc608SHong Zhang +  options - options database, use NULL for default global database
2375c5929fdfSBarry Smith .  pre - option prefix or NULL
2376e5c89e4eSSatish Balay .  opt - option name
23776b867d5aSJose E. Roman -  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2378e5c89e4eSSatish Balay 
2379d8d19677SJose E. Roman    Output Parameters:
2380e5c89e4eSSatish Balay +  value - the  value to return
238196ef3cdfSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2382e5c89e4eSSatish Balay 
2383e5c89e4eSSatish Balay    Level: beginner
2384e5c89e4eSSatish Balay 
238595452b02SPatrick Sanan    Notes:
238695452b02SPatrick Sanan     If the user does not supply the option value is NOT changed. Thus
23872efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2388e5c89e4eSSatish Balay 
23892efd9cb1SBarry Smith           List is usually something like PCASMTypes or some other predefined list of enum names
2390e5c89e4eSSatish Balay 
2391db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2392db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2393db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2394db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2395c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2396db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2397db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2398e5c89e4eSSatish Balay @*/
2399c5929fdfSBarry Smith PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set)
2400e5c89e4eSSatish Balay {
240169a24498SJed Brown   PetscInt       ntext = 0,tval;
2402ace3abfcSBarry Smith   PetscBool      fset;
2403e5c89e4eSSatish Balay 
2404e5c89e4eSSatish Balay   PetscFunctionBegin;
24052d747510SLisandro Dalcin   PetscValidCharPointer(opt,3);
2406e5c89e4eSSatish Balay   while (list[ntext++]) {
240708401ef6SPierre Jolivet     PetscCheck(ntext <= 50,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
2408e5c89e4eSSatish Balay   }
240908401ef6SPierre Jolivet   PetscCheck(ntext >= 3,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
2410e5c89e4eSSatish Balay   ntext -= 3;
24119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset));
241269a24498SJed Brown   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2413809ceb46SBarry Smith   if (fset) *value = (PetscEnum)tval;
2414809ceb46SBarry Smith   if (set) *set = fset;
2415e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2416e5c89e4eSSatish Balay }
2417e5c89e4eSSatish Balay 
2418e5c89e4eSSatish Balay /*@C
24192d747510SLisandro Dalcin    PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2420e5c89e4eSSatish Balay 
2421e5c89e4eSSatish Balay    Not Collective
2422e5c89e4eSSatish Balay 
2423e5c89e4eSSatish Balay    Input Parameters:
24245c9cc608SHong Zhang +  options - options database, use NULL for default global database
2425c5929fdfSBarry Smith .  pre - the string to prepend to the name or NULL
2426e5c89e4eSSatish Balay -  name - the option one is seeking
2427e5c89e4eSSatish Balay 
2428d8d19677SJose E. Roman    Output Parameters:
24292d747510SLisandro Dalcin +  ivalue - the integer value to return
243096ef3cdfSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2431e5c89e4eSSatish Balay 
2432e5c89e4eSSatish Balay    Level: beginner
2433e5c89e4eSSatish Balay 
2434e5c89e4eSSatish Balay    Notes:
24352d747510SLisandro Dalcin    If the user does not supply the option ivalue is NOT changed. Thus
24362efd9cb1SBarry Smith    you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
24375c07ccb8SBarry Smith 
2438db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2439db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2440db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
2441db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2442c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2443db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2444db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2445e5c89e4eSSatish Balay @*/
24462d747510SLisandro Dalcin PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set)
2447e5c89e4eSSatish Balay {
24482d747510SLisandro Dalcin   const char     *value;
24492d747510SLisandro Dalcin   PetscBool      flag;
2450e5c89e4eSSatish Balay 
2451e5c89e4eSSatish Balay   PetscFunctionBegin;
24522d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
24532d747510SLisandro Dalcin   PetscValidIntPointer(ivalue,4);
24549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2455e5c89e4eSSatish Balay   if (flag) {
245634a9cc2cSBarry Smith     if (!value) {
24572d747510SLisandro Dalcin       if (set) *set = PETSC_FALSE;
245834a9cc2cSBarry Smith     } else {
24592d747510SLisandro Dalcin       if (set) *set = PETSC_TRUE;
24609566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value,ivalue));
2461e5c89e4eSSatish Balay     }
2462e5c89e4eSSatish Balay   } else {
246396ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2464e5c89e4eSSatish Balay   }
2465e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2466e5c89e4eSSatish Balay }
2467e5c89e4eSSatish Balay 
2468e2446a98SMatthew Knepley /*@C
2469e5c89e4eSSatish Balay    PetscOptionsGetReal - Gets the double precision value for a particular
2470e5c89e4eSSatish Balay    option in the database.
2471e5c89e4eSSatish Balay 
2472e5c89e4eSSatish Balay    Not Collective
2473e5c89e4eSSatish Balay 
2474e5c89e4eSSatish Balay    Input Parameters:
24755c9cc608SHong Zhang +  options - options database, use NULL for default global database
2476c5929fdfSBarry Smith .  pre - string to prepend to each name or NULL
2477e5c89e4eSSatish Balay -  name - the option one is seeking
2478e5c89e4eSSatish Balay 
2479d8d19677SJose E. Roman    Output Parameters:
2480e5c89e4eSSatish Balay +  dvalue - the double value to return
248196ef3cdfSSatish Balay -  set - PETSC_TRUE if found, PETSC_FALSE if not found
2482e5c89e4eSSatish Balay 
248395452b02SPatrick Sanan    Notes:
248495452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
24852efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2486e4974155SBarry Smith 
2487e5c89e4eSSatish Balay    Level: beginner
2488e5c89e4eSSatish Balay 
2489db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2490c2e3fba1SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2491db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2492c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2493db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2494db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2495e5c89e4eSSatish Balay @*/
2496c5929fdfSBarry Smith PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set)
2497e5c89e4eSSatish Balay {
24982d747510SLisandro Dalcin   const char     *value;
2499ace3abfcSBarry Smith   PetscBool      flag;
2500e5c89e4eSSatish Balay 
2501e5c89e4eSSatish Balay   PetscFunctionBegin;
25022d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
25032d747510SLisandro Dalcin   PetscValidRealPointer(dvalue,4);
25049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2505e5c89e4eSSatish Balay   if (flag) {
2506a297a907SKarl Rupp     if (!value) {
2507a297a907SKarl Rupp       if (set) *set = PETSC_FALSE;
2508a297a907SKarl Rupp     } else {
2509a297a907SKarl Rupp       if (set) *set = PETSC_TRUE;
25109566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value,dvalue));
2511a297a907SKarl Rupp     }
2512e5c89e4eSSatish Balay   } else {
251396ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2514e5c89e4eSSatish Balay   }
2515e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2516e5c89e4eSSatish Balay }
2517e5c89e4eSSatish Balay 
2518e5c89e4eSSatish Balay /*@C
2519e5c89e4eSSatish Balay    PetscOptionsGetScalar - Gets the scalar value for a particular
2520e5c89e4eSSatish Balay    option in the database.
2521e5c89e4eSSatish Balay 
2522e5c89e4eSSatish Balay    Not Collective
2523e5c89e4eSSatish Balay 
2524e5c89e4eSSatish Balay    Input Parameters:
25255c9cc608SHong Zhang +  options - options database, use NULL for default global database
2526c5929fdfSBarry Smith .  pre - string to prepend to each name or NULL
2527e5c89e4eSSatish Balay -  name - the option one is seeking
2528e5c89e4eSSatish Balay 
2529d8d19677SJose E. Roman    Output Parameters:
2530e5c89e4eSSatish Balay +  dvalue - the double value to return
253196ef3cdfSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2532e5c89e4eSSatish Balay 
2533e5c89e4eSSatish Balay    Level: beginner
2534e5c89e4eSSatish Balay 
2535e5c89e4eSSatish Balay    Usage:
2536eb4ae41dSBarry Smith    A complex number 2+3i must be specified with NO spaces
2537e5c89e4eSSatish Balay 
253895452b02SPatrick Sanan    Notes:
253995452b02SPatrick Sanan     If the user does not supply the option dvalue is NOT changed. Thus
25402efd9cb1SBarry Smith      you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2541e4974155SBarry Smith 
2542db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2543db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2544db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2545c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2546db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2547db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2548e5c89e4eSSatish Balay @*/
2549c5929fdfSBarry Smith PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set)
2550e5c89e4eSSatish Balay {
25512d747510SLisandro Dalcin   const char     *value;
2552ace3abfcSBarry Smith   PetscBool      flag;
2553e5c89e4eSSatish Balay 
2554e5c89e4eSSatish Balay   PetscFunctionBegin;
25552d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
25562d747510SLisandro Dalcin   PetscValidScalarPointer(dvalue,4);
25579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2558e5c89e4eSSatish Balay   if (flag) {
2559e5c89e4eSSatish Balay     if (!value) {
256096ef3cdfSSatish Balay       if (set) *set = PETSC_FALSE;
2561e5c89e4eSSatish Balay     } else {
2562e5c89e4eSSatish Balay #if !defined(PETSC_USE_COMPLEX)
25639566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToReal(value,dvalue));
2564e5c89e4eSSatish Balay #else
25659566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToScalar(value,dvalue));
2566e5c89e4eSSatish Balay #endif
256796ef3cdfSSatish Balay       if (set) *set = PETSC_TRUE;
2568e5c89e4eSSatish Balay     }
2569e5c89e4eSSatish Balay   } else { /* flag */
257096ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2571e5c89e4eSSatish Balay   }
2572e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2573e5c89e4eSSatish Balay }
2574e5c89e4eSSatish Balay 
2575e5c89e4eSSatish Balay /*@C
2576e5c89e4eSSatish Balay    PetscOptionsGetString - Gets the string value for a particular option in
2577e5c89e4eSSatish Balay    the database.
2578e5c89e4eSSatish Balay 
2579e5c89e4eSSatish Balay    Not Collective
2580e5c89e4eSSatish Balay 
2581e5c89e4eSSatish Balay    Input Parameters:
25825c9cc608SHong Zhang +  options - options database, use NULL for default global database
2583c5929fdfSBarry Smith .  pre - string to prepend to name or NULL
2584e5c89e4eSSatish Balay .  name - the option one is seeking
2585bcbf2dc5SJed Brown -  len - maximum length of the string including null termination
2586e5c89e4eSSatish Balay 
2587e5c89e4eSSatish Balay    Output Parameters:
2588e5c89e4eSSatish Balay +  string - location to copy string
258996ef3cdfSSatish Balay -  set - PETSC_TRUE if found, else PETSC_FALSE
2590e5c89e4eSSatish Balay 
2591e5c89e4eSSatish Balay    Level: beginner
2592e5c89e4eSSatish Balay 
2593e5c89e4eSSatish Balay    Fortran Note:
2594e5c89e4eSSatish Balay    The Fortran interface is slightly different from the C/C++
2595e5c89e4eSSatish Balay    interface (len is not used).  Sample usage in Fortran follows
2596e5c89e4eSSatish Balay .vb
2597e5c89e4eSSatish Balay       character *20    string
259893e6ba5cSBarry Smith       PetscErrorCode   ierr
259993e6ba5cSBarry Smith       PetscBool        set
26001b266c99SBarry Smith       call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2601e5c89e4eSSatish Balay .ve
2602e5c89e4eSSatish Balay 
260395452b02SPatrick Sanan    Notes:
260495452b02SPatrick Sanan     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
2605e4974155SBarry Smith 
26062efd9cb1SBarry Smith            If the user does not use the option then the string is not changed. Thus
26072efd9cb1SBarry Smith            you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
26082efd9cb1SBarry Smith 
2609f3dea69dSBarry Smith     Note:
2610f3dea69dSBarry Smith       Even if the user provided no string (for example -optionname -someotheroption) the flag is set to PETSC_TRUE (and the string is fulled with nulls).
2611f3dea69dSBarry Smith 
2612db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2613db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2614db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2615c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2616db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2617db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
2618e5c89e4eSSatish Balay @*/
2619c5929fdfSBarry Smith PetscErrorCode PetscOptionsGetString(PetscOptions options,const char pre[],const char name[],char string[],size_t len,PetscBool *set)
2620e5c89e4eSSatish Balay {
26212d747510SLisandro Dalcin   const char     *value;
2622ace3abfcSBarry Smith   PetscBool      flag;
2623e5c89e4eSSatish Balay 
2624e5c89e4eSSatish Balay   PetscFunctionBegin;
26252d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
26262d747510SLisandro Dalcin   PetscValidCharPointer(string,4);
26279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag));
2628e5c89e4eSSatish Balay   if (!flag) {
262996ef3cdfSSatish Balay     if (set) *set = PETSC_FALSE;
2630e5c89e4eSSatish Balay   } else {
263196ef3cdfSSatish Balay     if (set) *set = PETSC_TRUE;
26329566063dSJacob Faibussowitsch     if (value) PetscCall(PetscStrncpy(string,value,len));
26339566063dSJacob Faibussowitsch     else PetscCall(PetscArrayzero(string,len));
2634e5c89e4eSSatish Balay   }
2635e5c89e4eSSatish Balay   PetscFunctionReturn(0);
2636e5c89e4eSSatish Balay }
2637e5c89e4eSSatish Balay 
2638c5929fdfSBarry Smith char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[])
263914ce751eSBarry Smith {
26402d747510SLisandro Dalcin   const char *value;
264114ce751eSBarry Smith   PetscBool   flag;
264214ce751eSBarry Smith 
264314ce751eSBarry Smith   PetscFunctionBegin;
264439a651e2SJacob Faibussowitsch   if (PetscOptionsFindPair(options,pre,name,&value,&flag)) PetscFunctionReturn(NULL);
26452d747510SLisandro Dalcin   if (flag) PetscFunctionReturn((char*)value);
264639a651e2SJacob Faibussowitsch   PetscFunctionReturn(NULL);
264714ce751eSBarry Smith }
264814ce751eSBarry Smith 
26492d747510SLisandro Dalcin /*@C
26502d747510SLisandro Dalcin   PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2651f1a722f8SMatthew G. Knepley   option in the database.  The values must be separated with commas with no intervening spaces.
26522d747510SLisandro Dalcin 
26532d747510SLisandro Dalcin   Not Collective
26542d747510SLisandro Dalcin 
26552d747510SLisandro Dalcin   Input Parameters:
26562d747510SLisandro Dalcin + options - options database, use NULL for default global database
26572d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
26586b867d5aSJose E. Roman - name - the option one is seeking
26596b867d5aSJose E. Roman 
2660d8d19677SJose E. Roman   Output Parameters:
26612d747510SLisandro Dalcin + dvalue - the integer values to return
2662f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
26632d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
26642d747510SLisandro Dalcin 
26652d747510SLisandro Dalcin   Level: beginner
26662d747510SLisandro Dalcin 
26672d747510SLisandro Dalcin   Notes:
2668f1a722f8SMatthew G. Knepley   TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE. FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
26692d747510SLisandro Dalcin 
2670db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2671db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2672db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2673c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2674db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2675db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
26762d747510SLisandro Dalcin @*/
26772d747510SLisandro Dalcin PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set)
26782d747510SLisandro Dalcin {
26792d747510SLisandro Dalcin   const char     *svalue;
26802d747510SLisandro Dalcin   char           *value;
26812d747510SLisandro Dalcin   PetscInt       n = 0;
26822d747510SLisandro Dalcin   PetscBool      flag;
26832d747510SLisandro Dalcin   PetscToken     token;
26842d747510SLisandro Dalcin 
26852d747510SLisandro Dalcin   PetscFunctionBegin;
26862d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
2687064a246eSJacob Faibussowitsch   PetscValidBoolPointer(dvalue,4);
26882d747510SLisandro Dalcin   PetscValidIntPointer(nmax,5);
26892d747510SLisandro Dalcin 
26909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
26912d747510SLisandro Dalcin   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
26922d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
26939566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue,',',&token));
26949566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token,&value));
26952d747510SLisandro Dalcin   while (value && n < *nmax) {
26969566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToBool(value,dvalue));
26979566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token,&value));
26982d747510SLisandro Dalcin     dvalue++;
26992d747510SLisandro Dalcin     n++;
27002d747510SLisandro Dalcin   }
27019566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
27022d747510SLisandro Dalcin   *nmax = n;
27032d747510SLisandro Dalcin   PetscFunctionReturn(0);
27042d747510SLisandro Dalcin }
27052d747510SLisandro Dalcin 
27062d747510SLisandro Dalcin /*@C
27072d747510SLisandro Dalcin   PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
27082d747510SLisandro Dalcin 
27092d747510SLisandro Dalcin   Not Collective
27102d747510SLisandro Dalcin 
27112d747510SLisandro Dalcin   Input Parameters:
27122d747510SLisandro Dalcin + options - options database, use NULL for default global database
27132d747510SLisandro Dalcin . pre - option prefix or NULL
27142d747510SLisandro Dalcin . name - option name
27156b867d5aSJose E. Roman - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
27166b867d5aSJose E. Roman 
27172d747510SLisandro Dalcin   Output Parameters:
27182d747510SLisandro Dalcin + ivalue - the  enum values to return
2719f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
27202d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
27212d747510SLisandro Dalcin 
27222d747510SLisandro Dalcin   Level: beginner
27232d747510SLisandro Dalcin 
27242d747510SLisandro Dalcin   Notes:
27252d747510SLisandro Dalcin   The array must be passed as a comma separated list.
27262d747510SLisandro Dalcin 
27272d747510SLisandro Dalcin   There must be no intervening spaces between the values.
27282d747510SLisandro Dalcin 
27292d747510SLisandro Dalcin   list is usually something like PCASMTypes or some other predefined list of enum names.
27302d747510SLisandro Dalcin 
2731db781477SPatrick Sanan .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2732db781477SPatrick Sanan           `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
2733db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, `PetscOptionsName()`,
2734c2e3fba1SPatrick Sanan           `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
2735db781477SPatrick Sanan           `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2736db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
27372d747510SLisandro Dalcin @*/
27382d747510SLisandro Dalcin PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set)
27392d747510SLisandro Dalcin {
27402d747510SLisandro Dalcin   const char     *svalue;
27412d747510SLisandro Dalcin   char           *value;
27422d747510SLisandro Dalcin   PetscInt       n = 0;
27432d747510SLisandro Dalcin   PetscEnum      evalue;
27442d747510SLisandro Dalcin   PetscBool      flag;
27452d747510SLisandro Dalcin   PetscToken     token;
27462d747510SLisandro Dalcin 
27472d747510SLisandro Dalcin   PetscFunctionBegin;
27482d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
27492d747510SLisandro Dalcin   PetscValidPointer(list,4);
27502d747510SLisandro Dalcin   PetscValidPointer(ivalue,5);
27512d747510SLisandro Dalcin   PetscValidIntPointer(nmax,6);
27522d747510SLisandro Dalcin 
27539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
27542d747510SLisandro Dalcin   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
27552d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
27569566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue,',',&token));
27579566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token,&value));
27582d747510SLisandro Dalcin   while (value && n < *nmax) {
27599566063dSJacob Faibussowitsch     PetscCall(PetscEnumFind(list,value,&evalue,&flag));
276028b400f6SJacob Faibussowitsch     PetscCheck(flag,PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
27612d747510SLisandro Dalcin     ivalue[n++] = evalue;
27629566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token,&value));
27632d747510SLisandro Dalcin   }
27649566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
27652d747510SLisandro Dalcin   *nmax = n;
27662d747510SLisandro Dalcin   PetscFunctionReturn(0);
27672d747510SLisandro Dalcin }
27682d747510SLisandro Dalcin 
27692d747510SLisandro Dalcin /*@C
2770f1a722f8SMatthew G. Knepley   PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
27712d747510SLisandro Dalcin 
27722d747510SLisandro Dalcin   Not Collective
27732d747510SLisandro Dalcin 
27742d747510SLisandro Dalcin   Input Parameters:
27752d747510SLisandro Dalcin + options - options database, use NULL for default global database
27762d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
27776b867d5aSJose E. Roman - name - the option one is seeking
27786b867d5aSJose E. Roman 
2779d8d19677SJose E. Roman   Output Parameters:
27802d747510SLisandro Dalcin + ivalue - the integer values to return
2781f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
27822d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
27832d747510SLisandro Dalcin 
27842d747510SLisandro Dalcin   Level: beginner
27852d747510SLisandro Dalcin 
27862d747510SLisandro Dalcin   Notes:
27872d747510SLisandro Dalcin   The array can be passed as
2788f1a722f8SMatthew G. Knepley .vb
27892d747510SLisandro Dalcin   a comma separated list:                                 0,1,2,3,4,5,6,7
27902d747510SLisandro Dalcin   a range (start-end+1):                                  0-8
27912d747510SLisandro Dalcin   a range with given increment (start-end+1:inc):         0-7:2
27922d747510SLisandro Dalcin   a combination of values and ranges separated by commas: 0,1-8,8-15:2
2793f1a722f8SMatthew G. Knepley .ve
27942d747510SLisandro Dalcin 
27952d747510SLisandro Dalcin   There must be no intervening spaces between the values.
27962d747510SLisandro Dalcin 
2797db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2798db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2799db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2800c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2801db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2802db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
28032d747510SLisandro Dalcin @*/
28042d747510SLisandro Dalcin PetscErrorCode PetscOptionsGetIntArray(PetscOptions options,const char pre[],const char name[],PetscInt ivalue[],PetscInt *nmax,PetscBool *set)
28052d747510SLisandro Dalcin {
28062d747510SLisandro Dalcin   const char     *svalue;
28072d747510SLisandro Dalcin   char           *value;
28082d747510SLisandro Dalcin   PetscInt       n = 0,i,j,start,end,inc,nvalues;
28092d747510SLisandro Dalcin   size_t         len;
28102d747510SLisandro Dalcin   PetscBool      flag,foundrange;
28112d747510SLisandro Dalcin   PetscToken     token;
28122d747510SLisandro Dalcin 
28132d747510SLisandro Dalcin   PetscFunctionBegin;
28142d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
28152d747510SLisandro Dalcin   PetscValidIntPointer(ivalue,4);
28162d747510SLisandro Dalcin   PetscValidIntPointer(nmax,5);
28172d747510SLisandro Dalcin 
28189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
28192d747510SLisandro Dalcin   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
28202d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
28219566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue,',',&token));
28229566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token,&value));
28232d747510SLisandro Dalcin   while (value && n < *nmax) {
28242d747510SLisandro Dalcin     /* look for form  d-D where d and D are integers */
28252d747510SLisandro Dalcin     foundrange = PETSC_FALSE;
28269566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(value,&len));
28272d747510SLisandro Dalcin     if (value[0] == '-') i=2;
28282d747510SLisandro Dalcin     else i=1;
28292d747510SLisandro Dalcin     for (;i<(int)len; i++) {
28302d747510SLisandro Dalcin       if (value[i] == '-') {
2831cc73adaaSBarry Smith         PetscCheck(i != (int)len-1,PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %" PetscInt_FMT "-th array entry %s",n,value);
28322d747510SLisandro Dalcin         value[i] = 0;
28332d747510SLisandro Dalcin 
28349566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value,&start));
28352d747510SLisandro Dalcin         inc  = 1;
28362d747510SLisandro Dalcin         j    = i+1;
28372d747510SLisandro Dalcin         for (;j<(int)len; j++) {
28382d747510SLisandro Dalcin           if (value[j] == ':') {
28392d747510SLisandro Dalcin             value[j] = 0;
28402d747510SLisandro Dalcin 
28419566063dSJacob Faibussowitsch             PetscCall(PetscOptionsStringToInt(value+j+1,&inc));
284208401ef6SPierre 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);
28432d747510SLisandro Dalcin             break;
28442d747510SLisandro Dalcin           }
28452d747510SLisandro Dalcin         }
28469566063dSJacob Faibussowitsch         PetscCall(PetscOptionsStringToInt(value+i+1,&end));
284708401ef6SPierre 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);
28482d747510SLisandro Dalcin         nvalues = (end-start)/inc + (end-start)%inc;
2849cc73adaaSBarry 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);
28502d747510SLisandro Dalcin         for (;start<end; start+=inc) {
28512d747510SLisandro Dalcin           *ivalue = start; ivalue++;n++;
28522d747510SLisandro Dalcin         }
28532d747510SLisandro Dalcin         foundrange = PETSC_TRUE;
28542d747510SLisandro Dalcin         break;
28552d747510SLisandro Dalcin       }
28562d747510SLisandro Dalcin     }
28572d747510SLisandro Dalcin     if (!foundrange) {
28589566063dSJacob Faibussowitsch       PetscCall(PetscOptionsStringToInt(value,ivalue));
28592d747510SLisandro Dalcin       ivalue++;
28602d747510SLisandro Dalcin       n++;
28612d747510SLisandro Dalcin     }
28629566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token,&value));
28632d747510SLisandro Dalcin   }
28649566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
28652d747510SLisandro Dalcin   *nmax = n;
28662d747510SLisandro Dalcin   PetscFunctionReturn(0);
28672d747510SLisandro Dalcin }
28682d747510SLisandro Dalcin 
28692d747510SLisandro Dalcin /*@C
28702d747510SLisandro Dalcin   PetscOptionsGetRealArray - Gets an array of double precision values for a
2871f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
28722d747510SLisandro Dalcin 
28732d747510SLisandro Dalcin   Not Collective
28742d747510SLisandro Dalcin 
28752d747510SLisandro Dalcin   Input Parameters:
28762d747510SLisandro Dalcin + options - options database, use NULL for default global database
28772d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
28786b867d5aSJose E. Roman - name - the option one is seeking
28796b867d5aSJose E. Roman 
28802d747510SLisandro Dalcin   Output Parameters:
28812d747510SLisandro Dalcin + dvalue - the double values to return
2882f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
28832d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
28842d747510SLisandro Dalcin 
28852d747510SLisandro Dalcin   Level: beginner
28862d747510SLisandro Dalcin 
2887db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2888db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2889db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2890c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2891db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2892db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
28932d747510SLisandro Dalcin @*/
28942d747510SLisandro Dalcin PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set)
28952d747510SLisandro Dalcin {
28962d747510SLisandro Dalcin   const char     *svalue;
28972d747510SLisandro Dalcin   char           *value;
28982d747510SLisandro Dalcin   PetscInt       n = 0;
28992d747510SLisandro Dalcin   PetscBool      flag;
29002d747510SLisandro Dalcin   PetscToken     token;
29012d747510SLisandro Dalcin 
29022d747510SLisandro Dalcin   PetscFunctionBegin;
29032d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
29042d747510SLisandro Dalcin   PetscValidRealPointer(dvalue,4);
29052d747510SLisandro Dalcin   PetscValidIntPointer(nmax,5);
29062d747510SLisandro Dalcin 
29079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
29082d747510SLisandro Dalcin   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
29092d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29109566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue,',',&token));
29119566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token,&value));
29122d747510SLisandro Dalcin   while (value && n < *nmax) {
29139566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToReal(value,dvalue++));
29149566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token,&value));
29152d747510SLisandro Dalcin     n++;
29162d747510SLisandro Dalcin   }
29179566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29182d747510SLisandro Dalcin   *nmax = n;
29192d747510SLisandro Dalcin   PetscFunctionReturn(0);
29202d747510SLisandro Dalcin }
29212d747510SLisandro Dalcin 
29222d747510SLisandro Dalcin /*@C
29232d747510SLisandro Dalcin   PetscOptionsGetScalarArray - Gets an array of scalars for a
2924f1a722f8SMatthew G. Knepley   particular option in the database.  The values must be separated with commas with no intervening spaces.
29252d747510SLisandro Dalcin 
29262d747510SLisandro Dalcin   Not Collective
29272d747510SLisandro Dalcin 
29282d747510SLisandro Dalcin   Input Parameters:
29292d747510SLisandro Dalcin + options - options database, use NULL for default global database
29302d747510SLisandro Dalcin . pre - string to prepend to each name or NULL
29316b867d5aSJose E. Roman - name - the option one is seeking
29326b867d5aSJose E. Roman 
29332d747510SLisandro Dalcin   Output Parameters:
29342d747510SLisandro Dalcin + dvalue - the scalar values to return
2935f1a722f8SMatthew G. Knepley . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
29362d747510SLisandro Dalcin - set - PETSC_TRUE if found, else PETSC_FALSE
29372d747510SLisandro Dalcin 
29382d747510SLisandro Dalcin   Level: beginner
29392d747510SLisandro Dalcin 
2940db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2941db781477SPatrick Sanan           `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
2942db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2943c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2944db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2945db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
29462d747510SLisandro Dalcin @*/
29472d747510SLisandro Dalcin PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set)
29482d747510SLisandro Dalcin {
29492d747510SLisandro Dalcin   const char     *svalue;
29502d747510SLisandro Dalcin   char           *value;
29512d747510SLisandro Dalcin   PetscInt       n = 0;
29522d747510SLisandro Dalcin   PetscBool      flag;
29532d747510SLisandro Dalcin   PetscToken     token;
29542d747510SLisandro Dalcin 
29552d747510SLisandro Dalcin   PetscFunctionBegin;
29562d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
2957064a246eSJacob Faibussowitsch   PetscValidScalarPointer(dvalue,4);
29582d747510SLisandro Dalcin   PetscValidIntPointer(nmax,5);
29592d747510SLisandro Dalcin 
29609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
29612d747510SLisandro Dalcin   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
29622d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
29639566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue,',',&token));
29649566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token,&value));
29652d747510SLisandro Dalcin   while (value && n < *nmax) {
29669566063dSJacob Faibussowitsch     PetscCall(PetscOptionsStringToScalar(value,dvalue++));
29679566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token,&value));
29682d747510SLisandro Dalcin     n++;
29692d747510SLisandro Dalcin   }
29709566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
29712d747510SLisandro Dalcin   *nmax = n;
29722d747510SLisandro Dalcin   PetscFunctionReturn(0);
29732d747510SLisandro Dalcin }
297414ce751eSBarry Smith 
2975e5c89e4eSSatish Balay /*@C
2976e5c89e4eSSatish Balay   PetscOptionsGetStringArray - Gets an array of string values for a particular
2977f1a722f8SMatthew G. Knepley   option in the database. The values must be separated with commas with no intervening spaces.
2978e5c89e4eSSatish Balay 
2979e5c89e4eSSatish Balay   Not Collective
2980e5c89e4eSSatish Balay 
2981e5c89e4eSSatish Balay   Input Parameters:
29825c9cc608SHong Zhang + options - options database, use NULL for default global database
2983c5929fdfSBarry Smith . pre - string to prepend to name or NULL
29846b867d5aSJose E. Roman - name - the option one is seeking
29856b867d5aSJose E. Roman 
2986e7b76fa7SPatrick Sanan   Output Parameters:
2987e5c89e4eSSatish Balay + strings - location to copy strings
2988f1a722f8SMatthew G. Knepley . nmax - On input maximum number of strings, on output the actual number of strings found
298996ef3cdfSSatish Balay - set - PETSC_TRUE if found, else PETSC_FALSE
2990e5c89e4eSSatish Balay 
2991e5c89e4eSSatish Balay   Level: beginner
2992e5c89e4eSSatish Balay 
2993e5c89e4eSSatish Balay   Notes:
2994e7b76fa7SPatrick Sanan   The nmax parameter is used for both input and output.
2995e7b76fa7SPatrick Sanan 
2996e5c89e4eSSatish Balay   The user should pass in an array of pointers to char, to hold all the
2997e5c89e4eSSatish Balay   strings returned by this function.
2998e5c89e4eSSatish Balay 
2999e5c89e4eSSatish Balay   The user is responsible for deallocating the strings that are
3000e5c89e4eSSatish Balay   returned. The Fortran interface for this routine is not supported.
3001e5c89e4eSSatish Balay 
3002db781477SPatrick Sanan .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3003db781477SPatrick Sanan           `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3004db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3005c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3006db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3007db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
3008e5c89e4eSSatish Balay @*/
3009c5929fdfSBarry Smith PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set)
3010e5c89e4eSSatish Balay {
30112d747510SLisandro Dalcin   const char     *svalue;
3012e5c89e4eSSatish Balay   char           *value;
30132d747510SLisandro Dalcin   PetscInt       n = 0;
3014ace3abfcSBarry Smith   PetscBool      flag;
30159c9d3cfdSBarry Smith   PetscToken     token;
3016e5c89e4eSSatish Balay 
3017e5c89e4eSSatish Balay   PetscFunctionBegin;
30182d747510SLisandro Dalcin   PetscValidCharPointer(name,3);
30192d747510SLisandro Dalcin   PetscValidPointer(strings,4);
30202d747510SLisandro Dalcin   PetscValidIntPointer(nmax,5);
3021e5c89e4eSSatish Balay 
30229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,pre,name,&svalue,&flag));
30232d747510SLisandro Dalcin   if (!flag || !svalue)  { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);}
30242d747510SLisandro Dalcin   if (set) *set = PETSC_TRUE;
30259566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(svalue,',',&token));
30269566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token,&value));
30272d747510SLisandro Dalcin   while (value && n < *nmax) {
30289566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(value,&strings[n]));
30299566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token,&value));
3030e5c89e4eSSatish Balay     n++;
3031e5c89e4eSSatish Balay   }
30329566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
3033e5c89e4eSSatish Balay   *nmax = n;
3034e5c89e4eSSatish Balay   PetscFunctionReturn(0);
3035e5c89e4eSSatish Balay }
303606824ed3SPatrick Sanan 
303706824ed3SPatrick Sanan /*@C
303806824ed3SPatrick Sanan    PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one
303906824ed3SPatrick Sanan 
304006824ed3SPatrick Sanan    Prints a deprecation warning, unless an option is supplied to suppress.
304106824ed3SPatrick Sanan 
30421c9f3c13SBarry Smith    Logically Collective
304306824ed3SPatrick Sanan 
304406824ed3SPatrick Sanan    Input Parameters:
30459503aa97SPatrick Sanan +  pre - string to prepend to name or NULL
304606824ed3SPatrick Sanan .  oldname - the old, deprecated option
304706824ed3SPatrick Sanan .  newname - the new option, or NULL if option is purely removed
30489f3a6782SPatrick Sanan .  version - a string describing the version of first deprecation, e.g. "3.9"
30499f3a6782SPatrick Sanan -  info - additional information string, or NULL.
305006824ed3SPatrick Sanan 
305106824ed3SPatrick Sanan    Options Database Keys:
305206824ed3SPatrick Sanan . -options_suppress_deprecated_warnings - do not print deprecation warnings
305306824ed3SPatrick Sanan 
305406824ed3SPatrick Sanan    Notes:
30551c9f3c13SBarry Smith    Must be called between PetscOptionsBegin() (or PetscObjectOptionsBegin()) and PetscOptionsEnd().
30561c9f3c13SBarry Smith    Only the proces of rank zero that owns the PetscOptionsItems are argument (managed by PetscOptionsBegin() or
30571c9f3c13SBarry Smith    PetscObjectOptionsBegin() prints the information
3058b40114eaSPatrick Sanan    If newname is provided, the old option is replaced. Otherwise, it remains
3059b40114eaSPatrick Sanan    in the options database.
30609f3a6782SPatrick Sanan    If an option is not replaced, the info argument should be used to advise the user
30619f3a6782SPatrick Sanan    on how to proceed.
30629f3a6782SPatrick Sanan    There is a limit on the length of the warning printed, so very long strings
30639f3a6782SPatrick Sanan    provided as info may be truncated.
306406824ed3SPatrick Sanan 
306506824ed3SPatrick Sanan    Level: developer
306606824ed3SPatrick Sanan 
3067db781477SPatrick Sanan .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
306806824ed3SPatrick Sanan 
306906824ed3SPatrick Sanan @*/
30709f3a6782SPatrick Sanan PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[])
307106824ed3SPatrick Sanan {
307206824ed3SPatrick Sanan   PetscBool          found,quiet;
307306824ed3SPatrick Sanan   const char         *value;
307406824ed3SPatrick Sanan   const char * const quietopt="-options_suppress_deprecated_warnings";
30759f3a6782SPatrick Sanan   char               msg[4096];
3076b0bdc838SStefano Zampini   char               *prefix = NULL;
3077b0bdc838SStefano Zampini   PetscOptions       options = NULL;
3078b0bdc838SStefano Zampini   MPI_Comm           comm = PETSC_COMM_SELF;
307906824ed3SPatrick Sanan 
308006824ed3SPatrick Sanan   PetscFunctionBegin;
308106824ed3SPatrick Sanan   PetscValidCharPointer(oldname,2);
308206824ed3SPatrick Sanan   PetscValidCharPointer(version,4);
3083b0bdc838SStefano Zampini   if (PetscOptionsObject) {
3084b0bdc838SStefano Zampini     prefix  = PetscOptionsObject->prefix;
3085b0bdc838SStefano Zampini     options = PetscOptionsObject->options;
3086b0bdc838SStefano Zampini     comm    = PetscOptionsObject->comm;
3087b0bdc838SStefano Zampini   }
30889566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFindPair(options,prefix,oldname,&value,&found));
308906824ed3SPatrick Sanan   if (found) {
309006824ed3SPatrick Sanan     if (newname) {
30911baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPush(options,prefix));
30929566063dSJacob Faibussowitsch       PetscCall(PetscOptionsSetValue(options,newname,value));
30931baa6e33SBarry Smith       if (prefix) PetscCall(PetscOptionsPrefixPop(options));
30949566063dSJacob Faibussowitsch       PetscCall(PetscOptionsClearValue(options,oldname));
3095b40114eaSPatrick Sanan     }
309606824ed3SPatrick Sanan     quiet = PETSC_FALSE;
30979566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetBool(options,NULL,quietopt,&quiet,NULL));
309806824ed3SPatrick Sanan     if (!quiet) {
30999566063dSJacob Faibussowitsch       PetscCall(PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option "));
31009566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg,oldname));
31019566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg," is deprecated as of version "));
31029566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg,version));
31039566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg," and will be removed in a future release."));
310406824ed3SPatrick Sanan       if (newname) {
31059566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg," Please use the option "));
31069566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg,newname));
31079566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg," instead."));
310806824ed3SPatrick Sanan       }
31099f3a6782SPatrick Sanan       if (info) {
31109566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg," "));
31119566063dSJacob Faibussowitsch         PetscCall(PetscStrcat(msg,info));
31129f3a6782SPatrick Sanan       }
31139566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg," (Silence this warning with "));
31149566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg,quietopt));
31159566063dSJacob Faibussowitsch       PetscCall(PetscStrcat(msg,")\n"));
31169566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(comm,"%s",msg));
311706824ed3SPatrick Sanan     }
311806824ed3SPatrick Sanan   }
311906824ed3SPatrick Sanan   PetscFunctionReturn(0);
312006824ed3SPatrick Sanan }
3121