Actual source code: options.c
1: /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
2: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for atoll() */
4: /*
5: These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
6: This provides the low-level interface, the high level interface is in aoptions.c
8: Some routines use regular malloc and free because it cannot know what malloc is requested with the
9: options database until it has already processed the input.
10: */
12: #include <petsc/private/petscimpl.h>
13: #include <petscviewer.h>
14: #include <ctype.h>
15: #if PetscDefined(HAVE_MALLOC_H)
16: #include <malloc.h>
17: #endif
18: #if PetscDefined(HAVE_STRINGS_H)
19: #include <strings.h> /* strcasecmp */
20: #endif
22: #if PetscDefined(HAVE_STRCASECMP)
23: #define PetscOptNameCmp(a, b) strcasecmp(a, b)
24: #elif PetscDefined(HAVE_STRICMP)
25: #define PetscOptNameCmp(a, b) stricmp(a, b)
26: #else
27: #define PetscOptNameCmp(a, b) Error_strcasecmp_not_found
28: #endif
30: #include <petsc/private/hashtable.h>
32: /* This assumes ASCII encoding and ignores locale settings */
33: /* Using tolower() is about 2X slower in microbenchmarks */
34: static inline int PetscToLower(int c)
35: {
36: return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
37: }
39: /* Bob Jenkins's one at a time hash function (case-insensitive) */
40: static inline unsigned int PetscOptHash(const char key[])
41: {
42: unsigned int hash = 0;
43: while (*key) {
44: hash += PetscToLower(*key++);
45: hash += hash << 10;
46: hash ^= hash >> 6;
47: }
48: hash += hash << 3;
49: hash ^= hash >> 11;
50: hash += hash << 15;
51: return hash;
52: }
54: static inline int PetscOptEqual(const char a[], const char b[])
55: {
56: return !PetscOptNameCmp(a, b);
57: }
59: KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
61: #define MAXPREFIXES 25
62: #define MAXOPTIONSMONITORS 5
64: const char *PetscOptionSources[] = {"code", "command line", "file", "environment"};
66: // This table holds all the options set by the user
67: struct _n_PetscOptions {
68: PetscOptions previous;
70: int N; /* number of options */
71: int Nalloc; /* number of allocated options */
72: char **names; /* option names */
73: char **values; /* option values */
74: PetscBool *used; /* flag option use */
75: PetscOptionSource *source; /* source for option value */
76: PetscBool precedentProcessed;
78: /* Hash table */
79: khash_t(HO) *ht;
81: /* Prefixes */
82: int prefixind;
83: int prefixstack[MAXPREFIXES];
84: char prefix[PETSC_MAX_OPTION_NAME];
86: /* Aliases */
87: int Na; /* number or aliases */
88: int Naalloc; /* number of allocated aliases */
89: char **aliases1; /* aliased */
90: char **aliases2; /* aliasee */
92: /* Help */
93: PetscBool help; /* flag whether "-help" is in the database */
94: PetscBool help_intro; /* flag whether "-help intro" is in the database */
95: int help_nmansecs; /* number of manual sections given as "-help mansec,..."; 0 means the help output is not restricted; int, not PetscInt, to match PetscStrToArray() */
96: char **help_mansecs; /* the manual sections themselves; only the options blocks in one of them are printed */
98: /* Monitors */
99: PetscBool monitorFromOptions, monitorCancel;
100: PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], PetscOptionSource, void *); /* returns control to user after */
101: PetscCtxDestroyFn *monitordestroy[MAXOPTIONSMONITORS]; /* callback for monitor destruction */
102: void *monitorcontext[MAXOPTIONSMONITORS]; /* to pass arbitrary user data into monitor */
103: PetscInt numbermonitors; /* to, for instance, detect options being set */
104: };
106: static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
108: /* list of options which precede others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
109: /* these options can only take boolean values, the code will crash if given a non-boolean value.
110: -help is the exception: it also accepts "intro" and a comma-separated list of manual sections. A bare
111: -help 0, 1, yes, no, on, off, true or false is read as a logical value, so a manual section named that
112: way can only be selected as part of such a list, as in "-help 0,ksp" */
113: static const char *precedentOptions[] = {"-petsc_ci", "-options_monitor", "-options_monitor_cancel", "-help", "-skip_petscrc"};
114: enum PetscPrecedentOption {
115: PO_CI_ENABLE,
116: PO_OPTIONS_MONITOR,
117: PO_OPTIONS_MONITOR_CANCEL,
118: PO_HELP,
119: PO_SKIP_PETSCRC,
120: PO_NUM
121: };
123: PETSC_INTERN PetscErrorCode PetscOptionsSetValue_Private(PetscOptions, const char[], const char[], int *, PetscOptionSource);
124: PETSC_INTERN PetscErrorCode PetscOptionsInsertStringYAML_Private(PetscOptions, const char[], PetscOptionSource);
125: static PetscErrorCode PetscOptionsStringToBool_Private(const char[], PetscBool *, PetscBool *);
127: /*
128: Options events monitor
129: */
130: static PetscErrorCode PetscOptionsMonitor(PetscOptions options, const char name[], const char value[], PetscOptionSource source)
131: {
132: PetscFunctionBegin;
133: if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name, value, source, NULL));
134: for (PetscInt i = 0; i < options->numbermonitors; i++) PetscCall((*options->monitor[i])(name, value, source, options->monitorcontext[i]));
135: PetscFunctionReturn(PETSC_SUCCESS);
136: }
138: /*@
139: PetscOptionsCreate - Creates an empty options database.
141: Logically Collective
143: Output Parameter:
144: . options - Options database object
146: Level: advanced
148: Note:
149: Though PETSc has a concept of multiple options database the current code uses a single default `PetscOptions` object
151: Developer Notes:
152: We may want eventually to pass a `MPI_Comm` to determine the ownership of the object
154: This object never got developed after being introduced, it is not clear that supporting multiple `PetscOptions` objects is useful
156: .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
157: @*/
158: PetscErrorCode PetscOptionsCreate(PetscOptions *options)
159: {
160: PetscFunctionBegin;
161: PetscAssertPointer(options, 1);
162: *options = (PetscOptions)calloc(1, sizeof(**options));
163: PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
164: PetscFunctionReturn(PETSC_SUCCESS);
165: }
167: /*@
168: PetscOptionsDestroy - Destroys an option database.
170: Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
172: Input Parameter:
173: . options - the `PetscOptions` object
175: Level: advanced
177: .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsSetValue()`
178: @*/
179: PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
180: {
181: PetscFunctionBegin;
182: PetscAssertPointer(options, 1);
183: if (!*options) PetscFunctionReturn(PETSC_SUCCESS);
184: 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()");
185: PetscCall(PetscOptionsClear(*options));
186: /* XXX what about monitors ? */
187: free(*options);
188: *options = NULL;
189: PetscFunctionReturn(PETSC_SUCCESS);
190: }
192: /*@
193: PetscOptionsCreateDefault - Creates the default global options database if it does not already exist
195: Logically collective
197: Level: developer
199: Note:
200: This is called during `PetscInitialize()`; user code normally does not need to call it directly.
202: .seealso: `PetscOptionsDestroyDefault()`, `PetscOptionsCreate()`, `PetscOptionsPush()`, `PetscOptionsPop()`
203: @*/
204: PetscErrorCode PetscOptionsCreateDefault(void)
205: {
206: PetscFunctionBegin;
207: if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
208: PetscFunctionReturn(PETSC_SUCCESS);
209: }
211: /*@
212: PetscOptionsPush - Push a new `PetscOptions` object as the default provider of options
213: Allows using different parts of a code to use different options databases
215: Logically Collective
217: Input Parameter:
218: . opt - the options obtained with `PetscOptionsCreate()`
220: Level: advanced
222: Notes:
223: Use `PetscOptionsPop()` to return to the previous default options database
225: The collectivity of this routine is complex; only the MPI ranks that call this routine will
226: have the affect of these options. If some processes that create objects call this routine and others do
227: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
228: on different ranks.
230: Developer Notes:
231: Though this functionality has been provided it has never been used in PETSc and might be removed.
233: .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
234: @*/
235: PetscErrorCode PetscOptionsPush(PetscOptions opt)
236: {
237: PetscFunctionBegin;
238: PetscCall(PetscOptionsCreateDefault());
239: opt->previous = defaultoptions;
240: defaultoptions = opt;
241: PetscFunctionReturn(PETSC_SUCCESS);
242: }
244: /*@
245: PetscOptionsPop - Pop the most recent `PetscOptionsPush()` to return to the previous default options
247: Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
249: Level: advanced
251: .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
252: @*/
253: PetscErrorCode PetscOptionsPop(void)
254: {
255: PetscOptions current = defaultoptions;
257: PetscFunctionBegin;
258: PetscCheck(defaultoptions, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing default options");
259: PetscCheck(defaultoptions->previous, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscOptionsPop() called too many times");
260: defaultoptions = defaultoptions->previous;
261: current->previous = NULL;
262: PetscFunctionReturn(PETSC_SUCCESS);
263: }
265: /*@
266: PetscOptionsDestroyDefault - Destroys the default global options database
268: Logically collective
270: Level: developer
272: Note:
273: This is called during `PetscFinalize()`; any options databases the user pushed but did not pop are also destroyed.
275: .seealso: `PetscOptionsCreateDefault()`, `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`
276: @*/
277: PetscErrorCode PetscOptionsDestroyDefault(void)
278: {
279: PetscFunctionBegin;
280: if (!defaultoptions) PetscFunctionReturn(PETSC_SUCCESS);
281: /* Destroy any options that the user forgot to pop */
282: while (defaultoptions->previous) {
283: PetscOptions tmp = defaultoptions;
285: PetscCall(PetscOptionsPop());
286: PetscCall(PetscOptionsDestroy(&tmp));
287: }
288: PetscCall(PetscOptionsDestroy(&defaultoptions));
289: PetscFunctionReturn(PETSC_SUCCESS);
290: }
292: /*@
293: PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
295: Not Collective
297: Input Parameter:
298: . key - string to check if valid
300: Output Parameter:
301: . valid - `PETSC_TRUE` if a valid key
303: Level: intermediate
305: .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`
306: @*/
307: PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid)
308: {
309: char *ptr;
310: PETSC_UNUSED double d;
312: PetscFunctionBegin;
313: if (key) PetscAssertPointer(key, 1);
314: PetscAssertPointer(valid, 2);
315: *valid = PETSC_FALSE;
316: if (!key) PetscFunctionReturn(PETSC_SUCCESS);
317: if (key[0] != '-') PetscFunctionReturn(PETSC_SUCCESS);
318: if (key[1] == '-') key++;
319: if (!isalpha((int)key[1])) PetscFunctionReturn(PETSC_SUCCESS);
320: d = strtod(key, &ptr);
321: if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(PETSC_SUCCESS);
322: *valid = PETSC_TRUE;
323: PetscFunctionReturn(PETSC_SUCCESS);
324: }
326: static PetscErrorCode PetscOptionsInsertString_Private(PetscOptions options, const char in_str[], PetscOptionSource source)
327: {
328: const char *first, *second;
329: PetscToken token;
331: PetscFunctionBegin;
332: PetscCall(PetscTokenCreate(in_str, ' ', &token));
333: PetscCall(PetscTokenFind(token, &first));
334: while (first) {
335: PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
337: PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
338: PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
339: PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
340: PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
341: PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
342: PetscCall(PetscOptionsValidKey(first, &key));
343: if (!key) {
344: PetscCall(PetscTokenFind(token, &first));
345: } else if (isfile) {
346: PetscCall(PetscTokenFind(token, &second));
347: PetscCall(PetscOptionsInsertFile(PETSC_COMM_SELF, options, second, PETSC_TRUE));
348: PetscCall(PetscTokenFind(token, &first));
349: } else if (isfileyaml) {
350: PetscCall(PetscTokenFind(token, &second));
351: PetscCall(PetscOptionsInsertFileYAML(PETSC_COMM_SELF, options, second, PETSC_TRUE));
352: PetscCall(PetscTokenFind(token, &first));
353: } else if (isstringyaml) {
354: PetscCall(PetscTokenFind(token, &second));
355: PetscCall(PetscOptionsInsertStringYAML_Private(options, second, source));
356: PetscCall(PetscTokenFind(token, &first));
357: } else if (ispush) {
358: PetscCall(PetscTokenFind(token, &second));
359: PetscCall(PetscOptionsPrefixPush(options, second));
360: PetscCall(PetscTokenFind(token, &first));
361: } else if (ispop) {
362: PetscCall(PetscOptionsPrefixPop(options));
363: PetscCall(PetscTokenFind(token, &first));
364: } else {
365: PetscCall(PetscTokenFind(token, &second));
366: PetscCall(PetscOptionsValidKey(second, &key));
367: if (!key) {
368: PetscCall(PetscOptionsSetValue_Private(options, first, second, NULL, source));
369: PetscCall(PetscTokenFind(token, &first));
370: } else {
371: PetscCall(PetscOptionsSetValue_Private(options, first, NULL, NULL, source));
372: first = second;
373: }
374: }
375: }
376: PetscCall(PetscTokenDestroy(&token));
377: PetscFunctionReturn(PETSC_SUCCESS);
378: }
380: /*@
381: PetscOptionsInsertString - Inserts options into the database from a string
383: Logically Collective
385: Input Parameters:
386: + options - options object
387: - in_str - string that contains options separated by blanks
389: Level: intermediate
391: The collectivity of this routine is complex; only the MPI processes that call this routine will
392: have the affect of these options. If some processes that create objects call this routine and others do
393: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
394: on different ranks.
396: Contributed by Boyana Norris
398: .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
399: `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
400: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
401: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
402: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
403: `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
404: @*/
405: PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[])
406: {
407: PetscFunctionBegin;
408: PetscCall(PetscOptionsInsertString_Private(options, in_str, PETSC_OPT_CODE));
409: PetscFunctionReturn(PETSC_SUCCESS);
410: }
412: /*
413: Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
414: */
415: static char *Petscgetline(FILE *f)
416: {
417: size_t size = 0;
418: size_t len = 0;
419: size_t last = 0;
420: char *buf = NULL;
422: if (feof(f)) return NULL;
423: do {
424: size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
425: buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
426: /* Actually do the read. Note that fgets puts a terminal '\0' on the
427: end of the string, so we make sure we overwrite this */
428: if (!fgets(buf + len, 1024, f)) buf[len] = 0;
429: PetscCallAbort(PETSC_COMM_SELF, PetscStrlen(buf, &len));
430: last = len - 1;
431: } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
432: if (len) return buf;
433: free(buf);
434: return NULL;
435: }
437: static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml)
438: {
439: char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
441: PetscFunctionBegin;
442: *yaml = PETSC_FALSE;
443: PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
444: PetscCall(PetscFixFilename(fname, path));
445: PetscCall(PetscStrendswith(path, ":yaml", yaml));
446: if (*yaml) {
447: PetscCall(PetscStrrchr(path, ':', &tail));
448: tail[-1] = 0; /* remove ":yaml" suffix from path */
449: }
450: PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
451: /* check for standard YAML and JSON filename extensions */
452: if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
453: if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
454: if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
455: if (!*yaml) { /* check file contents */
456: PetscMPIInt rank;
457: PetscCallMPI(MPI_Comm_rank(comm, &rank));
458: if (rank == 0) {
459: FILE *fh = fopen(filename, "r");
460: if (fh) {
461: char buf[6] = "";
462: if (fread(buf, 1, 6, fh) > 0) {
463: PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml)); /* check for '%YAML' tag */
464: if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
465: }
466: (void)fclose(fh);
467: }
468: }
469: PetscCallMPI(MPI_Bcast(yaml, 1, MPI_C_BOOL, 0, comm));
470: }
471: PetscFunctionReturn(PETSC_SUCCESS);
472: }
474: static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
475: {
476: char *string, *vstring = NULL, *astring = NULL, *packed = NULL;
477: const char *tokens[4];
478: size_t len;
479: PetscCount bytes;
480: FILE *fd;
481: PetscToken token = NULL;
482: int err;
483: char *cmatch = NULL;
484: const char cmt = '#';
485: PetscInt line = 1;
486: PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
487: PetscBool isdir, alias = PETSC_FALSE, valid;
489: PetscFunctionBegin;
490: PetscCall(PetscMemzero(tokens, sizeof(tokens)));
491: PetscCallMPI(MPI_Comm_rank(comm, &rank));
492: if (rank == 0) {
493: char fpath[PETSC_MAX_PATH_LEN];
494: char fname[PETSC_MAX_PATH_LEN];
496: PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fname, sizeof(fname)));
497: PetscCall(PetscFixFilename(fname, fpath));
498: PetscCall(PetscGetFullPath(fpath, fname, sizeof(fname)));
500: fd = fopen(fname, "r");
501: PetscCall(PetscTestDirectory(fname, 'r', &isdir));
502: PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
503: if (fd && !isdir) {
504: PetscSegBuffer vseg, aseg;
506: PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
507: PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
509: /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
510: PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
512: while ((string = Petscgetline(fd))) {
513: /* eliminate comments from each line */
514: PetscCall(PetscStrchr(string, cmt, &cmatch));
515: if (cmatch) *cmatch = 0;
516: PetscCall(PetscStrlen(string, &len));
517: /* replace tabs, ^M, \n with " " */
518: for (size_t i = 0; i < len; i++) {
519: if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
520: }
521: PetscCall(PetscTokenCreate(string, ' ', &token));
522: PetscCall(PetscTokenFind(token, &tokens[0]));
523: if (!tokens[0]) {
524: goto destroy;
525: } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
526: PetscCall(PetscTokenFind(token, &tokens[0]));
527: }
528: for (PetscInt i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
529: if (!tokens[0]) {
530: goto destroy;
531: } else if (tokens[0][0] == '-') {
532: PetscCall(PetscOptionsValidKey(tokens[0], &valid));
533: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": invalid option %s", fname, line, tokens[0]);
534: PetscCall(PetscStrlen(tokens[0], &len));
535: PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
536: PetscCall(PetscArraycpy(vstring, tokens[0], len));
537: vstring[len] = ' ';
538: if (tokens[1]) {
539: PetscCall(PetscOptionsValidKey(tokens[1], &valid));
540: 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]);
541: PetscCall(PetscStrlen(tokens[1], &len));
542: PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
543: vstring[0] = '"';
544: PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
545: vstring[len + 1] = '"';
546: vstring[len + 2] = ' ';
547: }
548: } else {
549: PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
550: PetscCheck(alias, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown first token in options file %s line %" PetscInt_FMT ": %s", fname, line, tokens[0]);
551: PetscCall(PetscOptionsValidKey(tokens[1], &valid));
552: 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]);
553: 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]);
554: PetscCall(PetscOptionsValidKey(tokens[2], &valid));
555: 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]);
556: PetscCall(PetscStrlen(tokens[1], &len));
557: PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
558: PetscCall(PetscArraycpy(astring, tokens[1], len));
559: astring[len] = ' ';
561: PetscCall(PetscStrlen(tokens[2], &len));
562: PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
563: PetscCall(PetscArraycpy(astring, tokens[2], len));
564: astring[len] = ' ';
565: }
566: {
567: const char *extraToken = alias ? tokens[3] : tokens[2];
568: PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
569: }
570: destroy:
571: free(string);
572: PetscCall(PetscTokenDestroy(&token));
573: alias = PETSC_FALSE;
574: line++;
575: }
576: err = fclose(fd);
577: PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
578: PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
579: PetscCall(PetscMPIIntCast(bytes, &acnt));
580: PetscCall(PetscSegBufferGet(aseg, 1, &astring));
581: astring[0] = 0;
582: PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
583: PetscCall(PetscMPIIntCast(bytes, &cnt));
584: PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
585: vstring[0] = 0;
586: PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
587: PetscCall(PetscSegBufferExtractTo(aseg, packed));
588: PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
589: PetscCall(PetscSegBufferDestroy(&aseg));
590: PetscCall(PetscSegBufferDestroy(&vseg));
591: } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
592: }
594: counts[0] = acnt;
595: counts[1] = cnt;
596: err = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
597: 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/");
598: acnt = counts[0];
599: cnt = counts[1];
600: if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
601: if (acnt || cnt) {
602: PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
603: astring = packed;
604: vstring = packed + acnt + 1;
605: }
607: if (acnt) {
608: PetscCall(PetscTokenCreate(astring, ' ', &token));
609: PetscCall(PetscTokenFind(token, &tokens[0]));
610: while (tokens[0]) {
611: PetscCall(PetscTokenFind(token, &tokens[1]));
612: PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
613: PetscCall(PetscTokenFind(token, &tokens[0]));
614: }
615: PetscCall(PetscTokenDestroy(&token));
616: }
618: if (cnt) PetscCall(PetscOptionsInsertString_Private(options, vstring, PETSC_OPT_FILE));
619: PetscCall(PetscFree(packed));
620: PetscFunctionReturn(PETSC_SUCCESS);
621: }
623: /*@
624: PetscOptionsInsertFile - Inserts options into the database from a file.
626: Collective
628: Input Parameters:
629: + comm - the processes that will share the options (usually `PETSC_COMM_WORLD`)
630: . options - options database, use `NULL` for default global database
631: . file - name of file,
632: ".yml" and ".yaml" filename extensions are inserted as YAML options,
633: append ":yaml" to filename to force YAML options.
634: - require - if `PETSC_TRUE` will generate an error if the file does not exist
636: Level: developer
638: Notes:
639: Use # for lines that are comments and which should be ignored.
640: Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
641: 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
642: calls to `XXXSetFromOptions()`, it should not be used for options listed under PetscInitialize().
643: The collectivity of this routine is complex; only the MPI processes in comm will
644: have the effect of these options. If some processes that create objects call this routine and others do
645: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
646: on different ranks.
648: .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
649: `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
650: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
651: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
652: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
653: `PetscOptionsFList()`, `PetscOptionsEList()`
654: @*/
655: PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
656: {
657: char filename[PETSC_MAX_PATH_LEN];
658: PetscBool yaml;
660: PetscFunctionBegin;
661: PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
662: if (yaml) {
663: PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
664: } else {
665: PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
666: }
667: PetscFunctionReturn(PETSC_SUCCESS);
668: }
670: /*@
671: PetscOptionsInsertArgs - Inserts options into the database from a array of strings
673: Logically Collective
675: Input Parameters:
676: + options - options object
677: . argc - the array length
678: - args - the string array
680: Level: intermediate
682: .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
683: @*/
684: PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, const char *const args[])
685: {
686: int left = PetscMax(argc, 0);
687: const char *const *eargs = args;
689: PetscFunctionBegin;
690: while (left) {
691: PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
692: PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
693: PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
694: PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
695: PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
696: PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
697: PetscCall(PetscOptionsValidKey(eargs[0], &key));
698: if (!key) {
699: eargs++;
700: left--;
701: } else if (isfile) {
702: PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
703: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, eargs[1], PETSC_TRUE));
704: eargs += 2;
705: left -= 2;
706: } else if (isfileyaml) {
707: PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
708: PetscCall(PetscOptionsInsertFileYAML(PETSC_COMM_WORLD, options, eargs[1], PETSC_TRUE));
709: eargs += 2;
710: left -= 2;
711: } else if (isstringyaml) {
712: PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
713: PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
714: eargs += 2;
715: left -= 2;
716: } else if (ispush) {
717: PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
718: PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
719: PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
720: eargs += 2;
721: left -= 2;
722: } else if (ispop) {
723: PetscCall(PetscOptionsPrefixPop(options));
724: eargs++;
725: left--;
726: } else {
727: PetscBool nextiskey = PETSC_FALSE;
728: if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
729: if (left < 2 || nextiskey) {
730: PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
731: eargs++;
732: left--;
733: } else {
734: PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
735: eargs += 2;
736: left -= 2;
737: }
738: }
739: }
740: PetscFunctionReturn(PETSC_SUCCESS);
741: }
743: static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], const PetscBool set[], PetscBool *flg)
744: {
745: PetscFunctionBegin;
746: if (set[opt]) PetscCall(PetscOptionsStringToBool(val[opt], flg));
747: else *flg = PETSC_FALSE;
748: PetscFunctionReturn(PETSC_SUCCESS);
749: }
751: /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
752: static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
753: {
754: const char *const *opt = precedentOptions;
755: const size_t n = PO_NUM;
756: size_t o;
757: int a;
758: const char **val;
759: char **cval;
760: PetscBool *set, unneeded;
761: PetscBool isbool = PETSC_FALSE, helpval = PETSC_FALSE;
763: PetscFunctionBegin;
764: PetscCall(PetscCalloc2(n, &cval, n, &set));
765: val = (const char **)cval;
767: /* Look for options possibly set using PetscOptionsSetValue beforehand */
768: for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
770: /* Loop through all args to collect last occurring value of each option */
771: for (a = 1; a < argc; a++) {
772: PetscBool valid, eq;
774: PetscCall(PetscOptionsValidKey(args[a], &valid));
775: if (!valid) continue;
776: for (o = 0; o < n; o++) {
777: PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
778: if (eq) {
779: set[o] = PETSC_TRUE;
780: if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
781: else val[o] = args[a + 1];
782: break;
783: }
784: }
785: }
787: /* Process flags */
788: /* "-help" accepts a logical value, "intro" or a list of manual sections; PetscOptionsSetValue_Private()
789: reads it the same way below, and records the manual sections when the option is stored */
790: PetscCall(PetscOptionsStringToBool_Private(val[PO_HELP], &helpval, &isbool));
791: PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
792: if (set[PO_HELP]) options->help = isbool ? helpval : PETSC_TRUE;
793: else options->help = PETSC_FALSE;
794: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
795: /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
796: if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
797: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
798: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
799: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
800: *skip_petscrc_set = set[PO_SKIP_PETSCRC];
802: /* Store precedent options in database and mark them as used */
803: for (o = 1; o < n; o++) {
804: if (set[o]) {
805: PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
806: options->used[a] = PETSC_TRUE;
807: }
808: }
809: PetscCall(PetscFree2(cval, set));
810: options->precedentProcessed = PETSC_TRUE;
811: PetscFunctionReturn(PETSC_SUCCESS);
812: }
814: static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
815: {
816: PetscFunctionBegin;
817: PetscAssertPointer(flg, 3);
818: *flg = PETSC_FALSE;
819: if (options->precedentProcessed) {
820: for (int i = 0; i < PO_NUM; ++i) {
821: if (!PetscOptNameCmp(precedentOptions[i], name)) {
822: /* check if precedent option has been set already */
823: PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
824: if (*flg) break;
825: }
826: }
827: }
828: PetscFunctionReturn(PETSC_SUCCESS);
829: }
831: /*@
832: PetscOptionsInsert - Inserts into the options database from the command line,
833: the environmental variable and a file.
835: Collective on `PETSC_COMM_WORLD`
837: Input Parameters:
838: + options - options database or `NULL` for the default global database
839: . argc - count of number of command line arguments
840: . args - the command line arguments
841: - file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
842: Use `NULL` or empty string to not check for code specific file.
843: Also checks ~/.petscrc, .petscrc and petscrc.
844: Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
846: Options Database Keys:
847: + -options_file filename - read options from a file
848: - -options_file_yaml filename - read options from a YAML file
850: Level: advanced
852: Notes:
853: Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
854: the user does not typically need to call this routine. `PetscOptionsInsert()`
855: can be called several times, adding additional entries into the database.
857: See `PetscInitialize()` for options related to option database monitoring.
859: .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
860: `PetscInitialize()`
861: @*/
862: PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[]) PeNS
863: {
864: PetscMPIInt rank;
865: PetscBool hasArgs = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
866: PetscBool skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
867: char *eoptions = NULL;
868: size_t len = 0;
870: PetscFunctionBegin;
871: PetscCheck(!hasArgs || (args && *args), PETSC_COMM_WORLD, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
872: PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
874: if (!options) {
875: PetscCall(PetscOptionsCreateDefault());
876: options = defaultoptions;
877: }
878: if (hasArgs) {
879: /* process options with absolute precedence */
880: PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
881: PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
882: }
883: if (file && file[0]) {
884: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, file, PETSC_TRUE));
885: /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
886: if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
887: }
888: if (!skipPetscrc) {
889: char filename[PETSC_MAX_PATH_LEN];
891: PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
892: PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, PETSC_COMM_WORLD));
893: if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
894: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, filename, PETSC_FALSE));
895: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, ".petscrc", PETSC_FALSE));
896: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, "petscrc", PETSC_FALSE));
897: }
899: /* insert environment options */
900: if (rank == 0) {
901: eoptions = getenv("PETSC_OPTIONS");
902: PetscCall(PetscStrlen(eoptions, &len));
903: }
904: PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, PETSC_COMM_WORLD));
905: if (len) {
906: if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
907: PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, PETSC_COMM_WORLD));
908: if (rank) eoptions[len] = 0;
909: PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
910: if (rank) PetscCall(PetscFree(eoptions));
911: }
913: /* insert YAML environment options */
914: if (rank == 0) {
915: eoptions = getenv("PETSC_OPTIONS_YAML");
916: PetscCall(PetscStrlen(eoptions, &len));
917: }
918: PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, PETSC_COMM_WORLD));
919: if (len) {
920: if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
921: PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, PETSC_COMM_WORLD));
922: if (rank) eoptions[len] = 0;
923: PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
924: if (rank) PetscCall(PetscFree(eoptions));
925: }
927: /* insert command line options here because they take precedence over arguments in petscrc/environment */
928: if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, (const char *const *)*args + 1));
929: PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
930: PetscFunctionReturn(PETSC_SUCCESS);
931: }
933: /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
934: /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
935: static const char *PetscCIOptions[] = {"malloc_debug", "malloc_dump", "malloc_test", "malloc", "nox", "nox_warning", "display", "saws_port_auto_select", "saws_port_auto_select_silent", "vecscatter_mpi1", "check_pointer_intensity", "cuda_initialize", "error_output_stdout", "use_gpu_aware_mpi", "checkfunctionlist", "fp_trap", "petsc_ci", "petsc_ci_portable_error_output", "options_left"};
937: static PetscBool PetscCIOption(const char *name)
938: {
939: PetscInt idx;
940: PetscBool found;
942: if (!PetscCIEnabled) return PETSC_FALSE;
943: PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
944: return found;
945: }
947: /*@
948: PetscOptionsView - Prints the options that have been loaded. This is
949: useful for debugging purposes.
951: Logically Collective, No Fortran Support
953: Input Parameters:
954: + options - options database, use `NULL` for default global database
955: - viewer - must be an `PETSCVIEWERASCII` viewer
957: Options Database Key:
958: . -options_view (true|false) - Activates `PetscOptionsView()` within `PetscFinalize()`.
960: Level: advanced
962: Note:
963: Only the MPI rank 0 of the `MPI_Comm` used to create `viewer` displays the option values. Other processes
964: may have different values but they are not printed.
966: .seealso: `PetscOptionsAllUsed()`
967: @*/
968: PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
969: {
970: PetscInt i, N = 0;
971: PetscBool isascii;
973: PetscFunctionBegin;
975: options = options ? options : defaultoptions;
976: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
977: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
978: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
980: for (i = 0; i < options->N; i++) {
981: if (PetscCIOption(options->names[i])) continue;
982: N++;
983: }
985: if (!N) {
986: PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
987: PetscFunctionReturn(PETSC_SUCCESS);
988: }
990: PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
991: for (i = 0; i < options->N; i++) {
992: if (PetscCIOption(options->names[i])) continue;
993: if (options->values[i]) {
994: PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
995: } else {
996: PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
997: }
998: PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
999: }
1000: PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
1001: PetscFunctionReturn(PETSC_SUCCESS);
1002: }
1004: /*@
1005: PetscOptionsLeftError - Prints a warning listing any options in the default database that were never used
1007: Not Collective
1009: Level: developer
1011: Note:
1012: This is intended for use inside PETSc error handlers. Unused options may indicate a program that crashed before it
1013: read them, a spelling mistake, or an option intended for a different context.
1015: .seealso: `PetscOptionsLeft()`, `PetscOptionsAllUsed()`, `PetscOptionsView()`
1016: @*/
1017: PetscErrorCode PetscOptionsLeftError(void)
1018: {
1019: PetscInt i, nopt = 0;
1021: for (i = 0; i < defaultoptions->N; i++) {
1022: if (!defaultoptions->used[i]) {
1023: if (PetscCIOption(defaultoptions->names[i])) continue;
1024: nopt++;
1025: }
1026: }
1027: if (nopt) {
1028: PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
1029: for (i = 0; i < defaultoptions->N; i++) {
1030: if (!defaultoptions->used[i]) {
1031: if (PetscCIOption(defaultoptions->names[i])) continue;
1032: if (defaultoptions->values[i]) PetscCall((*PetscErrorPrintf)(" Option left: name:-%s value: %s source: %s\n", defaultoptions->names[i], defaultoptions->values[i], PetscOptionSources[defaultoptions->source[i]]));
1033: else PetscCall((*PetscErrorPrintf)(" Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
1034: }
1035: }
1036: }
1037: return PETSC_SUCCESS;
1038: }
1040: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1041: {
1042: PetscInt i, N = 0;
1043: PetscOptions options = defaultoptions;
1045: for (i = 0; i < options->N; i++) {
1046: if (PetscCIOption(options->names[i])) continue;
1047: N++;
1048: }
1050: if (N) {
1051: PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1052: } else {
1053: PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1054: }
1055: for (i = 0; i < options->N; i++) {
1056: if (PetscCIOption(options->names[i])) continue;
1057: if (options->values[i]) {
1058: PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1059: } else {
1060: PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1061: }
1062: }
1063: return PETSC_SUCCESS;
1064: }
1066: /*@
1067: PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
1069: Logically Collective
1071: Input Parameters:
1072: + options - options database, or `NULL` for the default global database
1073: - prefix - The string to append to the existing prefix
1075: Options Database Keys:
1076: + -prefix_push some_prefix_ - push the given prefix
1077: - -prefix_pop - pop the last prefix
1079: Level: advanced
1081: Notes:
1082: It is common to use this in conjunction with `-options_file` as in
1083: .vb
1084: -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
1085: .ve
1086: where the files no longer require all options to be prefixed with `-system2_`.
1088: The collectivity of this routine is complex; only the MPI processes that call this routine will
1089: have the affect of these options. If some processes that create objects call this routine and others do
1090: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1091: on different ranks.
1093: .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
1094: @*/
1095: PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1096: {
1097: size_t n;
1098: PetscInt start;
1099: char key[PETSC_MAX_OPTION_NAME + 1];
1100: PetscBool valid;
1102: PetscFunctionBegin;
1103: PetscAssertPointer(prefix, 2);
1104: options = options ? options : defaultoptions;
1105: PetscCheck(options->prefixind < MAXPREFIXES, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum depth of prefix stack %d exceeded, recompile src/sys/objects/options.c with larger value for MAXPREFIXES", MAXPREFIXES);
1106: key[0] = '-'; /* keys must start with '-' */
1107: PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
1108: PetscCall(PetscOptionsValidKey(key, &valid));
1109: if (!valid && options->prefixind > 0 && isdigit((int)prefix[0])) valid = PETSC_TRUE; /* If the prefix stack is not empty, make numbers a valid prefix */
1110: 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" : "");
1111: start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
1112: PetscCall(PetscStrlen(prefix, &n));
1113: PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
1114: PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
1115: options->prefixstack[options->prefixind++] = (int)(start + n);
1116: PetscFunctionReturn(PETSC_SUCCESS);
1117: }
1119: /*@
1120: PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
1122: Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
1124: Input Parameter:
1125: . options - options database, or `NULL` for the default global database
1127: Level: advanced
1129: .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
1130: @*/
1131: PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1132: {
1133: PetscInt offset;
1135: PetscFunctionBegin;
1136: options = options ? options : defaultoptions;
1137: PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
1138: options->prefixind--;
1139: offset = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
1140: options->prefix[offset] = 0;
1141: PetscFunctionReturn(PETSC_SUCCESS);
1142: }
1144: /* Releases the manual sections recorded from "-help mansec,..." and marks the help output as unrestricted. */
1145: static PetscErrorCode PetscOptionsHelpManSecsClear_Private(PetscOptions options)
1146: {
1147: PetscFunctionBegin;
1148: PetscCall(PetscStrToArrayDestroy(options->help_nmansecs, options->help_mansecs));
1149: options->help_nmansecs = 0;
1150: options->help_mansecs = NULL;
1151: PetscFunctionReturn(PETSC_SUCCESS);
1152: }
1154: /*@
1155: PetscOptionsClear - Removes all options form the database leaving it empty.
1157: Logically Collective
1159: Input Parameter:
1160: . options - options database, use `NULL` for the default global database
1162: Level: developer
1164: Note:
1165: The collectivity of this routine is complex; only the MPI processes that call this routine will
1166: have the affect of these options. If some processes that create objects call this routine and others do
1167: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1168: on different ranks.
1170: Developer Note:
1171: Uses `free()` directly because the current option values were set with `malloc()`
1173: .seealso: `PetscOptionsInsert()`
1174: @*/
1175: PetscErrorCode PetscOptionsClear(PetscOptions options)
1176: {
1177: PetscInt i;
1179: PetscFunctionBegin;
1180: options = options ? options : defaultoptions;
1181: if (!options) PetscFunctionReturn(PETSC_SUCCESS);
1183: for (i = 0; i < options->N; i++) {
1184: if (options->names[i]) free(options->names[i]);
1185: if (options->values[i]) free(options->values[i]);
1186: }
1187: options->N = 0;
1188: free(options->names);
1189: free(options->values);
1190: free(options->used);
1191: free(options->source);
1192: options->names = NULL;
1193: options->values = NULL;
1194: options->used = NULL;
1195: options->source = NULL;
1196: options->Nalloc = 0;
1198: for (i = 0; i < options->Na; i++) {
1199: free(options->aliases1[i]);
1200: free(options->aliases2[i]);
1201: }
1202: options->Na = 0;
1203: free(options->aliases1);
1204: free(options->aliases2);
1205: options->aliases1 = options->aliases2 = NULL;
1206: options->Naalloc = 0;
1208: /* destroy hash table */
1209: kh_destroy(HO, options->ht);
1210: options->ht = NULL;
1212: options->prefixind = 0;
1213: options->prefix[0] = 0;
1214: options->help = PETSC_FALSE;
1215: options->help_intro = PETSC_FALSE;
1216: PetscCall(PetscOptionsHelpManSecsClear_Private(options));
1217: PetscFunctionReturn(PETSC_SUCCESS);
1218: }
1220: /*@
1221: PetscOptionsSetAlias - Makes a key and alias for another key
1223: Logically Collective
1225: Input Parameters:
1226: + options - options database, or `NULL` for default global database
1227: . newname - the alias
1228: - oldname - the name that alias will refer to
1230: Level: advanced
1232: Note:
1233: The collectivity of this routine is complex; only the MPI processes that call this routine will
1234: have the affect of these options. If some processes that create objects call this routine and others do
1235: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1236: on different ranks.
1238: Developer Note:
1239: Uses `malloc()` directly because PETSc may not be initialized yet.
1241: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1242: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1243: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1244: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1245: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1246: `PetscOptionsFList()`, `PetscOptionsEList()`
1247: @*/
1248: PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1249: {
1250: size_t len;
1251: PetscBool valid;
1253: PetscFunctionBegin;
1254: PetscAssertPointer(newname, 2);
1255: PetscAssertPointer(oldname, 3);
1256: options = options ? options : defaultoptions;
1257: PetscCall(PetscOptionsValidKey(newname, &valid));
1258: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
1259: PetscCall(PetscOptionsValidKey(oldname, &valid));
1260: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
1262: if (options->Na == options->Naalloc) {
1263: char **tmpA1, **tmpA2;
1265: options->Naalloc = PetscMax(4, options->Naalloc * 2);
1266: tmpA1 = (char **)malloc(options->Naalloc * sizeof(char *));
1267: tmpA2 = (char **)malloc(options->Naalloc * sizeof(char *));
1268: for (int i = 0; i < options->Na; ++i) {
1269: tmpA1[i] = options->aliases1[i];
1270: tmpA2[i] = options->aliases2[i];
1271: }
1272: free(options->aliases1);
1273: free(options->aliases2);
1274: options->aliases1 = tmpA1;
1275: options->aliases2 = tmpA2;
1276: }
1277: newname++;
1278: oldname++;
1279: PetscCall(PetscStrlen(newname, &len));
1280: options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1281: PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
1282: PetscCall(PetscStrlen(oldname, &len));
1283: options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1284: PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
1285: ++options->Na;
1286: PetscFunctionReturn(PETSC_SUCCESS);
1287: }
1289: /*@
1290: PetscOptionsSetValue - Sets an option name-value pair in the options
1291: database, overriding whatever is already present.
1293: Logically Collective
1295: Input Parameters:
1296: + options - options database, use `NULL` for the default global database
1297: . name - name of option, this SHOULD have the - prepended
1298: - value - the option value (not used for all options, so can be `NULL`)
1300: Level: intermediate
1302: Note:
1303: This function can be called BEFORE `PetscInitialize()`
1305: The collectivity of this routine is complex; only the MPI processes that call this routine will
1306: have the affect of these options. If some processes that create objects call this routine and others do
1307: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1308: on different ranks.
1310: Developer Note:
1311: Uses `malloc()` directly because PETSc may not be initialized yet.
1313: .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1314: @*/
1315: PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1316: {
1317: PetscFunctionBegin;
1318: PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
1319: PetscFunctionReturn(PETSC_SUCCESS);
1320: }
1322: PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1323: {
1324: size_t len;
1325: int n, i;
1326: char **names;
1327: char fullname[PETSC_MAX_OPTION_NAME] = "";
1328: PetscBool flg;
1330: PetscFunctionBegin;
1331: if (!options) {
1332: PetscCall(PetscOptionsCreateDefault());
1333: options = defaultoptions;
1334: }
1335: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
1337: PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
1338: if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1340: name++; /* skip starting dash */
1342: if (options->prefixind > 0) {
1343: strncpy(fullname, options->prefix, sizeof(fullname));
1344: fullname[sizeof(fullname) - 1] = 0;
1345: strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
1346: fullname[sizeof(fullname) - 1] = 0;
1347: name = fullname;
1348: }
1350: /* check against aliases */
1351: for (i = 0; i < options->Na; i++) {
1352: int result = PetscOptNameCmp(options->aliases1[i], name);
1353: if (!result) {
1354: name = options->aliases2[i];
1355: break;
1356: }
1357: }
1359: /* slow search */
1360: n = options->N;
1361: names = options->names;
1362: for (i = 0; i < options->N; i++) {
1363: int result = PetscOptNameCmp(names[i], name);
1364: if (!result) {
1365: n = i;
1366: goto setvalue;
1367: } else if (result > 0) {
1368: n = i;
1369: break;
1370: }
1371: }
1372: if (options->N == options->Nalloc) {
1373: char **names, **values;
1374: PetscBool *used;
1375: PetscOptionSource *source;
1377: options->Nalloc = PetscMax(10, options->Nalloc * 2);
1378: names = (char **)malloc(options->Nalloc * sizeof(char *));
1379: values = (char **)malloc(options->Nalloc * sizeof(char *));
1380: used = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
1381: source = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
1382: for (int i = 0; i < options->N; ++i) {
1383: names[i] = options->names[i];
1384: values[i] = options->values[i];
1385: used[i] = options->used[i];
1386: source[i] = options->source[i];
1387: }
1388: free(options->names);
1389: free(options->values);
1390: free(options->used);
1391: free(options->source);
1392: options->names = names;
1393: options->values = values;
1394: options->used = used;
1395: options->source = source;
1396: }
1398: /* shift remaining values up 1 */
1399: for (i = options->N; i > n; i--) {
1400: options->names[i] = options->names[i - 1];
1401: options->values[i] = options->values[i - 1];
1402: options->used[i] = options->used[i - 1];
1403: options->source[i] = options->source[i - 1];
1404: }
1405: options->names[n] = NULL;
1406: options->values[n] = NULL;
1407: options->used[n] = PETSC_FALSE;
1408: options->source[n] = PETSC_OPT_CODE;
1409: options->N++;
1411: /* destroy hash table */
1412: kh_destroy(HO, options->ht);
1413: options->ht = NULL;
1415: /* set new name */
1416: len = strlen(name);
1417: options->names[n] = (char *)malloc((len + 1) * sizeof(char));
1418: PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1419: strcpy(options->names[n], name);
1421: setvalue:
1422: /* set new value */
1423: if (options->values[n]) free(options->values[n]);
1424: len = value ? strlen(value) : 0;
1425: if (len) {
1426: options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1427: if (!options->values[n]) return PETSC_ERR_MEM;
1428: strcpy(options->values[n], value);
1429: options->values[n][len] = '\0';
1430: } else {
1431: options->values[n] = NULL;
1432: }
1433: options->source[n] = source;
1435: /* handle -help so that it can be set from anywhere */
1436: if (!PetscOptNameCmp(name, "help")) {
1437: PetscBool isbool = PETSC_FALSE, helpval = PETSC_FALSE;
1439: PetscCall(PetscOptionsStringToBool_Private(value, &helpval, &isbool));
1440: options->help = isbool ? helpval : PETSC_TRUE;
1441: options->help_intro = (!isbool && value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
1442: options->used[n] = PETSC_TRUE;
1443: PetscCall(PetscOptionsHelpManSecsClear_Private(options));
1444: /* a value that is neither a logical value nor "intro" is a comma-separated list of manual sections that
1445: restricts the help output; PetscStrToArray() uses raw malloc()/free() like names[]/values[], as needed
1446: here since -help is processed before the tracking allocator is set up */
1447: if (!isbool && value && value[0] && !options->help_intro) PetscCall(PetscStrToArray(value, ',', &options->help_nmansecs, &options->help_mansecs));
1448: }
1450: PetscCall(PetscOptionsMonitor(options, name, value ? value : "", source));
1451: if (pos) *pos = n;
1452: PetscFunctionReturn(PETSC_SUCCESS);
1453: }
1455: /*@
1456: PetscOptionsClearValue - Clears an option name-value pair in the options
1457: database, overriding whatever is already present.
1459: Logically Collective
1461: Input Parameters:
1462: + options - options database, use `NULL` for the default global database
1463: - name - name of option, this SHOULD have the - prepended
1465: Level: intermediate
1467: Note:
1468: The collectivity of this routine is complex; only the MPI processes that call this routine will
1469: have the affect of these options. If some processes that create objects call this routine and others do
1470: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1471: on different ranks.
1473: Developer Note:
1474: Uses `free()` directly because the options have been set with `malloc()`
1476: .seealso: `PetscOptionsInsert()`
1477: @*/
1478: PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1479: {
1480: int N, n, i;
1481: char **names;
1483: PetscFunctionBegin;
1484: options = options ? options : defaultoptions;
1485: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1486: if (!PetscOptNameCmp(name, "-help")) {
1487: options->help = options->help_intro = PETSC_FALSE;
1488: PetscCall(PetscOptionsHelpManSecsClear_Private(options));
1489: }
1491: name++; /* skip starting dash */
1493: /* slow search */
1494: N = n = options->N;
1495: names = options->names;
1496: for (i = 0; i < N; i++) {
1497: int result = PetscOptNameCmp(names[i], name);
1498: if (!result) {
1499: n = i;
1500: break;
1501: } else if (result > 0) {
1502: n = N;
1503: break;
1504: }
1505: }
1506: if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1508: /* remove name and value */
1509: if (options->names[n]) free(options->names[n]);
1510: if (options->values[n]) free(options->values[n]);
1511: /* shift remaining values down 1 */
1512: for (i = n; i < N - 1; i++) {
1513: options->names[i] = options->names[i + 1];
1514: options->values[i] = options->values[i + 1];
1515: options->used[i] = options->used[i + 1];
1516: options->source[i] = options->source[i + 1];
1517: }
1518: options->N--;
1520: /* destroy hash table */
1521: kh_destroy(HO, options->ht);
1522: options->ht = NULL;
1524: PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
1525: PetscFunctionReturn(PETSC_SUCCESS);
1526: }
1528: /*@
1529: PetscOptionsFindPair - Gets an option name-value pair from the options database.
1531: Not Collective
1533: Input Parameters:
1534: + options - options database, use `NULL` for the default global database
1535: . pre - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
1536: - name - name of option, this SHOULD have the "-" prepended
1538: Output Parameters:
1539: + value - the option value (optional, not used for all options)
1540: - set - whether the option is set (optional)
1542: Level: developer
1544: Note:
1545: Each process may find different values or no value depending on how options were inserted into the database
1547: .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1548: @*/
1549: PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1550: {
1551: char buf[PETSC_MAX_OPTION_NAME];
1552: PetscBool matchnumbers = PETSC_TRUE;
1554: PetscFunctionBegin;
1555: if (!options) {
1556: PetscCall(PetscOptionsCreateDefault());
1557: options = defaultoptions;
1558: }
1559: PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1560: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1562: name++; /* skip starting dash */
1564: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1565: if (pre && pre[0]) {
1566: char *ptr = buf;
1567: if (name[0] == '-') {
1568: *ptr++ = '-';
1569: name++;
1570: }
1571: PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
1572: PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
1573: name = buf;
1574: }
1576: if (PetscDefined(USE_DEBUG)) {
1577: PetscBool valid;
1578: char key[PETSC_MAX_OPTION_NAME + 1] = "-";
1579: PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
1580: PetscCall(PetscOptionsValidKey(key, &valid));
1581: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1582: }
1584: if (!options->ht) {
1585: int i, ret;
1586: khiter_t it;
1587: khash_t(HO) *ht;
1588: ht = kh_init(HO);
1589: PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
1590: ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
1591: PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
1592: for (i = 0; i < options->N; i++) {
1593: it = kh_put(HO, ht, options->names[i], &ret);
1594: PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
1595: kh_val(ht, it) = i;
1596: }
1597: options->ht = ht;
1598: }
1600: khash_t(HO) *ht = options->ht;
1601: khiter_t it = kh_get(HO, ht, name);
1602: if (it != kh_end(ht)) {
1603: int i = kh_val(ht, it);
1604: options->used[i] = PETSC_TRUE;
1605: if (value) *value = options->values[i];
1606: if (set) *set = PETSC_TRUE;
1607: PetscFunctionReturn(PETSC_SUCCESS);
1608: }
1610: /*
1611: The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
1612: Maybe this special lookup mode should be enabled on request with a push/pop API.
1613: The feature of matching _%d_ used sparingly in the codebase.
1614: */
1615: if (matchnumbers) {
1616: int i, j, cnt = 0, locs[16], loce[16];
1617: /* determine the location and number of all _%d_ in the key */
1618: for (i = 0; name[i]; i++) {
1619: if (name[i] == '_') {
1620: for (j = i + 1; name[j]; j++) {
1621: if (name[j] >= '0' && name[j] <= '9') continue;
1622: if (name[j] == '_' && j > i + 1) { /* found a number */
1623: locs[cnt] = i + 1;
1624: loce[cnt++] = j + 1;
1625: }
1626: i = j - 1;
1627: break;
1628: }
1629: }
1630: }
1631: for (i = 0; i < cnt; i++) {
1632: PetscBool found;
1633: char opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
1634: PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
1635: PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
1636: PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
1637: PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
1638: if (found) {
1639: if (set) *set = PETSC_TRUE;
1640: PetscFunctionReturn(PETSC_SUCCESS);
1641: }
1642: }
1643: }
1645: if (set) *set = PETSC_FALSE;
1646: PetscFunctionReturn(PETSC_SUCCESS);
1647: }
1649: /* Check whether any option begins with pre+name */
1650: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *option[], const char *value[], PetscBool *set)
1651: {
1652: char buf[PETSC_MAX_OPTION_NAME];
1653: int numCnt = 0, locs[16], loce[16];
1655: PetscFunctionBegin;
1656: options = options ? options : defaultoptions;
1657: PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1658: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1660: name++; /* skip starting dash */
1662: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1663: if (pre && pre[0]) {
1664: char *ptr = buf;
1665: if (name[0] == '-') {
1666: *ptr++ = '-';
1667: name++;
1668: }
1669: PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
1670: PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
1671: name = buf;
1672: }
1674: if (PetscDefined(USE_DEBUG)) {
1675: PetscBool valid;
1676: char key[PETSC_MAX_OPTION_NAME + 1] = "-";
1677: PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
1678: PetscCall(PetscOptionsValidKey(key, &valid));
1679: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1680: }
1682: /* determine the location and number of all _%d_ in the key */
1683: {
1684: int i, j;
1685: for (i = 0; name[i]; i++) {
1686: if (name[i] == '_') {
1687: for (j = i + 1; name[j]; j++) {
1688: if (name[j] >= '0' && name[j] <= '9') continue;
1689: if (name[j] == '_' && j > i + 1) { /* found a number */
1690: locs[numCnt] = i + 1;
1691: loce[numCnt++] = j + 1;
1692: }
1693: i = j - 1;
1694: break;
1695: }
1696: }
1697: }
1698: }
1700: /* slow search */
1701: for (int c = -1; c < numCnt; ++c) {
1702: char opt[PETSC_MAX_OPTION_NAME + 2] = "";
1703: size_t len;
1705: if (c < 0) {
1706: PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1707: } else {
1708: PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1709: PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1710: }
1711: PetscCall(PetscStrlen(opt, &len));
1712: for (int i = 0; i < options->N; i++) {
1713: PetscBool match;
1715: PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1716: if (match) {
1717: options->used[i] = PETSC_TRUE;
1718: if (option) *option = options->names[i];
1719: if (value) *value = options->values[i];
1720: if (set) *set = PETSC_TRUE;
1721: PetscFunctionReturn(PETSC_SUCCESS);
1722: }
1723: }
1724: }
1726: if (set) *set = PETSC_FALSE;
1727: PetscFunctionReturn(PETSC_SUCCESS);
1728: }
1730: /*@
1731: PetscOptionsReject - Generates an error if a certain option is given.
1733: Not Collective
1735: Input Parameters:
1736: + options - options database, use `NULL` for default global database
1737: . pre - the option prefix (may be `NULL`)
1738: . name - the option name one is seeking
1739: - mess - error message (may be `NULL`)
1741: Level: advanced
1743: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1744: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1745: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1746: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1747: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1748: `PetscOptionsFList()`, `PetscOptionsEList()`
1749: @*/
1750: PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1751: {
1752: PetscBool flag = PETSC_FALSE;
1754: PetscFunctionBegin;
1755: PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1756: if (flag) {
1757: PetscCheck(!mess || !mess[0], PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s with %s", pre ? pre : "", name + 1, mess);
1758: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1759: }
1760: PetscFunctionReturn(PETSC_SUCCESS);
1761: }
1763: /*@
1764: PetscOptionsHasHelp - Determines whether help output has been requested with the "-help" option.
1766: Not Collective
1768: Input Parameter:
1769: . options - options database, use `NULL` for default global database
1771: Output Parameter:
1772: . set - `PETSC_TRUE` if requested else `PETSC_FALSE`.
1774: Level: advanced
1776: Note:
1777: `-help` accepts a logical value, so this returns `PETSC_FALSE` for `-help 0`, `-help no`, `-help false`
1778: and `-help off` even though "-help" is then in the database. It returns `PETSC_TRUE` for `-help mansec`,
1779: which restricts rather than suppresses the help output.
1781: .seealso: `PetscOptionsHasName()`
1782: @*/
1783: PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1784: {
1785: PetscFunctionBegin;
1786: PetscAssertPointer(set, 2);
1787: options = options ? options : defaultoptions;
1788: *set = options->help;
1789: PetscFunctionReturn(PETSC_SUCCESS);
1790: }
1792: PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1793: {
1794: PetscFunctionBegin;
1795: PetscAssertPointer(set, 2);
1796: options = options ? options : defaultoptions;
1797: *set = options->help_intro;
1798: PetscFunctionReturn(PETSC_SUCCESS);
1799: }
1801: /* Returns the manual sections given with "-help mansec,...", with n set to 0 when the help output should not be
1802: restricted. mansec may be NULL. The returned array is borrowed and remains valid until the option is cleared. */
1803: PetscErrorCode PetscOptionsHelpManSecs_Internal(PetscOptions options, PetscInt *n, const char *const *mansec[])
1804: {
1805: PetscFunctionBegin;
1806: PetscAssertPointer(n, 2);
1807: options = options ? options : defaultoptions;
1808: *n = options->help_nmansecs;
1809: if (mansec) *mansec = (const char *const *)options->help_mansecs;
1810: PetscFunctionReturn(PETSC_SUCCESS);
1811: }
1813: /* Returns in print whether the help output documented in manual section mansec should be printed, taking both
1814: "-help" and any "-help mansec,..." restriction into account. mansec is the manual section that help belongs
1815: to; it may be NULL for help that belongs to none, which a restriction never selects. */
1816: PetscErrorCode PetscOptionsHelpPrintable_Internal(PetscOptions options, const char mansec[], PetscBool *print)
1817: {
1818: PetscInt nmansec = 0, idx = 0;
1819: const char *const *mansecs = NULL;
1821: PetscFunctionBegin;
1822: PetscAssertPointer(print, 3);
1823: PetscCall(PetscOptionsHasHelp(options, print));
1824: if (!*print) PetscFunctionReturn(PETSC_SUCCESS);
1825: PetscCall(PetscOptionsHelpManSecs_Internal(options, &nmansec, &mansecs));
1826: if (!nmansec) PetscFunctionReturn(PETSC_SUCCESS);
1827: *print = PETSC_FALSE;
1828: if (mansec && mansec[0]) PetscCall(PetscEListFind(nmansec, mansecs, mansec, &idx, print));
1829: PetscFunctionReturn(PETSC_SUCCESS);
1830: }
1832: /*@
1833: PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or Boolean, even
1834: if its value is set to false.
1836: Not Collective
1838: Input Parameters:
1839: + options - options database, use `NULL` for default global database
1840: . pre - string to prepend to the name or `NULL`
1841: - name - the option one is seeking
1843: Output Parameter:
1844: . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1846: Level: beginner
1848: Note:
1849: In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
1851: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1852: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1853: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1854: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1855: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1856: `PetscOptionsFList()`, `PetscOptionsEList()`
1857: @*/
1858: PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1859: {
1860: const char *value;
1861: PetscBool flag;
1863: PetscFunctionBegin;
1864: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
1865: if (set) *set = flag;
1866: PetscFunctionReturn(PETSC_SUCCESS);
1867: }
1869: /*@
1870: PetscOptionsGetAll - Lists all the options the program was run with in a single string.
1872: Not Collective
1874: Input Parameter:
1875: . options - the options database, use `NULL` for the default global database
1877: Output Parameter:
1878: . copts - pointer where string pointer is stored
1880: Level: advanced
1882: Notes:
1883: The string should be freed with `PetscFree()`
1885: Each process may have different values depending on how the options were inserted into the database
1887: .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`,
1888: `PetscOptionsLeftGet()`
1889: @*/
1890: PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[]) PeNS
1891: {
1892: PetscInt i;
1893: size_t len = 1, lent = 0;
1894: char *coptions = NULL;
1896: PetscFunctionBegin;
1897: PetscAssertPointer(copts, 2);
1898: options = options ? options : defaultoptions;
1899: /* count the length of the required string */
1900: for (i = 0; i < options->N; i++) {
1901: PetscCall(PetscStrlen(options->names[i], &lent));
1902: len += 2 + lent;
1903: if (options->values[i]) {
1904: PetscCall(PetscStrlen(options->values[i], &lent));
1905: len += 1 + lent;
1906: }
1907: }
1908: PetscCall(PetscMalloc1(len, &coptions));
1909: coptions[0] = 0;
1910: for (i = 0; i < options->N; i++) {
1911: PetscCall(PetscStrlcat(coptions, "-", len));
1912: PetscCall(PetscStrlcat(coptions, options->names[i], len));
1913: PetscCall(PetscStrlcat(coptions, " ", len));
1914: if (options->values[i]) {
1915: PetscCall(PetscStrlcat(coptions, options->values[i], len));
1916: PetscCall(PetscStrlcat(coptions, " ", len));
1917: }
1918: }
1919: *copts = coptions;
1920: PetscFunctionReturn(PETSC_SUCCESS);
1921: }
1923: /*@
1924: PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
1926: Not Collective
1928: Input Parameters:
1929: + options - options database, use `NULL` for default global database
1930: - name - string name of option
1932: Output Parameter:
1933: . used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
1935: Level: advanced
1937: Note:
1938: The value returned may be different on each process and depends on which options have been processed
1939: on the given process
1941: .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
1942: @*/
1943: PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1944: {
1945: PetscInt i;
1947: PetscFunctionBegin;
1948: PetscAssertPointer(name, 2);
1949: PetscAssertPointer(used, 3);
1950: options = options ? options : defaultoptions;
1951: *used = PETSC_FALSE;
1952: for (i = 0; i < options->N; i++) {
1953: PetscCall(PetscStrcasecmp(options->names[i], name, used));
1954: if (*used) {
1955: *used = options->used[i];
1956: break;
1957: }
1958: }
1959: PetscFunctionReturn(PETSC_SUCCESS);
1960: }
1962: /*@
1963: PetscOptionsAllUsed - Returns a count of the number of options in the
1964: database that have never been selected.
1966: Not Collective
1968: Input Parameter:
1969: . options - options database, use `NULL` for default global database
1971: Output Parameter:
1972: . N - count of options not used
1974: Level: advanced
1976: Note:
1977: The value returned may be different on each process and depends on which options have been processed
1978: on the given process
1980: .seealso: `PetscOptionsView()`
1981: @*/
1982: PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1983: {
1984: PetscInt i, n = 0;
1986: PetscFunctionBegin;
1987: PetscAssertPointer(N, 2);
1988: options = options ? options : defaultoptions;
1989: for (i = 0; i < options->N; i++) {
1990: if (!options->used[i]) n++;
1991: }
1992: *N = n;
1993: PetscFunctionReturn(PETSC_SUCCESS);
1994: }
1996: /*@
1997: PetscOptionsLeft - Prints to screen any options that were set and never used.
1999: Not Collective
2001: Input Parameter:
2002: . options - options database; use `NULL` for default global database
2004: Options Database Key:
2005: . -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
2007: Level: advanced
2009: Notes:
2010: This is rarely used directly, it is called by `PetscFinalize()` by default (unless
2011: `-options_left false` is specified) to help users determine possible mistakes in their usage of
2012: options. This only prints values on process zero of `PETSC_COMM_WORLD`.
2014: Other processes depending the objects
2015: used may have different options that are left unused.
2017: .seealso: `PetscOptionsAllUsed()`
2018: @*/
2019: PetscErrorCode PetscOptionsLeft(PetscOptions options)
2020: {
2021: PetscInt cnt = 0;
2022: PetscOptions toptions;
2024: PetscFunctionBegin;
2025: toptions = options ? options : defaultoptions;
2026: for (PetscInt i = 0; i < toptions->N; i++) {
2027: if (!toptions->used[i]) {
2028: if (PetscCIOption(toptions->names[i])) continue;
2029: if (toptions->values[i]) {
2030: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s value: %s source: %s\n", toptions->names[i], toptions->values[i], PetscOptionSources[toptions->source[i]]));
2031: } else {
2032: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
2033: }
2034: }
2035: }
2036: if (!options) {
2037: toptions = defaultoptions;
2038: while (toptions->previous) {
2039: cnt++;
2040: toptions = toptions->previous;
2041: }
2042: if (cnt) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: You may have forgotten some calls to PetscOptionsPop(),\n PetscOptionsPop() has been called %" PetscInt_FMT " less times than PetscOptionsPush()\n", cnt));
2043: }
2044: PetscFunctionReturn(PETSC_SUCCESS);
2045: }
2047: /*@
2048: PetscOptionsLeftGet - Returns all options that were set and never used.
2050: Not Collective
2052: Input Parameter:
2053: . options - options database, use `NULL` for default global database
2055: Output Parameters:
2056: + N - count of options not used
2057: . names - names of options not used
2058: - values - values of options not used
2060: Level: advanced
2062: Notes:
2063: Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
2065: The value returned may be different on each process and depends on which options have been processed
2066: on the given process
2068: .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
2069: @*/
2070: PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
2071: {
2072: PetscInt n;
2074: PetscFunctionBegin;
2075: if (N) PetscAssertPointer(N, 2);
2076: if (names) PetscAssertPointer(names, 3);
2077: if (values) PetscAssertPointer(values, 4);
2078: options = options ? options : defaultoptions;
2080: /* The number of unused PETSc options */
2081: n = 0;
2082: for (PetscInt i = 0; i < options->N; i++) {
2083: if (PetscCIOption(options->names[i])) continue;
2084: if (!options->used[i]) n++;
2085: }
2086: if (N) *N = n;
2087: if (names) PetscCall(PetscMalloc1(n, names));
2088: if (values) PetscCall(PetscMalloc1(n, values));
2090: n = 0;
2091: if (names || values) {
2092: for (PetscInt i = 0; i < options->N; i++) {
2093: if (!options->used[i]) {
2094: if (PetscCIOption(options->names[i])) continue;
2095: if (names) (*names)[n] = options->names[i];
2096: if (values) (*values)[n] = options->values[i];
2097: n++;
2098: }
2099: }
2100: }
2101: PetscFunctionReturn(PETSC_SUCCESS);
2102: }
2104: /*@
2105: PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
2107: Not Collective
2109: Input Parameters:
2110: + options - options database, use `NULL` for default global database
2111: . N - count of options not used
2112: . names - names of options not used
2113: - values - values of options not used
2115: Level: advanced
2117: Notes:
2118: The user should pass the same pointer to `N` as they did when calling `PetscOptionsLeftGet()`
2120: .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
2121: @*/
2122: PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2123: {
2124: PetscFunctionBegin;
2125: (void)options;
2126: if (N) PetscAssertPointer(N, 2);
2127: if (names) PetscAssertPointer(names, 3);
2128: if (values) PetscAssertPointer(values, 4);
2129: if (N) *N = 0;
2130: if (names) PetscCall(PetscFree(*names));
2131: if (values) PetscCall(PetscFree(*values));
2132: PetscFunctionReturn(PETSC_SUCCESS);
2133: }
2135: /*@
2136: PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
2138: Logically Collective
2140: Input Parameters:
2141: + name - option name string
2142: . value - option value string
2143: . source - The source for the option
2144: - ctx - a `PETSCVIEWERASCII` or `NULL`
2146: Level: intermediate
2148: Notes:
2149: If ctx is `NULL`, `PetscPrintf()` is used.
2150: The first MPI process in the `PetscViewer` viewer actually prints the values, other
2151: processes may have different values set
2153: If `PetscCIEnabled` then do not print the test harness options
2155: .seealso: `PetscOptionsMonitorSet()`
2156: @*/
2157: PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], PetscOptionSource source, PetscCtx ctx)
2158: {
2159: PetscFunctionBegin;
2160: if (PetscCIOption(name)) PetscFunctionReturn(PETSC_SUCCESS);
2162: if (ctx) {
2163: PetscViewer viewer = (PetscViewer)ctx;
2164: if (!value) {
2165: PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
2166: } else if (!value[0]) {
2167: PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
2168: } else {
2169: PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
2170: }
2171: } else {
2172: if (!value) {
2173: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Removing option: %s\n", name));
2174: } else if (!value[0]) {
2175: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
2176: } else {
2177: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
2178: }
2179: }
2180: PetscFunctionReturn(PETSC_SUCCESS);
2181: }
2183: /*@
2184: PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
2185: modified the PETSc options database.
2187: Not Collective
2189: Input Parameters:
2190: + monitor - pointer to function (if this is `NULL`, it turns off monitoring
2191: . mctx - [optional] context for private data for the monitor routine (use `NULL` if
2192: no context is desired)
2193: - monitordestroy - [optional] routine that frees monitor context (may be `NULL`), see `PetscCtxDestroyFn` for its calling sequence
2195: Calling sequence of `monitor`:
2196: + name - option name string
2197: . value - option value string, a value of `NULL` indicates the option is being removed from the database. A value
2198: of "" indicates the option is in the database but has no value.
2199: . source - option source
2200: - mctx - optional monitoring context, as set by `PetscOptionsMonitorSet()`
2202: Options Database Keys:
2203: + -options_monitor viewer - turn on default monitoring of changes to the options database
2204: - -options_monitor_cancel - turn off any option monitors except the default monitor obtained with `-options_monitor`
2206: Level: intermediate
2208: Notes:
2209: See `PetscInitialize()` for options related to option database monitoring.
2211: The default is to do no monitoring. To print the name and value of options
2212: being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
2213: with a `NULL` monitoring context. Or use the option `-options_monitor viewer`.
2215: Several different monitoring routines may be set by calling
2216: `PetscOptionsMonitorSet()` multiple times; all will be called in the
2217: order in which they were set.
2219: .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`, `PetscCtxDestroyFn`
2220: @*/
2221: PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource source, PetscCtx mctx), PetscCtx mctx, PetscCtxDestroyFn *monitordestroy)
2222: {
2223: PetscOptions options = defaultoptions;
2225: PetscFunctionBegin;
2226: if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
2227: PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
2228: options->monitor[options->numbermonitors] = monitor;
2229: options->monitordestroy[options->numbermonitors] = monitordestroy;
2230: options->monitorcontext[options->numbermonitors++] = mctx;
2231: PetscFunctionReturn(PETSC_SUCCESS);
2232: }
2234: /*
2235: Same as PetscOptionsStringToBool() but reports in isbool whether value is one of the recognized
2236: logical values instead of raising an error when it is not.
2237: */
2238: static PetscErrorCode PetscOptionsStringToBool_Private(const char value[], PetscBool *a, PetscBool *isbool)
2239: {
2240: PetscBool istrue, isfalse;
2241: size_t len;
2243: PetscFunctionBegin;
2244: *isbool = PETSC_TRUE;
2245: /* PetscStrlen() returns 0 for NULL or "" */
2246: PetscCall(PetscStrlen(value, &len));
2247: if (!len) {
2248: *a = PETSC_TRUE;
2249: PetscFunctionReturn(PETSC_SUCCESS);
2250: }
2251: PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
2252: if (istrue) {
2253: *a = PETSC_TRUE;
2254: PetscFunctionReturn(PETSC_SUCCESS);
2255: }
2256: PetscCall(PetscStrcasecmp(value, "YES", &istrue));
2257: if (istrue) {
2258: *a = PETSC_TRUE;
2259: PetscFunctionReturn(PETSC_SUCCESS);
2260: }
2261: PetscCall(PetscStrcasecmp(value, "1", &istrue));
2262: if (istrue) {
2263: *a = PETSC_TRUE;
2264: PetscFunctionReturn(PETSC_SUCCESS);
2265: }
2266: PetscCall(PetscStrcasecmp(value, "on", &istrue));
2267: if (istrue) {
2268: *a = PETSC_TRUE;
2269: PetscFunctionReturn(PETSC_SUCCESS);
2270: }
2271: PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
2272: if (isfalse) {
2273: *a = PETSC_FALSE;
2274: PetscFunctionReturn(PETSC_SUCCESS);
2275: }
2276: PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
2277: if (isfalse) {
2278: *a = PETSC_FALSE;
2279: PetscFunctionReturn(PETSC_SUCCESS);
2280: }
2281: PetscCall(PetscStrcasecmp(value, "0", &isfalse));
2282: if (isfalse) {
2283: *a = PETSC_FALSE;
2284: PetscFunctionReturn(PETSC_SUCCESS);
2285: }
2286: PetscCall(PetscStrcasecmp(value, "off", &isfalse));
2287: if (isfalse) {
2288: *a = PETSC_FALSE;
2289: PetscFunctionReturn(PETSC_SUCCESS);
2290: }
2291: *a = PETSC_FALSE;
2292: *isbool = PETSC_FALSE;
2293: PetscFunctionReturn(PETSC_SUCCESS);
2294: }
2296: /*@
2297: PetscOptionsStringToBool - Converts a string to a `PetscBool`
2299: Not Collective
2301: Input Parameter:
2302: . value - the string to convert; may be `NULL` or `""`
2304: Output Parameter:
2305: . a - the resulting `PetscBool`
2307: Level: developer
2309: Note:
2310: Recognizes (case-insensitive) `TRUE`, `YES`, `1`, `on` as `PETSC_TRUE` and `FALSE`, `NO`, `0`, `off` as `PETSC_FALSE`.
2311: An empty or `NULL` string is treated as `PETSC_TRUE`. Any other input generates an error.
2313: .seealso: `PetscOptionsStringToInt()`, `PetscOptionsStringToReal()`, `PetscOptionsStringToScalar()`, `PetscOptionsGetBool()`
2314: @*/
2315: PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2316: {
2317: PetscBool isbool;
2319: PetscFunctionBegin;
2320: PetscCall(PetscOptionsStringToBool_Private(value, a, &isbool));
2321: PetscCheck(isbool, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
2322: PetscFunctionReturn(PETSC_SUCCESS);
2323: }
2325: /*@
2326: PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
2328: Not Collective
2330: Input Parameter:
2331: . name - the string to convert
2333: Output Parameter:
2334: . a - the resulting `PetscInt` value
2336: Level: developer
2338: Note:
2339: Recognizes the special strings `PETSC_DEFAULT`, `DEFAULT`, `PETSC_DECIDE`, `DECIDE`, `PETSC_DETERMINE`, `DETERMINE`, `PETSC_UNLIMITED`,
2340: `UNLIMITED`, and `mouse` (which returns `-1`). Otherwise the value is parsed as a base-10 integer.
2342: .seealso: `PetscOptionsStringToReal()`, `PetscOptionsStringToScalar()`, `PetscOptionsStringToBool()`, `PetscOptionsGetInt()`
2343: @*/
2344: PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2345: {
2346: size_t len;
2347: PetscBool decide, tdefault, mouse, unlimited;
2349: PetscFunctionBegin;
2350: PetscCall(PetscStrlen(name, &len));
2351: PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
2353: PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
2354: if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
2355: PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
2356: if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
2357: if (!decide) PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &decide));
2358: if (!decide) PetscCall(PetscStrcasecmp(name, "DETERMINE", &decide));
2359: PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &unlimited));
2360: if (!unlimited) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &unlimited));
2361: PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
2363: if (tdefault) *a = PETSC_DEFAULT;
2364: else if (decide) *a = PETSC_DECIDE;
2365: else if (unlimited) *a = PETSC_UNLIMITED;
2366: else if (mouse) *a = -1;
2367: else {
2368: char *endptr;
2369: long strtolval;
2371: strtolval = strtol(name, &endptr, 10);
2372: 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);
2374: #if PetscDefined(USE_64BIT_INDICES) && PetscDefined(HAVE_ATOLL)
2375: (void)strtolval;
2376: *a = atoll(name);
2377: #elif PetscDefined(USE_64BIT_INDICES) && PetscDefined(HAVE___INT64)
2378: (void)strtolval;
2379: *a = _atoi64(name);
2380: #else
2381: *a = (PetscInt)strtolval;
2382: #endif
2383: }
2384: PetscFunctionReturn(PETSC_SUCCESS);
2385: }
2387: #if PetscDefined(USE_REAL___FLOAT128)
2388: #include <quadmath.h>
2389: #endif
2391: static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2392: {
2393: PetscFunctionBegin;
2394: #if PetscDefined(USE_REAL___FLOAT128)
2395: *a = strtoflt128(name, endptr);
2396: #else
2397: *a = (PetscReal)strtod(name, endptr);
2398: #endif
2399: PetscFunctionReturn(PETSC_SUCCESS);
2400: }
2402: static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2403: {
2404: PetscBool hasi = PETSC_FALSE;
2405: char *ptr;
2406: PetscReal strtoval;
2408: PetscFunctionBegin;
2409: PetscCall(PetscStrtod(name, &strtoval, &ptr));
2410: if (ptr == name) {
2411: strtoval = 1.;
2412: hasi = PETSC_TRUE;
2413: if (name[0] == 'i') {
2414: ptr++;
2415: } else if (name[0] == '+' && name[1] == 'i') {
2416: ptr += 2;
2417: } else if (name[0] == '-' && name[1] == 'i') {
2418: strtoval = -1.;
2419: ptr += 2;
2420: }
2421: } else if (*ptr == 'i') {
2422: hasi = PETSC_TRUE;
2423: ptr++;
2424: }
2425: *endptr = ptr;
2426: *isImaginary = hasi;
2427: if (hasi) {
2428: #if !PetscDefined(USE_COMPLEX)
2429: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
2430: #else
2431: *a = PetscCMPLX(0., strtoval);
2432: #endif
2433: } else {
2434: *a = strtoval;
2435: }
2436: PetscFunctionReturn(PETSC_SUCCESS);
2437: }
2439: /*@
2440: PetscOptionsStringToReal - Converts a string to a `PetscReal` value. Handles special cases like `default` and `decide`
2442: Not Collective
2444: Input Parameter:
2445: . name - the string to convert
2447: Output Parameter:
2448: . a - the resulting `PetscReal` value
2450: Level: developer
2452: Note:
2453: Recognizes the special strings `PETSC_DEFAULT`, `DEFAULT`, `PETSC_DECIDE`, `DECIDE`, `PETSC_DETERMINE`, `DETERMINE`,
2454: `PETSC_UNLIMITED`, and `UNLIMITED`. Otherwise the value is parsed as a floating-point number.
2456: .seealso: `PetscOptionsStringToInt()`, `PetscOptionsStringToScalar()`, `PetscOptionsStringToBool()`, `PetscOptionsGetReal()`
2457: @*/
2458: PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2459: {
2460: size_t len;
2461: PetscBool match;
2462: char *endptr;
2464: PetscFunctionBegin;
2465: PetscCall(PetscStrlen(name, &len));
2466: PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
2468: PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
2469: if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
2470: if (match) {
2471: *a = PETSC_DEFAULT;
2472: PetscFunctionReturn(PETSC_SUCCESS);
2473: }
2475: PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
2476: if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
2477: if (match) {
2478: *a = PETSC_DECIDE;
2479: PetscFunctionReturn(PETSC_SUCCESS);
2480: }
2482: PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &match));
2483: if (!match) PetscCall(PetscStrcasecmp(name, "DETERMINE", &match));
2484: if (match) {
2485: *a = PETSC_DETERMINE;
2486: PetscFunctionReturn(PETSC_SUCCESS);
2487: }
2489: PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &match));
2490: if (!match) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &match));
2491: if (match) {
2492: *a = PETSC_UNLIMITED;
2493: PetscFunctionReturn(PETSC_SUCCESS);
2494: }
2496: PetscCall(PetscStrtod(name, a, &endptr));
2497: PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
2498: PetscFunctionReturn(PETSC_SUCCESS);
2499: }
2501: /*@
2502: PetscOptionsStringToScalar - Converts a string to a `PetscScalar` value; when PETSc is built with complex scalars, parses an optional imaginary part
2504: Not Collective
2506: Input Parameter:
2507: . name - the string to convert
2509: Output Parameter:
2510: . a - the resulting `PetscScalar` value
2512: Level: developer
2514: Note:
2515: Accepts forms such as `1.5`, `-2`, `3+4i`, `i`, or `-i`. Using an imaginary component when PETSc is built without complex scalars is an error.
2517: .seealso: `PetscOptionsStringToInt()`, `PetscOptionsStringToReal()`, `PetscOptionsStringToBool()`, `PetscOptionsGetScalar()`
2518: @*/
2519: PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2520: {
2521: PetscBool imag1;
2522: size_t len;
2523: PetscScalar val = 0.;
2524: char *ptr = NULL;
2526: PetscFunctionBegin;
2527: PetscCall(PetscStrlen(name, &len));
2528: PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
2529: PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
2530: #if PetscDefined(USE_COMPLEX)
2531: if ((size_t)(ptr - name) < len) {
2532: PetscBool imag2;
2533: PetscScalar val2;
2535: PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
2536: if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
2537: val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
2538: }
2539: #endif
2540: PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
2541: *a = val;
2542: PetscFunctionReturn(PETSC_SUCCESS);
2543: }
2545: /*@
2546: PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
2547: option in the database.
2549: Not Collective
2551: Input Parameters:
2552: + options - options database, use `NULL` for default global database
2553: . pre - the string to prepend to the name or `NULL`
2554: - name - the option one is seeking
2556: Output Parameters:
2557: + ivalue - the logical value to return
2558: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2560: Level: beginner
2562: Notes:
2563: The option values TRUE, YES, ON (case-insensitive) and 1 all translate to `PETSC_TRUE`
2565: The option values FALSE, NO, OFF (case-insensitive) and 0 all translate to `PETSC_FALSE`
2567: 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`
2568: is equivalent to `-requested_bool true`
2570: If the user does not supply the option at all `ivalue` is NOT changed. Thus
2571: you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
2573: .seealso: `PetscOptionsGetBool3()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2574: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2575: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2576: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2577: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2578: `PetscOptionsFList()`, `PetscOptionsEList()`
2579: @*/
2580: PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2581: {
2582: const char *value;
2583: PetscBool flag;
2585: PetscFunctionBegin;
2586: PetscAssertPointer(name, 3);
2587: if (ivalue) PetscAssertPointer(ivalue, 4);
2588: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2589: if (flag) {
2590: if (set) *set = PETSC_TRUE;
2591: PetscCall(PetscOptionsStringToBool(value, &flag));
2592: if (ivalue) *ivalue = flag;
2593: } else {
2594: if (set) *set = PETSC_FALSE;
2595: }
2596: PetscFunctionReturn(PETSC_SUCCESS);
2597: }
2599: /*@
2600: PetscOptionsGetBool3 - Gets the ternary logical (true, false or unknown) value for a particular
2601: option in the database.
2603: Not Collective
2605: Input Parameters:
2606: + options - options database, use `NULL` for default global database
2607: . pre - the string to prepend to the name or `NULL`
2608: - name - the option one is seeking
2610: Output Parameters:
2611: + ivalue - the ternary logical value to return
2612: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2614: Level: beginner
2616: Notes:
2617: The option values TRUE, YES, ON (case-insensitive) and 1 all translate to `PETSC_BOOL3_TRUE`
2619: The option values FALSE, NO, OFF (case-insensitive) and 0 all translate to `PETSC_BOOL3_FALSE`
2621: The option values UNKNOWN and AUTO (case-insensitive) all translate to `PETSC_BOOL3_UNKNOWN`
2623: If the option is given, but no value is provided, then `ivalue` will be set to `PETSC_BOOL3_TRUE` and `set` will be set to `PETSC_TRUE`. That is `-requested_bool3`
2624: is equivalent to `-requested_bool3 true`
2626: If the user does not supply the option at all `ivalue` is NOT changed. Thus
2627: you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
2629: .seealso: `PetscOptionsGetBool()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2630: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2631: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2632: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2633: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2634: `PetscOptionsFList()`, `PetscOptionsEList()`
2635: @*/
2636: PetscErrorCode PetscOptionsGetBool3(PetscOptions options, const char pre[], const char name[], PetscBool3 *ivalue, PetscBool *set)
2637: {
2638: const char *value;
2639: PetscBool flag;
2641: PetscFunctionBegin;
2642: PetscAssertPointer(name, 3);
2643: if (ivalue) PetscAssertPointer(ivalue, 4);
2644: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2645: if (flag) { // found the option
2646: PetscBool isAUTO = PETSC_FALSE, isUNKNOWN = PETSC_FALSE;
2648: if (set) *set = PETSC_TRUE;
2649: PetscCall(PetscStrcasecmp("AUTO", value, &isAUTO)); // auto or AUTO
2650: if (!isAUTO) PetscCall(PetscStrcasecmp("UNKNOWN", value, &isUNKNOWN)); // unknown or UNKNOWN
2651: if (isAUTO || isUNKNOWN) {
2652: if (ivalue) *ivalue = PETSC_BOOL3_UNKNOWN;
2653: } else { // handle boolean values (if no value is given, it returns true)
2654: PetscCall(PetscOptionsStringToBool(value, &flag));
2655: if (ivalue) *ivalue = PetscBoolToBool3(flag);
2656: }
2657: } else {
2658: if (set) *set = PETSC_FALSE;
2659: }
2660: PetscFunctionReturn(PETSC_SUCCESS);
2661: }
2663: /*@
2664: PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2666: Not Collective
2668: Input Parameters:
2669: + options - options database, use `NULL` for default global database
2670: . pre - the string to prepend to the name or `NULL`
2671: . opt - option name
2672: . list - the possible choices (one of these must be selected, anything else is invalid)
2673: - ntext - number of choices
2675: Output Parameters:
2676: + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2677: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2679: Level: intermediate
2681: Notes:
2682: If the user does not supply the option `value` is NOT changed. Thus
2683: you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2685: See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2687: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2688: `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2689: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2690: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2691: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2692: `PetscOptionsFList()`, `PetscOptionsEList()`
2693: @*/
2694: PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const list[], PetscInt ntext, PetscInt *value, PetscBool *set)
2695: {
2696: size_t alen, len = 0, tlen = 0;
2697: char *svalue;
2698: PetscBool aset, flg = PETSC_FALSE;
2700: PetscFunctionBegin;
2701: PetscAssertPointer(opt, 3);
2702: for (PetscInt i = 0; i < ntext; i++) {
2703: PetscCall(PetscStrlen(list[i], &alen));
2704: if (alen > len) len = alen;
2705: tlen += len + 1;
2706: }
2707: len += 5; /* a little extra space for user mistypes */
2708: PetscCall(PetscMalloc1(len, &svalue));
2709: PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2710: if (aset) {
2711: PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
2712: if (!flg) {
2713: char *avail;
2715: PetscCall(PetscMalloc1(tlen, &avail));
2716: avail[0] = '\0';
2717: for (PetscInt i = 0; i < ntext; i++) {
2718: PetscCall(PetscStrlcat(avail, list[i], tlen));
2719: PetscCall(PetscStrlcat(avail, " ", tlen));
2720: }
2721: PetscCall(PetscStrtolower(avail));
2722: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option \"%s\" for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
2723: }
2724: if (set) *set = PETSC_TRUE;
2725: } else if (set) *set = PETSC_FALSE;
2726: PetscCall(PetscFree(svalue));
2727: PetscFunctionReturn(PETSC_SUCCESS);
2728: }
2730: /*@
2731: PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2733: Not Collective
2735: Input Parameters:
2736: + options - options database, use `NULL` for default global database
2737: . pre - option prefix or `NULL`
2738: . opt - option name
2739: - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2741: Output Parameters:
2742: + value - the value to return
2743: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2745: Level: beginner
2747: Notes:
2748: If the user does not supply the option `value` is NOT changed. Thus
2749: you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2751: `list` is usually something like `PCASMTypes` or some other predefined list of enum names
2753: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2754: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2755: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2756: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2757: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2758: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2759: `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2760: @*/
2761: PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const list[], PetscEnum *value, PetscBool *set) PeNSS
2762: {
2763: PetscInt ntext = 0, tval;
2764: PetscBool fset;
2766: PetscFunctionBegin;
2767: PetscAssertPointer(opt, 3);
2768: while (list[ntext++]) PetscCheck(ntext <= 50, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument appears to be wrong or have more than 50 entries");
2769: PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2770: ntext -= 3;
2771: PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
2772: /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2773: if (fset) *value = (PetscEnum)tval;
2774: if (set) *set = fset;
2775: PetscFunctionReturn(PETSC_SUCCESS);
2776: }
2778: /*@
2779: PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2781: Not Collective
2783: Input Parameters:
2784: + options - options database, use `NULL` for default global database
2785: . pre - the string to prepend to the name or `NULL`
2786: - name - the option one is seeking
2788: Output Parameters:
2789: + ivalue - the integer value to return
2790: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2792: Level: beginner
2794: Notes:
2795: If the user does not supply the option `ivalue` is NOT changed. Thus
2796: you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
2798: Accepts the special values `determine`, `decide` and `unlimited`.
2800: Accepts the deprecated value `default`.
2802: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2803: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2804: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2805: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2806: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2807: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2808: `PetscOptionsFList()`, `PetscOptionsEList()`
2809: @*/
2810: PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2811: {
2812: const char *value;
2813: PetscBool flag;
2815: PetscFunctionBegin;
2816: PetscAssertPointer(name, 3);
2817: PetscAssertPointer(ivalue, 4);
2818: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2819: if (flag) {
2820: if (!value) {
2821: if (set) *set = PETSC_FALSE;
2822: } else {
2823: if (set) *set = PETSC_TRUE;
2824: PetscCall(PetscOptionsStringToInt(value, ivalue));
2825: }
2826: } else {
2827: if (set) *set = PETSC_FALSE;
2828: }
2829: PetscFunctionReturn(PETSC_SUCCESS);
2830: }
2832: /*@
2833: PetscOptionsGetMPIInt - Gets the MPI integer value for a particular option in the database.
2835: Not Collective
2837: Input Parameters:
2838: + options - options database, use `NULL` for default global database
2839: . pre - the string to prepend to the name or `NULL`
2840: - name - the option one is seeking
2842: Output Parameters:
2843: + ivalue - the MPI integer value to return
2844: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2846: Level: beginner
2848: Notes:
2849: If the user does not supply the option `ivalue` is NOT changed. Thus
2850: you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
2852: Accepts the special values `determine`, `decide` and `unlimited`.
2854: Accepts the deprecated value `default`.
2856: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2857: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2858: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2859: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2860: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2861: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2862: `PetscOptionsFList()`, `PetscOptionsEList()`
2863: @*/
2864: PetscErrorCode PetscOptionsGetMPIInt(PetscOptions options, const char pre[], const char name[], PetscMPIInt *ivalue, PetscBool *set)
2865: {
2866: PetscInt value;
2867: PetscBool flag;
2869: PetscFunctionBegin;
2870: PetscCall(PetscOptionsGetInt(options, pre, name, &value, &flag));
2871: if (flag) PetscCall(PetscMPIIntCast(value, ivalue));
2872: if (set) *set = flag;
2873: PetscFunctionReturn(PETSC_SUCCESS);
2874: }
2876: /*@
2877: PetscOptionsGetReal - Gets the double precision value for a particular
2878: option in the database.
2880: Not Collective
2882: Input Parameters:
2883: + options - options database, use `NULL` for default global database
2884: . pre - string to prepend to each name or `NULL`
2885: - name - the option one is seeking
2887: Output Parameters:
2888: + dvalue - the double value to return
2889: - set - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2891: Level: beginner
2893: Notes:
2894: Accepts the special values `determine`, `decide` and `unlimited`.
2896: Accepts the deprecated value `default`
2898: If the user does not supply the option `dvalue` is NOT changed. Thus
2899: you should ALWAYS initialize `dvalue` if you access it without first checking that the `set` flag is true.
2901: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2902: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2903: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2904: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2905: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2906: `PetscOptionsFList()`, `PetscOptionsEList()`
2907: @*/
2908: PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2909: {
2910: const char *value;
2911: PetscBool flag;
2913: PetscFunctionBegin;
2914: PetscAssertPointer(name, 3);
2915: PetscAssertPointer(dvalue, 4);
2916: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2917: if (flag) {
2918: if (!value) {
2919: if (set) *set = PETSC_FALSE;
2920: } else {
2921: if (set) *set = PETSC_TRUE;
2922: PetscCall(PetscOptionsStringToReal(value, dvalue));
2923: }
2924: } else {
2925: if (set) *set = PETSC_FALSE;
2926: }
2927: PetscFunctionReturn(PETSC_SUCCESS);
2928: }
2930: /*@
2931: PetscOptionsGetScalar - Gets the scalar value for a particular
2932: option in the database.
2934: Not Collective
2936: Input Parameters:
2937: + options - options database, use `NULL` for default global database
2938: . pre - string to prepend to each name or `NULL`
2939: - name - the option one is seeking
2941: Output Parameters:
2942: + dvalue - the scalar value to return
2943: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2945: Level: beginner
2947: Example Usage:
2948: A complex number 2+3i must be specified with NO spaces
2950: Note:
2951: If the user does not supply the option `dvalue` is NOT changed. Thus
2952: you should ALWAYS initialize `dvalue` if you access it without first checking if the `set` flag is true.
2954: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2955: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2956: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2957: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2958: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2959: `PetscOptionsFList()`, `PetscOptionsEList()`
2960: @*/
2961: PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2962: {
2963: const char *value;
2964: PetscBool flag;
2966: PetscFunctionBegin;
2967: PetscAssertPointer(name, 3);
2968: PetscAssertPointer(dvalue, 4);
2969: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2970: if (flag) {
2971: if (!value) {
2972: if (set) *set = PETSC_FALSE;
2973: } else {
2974: #if !PetscDefined(USE_COMPLEX)
2975: PetscCall(PetscOptionsStringToReal(value, dvalue));
2976: #else
2977: PetscCall(PetscOptionsStringToScalar(value, dvalue));
2978: #endif
2979: if (set) *set = PETSC_TRUE;
2980: }
2981: } else { /* flag */
2982: if (set) *set = PETSC_FALSE;
2983: }
2984: PetscFunctionReturn(PETSC_SUCCESS);
2985: }
2987: /*@
2988: PetscOptionsGetString - Gets the string value for a particular option in
2989: the database.
2991: Not Collective
2993: Input Parameters:
2994: + options - options database, use `NULL` for default global database
2995: . pre - string to prepend to name or `NULL`
2996: . name - the option one is seeking
2997: - len - maximum length of the string including null termination
2999: Output Parameters:
3000: + string - location to copy string
3001: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3003: Level: beginner
3005: Note:
3006: 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`
3008: If the user does not use the option then `string` is not changed. Thus
3009: you should ALWAYS initialize `string` if you access it without first checking that the `set` flag is true.
3011: Fortran Notes:
3012: The Fortran interface is slightly different from the C/C++
3013: interface. Sample usage in Fortran follows
3014: .vb
3015: character *20 string
3016: PetscErrorCode ierr
3017: PetscBool set
3018: call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
3019: .ve
3021: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3022: `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3023: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3024: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3025: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3026: `PetscOptionsFList()`, `PetscOptionsEList()`
3027: @*/
3028: PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set) PeNS
3029: {
3030: const char *value;
3031: PetscBool flag;
3033: PetscFunctionBegin;
3034: PetscAssertPointer(name, 3);
3035: PetscAssertPointer(string, 4);
3036: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
3037: if (!flag) {
3038: if (set) *set = PETSC_FALSE;
3039: } else {
3040: if (set) *set = PETSC_TRUE;
3041: if (value) PetscCall(PetscStrncpy(string, value, len));
3042: else PetscCall(PetscArrayzero(string, len));
3043: }
3044: PetscFunctionReturn(PETSC_SUCCESS);
3045: }
3047: /*@
3048: PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
3049: option in the database. The values must be separated with commas with no intervening spaces.
3051: Not Collective
3053: Input Parameters:
3054: + options - options database, use `NULL` for default global database
3055: . pre - string to prepend to each name or `NULL`
3056: - name - the option one is seeking
3058: Output Parameters:
3059: + dvalue - the Boolean values to return
3060: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3061: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3063: Level: beginner
3065: Notes:
3066: The option values TRUE, YES, ON (case-insensitive) and 1 all translate to `PETSC_TRUE`
3068: The option values FALSE, NO, OFF (case-insensitive) and 0 all translate to `PETSC_FALSE`
3070: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3071: `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3072: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3073: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3074: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3075: `PetscOptionsFList()`, `PetscOptionsEList()`
3076: @*/
3077: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
3078: {
3079: const char *svalue;
3080: const char *value;
3081: PetscInt n = 0;
3082: PetscBool flag;
3083: PetscToken token;
3085: PetscFunctionBegin;
3086: PetscAssertPointer(name, 3);
3087: PetscAssertPointer(nmax, 5);
3088: if (*nmax) PetscAssertPointer(dvalue, 4);
3090: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3091: if (!flag || !svalue) {
3092: if (set) *set = PETSC_FALSE;
3093: *nmax = 0;
3094: PetscFunctionReturn(PETSC_SUCCESS);
3095: }
3096: if (set) *set = PETSC_TRUE;
3097: PetscCall(PetscTokenCreate(svalue, ',', &token));
3098: PetscCall(PetscTokenFind(token, &value));
3099: while (value && n < *nmax) {
3100: PetscCall(PetscOptionsStringToBool(value, dvalue));
3101: PetscCall(PetscTokenFind(token, &value));
3102: dvalue++;
3103: n++;
3104: }
3105: PetscCall(PetscTokenDestroy(&token));
3106: *nmax = n;
3107: PetscFunctionReturn(PETSC_SUCCESS);
3108: }
3110: /*@
3111: PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
3113: Not Collective
3115: Input Parameters:
3116: + options - options database, use `NULL` for default global database
3117: . pre - option prefix or `NULL`
3118: . name - option name
3119: - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
3121: Output Parameters:
3122: + ivalue - the enum values to return
3123: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3124: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3126: Level: beginner
3128: Notes:
3129: The array must be passed as a comma separated list with no spaces between the items.
3131: `list` is usually something like `PCASMTypes` or some other predefined list of enum names.
3133: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
3134: `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3135: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsName()`,
3136: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
3137: `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3138: `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
3139: @*/
3140: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const list[], PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
3141: {
3142: const char *svalue;
3143: const char *value;
3144: PetscInt n = 0;
3145: PetscEnum evalue;
3146: PetscBool flag;
3147: PetscToken token;
3149: PetscFunctionBegin;
3150: PetscAssertPointer(name, 3);
3151: PetscAssertPointer(list, 4);
3152: PetscAssertPointer(nmax, 6);
3153: if (*nmax) PetscAssertPointer(ivalue, 5);
3155: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3156: if (!flag || !svalue) {
3157: if (set) *set = PETSC_FALSE;
3158: *nmax = 0;
3159: PetscFunctionReturn(PETSC_SUCCESS);
3160: }
3161: if (set) *set = PETSC_TRUE;
3162: PetscCall(PetscTokenCreate(svalue, ',', &token));
3163: PetscCall(PetscTokenFind(token, &value));
3164: while (value && n < *nmax) {
3165: PetscCall(PetscEnumFind(list, value, &evalue, &flag));
3166: PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
3167: ivalue[n++] = evalue;
3168: PetscCall(PetscTokenFind(token, &value));
3169: }
3170: PetscCall(PetscTokenDestroy(&token));
3171: *nmax = n;
3172: PetscFunctionReturn(PETSC_SUCCESS);
3173: }
3175: /*@
3176: PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
3178: Not Collective
3180: Input Parameters:
3181: + options - options database, use `NULL` for default global database
3182: . pre - string to prepend to each name or `NULL`
3183: - name - the option one is seeking
3185: Output Parameters:
3186: + ivalue - the integer values to return
3187: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3188: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3190: Level: beginner
3192: Notes:
3193: The array can be passed as
3194: + a comma separated list - 0,1,2,3,4,5,6,7
3195: . a range (start\-end+1) - 0-8
3196: . a range with given increment (start\-end+1:inc) - 0-7:2
3197: - a combination of values and ranges separated by commas - 0,1-8,8-15:2
3199: There must be no intervening spaces between the values.
3201: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3202: `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3203: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3204: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3205: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3206: `PetscOptionsFList()`, `PetscOptionsEList()`
3207: @*/
3208: PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
3209: {
3210: const char *svalue;
3211: const char *value;
3212: PetscInt n = 0, i, j, start, end, inc, nvalues;
3213: size_t len;
3214: PetscBool flag, foundrange;
3215: PetscToken token;
3217: PetscFunctionBegin;
3218: PetscAssertPointer(name, 3);
3219: PetscAssertPointer(nmax, 5);
3220: if (*nmax) PetscAssertPointer(ivalue, 4);
3222: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3223: if (!flag || !svalue) {
3224: if (set) *set = PETSC_FALSE;
3225: *nmax = 0;
3226: PetscFunctionReturn(PETSC_SUCCESS);
3227: }
3228: if (set) *set = PETSC_TRUE;
3229: PetscCall(PetscTokenCreate(svalue, ',', &token));
3230: PetscCall(PetscTokenFind(token, &value));
3231: while (value && n < *nmax) {
3232: char *iivalue;
3234: /* look for form d-D where d and D are integers */
3235: PetscCall(PetscStrallocpy(value, &iivalue));
3236: foundrange = PETSC_FALSE;
3237: PetscCall(PetscStrlen(iivalue, &len));
3238: if (iivalue[0] == '-') i = 2;
3239: else i = 1;
3240: for (; i < (int)len; i++) {
3241: if (iivalue[i] == '-') {
3242: PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, iivalue);
3243: iivalue[i] = 0;
3245: PetscCall(PetscOptionsStringToInt(iivalue, &start));
3246: inc = 1;
3247: j = i + 1;
3248: for (; j < (int)len; j++) {
3249: if (iivalue[j] == ':') {
3250: iivalue[j] = 0;
3252: PetscCall(PetscOptionsStringToInt(iivalue + j + 1, &inc));
3253: PetscCheck(inc > 0, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry,%s cannot have negative increment", n, iivalue + j + 1);
3254: break;
3255: }
3256: }
3257: PetscCall(PetscOptionsStringToInt(iivalue + i + 1, &end));
3258: PetscCheck(end > start, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, %s-%s cannot have decreasing list", n, iivalue, iivalue + i + 1);
3259: nvalues = (end - start) / inc + (end - start) % inc;
3260: 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);
3261: for (; start < end; start += inc) {
3262: *ivalue = start;
3263: ivalue++;
3264: n++;
3265: }
3266: foundrange = PETSC_TRUE;
3267: break;
3268: }
3269: }
3270: if (!foundrange) {
3271: PetscCall(PetscOptionsStringToInt(value, ivalue));
3272: ivalue++;
3273: n++;
3274: }
3275: PetscCall(PetscFree(iivalue));
3276: PetscCall(PetscTokenFind(token, &value));
3277: }
3278: PetscCall(PetscTokenDestroy(&token));
3279: *nmax = n;
3280: PetscFunctionReturn(PETSC_SUCCESS);
3281: }
3283: /*@
3284: PetscOptionsGetRealArray - Gets an array of double precision values for a
3285: particular option in the database. The values must be separated with commas with no intervening spaces.
3287: Not Collective
3289: Input Parameters:
3290: + options - options database, use `NULL` for default global database
3291: . pre - string to prepend to each name or `NULL`
3292: - name - the option one is seeking
3294: Output Parameters:
3295: + dvalue - the double values to return
3296: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3297: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3299: Level: beginner
3301: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3302: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3303: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3304: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3305: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3306: `PetscOptionsFList()`, `PetscOptionsEList()`
3307: @*/
3308: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
3309: {
3310: const char *svalue;
3311: const char *value;
3312: PetscInt n = 0;
3313: PetscBool flag;
3314: PetscToken token;
3316: PetscFunctionBegin;
3317: PetscAssertPointer(name, 3);
3318: PetscAssertPointer(nmax, 5);
3319: if (*nmax) PetscAssertPointer(dvalue, 4);
3321: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3322: if (!flag || !svalue) {
3323: if (set) *set = PETSC_FALSE;
3324: *nmax = 0;
3325: PetscFunctionReturn(PETSC_SUCCESS);
3326: }
3327: if (set) *set = PETSC_TRUE;
3328: PetscCall(PetscTokenCreate(svalue, ',', &token));
3329: PetscCall(PetscTokenFind(token, &value));
3330: while (value && n < *nmax) {
3331: PetscCall(PetscOptionsStringToReal(value, dvalue++));
3332: PetscCall(PetscTokenFind(token, &value));
3333: n++;
3334: }
3335: PetscCall(PetscTokenDestroy(&token));
3336: *nmax = n;
3337: PetscFunctionReturn(PETSC_SUCCESS);
3338: }
3340: /*@
3341: PetscOptionsGetScalarArray - Gets an array of scalars for a
3342: particular option in the database. The values must be separated with commas with no intervening spaces.
3344: Not Collective
3346: Input Parameters:
3347: + options - options database, use `NULL` for default global database
3348: . pre - string to prepend to each name or `NULL`
3349: - name - the option one is seeking
3351: Output Parameters:
3352: + dvalue - the scalar values to return
3353: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3354: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3356: Level: beginner
3358: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3359: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3360: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3361: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3362: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3363: `PetscOptionsFList()`, `PetscOptionsEList()`
3364: @*/
3365: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3366: {
3367: const char *svalue;
3368: const char *value;
3369: PetscInt n = 0;
3370: PetscBool flag;
3371: PetscToken token;
3373: PetscFunctionBegin;
3374: PetscAssertPointer(name, 3);
3375: PetscAssertPointer(nmax, 5);
3376: if (*nmax) PetscAssertPointer(dvalue, 4);
3378: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3379: if (!flag || !svalue) {
3380: if (set) *set = PETSC_FALSE;
3381: *nmax = 0;
3382: PetscFunctionReturn(PETSC_SUCCESS);
3383: }
3384: if (set) *set = PETSC_TRUE;
3385: PetscCall(PetscTokenCreate(svalue, ',', &token));
3386: PetscCall(PetscTokenFind(token, &value));
3387: while (value && n < *nmax) {
3388: PetscCall(PetscOptionsStringToScalar(value, dvalue++));
3389: PetscCall(PetscTokenFind(token, &value));
3390: n++;
3391: }
3392: PetscCall(PetscTokenDestroy(&token));
3393: *nmax = n;
3394: PetscFunctionReturn(PETSC_SUCCESS);
3395: }
3397: /*@
3398: PetscOptionsGetStringArray - Gets an array of string values for a particular
3399: option in the database. The values must be separated with commas with no intervening spaces.
3401: Not Collective; No Fortran Support
3403: Input Parameters:
3404: + options - options database, use `NULL` for default global database
3405: . pre - string to prepend to name or `NULL`
3406: - name - the option one is seeking
3408: Output Parameters:
3409: + strings - location to copy strings
3410: . nmax - On input maximum number of strings, on output the actual number of strings found
3411: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3413: Level: beginner
3415: Notes:
3416: The `nmax` parameter is used for both input and output.
3418: The user should pass in an array of pointers to `char`, to hold all the
3419: strings returned by this function.
3421: The user is responsible for deallocating the strings that are
3422: returned.
3424: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3425: `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3426: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3427: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3428: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3429: `PetscOptionsFList()`, `PetscOptionsEList()`
3430: @*/
3431: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set) PeNS
3432: {
3433: const char *svalue;
3434: const char *value;
3435: PetscInt n = 0;
3436: PetscBool flag;
3437: PetscToken token;
3439: PetscFunctionBegin;
3440: PetscAssertPointer(name, 3);
3441: PetscAssertPointer(nmax, 5);
3442: if (*nmax) PetscAssertPointer(strings, 4);
3444: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3445: if (!flag || !svalue) {
3446: if (set) *set = PETSC_FALSE;
3447: *nmax = 0;
3448: PetscFunctionReturn(PETSC_SUCCESS);
3449: }
3450: if (set) *set = PETSC_TRUE;
3451: PetscCall(PetscTokenCreate(svalue, ',', &token));
3452: PetscCall(PetscTokenFind(token, &value));
3453: while (value && n < *nmax) {
3454: PetscCall(PetscStrallocpy(value, &strings[n]));
3455: PetscCall(PetscTokenFind(token, &value));
3456: n++;
3457: }
3458: PetscCall(PetscTokenDestroy(&token));
3459: *nmax = n;
3460: PetscFunctionReturn(PETSC_SUCCESS);
3461: }
3463: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems PetscOptionsObject, MPI_Comm incomm, const char inprefix[], const char oldname[], const char newname[], const char version[], const char info[])
3464: {
3465: PetscBool found, quiet;
3466: const char *value;
3467: const char *const quietopt = "-options_suppress_deprecated_warnings";
3468: char msg[4096];
3469: const char *prefix = NULL;
3470: PetscOptions options = NULL;
3471: MPI_Comm comm = PETSC_COMM_SELF;
3473: PetscFunctionBegin;
3474: PetscAssertPointer(oldname, 4);
3475: PetscAssertPointer(version, 6);
3476: if (PetscOptionsObject) {
3477: prefix = PetscOptionsObject->prefix;
3478: options = PetscOptionsObject->options;
3479: comm = PetscOptionsObject->comm;
3480: } else {
3481: prefix = inprefix;
3482: comm = incomm;
3483: }
3485: PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
3486: if (found) {
3487: if (newname) {
3488: PetscBool newfound;
3490: /* do not overwrite if the new option has been provided */
3491: PetscCall(PetscOptionsFindPair(options, prefix, newname, NULL, &newfound));
3492: if (!newfound) {
3493: if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
3494: PetscCall(PetscOptionsSetValue(options, newname, value));
3495: if (prefix) PetscCall(PetscOptionsPrefixPop(options));
3496: }
3497: if (prefix) {
3498: char key[PETSC_MAX_OPTION_NAME];
3500: PetscCall(PetscSNPrintf(key, sizeof(key), "-%s%s", prefix, oldname + 1));
3501: PetscCall(PetscOptionsClearValue(options, key));
3502: } else PetscCall(PetscOptionsClearValue(options, oldname));
3503: }
3504: quiet = PETSC_FALSE;
3505: PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
3506: if (!quiet) {
3507: PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option -", sizeof(msg)));
3508: PetscCall(PetscStrlcat(msg, prefix, sizeof(msg)));
3509: PetscCall(PetscStrlcat(msg, oldname + 1, sizeof(msg)));
3510: PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3511: PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
3512: PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
3513: if (newname) {
3514: PetscCall(PetscStrlcat(msg, " Use the option -", sizeof(msg)));
3515: PetscCall(PetscStrlcat(msg, prefix, sizeof(msg)));
3516: PetscCall(PetscStrlcat(msg, newname + 1, sizeof(msg)));
3517: PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
3518: }
3519: if (info) {
3520: PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3521: PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
3522: }
3523: PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3524: PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3525: PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
3526: PetscCall(PetscPrintf(comm, "%s", msg));
3527: }
3528: }
3529: PetscFunctionReturn(PETSC_SUCCESS);
3530: }