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 */
96: /* Monitors */
97: PetscBool monitorFromOptions, monitorCancel;
98: PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], PetscOptionSource, void *); /* returns control to user after */
99: PetscCtxDestroyFn *monitordestroy[MAXOPTIONSMONITORS]; /* callback for monitor destruction */
100: void *monitorcontext[MAXOPTIONSMONITORS]; /* to pass arbitrary user data into monitor */
101: PetscInt numbermonitors; /* to, for instance, detect options being set */
102: };
104: static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
106: /* list of options which precede others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
107: /* these options can only take boolean values, the code will crash if given a non-boolean value */
108: static const char *precedentOptions[] = {"-petsc_ci", "-options_monitor", "-options_monitor_cancel", "-help", "-skip_petscrc"};
109: enum PetscPrecedentOption {
110: PO_CI_ENABLE,
111: PO_OPTIONS_MONITOR,
112: PO_OPTIONS_MONITOR_CANCEL,
113: PO_HELP,
114: PO_SKIP_PETSCRC,
115: PO_NUM
116: };
118: PETSC_INTERN PetscErrorCode PetscOptionsSetValue_Private(PetscOptions, const char[], const char[], int *, PetscOptionSource);
119: PETSC_INTERN PetscErrorCode PetscOptionsInsertStringYAML_Private(PetscOptions, const char[], PetscOptionSource);
121: /*
122: Options events monitor
123: */
124: static PetscErrorCode PetscOptionsMonitor(PetscOptions options, const char name[], const char value[], PetscOptionSource source)
125: {
126: PetscFunctionBegin;
127: if (options->monitorFromOptions) PetscCall(PetscOptionsMonitorDefault(name, value, source, NULL));
128: for (PetscInt i = 0; i < options->numbermonitors; i++) PetscCall((*options->monitor[i])(name, value, source, options->monitorcontext[i]));
129: PetscFunctionReturn(PETSC_SUCCESS);
130: }
132: /*@
133: PetscOptionsCreate - Creates an empty options database.
135: Logically Collective
137: Output Parameter:
138: . options - Options database object
140: Level: advanced
142: Note:
143: Though PETSc has a concept of multiple options database the current code uses a single default `PetscOptions` object
145: Developer Notes:
146: We may want eventually to pass a `MPI_Comm` to determine the ownership of the object
148: This object never got developed after being introduced, it is not clear that supporting multiple `PetscOptions` objects is useful
150: .seealso: `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`
151: @*/
152: PetscErrorCode PetscOptionsCreate(PetscOptions *options)
153: {
154: PetscFunctionBegin;
155: PetscAssertPointer(options, 1);
156: *options = (PetscOptions)calloc(1, sizeof(**options));
157: PetscCheck(*options, PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate the options database");
158: PetscFunctionReturn(PETSC_SUCCESS);
159: }
161: /*@
162: PetscOptionsDestroy - Destroys an option database.
164: Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
166: Input Parameter:
167: . options - the `PetscOptions` object
169: Level: advanced
171: .seealso: `PetscOptionsInsert()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsSetValue()`
172: @*/
173: PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
174: {
175: PetscFunctionBegin;
176: PetscAssertPointer(options, 1);
177: if (!*options) PetscFunctionReturn(PETSC_SUCCESS);
178: 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()");
179: PetscCall(PetscOptionsClear(*options));
180: /* XXX what about monitors ? */
181: free(*options);
182: *options = NULL;
183: PetscFunctionReturn(PETSC_SUCCESS);
184: }
186: /*@
187: PetscOptionsCreateDefault - Creates the default global options database if it does not already exist
189: Logically collective
191: Level: developer
193: Note:
194: This is called during `PetscInitialize()`; user code normally does not need to call it directly.
196: .seealso: `PetscOptionsDestroyDefault()`, `PetscOptionsCreate()`, `PetscOptionsPush()`, `PetscOptionsPop()`
197: @*/
198: PetscErrorCode PetscOptionsCreateDefault(void)
199: {
200: PetscFunctionBegin;
201: if (PetscUnlikely(!defaultoptions)) PetscCall(PetscOptionsCreate(&defaultoptions));
202: PetscFunctionReturn(PETSC_SUCCESS);
203: }
205: /*@
206: PetscOptionsPush - Push a new `PetscOptions` object as the default provider of options
207: Allows using different parts of a code to use different options databases
209: Logically Collective
211: Input Parameter:
212: . opt - the options obtained with `PetscOptionsCreate()`
214: Level: advanced
216: Notes:
217: Use `PetscOptionsPop()` to return to the previous default options database
219: The collectivity of this routine is complex; only the MPI ranks that call this routine will
220: have the affect of these options. If some processes that create objects call this routine and others do
221: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
222: on different ranks.
224: Developer Notes:
225: Though this functionality has been provided it has never been used in PETSc and might be removed.
227: .seealso: `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
228: @*/
229: PetscErrorCode PetscOptionsPush(PetscOptions opt)
230: {
231: PetscFunctionBegin;
232: PetscCall(PetscOptionsCreateDefault());
233: opt->previous = defaultoptions;
234: defaultoptions = opt;
235: PetscFunctionReturn(PETSC_SUCCESS);
236: }
238: /*@
239: PetscOptionsPop - Pop the most recent `PetscOptionsPush()` to return to the previous default options
241: Logically Collective on whatever communicator was associated with the call to `PetscOptionsCreate()`
243: Level: advanced
245: .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`, `PetscOptionsSetValue()`, `PetscOptionsLeft()`
246: @*/
247: PetscErrorCode PetscOptionsPop(void)
248: {
249: PetscOptions current = defaultoptions;
251: PetscFunctionBegin;
252: PetscCheck(defaultoptions, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing default options");
253: PetscCheck(defaultoptions->previous, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscOptionsPop() called too many times");
254: defaultoptions = defaultoptions->previous;
255: current->previous = NULL;
256: PetscFunctionReturn(PETSC_SUCCESS);
257: }
259: /*@
260: PetscOptionsDestroyDefault - Destroys the default global options database
262: Logically collective
264: Level: developer
266: Note:
267: This is called during `PetscFinalize()`; any options databases the user pushed but did not pop are also destroyed.
269: .seealso: `PetscOptionsCreateDefault()`, `PetscOptionsDestroy()`, `PetscOptionsPush()`, `PetscOptionsPop()`
270: @*/
271: PetscErrorCode PetscOptionsDestroyDefault(void)
272: {
273: PetscFunctionBegin;
274: if (!defaultoptions) PetscFunctionReturn(PETSC_SUCCESS);
275: /* Destroy any options that the user forgot to pop */
276: while (defaultoptions->previous) {
277: PetscOptions tmp = defaultoptions;
279: PetscCall(PetscOptionsPop());
280: PetscCall(PetscOptionsDestroy(&tmp));
281: }
282: PetscCall(PetscOptionsDestroy(&defaultoptions));
283: PetscFunctionReturn(PETSC_SUCCESS);
284: }
286: /*@
287: PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
289: Not Collective
291: Input Parameter:
292: . key - string to check if valid
294: Output Parameter:
295: . valid - `PETSC_TRUE` if a valid key
297: Level: intermediate
299: .seealso: `PetscOptionsCreate()`, `PetscOptionsInsert()`
300: @*/
301: PetscErrorCode PetscOptionsValidKey(const char key[], PetscBool *valid)
302: {
303: char *ptr;
304: PETSC_UNUSED double d;
306: PetscFunctionBegin;
307: if (key) PetscAssertPointer(key, 1);
308: PetscAssertPointer(valid, 2);
309: *valid = PETSC_FALSE;
310: if (!key) PetscFunctionReturn(PETSC_SUCCESS);
311: if (key[0] != '-') PetscFunctionReturn(PETSC_SUCCESS);
312: if (key[1] == '-') key++;
313: if (!isalpha((int)key[1])) PetscFunctionReturn(PETSC_SUCCESS);
314: d = strtod(key, &ptr);
315: if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(PETSC_SUCCESS);
316: *valid = PETSC_TRUE;
317: PetscFunctionReturn(PETSC_SUCCESS);
318: }
320: static PetscErrorCode PetscOptionsInsertString_Private(PetscOptions options, const char in_str[], PetscOptionSource source)
321: {
322: const char *first, *second;
323: PetscToken token;
325: PetscFunctionBegin;
326: PetscCall(PetscTokenCreate(in_str, ' ', &token));
327: PetscCall(PetscTokenFind(token, &first));
328: while (first) {
329: PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
331: PetscCall(PetscStrcasecmp(first, "-options_file", &isfile));
332: PetscCall(PetscStrcasecmp(first, "-options_file_yaml", &isfileyaml));
333: PetscCall(PetscStrcasecmp(first, "-options_string_yaml", &isstringyaml));
334: PetscCall(PetscStrcasecmp(first, "-prefix_push", &ispush));
335: PetscCall(PetscStrcasecmp(first, "-prefix_pop", &ispop));
336: PetscCall(PetscOptionsValidKey(first, &key));
337: if (!key) {
338: PetscCall(PetscTokenFind(token, &first));
339: } else if (isfile) {
340: PetscCall(PetscTokenFind(token, &second));
341: PetscCall(PetscOptionsInsertFile(PETSC_COMM_SELF, options, second, PETSC_TRUE));
342: PetscCall(PetscTokenFind(token, &first));
343: } else if (isfileyaml) {
344: PetscCall(PetscTokenFind(token, &second));
345: PetscCall(PetscOptionsInsertFileYAML(PETSC_COMM_SELF, options, second, PETSC_TRUE));
346: PetscCall(PetscTokenFind(token, &first));
347: } else if (isstringyaml) {
348: PetscCall(PetscTokenFind(token, &second));
349: PetscCall(PetscOptionsInsertStringYAML_Private(options, second, source));
350: PetscCall(PetscTokenFind(token, &first));
351: } else if (ispush) {
352: PetscCall(PetscTokenFind(token, &second));
353: PetscCall(PetscOptionsPrefixPush(options, second));
354: PetscCall(PetscTokenFind(token, &first));
355: } else if (ispop) {
356: PetscCall(PetscOptionsPrefixPop(options));
357: PetscCall(PetscTokenFind(token, &first));
358: } else {
359: PetscCall(PetscTokenFind(token, &second));
360: PetscCall(PetscOptionsValidKey(second, &key));
361: if (!key) {
362: PetscCall(PetscOptionsSetValue_Private(options, first, second, NULL, source));
363: PetscCall(PetscTokenFind(token, &first));
364: } else {
365: PetscCall(PetscOptionsSetValue_Private(options, first, NULL, NULL, source));
366: first = second;
367: }
368: }
369: }
370: PetscCall(PetscTokenDestroy(&token));
371: PetscFunctionReturn(PETSC_SUCCESS);
372: }
374: /*@
375: PetscOptionsInsertString - Inserts options into the database from a string
377: Logically Collective
379: Input Parameters:
380: + options - options object
381: - in_str - string that contains options separated by blanks
383: Level: intermediate
385: The collectivity of this routine is complex; only the MPI processes that call this routine will
386: have the affect of these options. If some processes that create objects call this routine and others do
387: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
388: on different ranks.
390: Contributed by Boyana Norris
392: .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
393: `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
394: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
395: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
396: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
397: `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`
398: @*/
399: PetscErrorCode PetscOptionsInsertString(PetscOptions options, const char in_str[])
400: {
401: PetscFunctionBegin;
402: PetscCall(PetscOptionsInsertString_Private(options, in_str, PETSC_OPT_CODE));
403: PetscFunctionReturn(PETSC_SUCCESS);
404: }
406: /*
407: Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
408: */
409: static char *Petscgetline(FILE *f)
410: {
411: size_t size = 0;
412: size_t len = 0;
413: size_t last = 0;
414: char *buf = NULL;
416: if (feof(f)) return NULL;
417: do {
418: size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
419: buf = (char *)realloc((void *)buf, size); /* realloc(NULL,n) is the same as malloc(n) */
420: /* Actually do the read. Note that fgets puts a terminal '\0' on the
421: end of the string, so we make sure we overwrite this */
422: if (!fgets(buf + len, 1024, f)) buf[len] = 0;
423: PetscCallAbort(PETSC_COMM_SELF, PetscStrlen(buf, &len));
424: last = len - 1;
425: } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
426: if (len) return buf;
427: free(buf);
428: return NULL;
429: }
431: static PetscErrorCode PetscOptionsFilename(MPI_Comm comm, const char file[], char filename[PETSC_MAX_PATH_LEN], PetscBool *yaml)
432: {
433: char fname[PETSC_MAX_PATH_LEN + 8], path[PETSC_MAX_PATH_LEN + 8], *tail;
435: PetscFunctionBegin;
436: *yaml = PETSC_FALSE;
437: PetscCall(PetscStrreplace(comm, file, fname, sizeof(fname)));
438: PetscCall(PetscFixFilename(fname, path));
439: PetscCall(PetscStrendswith(path, ":yaml", yaml));
440: if (*yaml) {
441: PetscCall(PetscStrrchr(path, ':', &tail));
442: tail[-1] = 0; /* remove ":yaml" suffix from path */
443: }
444: PetscCall(PetscStrncpy(filename, path, PETSC_MAX_PATH_LEN));
445: /* check for standard YAML and JSON filename extensions */
446: if (!*yaml) PetscCall(PetscStrendswith(filename, ".yaml", yaml));
447: if (!*yaml) PetscCall(PetscStrendswith(filename, ".yml", yaml));
448: if (!*yaml) PetscCall(PetscStrendswith(filename, ".json", yaml));
449: if (!*yaml) { /* check file contents */
450: PetscMPIInt rank;
451: PetscCallMPI(MPI_Comm_rank(comm, &rank));
452: if (rank == 0) {
453: FILE *fh = fopen(filename, "r");
454: if (fh) {
455: char buf[6] = "";
456: if (fread(buf, 1, 6, fh) > 0) {
457: PetscCall(PetscStrncmp(buf, "%YAML ", 6, yaml)); /* check for '%YAML' tag */
458: if (!*yaml) PetscCall(PetscStrncmp(buf, "---", 3, yaml)); /* check for document start */
459: }
460: (void)fclose(fh);
461: }
462: }
463: PetscCallMPI(MPI_Bcast(yaml, 1, MPI_C_BOOL, 0, comm));
464: }
465: PetscFunctionReturn(PETSC_SUCCESS);
466: }
468: static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
469: {
470: char *string, *vstring = NULL, *astring = NULL, *packed = NULL;
471: const char *tokens[4];
472: size_t len;
473: PetscCount bytes;
474: FILE *fd;
475: PetscToken token = NULL;
476: int err;
477: char *cmatch = NULL;
478: const char cmt = '#';
479: PetscInt line = 1;
480: PetscMPIInt rank, cnt = 0, acnt = 0, counts[2];
481: PetscBool isdir, alias = PETSC_FALSE, valid;
483: PetscFunctionBegin;
484: PetscCall(PetscMemzero(tokens, sizeof(tokens)));
485: PetscCallMPI(MPI_Comm_rank(comm, &rank));
486: if (rank == 0) {
487: char fpath[PETSC_MAX_PATH_LEN];
488: char fname[PETSC_MAX_PATH_LEN];
490: PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fname, sizeof(fname)));
491: PetscCall(PetscFixFilename(fname, fpath));
492: PetscCall(PetscGetFullPath(fpath, fname, sizeof(fname)));
494: fd = fopen(fname, "r");
495: PetscCall(PetscTestDirectory(fname, 'r', &isdir));
496: PetscCheck(!isdir || !require, PETSC_COMM_SELF, PETSC_ERR_USER, "Specified options file %s is a directory", fname);
497: if (fd && !isdir) {
498: PetscSegBuffer vseg, aseg;
500: PetscCall(PetscSegBufferCreate(1, 4000, &vseg));
501: PetscCall(PetscSegBufferCreate(1, 2000, &aseg));
503: /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
504: PetscCall(PetscInfo(NULL, "Opened options file %s\n", file));
506: while ((string = Petscgetline(fd))) {
507: /* eliminate comments from each line */
508: PetscCall(PetscStrchr(string, cmt, &cmatch));
509: if (cmatch) *cmatch = 0;
510: PetscCall(PetscStrlen(string, &len));
511: /* replace tabs, ^M, \n with " " */
512: for (size_t i = 0; i < len; i++) {
513: if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') string[i] = ' ';
514: }
515: PetscCall(PetscTokenCreate(string, ' ', &token));
516: PetscCall(PetscTokenFind(token, &tokens[0]));
517: if (!tokens[0]) {
518: goto destroy;
519: } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
520: PetscCall(PetscTokenFind(token, &tokens[0]));
521: }
522: for (PetscInt i = 1; i < 4; i++) PetscCall(PetscTokenFind(token, &tokens[i]));
523: if (!tokens[0]) {
524: goto destroy;
525: } else if (tokens[0][0] == '-') {
526: PetscCall(PetscOptionsValidKey(tokens[0], &valid));
527: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": invalid option %s", fname, line, tokens[0]);
528: PetscCall(PetscStrlen(tokens[0], &len));
529: PetscCall(PetscSegBufferGet(vseg, len + 1, &vstring));
530: PetscCall(PetscArraycpy(vstring, tokens[0], len));
531: vstring[len] = ' ';
532: if (tokens[1]) {
533: PetscCall(PetscOptionsValidKey(tokens[1], &valid));
534: 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]);
535: PetscCall(PetscStrlen(tokens[1], &len));
536: PetscCall(PetscSegBufferGet(vseg, len + 3, &vstring));
537: vstring[0] = '"';
538: PetscCall(PetscArraycpy(vstring + 1, tokens[1], len));
539: vstring[len + 1] = '"';
540: vstring[len + 2] = ' ';
541: }
542: } else {
543: PetscCall(PetscStrcasecmp(tokens[0], "alias", &alias));
544: PetscCheck(alias, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown first token in options file %s line %" PetscInt_FMT ": %s", fname, line, tokens[0]);
545: PetscCall(PetscOptionsValidKey(tokens[1], &valid));
546: 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]);
547: 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]);
548: PetscCall(PetscOptionsValidKey(tokens[2], &valid));
549: 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]);
550: PetscCall(PetscStrlen(tokens[1], &len));
551: PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
552: PetscCall(PetscArraycpy(astring, tokens[1], len));
553: astring[len] = ' ';
555: PetscCall(PetscStrlen(tokens[2], &len));
556: PetscCall(PetscSegBufferGet(aseg, len + 1, &astring));
557: PetscCall(PetscArraycpy(astring, tokens[2], len));
558: astring[len] = ' ';
559: }
560: {
561: const char *extraToken = alias ? tokens[3] : tokens[2];
562: PetscCheck(!extraToken, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Error in options file %s line %" PetscInt_FMT ": extra token %s", fname, line, extraToken);
563: }
564: destroy:
565: free(string);
566: PetscCall(PetscTokenDestroy(&token));
567: alias = PETSC_FALSE;
568: line++;
569: }
570: err = fclose(fd);
571: PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file %s", fname);
572: PetscCall(PetscSegBufferGetSize(aseg, &bytes)); /* size without null termination */
573: PetscCall(PetscMPIIntCast(bytes, &acnt));
574: PetscCall(PetscSegBufferGet(aseg, 1, &astring));
575: astring[0] = 0;
576: PetscCall(PetscSegBufferGetSize(vseg, &bytes)); /* size without null termination */
577: PetscCall(PetscMPIIntCast(bytes, &cnt));
578: PetscCall(PetscSegBufferGet(vseg, 1, &vstring));
579: vstring[0] = 0;
580: PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
581: PetscCall(PetscSegBufferExtractTo(aseg, packed));
582: PetscCall(PetscSegBufferExtractTo(vseg, packed + acnt + 1));
583: PetscCall(PetscSegBufferDestroy(&aseg));
584: PetscCall(PetscSegBufferDestroy(&vseg));
585: } else PetscCheck(!require, PETSC_COMM_SELF, PETSC_ERR_USER, "Unable to open options file %s", fname);
586: }
588: counts[0] = acnt;
589: counts[1] = cnt;
590: err = MPI_Bcast(counts, 2, MPI_INT, 0, comm);
591: 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/");
592: acnt = counts[0];
593: cnt = counts[1];
594: if (rank) PetscCall(PetscMalloc1(2 + acnt + cnt, &packed));
595: if (acnt || cnt) {
596: PetscCallMPI(MPI_Bcast(packed, 2 + acnt + cnt, MPI_CHAR, 0, comm));
597: astring = packed;
598: vstring = packed + acnt + 1;
599: }
601: if (acnt) {
602: PetscCall(PetscTokenCreate(astring, ' ', &token));
603: PetscCall(PetscTokenFind(token, &tokens[0]));
604: while (tokens[0]) {
605: PetscCall(PetscTokenFind(token, &tokens[1]));
606: PetscCall(PetscOptionsSetAlias(options, tokens[0], tokens[1]));
607: PetscCall(PetscTokenFind(token, &tokens[0]));
608: }
609: PetscCall(PetscTokenDestroy(&token));
610: }
612: if (cnt) PetscCall(PetscOptionsInsertString_Private(options, vstring, PETSC_OPT_FILE));
613: PetscCall(PetscFree(packed));
614: PetscFunctionReturn(PETSC_SUCCESS);
615: }
617: /*@
618: PetscOptionsInsertFile - Inserts options into the database from a file.
620: Collective
622: Input Parameters:
623: + comm - the processes that will share the options (usually `PETSC_COMM_WORLD`)
624: . options - options database, use `NULL` for default global database
625: . file - name of file,
626: ".yml" and ".yaml" filename extensions are inserted as YAML options,
627: append ":yaml" to filename to force YAML options.
628: - require - if `PETSC_TRUE` will generate an error if the file does not exist
630: Level: developer
632: Notes:
633: Use # for lines that are comments and which should be ignored.
634: Usually, instead of using this command, one should list the file name in the call to `PetscInitialize()`, this insures that certain options
635: 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
636: calls to `XXXSetFromOptions()`, it should not be used for options listed under PetscInitialize().
637: The collectivity of this routine is complex; only the MPI processes in comm will
638: have the effect of these options. If some processes that create objects call this routine and others do
639: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
640: on different ranks.
642: .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
643: `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
644: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
645: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
646: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
647: `PetscOptionsFList()`, `PetscOptionsEList()`
648: @*/
649: PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
650: {
651: char filename[PETSC_MAX_PATH_LEN];
652: PetscBool yaml;
654: PetscFunctionBegin;
655: PetscCall(PetscOptionsFilename(comm, file, filename, &yaml));
656: if (yaml) {
657: PetscCall(PetscOptionsInsertFileYAML(comm, options, filename, require));
658: } else {
659: PetscCall(PetscOptionsInsertFilePetsc(comm, options, filename, require));
660: }
661: PetscFunctionReturn(PETSC_SUCCESS);
662: }
664: /*@C
665: PetscOptionsInsertArgs - Inserts options into the database from a array of strings
667: Logically Collective
669: Input Parameters:
670: + options - options object
671: . argc - the array length
672: - args - the string array
674: Level: intermediate
676: .seealso: `PetscOptions`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`
677: @*/
678: PetscErrorCode PetscOptionsInsertArgs(PetscOptions options, int argc, const char *const args[])
679: {
680: int left = PetscMax(argc, 0);
681: const char *const *eargs = args;
683: PetscFunctionBegin;
684: while (left) {
685: PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
686: PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
687: PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
688: PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
689: PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
690: PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
691: PetscCall(PetscOptionsValidKey(eargs[0], &key));
692: if (!key) {
693: eargs++;
694: left--;
695: } else if (isfile) {
696: PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
697: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, eargs[1], PETSC_TRUE));
698: eargs += 2;
699: left -= 2;
700: } else if (isfileyaml) {
701: PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
702: PetscCall(PetscOptionsInsertFileYAML(PETSC_COMM_WORLD, options, eargs[1], PETSC_TRUE));
703: eargs += 2;
704: left -= 2;
705: } else if (isstringyaml) {
706: PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
707: PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
708: eargs += 2;
709: left -= 2;
710: } else if (ispush) {
711: PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
712: PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
713: PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
714: eargs += 2;
715: left -= 2;
716: } else if (ispop) {
717: PetscCall(PetscOptionsPrefixPop(options));
718: eargs++;
719: left--;
720: } else {
721: PetscBool nextiskey = PETSC_FALSE;
722: if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
723: if (left < 2 || nextiskey) {
724: PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
725: eargs++;
726: left--;
727: } else {
728: PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
729: eargs += 2;
730: left -= 2;
731: }
732: }
733: }
734: PetscFunctionReturn(PETSC_SUCCESS);
735: }
737: static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], const PetscBool set[], PetscBool *flg)
738: {
739: PetscFunctionBegin;
740: if (set[opt]) PetscCall(PetscOptionsStringToBool(val[opt], flg));
741: else *flg = PETSC_FALSE;
742: PetscFunctionReturn(PETSC_SUCCESS);
743: }
745: /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
746: static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
747: {
748: const char *const *opt = precedentOptions;
749: const size_t n = PO_NUM;
750: size_t o;
751: int a;
752: const char **val;
753: char **cval;
754: PetscBool *set, unneeded;
756: PetscFunctionBegin;
757: PetscCall(PetscCalloc2(n, &cval, n, &set));
758: val = (const char **)cval;
760: /* Look for options possibly set using PetscOptionsSetValue beforehand */
761: for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
763: /* Loop through all args to collect last occurring value of each option */
764: for (a = 1; a < argc; a++) {
765: PetscBool valid, eq;
767: PetscCall(PetscOptionsValidKey(args[a], &valid));
768: if (!valid) continue;
769: for (o = 0; o < n; o++) {
770: PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
771: if (eq) {
772: set[o] = PETSC_TRUE;
773: if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
774: else val[o] = args[a + 1];
775: break;
776: }
777: }
778: }
780: /* Process flags */
781: PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
782: if (options->help_intro) options->help = PETSC_TRUE;
783: else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
784: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
785: /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
786: if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
787: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
788: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
789: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
790: *skip_petscrc_set = set[PO_SKIP_PETSCRC];
792: /* Store precedent options in database and mark them as used */
793: for (o = 1; o < n; o++) {
794: if (set[o]) {
795: PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
796: options->used[a] = PETSC_TRUE;
797: }
798: }
799: PetscCall(PetscFree2(cval, set));
800: options->precedentProcessed = PETSC_TRUE;
801: PetscFunctionReturn(PETSC_SUCCESS);
802: }
804: static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
805: {
806: PetscFunctionBegin;
807: PetscAssertPointer(flg, 3);
808: *flg = PETSC_FALSE;
809: if (options->precedentProcessed) {
810: for (int i = 0; i < PO_NUM; ++i) {
811: if (!PetscOptNameCmp(precedentOptions[i], name)) {
812: /* check if precedent option has been set already */
813: PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
814: if (*flg) break;
815: }
816: }
817: }
818: PetscFunctionReturn(PETSC_SUCCESS);
819: }
821: /*@C
822: PetscOptionsInsert - Inserts into the options database from the command line,
823: the environmental variable and a file.
825: Collective on `PETSC_COMM_WORLD`
827: Input Parameters:
828: + options - options database or `NULL` for the default global database
829: . argc - count of number of command line arguments
830: . args - the command line arguments
831: - file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
832: Use `NULL` or empty string to not check for code specific file.
833: Also checks ~/.petscrc, .petscrc and petscrc.
834: Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
836: Options Database Keys:
837: + -options_file filename - read options from a file
838: - -options_file_yaml filename - read options from a YAML file
840: Level: advanced
842: Notes:
843: Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
844: the user does not typically need to call this routine. `PetscOptionsInsert()`
845: can be called several times, adding additional entries into the database.
847: See `PetscInitialize()` for options related to option database monitoring.
849: .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
850: `PetscInitialize()`
851: @*/
852: PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[]) PeNS
853: {
854: PetscMPIInt rank;
855: PetscBool hasArgs = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
856: PetscBool skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
857: char *eoptions = NULL;
858: size_t len = 0;
860: PetscFunctionBegin;
861: PetscCheck(!hasArgs || (args && *args), PETSC_COMM_WORLD, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
862: PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
864: if (!options) {
865: PetscCall(PetscOptionsCreateDefault());
866: options = defaultoptions;
867: }
868: if (hasArgs) {
869: /* process options with absolute precedence */
870: PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
871: PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
872: }
873: if (file && file[0]) {
874: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, file, PETSC_TRUE));
875: /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
876: if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
877: }
878: if (!skipPetscrc) {
879: char filename[PETSC_MAX_PATH_LEN];
881: PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
882: PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, PETSC_COMM_WORLD));
883: if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
884: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, filename, PETSC_FALSE));
885: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, ".petscrc", PETSC_FALSE));
886: PetscCall(PetscOptionsInsertFile(PETSC_COMM_WORLD, options, "petscrc", PETSC_FALSE));
887: }
889: /* insert environment options */
890: if (rank == 0) {
891: eoptions = getenv("PETSC_OPTIONS");
892: PetscCall(PetscStrlen(eoptions, &len));
893: }
894: PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, PETSC_COMM_WORLD));
895: if (len) {
896: if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
897: PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, PETSC_COMM_WORLD));
898: if (rank) eoptions[len] = 0;
899: PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
900: if (rank) PetscCall(PetscFree(eoptions));
901: }
903: /* insert YAML environment options */
904: if (rank == 0) {
905: eoptions = getenv("PETSC_OPTIONS_YAML");
906: PetscCall(PetscStrlen(eoptions, &len));
907: }
908: PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, PETSC_COMM_WORLD));
909: if (len) {
910: if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
911: PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, PETSC_COMM_WORLD));
912: if (rank) eoptions[len] = 0;
913: PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
914: if (rank) PetscCall(PetscFree(eoptions));
915: }
917: /* insert command line options here because they take precedence over arguments in petscrc/environment */
918: if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, (const char *const *)*args + 1));
919: PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
920: PetscFunctionReturn(PETSC_SUCCESS);
921: }
923: /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
924: /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
925: 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"};
927: static PetscBool PetscCIOption(const char *name)
928: {
929: PetscInt idx;
930: PetscBool found;
932: if (!PetscCIEnabled) return PETSC_FALSE;
933: PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
934: return found;
935: }
937: /*@
938: PetscOptionsView - Prints the options that have been loaded. This is
939: useful for debugging purposes.
941: Logically Collective, No Fortran Support
943: Input Parameters:
944: + options - options database, use `NULL` for default global database
945: - viewer - must be an `PETSCVIEWERASCII` viewer
947: Options Database Key:
948: . -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
950: Level: advanced
952: Note:
953: Only the MPI rank 0 of the `MPI_Comm` used to create view prints the option values. Other processes
954: may have different values but they are not printed.
956: .seealso: `PetscOptionsAllUsed()`
957: @*/
958: PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
959: {
960: PetscInt i, N = 0;
961: PetscBool isascii;
963: PetscFunctionBegin;
965: options = options ? options : defaultoptions;
966: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
967: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
968: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
970: for (i = 0; i < options->N; i++) {
971: if (PetscCIOption(options->names[i])) continue;
972: N++;
973: }
975: if (!N) {
976: PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
977: PetscFunctionReturn(PETSC_SUCCESS);
978: }
980: PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
981: for (i = 0; i < options->N; i++) {
982: if (PetscCIOption(options->names[i])) continue;
983: if (options->values[i]) {
984: PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
985: } else {
986: PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
987: }
988: PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
989: }
990: PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
991: PetscFunctionReturn(PETSC_SUCCESS);
992: }
994: /*@
995: PetscOptionsLeftError - Prints a warning listing any options in the default database that were never used
997: Not Collective
999: Level: developer
1001: Note:
1002: This is intended for use inside PETSc error handlers. Unused options may indicate a program that crashed before it
1003: read them, a spelling mistake, or an option intended for a different context.
1005: .seealso: `PetscOptionsLeft()`, `PetscOptionsAllUsed()`, `PetscOptionsView()`
1006: @*/
1007: PetscErrorCode PetscOptionsLeftError(void)
1008: {
1009: PetscInt i, nopt = 0;
1011: for (i = 0; i < defaultoptions->N; i++) {
1012: if (!defaultoptions->used[i]) {
1013: if (PetscCIOption(defaultoptions->names[i])) continue;
1014: nopt++;
1015: }
1016: }
1017: if (nopt) {
1018: PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
1019: for (i = 0; i < defaultoptions->N; i++) {
1020: if (!defaultoptions->used[i]) {
1021: if (PetscCIOption(defaultoptions->names[i])) continue;
1022: 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]]));
1023: else PetscCall((*PetscErrorPrintf)(" Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
1024: }
1025: }
1026: }
1027: return PETSC_SUCCESS;
1028: }
1030: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1031: {
1032: PetscInt i, N = 0;
1033: PetscOptions options = defaultoptions;
1035: for (i = 0; i < options->N; i++) {
1036: if (PetscCIOption(options->names[i])) continue;
1037: N++;
1038: }
1040: if (N) {
1041: PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1042: } else {
1043: PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1044: }
1045: for (i = 0; i < options->N; i++) {
1046: if (PetscCIOption(options->names[i])) continue;
1047: if (options->values[i]) {
1048: PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1049: } else {
1050: PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1051: }
1052: }
1053: return PETSC_SUCCESS;
1054: }
1056: /*@
1057: PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
1059: Logically Collective
1061: Input Parameters:
1062: + options - options database, or `NULL` for the default global database
1063: - prefix - The string to append to the existing prefix
1065: Options Database Keys:
1066: + -prefix_push some_prefix_ - push the given prefix
1067: - -prefix_pop - pop the last prefix
1069: Level: advanced
1071: Notes:
1072: It is common to use this in conjunction with `-options_file` as in
1073: .vb
1074: -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
1075: .ve
1076: where the files no longer require all options to be prefixed with `-system2_`.
1078: The collectivity of this routine is complex; only the MPI processes that call this routine will
1079: have the affect of these options. If some processes that create objects call this routine and others do
1080: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1081: on different ranks.
1083: .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
1084: @*/
1085: PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1086: {
1087: size_t n;
1088: PetscInt start;
1089: char key[PETSC_MAX_OPTION_NAME + 1];
1090: PetscBool valid;
1092: PetscFunctionBegin;
1093: PetscAssertPointer(prefix, 2);
1094: options = options ? options : defaultoptions;
1095: 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);
1096: key[0] = '-'; /* keys must start with '-' */
1097: PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
1098: PetscCall(PetscOptionsValidKey(key, &valid));
1099: if (!valid && options->prefixind > 0 && isdigit((int)prefix[0])) valid = PETSC_TRUE; /* If the prefix stack is not empty, make numbers a valid prefix */
1100: 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" : "");
1101: start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
1102: PetscCall(PetscStrlen(prefix, &n));
1103: PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
1104: PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
1105: options->prefixstack[options->prefixind++] = (int)(start + n);
1106: PetscFunctionReturn(PETSC_SUCCESS);
1107: }
1109: /*@
1110: PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
1112: Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
1114: Input Parameter:
1115: . options - options database, or `NULL` for the default global database
1117: Level: advanced
1119: .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
1120: @*/
1121: PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1122: {
1123: PetscInt offset;
1125: PetscFunctionBegin;
1126: options = options ? options : defaultoptions;
1127: PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
1128: options->prefixind--;
1129: offset = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
1130: options->prefix[offset] = 0;
1131: PetscFunctionReturn(PETSC_SUCCESS);
1132: }
1134: /*@
1135: PetscOptionsClear - Removes all options form the database leaving it empty.
1137: Logically Collective
1139: Input Parameter:
1140: . options - options database, use `NULL` for the default global database
1142: Level: developer
1144: Note:
1145: The collectivity of this routine is complex; only the MPI processes that call this routine will
1146: have the affect of these options. If some processes that create objects call this routine and others do
1147: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1148: on different ranks.
1150: Developer Note:
1151: Uses `free()` directly because the current option values were set with `malloc()`
1153: .seealso: `PetscOptionsInsert()`
1154: @*/
1155: PetscErrorCode PetscOptionsClear(PetscOptions options)
1156: {
1157: PetscInt i;
1159: PetscFunctionBegin;
1160: options = options ? options : defaultoptions;
1161: if (!options) PetscFunctionReturn(PETSC_SUCCESS);
1163: for (i = 0; i < options->N; i++) {
1164: if (options->names[i]) free(options->names[i]);
1165: if (options->values[i]) free(options->values[i]);
1166: }
1167: options->N = 0;
1168: free(options->names);
1169: free(options->values);
1170: free(options->used);
1171: free(options->source);
1172: options->names = NULL;
1173: options->values = NULL;
1174: options->used = NULL;
1175: options->source = NULL;
1176: options->Nalloc = 0;
1178: for (i = 0; i < options->Na; i++) {
1179: free(options->aliases1[i]);
1180: free(options->aliases2[i]);
1181: }
1182: options->Na = 0;
1183: free(options->aliases1);
1184: free(options->aliases2);
1185: options->aliases1 = options->aliases2 = NULL;
1186: options->Naalloc = 0;
1188: /* destroy hash table */
1189: kh_destroy(HO, options->ht);
1190: options->ht = NULL;
1192: options->prefixind = 0;
1193: options->prefix[0] = 0;
1194: options->help = PETSC_FALSE;
1195: options->help_intro = PETSC_FALSE;
1196: PetscFunctionReturn(PETSC_SUCCESS);
1197: }
1199: /*@
1200: PetscOptionsSetAlias - Makes a key and alias for another key
1202: Logically Collective
1204: Input Parameters:
1205: + options - options database, or `NULL` for default global database
1206: . newname - the alias
1207: - oldname - the name that alias will refer to
1209: Level: advanced
1211: Note:
1212: The collectivity of this routine is complex; only the MPI processes that call this routine will
1213: have the affect of these options. If some processes that create objects call this routine and others do
1214: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1215: on different ranks.
1217: Developer Note:
1218: Uses `malloc()` directly because PETSc may not be initialized yet.
1220: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1221: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1222: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1223: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1224: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1225: `PetscOptionsFList()`, `PetscOptionsEList()`
1226: @*/
1227: PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1228: {
1229: size_t len;
1230: PetscBool valid;
1232: PetscFunctionBegin;
1233: PetscAssertPointer(newname, 2);
1234: PetscAssertPointer(oldname, 3);
1235: options = options ? options : defaultoptions;
1236: PetscCall(PetscOptionsValidKey(newname, &valid));
1237: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
1238: PetscCall(PetscOptionsValidKey(oldname, &valid));
1239: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
1241: if (options->Na == options->Naalloc) {
1242: char **tmpA1, **tmpA2;
1244: options->Naalloc = PetscMax(4, options->Naalloc * 2);
1245: tmpA1 = (char **)malloc(options->Naalloc * sizeof(char *));
1246: tmpA2 = (char **)malloc(options->Naalloc * sizeof(char *));
1247: for (int i = 0; i < options->Na; ++i) {
1248: tmpA1[i] = options->aliases1[i];
1249: tmpA2[i] = options->aliases2[i];
1250: }
1251: free(options->aliases1);
1252: free(options->aliases2);
1253: options->aliases1 = tmpA1;
1254: options->aliases2 = tmpA2;
1255: }
1256: newname++;
1257: oldname++;
1258: PetscCall(PetscStrlen(newname, &len));
1259: options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1260: PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
1261: PetscCall(PetscStrlen(oldname, &len));
1262: options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1263: PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
1264: ++options->Na;
1265: PetscFunctionReturn(PETSC_SUCCESS);
1266: }
1268: /*@
1269: PetscOptionsSetValue - Sets an option name-value pair in the options
1270: database, overriding whatever is already present.
1272: Logically Collective
1274: Input Parameters:
1275: + options - options database, use `NULL` for the default global database
1276: . name - name of option, this SHOULD have the - prepended
1277: - value - the option value (not used for all options, so can be `NULL`)
1279: Level: intermediate
1281: Note:
1282: This function can be called BEFORE `PetscInitialize()`
1284: The collectivity of this routine is complex; only the MPI processes that call this routine will
1285: have the affect of these options. If some processes that create objects call this routine and others do
1286: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1287: on different ranks.
1289: Developer Note:
1290: Uses `malloc()` directly because PETSc may not be initialized yet.
1292: .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1293: @*/
1294: PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1295: {
1296: PetscFunctionBegin;
1297: PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
1298: PetscFunctionReturn(PETSC_SUCCESS);
1299: }
1301: PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1302: {
1303: size_t len;
1304: int n, i;
1305: char **names;
1306: char fullname[PETSC_MAX_OPTION_NAME] = "";
1307: PetscBool flg;
1309: PetscFunctionBegin;
1310: if (!options) {
1311: PetscCall(PetscOptionsCreateDefault());
1312: options = defaultoptions;
1313: }
1314: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
1316: PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
1317: if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1319: name++; /* skip starting dash */
1321: if (options->prefixind > 0) {
1322: strncpy(fullname, options->prefix, sizeof(fullname));
1323: fullname[sizeof(fullname) - 1] = 0;
1324: strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
1325: fullname[sizeof(fullname) - 1] = 0;
1326: name = fullname;
1327: }
1329: /* check against aliases */
1330: for (i = 0; i < options->Na; i++) {
1331: int result = PetscOptNameCmp(options->aliases1[i], name);
1332: if (!result) {
1333: name = options->aliases2[i];
1334: break;
1335: }
1336: }
1338: /* slow search */
1339: n = options->N;
1340: names = options->names;
1341: for (i = 0; i < options->N; i++) {
1342: int result = PetscOptNameCmp(names[i], name);
1343: if (!result) {
1344: n = i;
1345: goto setvalue;
1346: } else if (result > 0) {
1347: n = i;
1348: break;
1349: }
1350: }
1351: if (options->N == options->Nalloc) {
1352: char **names, **values;
1353: PetscBool *used;
1354: PetscOptionSource *source;
1356: options->Nalloc = PetscMax(10, options->Nalloc * 2);
1357: names = (char **)malloc(options->Nalloc * sizeof(char *));
1358: values = (char **)malloc(options->Nalloc * sizeof(char *));
1359: used = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
1360: source = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
1361: for (int i = 0; i < options->N; ++i) {
1362: names[i] = options->names[i];
1363: values[i] = options->values[i];
1364: used[i] = options->used[i];
1365: source[i] = options->source[i];
1366: }
1367: free(options->names);
1368: free(options->values);
1369: free(options->used);
1370: free(options->source);
1371: options->names = names;
1372: options->values = values;
1373: options->used = used;
1374: options->source = source;
1375: }
1377: /* shift remaining values up 1 */
1378: for (i = options->N; i > n; i--) {
1379: options->names[i] = options->names[i - 1];
1380: options->values[i] = options->values[i - 1];
1381: options->used[i] = options->used[i - 1];
1382: options->source[i] = options->source[i - 1];
1383: }
1384: options->names[n] = NULL;
1385: options->values[n] = NULL;
1386: options->used[n] = PETSC_FALSE;
1387: options->source[n] = PETSC_OPT_CODE;
1388: options->N++;
1390: /* destroy hash table */
1391: kh_destroy(HO, options->ht);
1392: options->ht = NULL;
1394: /* set new name */
1395: len = strlen(name);
1396: options->names[n] = (char *)malloc((len + 1) * sizeof(char));
1397: PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1398: strcpy(options->names[n], name);
1400: setvalue:
1401: /* set new value */
1402: if (options->values[n]) free(options->values[n]);
1403: len = value ? strlen(value) : 0;
1404: if (len) {
1405: options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1406: if (!options->values[n]) return PETSC_ERR_MEM;
1407: strcpy(options->values[n], value);
1408: options->values[n][len] = '\0';
1409: } else {
1410: options->values[n] = NULL;
1411: }
1412: options->source[n] = source;
1414: /* handle -help so that it can be set from anywhere */
1415: if (!PetscOptNameCmp(name, "help")) {
1416: options->help = PETSC_TRUE;
1417: options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
1418: options->used[n] = PETSC_TRUE;
1419: }
1421: PetscCall(PetscOptionsMonitor(options, name, value ? value : "", source));
1422: if (pos) *pos = n;
1423: PetscFunctionReturn(PETSC_SUCCESS);
1424: }
1426: /*@
1427: PetscOptionsClearValue - Clears an option name-value pair in the options
1428: database, overriding whatever is already present.
1430: Logically Collective
1432: Input Parameters:
1433: + options - options database, use `NULL` for the default global database
1434: - name - name of option, this SHOULD have the - prepended
1436: Level: intermediate
1438: Note:
1439: The collectivity of this routine is complex; only the MPI processes that call this routine will
1440: have the affect of these options. If some processes that create objects call this routine and others do
1441: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1442: on different ranks.
1444: Developer Note:
1445: Uses `free()` directly because the options have been set with `malloc()`
1447: .seealso: `PetscOptionsInsert()`
1448: @*/
1449: PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1450: {
1451: int N, n, i;
1452: char **names;
1454: PetscFunctionBegin;
1455: options = options ? options : defaultoptions;
1456: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1457: if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
1459: name++; /* skip starting dash */
1461: /* slow search */
1462: N = n = options->N;
1463: names = options->names;
1464: for (i = 0; i < N; i++) {
1465: int result = PetscOptNameCmp(names[i], name);
1466: if (!result) {
1467: n = i;
1468: break;
1469: } else if (result > 0) {
1470: n = N;
1471: break;
1472: }
1473: }
1474: if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1476: /* remove name and value */
1477: if (options->names[n]) free(options->names[n]);
1478: if (options->values[n]) free(options->values[n]);
1479: /* shift remaining values down 1 */
1480: for (i = n; i < N - 1; i++) {
1481: options->names[i] = options->names[i + 1];
1482: options->values[i] = options->values[i + 1];
1483: options->used[i] = options->used[i + 1];
1484: options->source[i] = options->source[i + 1];
1485: }
1486: options->N--;
1488: /* destroy hash table */
1489: kh_destroy(HO, options->ht);
1490: options->ht = NULL;
1492: PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
1493: PetscFunctionReturn(PETSC_SUCCESS);
1494: }
1496: /*@C
1497: PetscOptionsFindPair - Gets an option name-value pair from the options database.
1499: Not Collective
1501: Input Parameters:
1502: + options - options database, use `NULL` for the default global database
1503: . pre - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
1504: - name - name of option, this SHOULD have the "-" prepended
1506: Output Parameters:
1507: + value - the option value (optional, not used for all options)
1508: - set - whether the option is set (optional)
1510: Level: developer
1512: Note:
1513: Each process may find different values or no value depending on how options were inserted into the database
1515: .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1516: @*/
1517: PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1518: {
1519: char buf[PETSC_MAX_OPTION_NAME];
1520: PetscBool matchnumbers = PETSC_TRUE;
1522: PetscFunctionBegin;
1523: if (!options) {
1524: PetscCall(PetscOptionsCreateDefault());
1525: options = defaultoptions;
1526: }
1527: PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1528: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1530: name++; /* skip starting dash */
1532: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1533: if (pre && pre[0]) {
1534: char *ptr = buf;
1535: if (name[0] == '-') {
1536: *ptr++ = '-';
1537: name++;
1538: }
1539: PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
1540: PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
1541: name = buf;
1542: }
1544: if (PetscDefined(USE_DEBUG)) {
1545: PetscBool valid;
1546: char key[PETSC_MAX_OPTION_NAME + 1] = "-";
1547: PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
1548: PetscCall(PetscOptionsValidKey(key, &valid));
1549: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1550: }
1552: if (!options->ht) {
1553: int i, ret;
1554: khiter_t it;
1555: khash_t(HO) *ht;
1556: ht = kh_init(HO);
1557: PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
1558: ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
1559: PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
1560: for (i = 0; i < options->N; i++) {
1561: it = kh_put(HO, ht, options->names[i], &ret);
1562: PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
1563: kh_val(ht, it) = i;
1564: }
1565: options->ht = ht;
1566: }
1568: khash_t(HO) *ht = options->ht;
1569: khiter_t it = kh_get(HO, ht, name);
1570: if (it != kh_end(ht)) {
1571: int i = kh_val(ht, it);
1572: options->used[i] = PETSC_TRUE;
1573: if (value) *value = options->values[i];
1574: if (set) *set = PETSC_TRUE;
1575: PetscFunctionReturn(PETSC_SUCCESS);
1576: }
1578: /*
1579: The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
1580: Maybe this special lookup mode should be enabled on request with a push/pop API.
1581: The feature of matching _%d_ used sparingly in the codebase.
1582: */
1583: if (matchnumbers) {
1584: int i, j, cnt = 0, locs[16], loce[16];
1585: /* determine the location and number of all _%d_ in the key */
1586: for (i = 0; name[i]; i++) {
1587: if (name[i] == '_') {
1588: for (j = i + 1; name[j]; j++) {
1589: if (name[j] >= '0' && name[j] <= '9') continue;
1590: if (name[j] == '_' && j > i + 1) { /* found a number */
1591: locs[cnt] = i + 1;
1592: loce[cnt++] = j + 1;
1593: }
1594: i = j - 1;
1595: break;
1596: }
1597: }
1598: }
1599: for (i = 0; i < cnt; i++) {
1600: PetscBool found;
1601: char opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
1602: PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
1603: PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
1604: PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
1605: PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
1606: if (found) {
1607: if (set) *set = PETSC_TRUE;
1608: PetscFunctionReturn(PETSC_SUCCESS);
1609: }
1610: }
1611: }
1613: if (set) *set = PETSC_FALSE;
1614: PetscFunctionReturn(PETSC_SUCCESS);
1615: }
1617: /* Check whether any option begins with pre+name */
1618: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *option[], const char *value[], PetscBool *set)
1619: {
1620: char buf[PETSC_MAX_OPTION_NAME];
1621: int numCnt = 0, locs[16], loce[16];
1623: PetscFunctionBegin;
1624: options = options ? options : defaultoptions;
1625: PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1626: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1628: name++; /* skip starting dash */
1630: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1631: if (pre && pre[0]) {
1632: char *ptr = buf;
1633: if (name[0] == '-') {
1634: *ptr++ = '-';
1635: name++;
1636: }
1637: PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
1638: PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
1639: name = buf;
1640: }
1642: if (PetscDefined(USE_DEBUG)) {
1643: PetscBool valid;
1644: char key[PETSC_MAX_OPTION_NAME + 1] = "-";
1645: PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
1646: PetscCall(PetscOptionsValidKey(key, &valid));
1647: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1648: }
1650: /* determine the location and number of all _%d_ in the key */
1651: {
1652: int i, j;
1653: for (i = 0; name[i]; i++) {
1654: if (name[i] == '_') {
1655: for (j = i + 1; name[j]; j++) {
1656: if (name[j] >= '0' && name[j] <= '9') continue;
1657: if (name[j] == '_' && j > i + 1) { /* found a number */
1658: locs[numCnt] = i + 1;
1659: loce[numCnt++] = j + 1;
1660: }
1661: i = j - 1;
1662: break;
1663: }
1664: }
1665: }
1666: }
1668: /* slow search */
1669: for (int c = -1; c < numCnt; ++c) {
1670: char opt[PETSC_MAX_OPTION_NAME + 2] = "";
1671: size_t len;
1673: if (c < 0) {
1674: PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1675: } else {
1676: PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1677: PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1678: }
1679: PetscCall(PetscStrlen(opt, &len));
1680: for (int i = 0; i < options->N; i++) {
1681: PetscBool match;
1683: PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1684: if (match) {
1685: options->used[i] = PETSC_TRUE;
1686: if (option) *option = options->names[i];
1687: if (value) *value = options->values[i];
1688: if (set) *set = PETSC_TRUE;
1689: PetscFunctionReturn(PETSC_SUCCESS);
1690: }
1691: }
1692: }
1694: if (set) *set = PETSC_FALSE;
1695: PetscFunctionReturn(PETSC_SUCCESS);
1696: }
1698: /*@
1699: PetscOptionsReject - Generates an error if a certain option is given.
1701: Not Collective
1703: Input Parameters:
1704: + options - options database, use `NULL` for default global database
1705: . pre - the option prefix (may be `NULL`)
1706: . name - the option name one is seeking
1707: - mess - error message (may be `NULL`)
1709: Level: advanced
1711: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1712: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1713: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1714: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1715: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1716: `PetscOptionsFList()`, `PetscOptionsEList()`
1717: @*/
1718: PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1719: {
1720: PetscBool flag = PETSC_FALSE;
1722: PetscFunctionBegin;
1723: PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1724: if (flag) {
1725: PetscCheck(!mess || !mess[0], PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s with %s", pre ? pre : "", name + 1, mess);
1726: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1727: }
1728: PetscFunctionReturn(PETSC_SUCCESS);
1729: }
1731: /*@
1732: PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
1734: Not Collective
1736: Input Parameter:
1737: . options - options database, use `NULL` for default global database
1739: Output Parameter:
1740: . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1742: Level: advanced
1744: .seealso: `PetscOptionsHasName()`
1745: @*/
1746: PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1747: {
1748: PetscFunctionBegin;
1749: PetscAssertPointer(set, 2);
1750: options = options ? options : defaultoptions;
1751: *set = options->help;
1752: PetscFunctionReturn(PETSC_SUCCESS);
1753: }
1755: PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1756: {
1757: PetscFunctionBegin;
1758: PetscAssertPointer(set, 2);
1759: options = options ? options : defaultoptions;
1760: *set = options->help_intro;
1761: PetscFunctionReturn(PETSC_SUCCESS);
1762: }
1764: /*@
1765: PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or Boolean, even
1766: if its value is set to false.
1768: Not Collective
1770: Input Parameters:
1771: + options - options database, use `NULL` for default global database
1772: . pre - string to prepend to the name or `NULL`
1773: - name - the option one is seeking
1775: Output Parameter:
1776: . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1778: Level: beginner
1780: Note:
1781: In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
1783: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1784: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1785: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1786: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1787: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1788: `PetscOptionsFList()`, `PetscOptionsEList()`
1789: @*/
1790: PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1791: {
1792: const char *value;
1793: PetscBool flag;
1795: PetscFunctionBegin;
1796: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
1797: if (set) *set = flag;
1798: PetscFunctionReturn(PETSC_SUCCESS);
1799: }
1801: /*@C
1802: PetscOptionsGetAll - Lists all the options the program was run with in a single string.
1804: Not Collective
1806: Input Parameter:
1807: . options - the options database, use `NULL` for the default global database
1809: Output Parameter:
1810: . copts - pointer where string pointer is stored
1812: Level: advanced
1814: Notes:
1815: The string should be freed with `PetscFree()`
1817: Each process may have different values depending on how the options were inserted into the database
1819: .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`,
1820: `PetscOptionsLeftGet()`
1821: @*/
1822: PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[]) PeNS
1823: {
1824: PetscInt i;
1825: size_t len = 1, lent = 0;
1826: char *coptions = NULL;
1828: PetscFunctionBegin;
1829: PetscAssertPointer(copts, 2);
1830: options = options ? options : defaultoptions;
1831: /* count the length of the required string */
1832: for (i = 0; i < options->N; i++) {
1833: PetscCall(PetscStrlen(options->names[i], &lent));
1834: len += 2 + lent;
1835: if (options->values[i]) {
1836: PetscCall(PetscStrlen(options->values[i], &lent));
1837: len += 1 + lent;
1838: }
1839: }
1840: PetscCall(PetscMalloc1(len, &coptions));
1841: coptions[0] = 0;
1842: for (i = 0; i < options->N; i++) {
1843: PetscCall(PetscStrlcat(coptions, "-", len));
1844: PetscCall(PetscStrlcat(coptions, options->names[i], len));
1845: PetscCall(PetscStrlcat(coptions, " ", len));
1846: if (options->values[i]) {
1847: PetscCall(PetscStrlcat(coptions, options->values[i], len));
1848: PetscCall(PetscStrlcat(coptions, " ", len));
1849: }
1850: }
1851: *copts = coptions;
1852: PetscFunctionReturn(PETSC_SUCCESS);
1853: }
1855: /*@
1856: PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
1858: Not Collective
1860: Input Parameters:
1861: + options - options database, use `NULL` for default global database
1862: - name - string name of option
1864: Output Parameter:
1865: . used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
1867: Level: advanced
1869: Note:
1870: The value returned may be different on each process and depends on which options have been processed
1871: on the given process
1873: .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
1874: @*/
1875: PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1876: {
1877: PetscInt i;
1879: PetscFunctionBegin;
1880: PetscAssertPointer(name, 2);
1881: PetscAssertPointer(used, 3);
1882: options = options ? options : defaultoptions;
1883: *used = PETSC_FALSE;
1884: for (i = 0; i < options->N; i++) {
1885: PetscCall(PetscStrcasecmp(options->names[i], name, used));
1886: if (*used) {
1887: *used = options->used[i];
1888: break;
1889: }
1890: }
1891: PetscFunctionReturn(PETSC_SUCCESS);
1892: }
1894: /*@
1895: PetscOptionsAllUsed - Returns a count of the number of options in the
1896: database that have never been selected.
1898: Not Collective
1900: Input Parameter:
1901: . options - options database, use `NULL` for default global database
1903: Output Parameter:
1904: . N - count of options not used
1906: Level: advanced
1908: Note:
1909: The value returned may be different on each process and depends on which options have been processed
1910: on the given process
1912: .seealso: `PetscOptionsView()`
1913: @*/
1914: PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1915: {
1916: PetscInt i, n = 0;
1918: PetscFunctionBegin;
1919: PetscAssertPointer(N, 2);
1920: options = options ? options : defaultoptions;
1921: for (i = 0; i < options->N; i++) {
1922: if (!options->used[i]) n++;
1923: }
1924: *N = n;
1925: PetscFunctionReturn(PETSC_SUCCESS);
1926: }
1928: /*@
1929: PetscOptionsLeft - Prints to screen any options that were set and never used.
1931: Not Collective
1933: Input Parameter:
1934: . options - options database; use `NULL` for default global database
1936: Options Database Key:
1937: . -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
1939: Level: advanced
1941: Notes:
1942: This is rarely used directly, it is called by `PetscFinalize()` by default (unless
1943: `-options_left false` is specified) to help users determine possible mistakes in their usage of
1944: options. This only prints values on process zero of `PETSC_COMM_WORLD`.
1946: Other processes depending the objects
1947: used may have different options that are left unused.
1949: .seealso: `PetscOptionsAllUsed()`
1950: @*/
1951: PetscErrorCode PetscOptionsLeft(PetscOptions options)
1952: {
1953: PetscInt cnt = 0;
1954: PetscOptions toptions;
1956: PetscFunctionBegin;
1957: toptions = options ? options : defaultoptions;
1958: for (PetscInt i = 0; i < toptions->N; i++) {
1959: if (!toptions->used[i]) {
1960: if (PetscCIOption(toptions->names[i])) continue;
1961: if (toptions->values[i]) {
1962: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s value: %s source: %s\n", toptions->names[i], toptions->values[i], PetscOptionSources[toptions->source[i]]));
1963: } else {
1964: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
1965: }
1966: }
1967: }
1968: if (!options) {
1969: toptions = defaultoptions;
1970: while (toptions->previous) {
1971: cnt++;
1972: toptions = toptions->previous;
1973: }
1974: 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));
1975: }
1976: PetscFunctionReturn(PETSC_SUCCESS);
1977: }
1979: /*@C
1980: PetscOptionsLeftGet - Returns all options that were set and never used.
1982: Not Collective
1984: Input Parameter:
1985: . options - options database, use `NULL` for default global database
1987: Output Parameters:
1988: + N - count of options not used
1989: . names - names of options not used
1990: - values - values of options not used
1992: Level: advanced
1994: Notes:
1995: Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
1997: The value returned may be different on each process and depends on which options have been processed
1998: on the given process
2000: .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
2001: @*/
2002: PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
2003: {
2004: PetscInt n;
2006: PetscFunctionBegin;
2007: if (N) PetscAssertPointer(N, 2);
2008: if (names) PetscAssertPointer(names, 3);
2009: if (values) PetscAssertPointer(values, 4);
2010: options = options ? options : defaultoptions;
2012: /* The number of unused PETSc options */
2013: n = 0;
2014: for (PetscInt i = 0; i < options->N; i++) {
2015: if (PetscCIOption(options->names[i])) continue;
2016: if (!options->used[i]) n++;
2017: }
2018: if (N) *N = n;
2019: if (names) PetscCall(PetscMalloc1(n, names));
2020: if (values) PetscCall(PetscMalloc1(n, values));
2022: n = 0;
2023: if (names || values) {
2024: for (PetscInt i = 0; i < options->N; i++) {
2025: if (!options->used[i]) {
2026: if (PetscCIOption(options->names[i])) continue;
2027: if (names) (*names)[n] = options->names[i];
2028: if (values) (*values)[n] = options->values[i];
2029: n++;
2030: }
2031: }
2032: }
2033: PetscFunctionReturn(PETSC_SUCCESS);
2034: }
2036: /*@C
2037: PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
2039: Not Collective
2041: Input Parameters:
2042: + options - options database, use `NULL` for default global database
2043: . N - count of options not used
2044: . names - names of options not used
2045: - values - values of options not used
2047: Level: advanced
2049: Notes:
2050: The user should pass the same pointer to `N` as they did when calling `PetscOptionsLeftGet()`
2052: .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
2053: @*/
2054: PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2055: {
2056: PetscFunctionBegin;
2057: (void)options;
2058: if (N) PetscAssertPointer(N, 2);
2059: if (names) PetscAssertPointer(names, 3);
2060: if (values) PetscAssertPointer(values, 4);
2061: if (N) *N = 0;
2062: if (names) PetscCall(PetscFree(*names));
2063: if (values) PetscCall(PetscFree(*values));
2064: PetscFunctionReturn(PETSC_SUCCESS);
2065: }
2067: /*@C
2068: PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
2070: Logically Collective
2072: Input Parameters:
2073: + name - option name string
2074: . value - option value string
2075: . source - The source for the option
2076: - ctx - a `PETSCVIEWERASCII` or `NULL`
2078: Level: intermediate
2080: Notes:
2081: If ctx is `NULL`, `PetscPrintf()` is used.
2082: The first MPI process in the `PetscViewer` viewer actually prints the values, other
2083: processes may have different values set
2085: If `PetscCIEnabled` then do not print the test harness options
2087: .seealso: `PetscOptionsMonitorSet()`
2088: @*/
2089: PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], PetscOptionSource source, PetscCtx ctx)
2090: {
2091: PetscFunctionBegin;
2092: if (PetscCIOption(name)) PetscFunctionReturn(PETSC_SUCCESS);
2094: if (ctx) {
2095: PetscViewer viewer = (PetscViewer)ctx;
2096: if (!value) {
2097: PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
2098: } else if (!value[0]) {
2099: PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
2100: } else {
2101: PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
2102: }
2103: } else {
2104: if (!value) {
2105: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Removing option: %s\n", name));
2106: } else if (!value[0]) {
2107: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
2108: } else {
2109: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
2110: }
2111: }
2112: PetscFunctionReturn(PETSC_SUCCESS);
2113: }
2115: /*@C
2116: PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
2117: modified the PETSc options database.
2119: Not Collective
2121: Input Parameters:
2122: + monitor - pointer to function (if this is `NULL`, it turns off monitoring
2123: . mctx - [optional] context for private data for the monitor routine (use `NULL` if
2124: no context is desired)
2125: - monitordestroy - [optional] routine that frees monitor context (may be `NULL`), see `PetscCtxDestroyFn` for its calling sequence
2127: Calling sequence of `monitor`:
2128: + name - option name string
2129: . value - option value string, a value of `NULL` indicates the option is being removed from the database. A value
2130: of "" indicates the option is in the database but has no value.
2131: . source - option source
2132: - mctx - optional monitoring context, as set by `PetscOptionsMonitorSet()`
2134: Options Database Keys:
2135: + -options_monitor viewer - turn on default monitoring of changes to the options database
2136: - -options_monitor_cancel - turn off any option monitors except the default monitor obtained with `-options_monitor`
2138: Level: intermediate
2140: Notes:
2141: See `PetscInitialize()` for options related to option database monitoring.
2143: The default is to do no monitoring. To print the name and value of options
2144: being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
2145: with a `NULL` monitoring context. Or use the option `-options_monitor viewer`.
2147: Several different monitoring routines may be set by calling
2148: `PetscOptionsMonitorSet()` multiple times; all will be called in the
2149: order in which they were set.
2151: .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`, `PetscCtxDestroyFn`
2152: @*/
2153: PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource source, PetscCtx mctx), PetscCtx mctx, PetscCtxDestroyFn *monitordestroy)
2154: {
2155: PetscOptions options = defaultoptions;
2157: PetscFunctionBegin;
2158: if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
2159: PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
2160: options->monitor[options->numbermonitors] = monitor;
2161: options->monitordestroy[options->numbermonitors] = monitordestroy;
2162: options->monitorcontext[options->numbermonitors++] = mctx;
2163: PetscFunctionReturn(PETSC_SUCCESS);
2164: }
2166: /*@
2167: PetscOptionsStringToBool - Converts a string to a `PetscBool`
2169: Not Collective
2171: Input Parameter:
2172: . value - the string to convert; may be `NULL` or `""`
2174: Output Parameter:
2175: . a - the resulting `PetscBool`
2177: Level: developer
2179: Note:
2180: Recognizes (case-insensitive) `TRUE`, `YES`, `1`, `on` as `PETSC_TRUE` and `FALSE`, `NO`, `0`, `off` as `PETSC_FALSE`.
2181: An empty or `NULL` string is treated as `PETSC_TRUE`. Any other input generates an error.
2183: .seealso: `PetscOptionsStringToInt()`, `PetscOptionsStringToReal()`, `PetscOptionsStringToScalar()`, `PetscOptionsGetBool()`
2184: @*/
2185: PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2186: {
2187: PetscBool istrue, isfalse;
2188: size_t len;
2190: PetscFunctionBegin;
2191: /* PetscStrlen() returns 0 for NULL or "" */
2192: PetscCall(PetscStrlen(value, &len));
2193: if (!len) {
2194: *a = PETSC_TRUE;
2195: PetscFunctionReturn(PETSC_SUCCESS);
2196: }
2197: PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
2198: if (istrue) {
2199: *a = PETSC_TRUE;
2200: PetscFunctionReturn(PETSC_SUCCESS);
2201: }
2202: PetscCall(PetscStrcasecmp(value, "YES", &istrue));
2203: if (istrue) {
2204: *a = PETSC_TRUE;
2205: PetscFunctionReturn(PETSC_SUCCESS);
2206: }
2207: PetscCall(PetscStrcasecmp(value, "1", &istrue));
2208: if (istrue) {
2209: *a = PETSC_TRUE;
2210: PetscFunctionReturn(PETSC_SUCCESS);
2211: }
2212: PetscCall(PetscStrcasecmp(value, "on", &istrue));
2213: if (istrue) {
2214: *a = PETSC_TRUE;
2215: PetscFunctionReturn(PETSC_SUCCESS);
2216: }
2217: PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
2218: if (isfalse) {
2219: *a = PETSC_FALSE;
2220: PetscFunctionReturn(PETSC_SUCCESS);
2221: }
2222: PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
2223: if (isfalse) {
2224: *a = PETSC_FALSE;
2225: PetscFunctionReturn(PETSC_SUCCESS);
2226: }
2227: PetscCall(PetscStrcasecmp(value, "0", &isfalse));
2228: if (isfalse) {
2229: *a = PETSC_FALSE;
2230: PetscFunctionReturn(PETSC_SUCCESS);
2231: }
2232: PetscCall(PetscStrcasecmp(value, "off", &isfalse));
2233: if (isfalse) {
2234: *a = PETSC_FALSE;
2235: PetscFunctionReturn(PETSC_SUCCESS);
2236: }
2237: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
2238: }
2240: /*@
2241: PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
2243: Not Collective
2245: Input Parameter:
2246: . name - the string to convert
2248: Output Parameter:
2249: . a - the resulting `PetscInt` value
2251: Level: developer
2253: Note:
2254: Recognizes the special strings `PETSC_DEFAULT`, `DEFAULT`, `PETSC_DECIDE`, `DECIDE`, `PETSC_DETERMINE`, `DETERMINE`, `PETSC_UNLIMITED`,
2255: `UNLIMITED`, and `mouse` (which returns `-1`). Otherwise the value is parsed as a base-10 integer.
2257: .seealso: `PetscOptionsStringToReal()`, `PetscOptionsStringToScalar()`, `PetscOptionsStringToBool()`, `PetscOptionsGetInt()`
2258: @*/
2259: PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2260: {
2261: size_t len;
2262: PetscBool decide, tdefault, mouse, unlimited;
2264: PetscFunctionBegin;
2265: PetscCall(PetscStrlen(name, &len));
2266: PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
2268: PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
2269: if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
2270: PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
2271: if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
2272: if (!decide) PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &decide));
2273: if (!decide) PetscCall(PetscStrcasecmp(name, "DETERMINE", &decide));
2274: PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &unlimited));
2275: if (!unlimited) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &unlimited));
2276: PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
2278: if (tdefault) *a = PETSC_DEFAULT;
2279: else if (decide) *a = PETSC_DECIDE;
2280: else if (unlimited) *a = PETSC_UNLIMITED;
2281: else if (mouse) *a = -1;
2282: else {
2283: char *endptr;
2284: long strtolval;
2286: strtolval = strtol(name, &endptr, 10);
2287: 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);
2289: #if PetscDefined(USE_64BIT_INDICES) && PetscDefined(HAVE_ATOLL)
2290: (void)strtolval;
2291: *a = atoll(name);
2292: #elif PetscDefined(USE_64BIT_INDICES) && PetscDefined(HAVE___INT64)
2293: (void)strtolval;
2294: *a = _atoi64(name);
2295: #else
2296: *a = (PetscInt)strtolval;
2297: #endif
2298: }
2299: PetscFunctionReturn(PETSC_SUCCESS);
2300: }
2302: #if PetscDefined(USE_REAL___FLOAT128)
2303: #include <quadmath.h>
2304: #endif
2306: static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2307: {
2308: PetscFunctionBegin;
2309: #if PetscDefined(USE_REAL___FLOAT128)
2310: *a = strtoflt128(name, endptr);
2311: #else
2312: *a = (PetscReal)strtod(name, endptr);
2313: #endif
2314: PetscFunctionReturn(PETSC_SUCCESS);
2315: }
2317: static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2318: {
2319: PetscBool hasi = PETSC_FALSE;
2320: char *ptr;
2321: PetscReal strtoval;
2323: PetscFunctionBegin;
2324: PetscCall(PetscStrtod(name, &strtoval, &ptr));
2325: if (ptr == name) {
2326: strtoval = 1.;
2327: hasi = PETSC_TRUE;
2328: if (name[0] == 'i') {
2329: ptr++;
2330: } else if (name[0] == '+' && name[1] == 'i') {
2331: ptr += 2;
2332: } else if (name[0] == '-' && name[1] == 'i') {
2333: strtoval = -1.;
2334: ptr += 2;
2335: }
2336: } else if (*ptr == 'i') {
2337: hasi = PETSC_TRUE;
2338: ptr++;
2339: }
2340: *endptr = ptr;
2341: *isImaginary = hasi;
2342: if (hasi) {
2343: #if !PetscDefined(USE_COMPLEX)
2344: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
2345: #else
2346: *a = PetscCMPLX(0., strtoval);
2347: #endif
2348: } else {
2349: *a = strtoval;
2350: }
2351: PetscFunctionReturn(PETSC_SUCCESS);
2352: }
2354: /*@
2355: PetscOptionsStringToReal - Converts a string to a `PetscReal` value. Handles special cases like `default` and `decide`
2357: Not Collective
2359: Input Parameter:
2360: . name - the string to convert
2362: Output Parameter:
2363: . a - the resulting `PetscReal` value
2365: Level: developer
2367: Note:
2368: Recognizes the special strings `PETSC_DEFAULT`, `DEFAULT`, `PETSC_DECIDE`, `DECIDE`, `PETSC_DETERMINE`, `DETERMINE`,
2369: `PETSC_UNLIMITED`, and `UNLIMITED`. Otherwise the value is parsed as a floating-point number.
2371: .seealso: `PetscOptionsStringToInt()`, `PetscOptionsStringToScalar()`, `PetscOptionsStringToBool()`, `PetscOptionsGetReal()`
2372: @*/
2373: PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2374: {
2375: size_t len;
2376: PetscBool match;
2377: char *endptr;
2379: PetscFunctionBegin;
2380: PetscCall(PetscStrlen(name, &len));
2381: PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
2383: PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
2384: if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
2385: if (match) {
2386: *a = PETSC_DEFAULT;
2387: PetscFunctionReturn(PETSC_SUCCESS);
2388: }
2390: PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
2391: if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
2392: if (match) {
2393: *a = PETSC_DECIDE;
2394: PetscFunctionReturn(PETSC_SUCCESS);
2395: }
2397: PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &match));
2398: if (!match) PetscCall(PetscStrcasecmp(name, "DETERMINE", &match));
2399: if (match) {
2400: *a = PETSC_DETERMINE;
2401: PetscFunctionReturn(PETSC_SUCCESS);
2402: }
2404: PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &match));
2405: if (!match) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &match));
2406: if (match) {
2407: *a = PETSC_UNLIMITED;
2408: PetscFunctionReturn(PETSC_SUCCESS);
2409: }
2411: PetscCall(PetscStrtod(name, a, &endptr));
2412: PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
2413: PetscFunctionReturn(PETSC_SUCCESS);
2414: }
2416: /*@
2417: PetscOptionsStringToScalar - Converts a string to a `PetscScalar` value; when PETSc is built with complex scalars, parses an optional imaginary part
2419: Not Collective
2421: Input Parameter:
2422: . name - the string to convert
2424: Output Parameter:
2425: . a - the resulting `PetscScalar` value
2427: Level: developer
2429: Note:
2430: 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.
2432: .seealso: `PetscOptionsStringToInt()`, `PetscOptionsStringToReal()`, `PetscOptionsStringToBool()`, `PetscOptionsGetScalar()`
2433: @*/
2434: PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2435: {
2436: PetscBool imag1;
2437: size_t len;
2438: PetscScalar val = 0.;
2439: char *ptr = NULL;
2441: PetscFunctionBegin;
2442: PetscCall(PetscStrlen(name, &len));
2443: PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
2444: PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
2445: #if PetscDefined(USE_COMPLEX)
2446: if ((size_t)(ptr - name) < len) {
2447: PetscBool imag2;
2448: PetscScalar val2;
2450: PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
2451: if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
2452: val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
2453: }
2454: #endif
2455: PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
2456: *a = val;
2457: PetscFunctionReturn(PETSC_SUCCESS);
2458: }
2460: /*@C
2461: PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
2462: option in the database.
2464: Not Collective
2466: Input Parameters:
2467: + options - options database, use `NULL` for default global database
2468: . pre - the string to prepend to the name or `NULL`
2469: - name - the option one is seeking
2471: Output Parameters:
2472: + ivalue - the logical value to return
2473: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2475: Level: beginner
2477: Notes:
2478: TRUE, true, YES, yes, ON, on, nostring, and 1 all translate to `PETSC_TRUE`
2479: FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_FALSE`
2481: 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`
2482: is equivalent to `-requested_bool true`
2484: If the user does not supply the option at all `ivalue` is NOT changed. Thus
2485: you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
2487: .seealso: `PetscOptionsGetBool3()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2488: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2489: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2490: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2491: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2492: `PetscOptionsFList()`, `PetscOptionsEList()`
2493: @*/
2494: PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2495: {
2496: const char *value;
2497: PetscBool flag;
2499: PetscFunctionBegin;
2500: PetscAssertPointer(name, 3);
2501: if (ivalue) PetscAssertPointer(ivalue, 4);
2502: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2503: if (flag) {
2504: if (set) *set = PETSC_TRUE;
2505: PetscCall(PetscOptionsStringToBool(value, &flag));
2506: if (ivalue) *ivalue = flag;
2507: } else {
2508: if (set) *set = PETSC_FALSE;
2509: }
2510: PetscFunctionReturn(PETSC_SUCCESS);
2511: }
2513: /*@C
2514: PetscOptionsGetBool3 - Gets the ternary logical (true, false or unknown) value for a particular
2515: option in the database.
2517: Not Collective
2519: Input Parameters:
2520: + options - options database, use `NULL` for default global database
2521: . pre - the string to prepend to the name or `NULL`
2522: - name - the option one is seeking
2524: Output Parameters:
2525: + ivalue - the ternary logical value to return
2526: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2528: Level: beginner
2530: Notes:
2531: TRUE, true, YES, yes, ON, on, nostring and 1 all translate to `PETSC_BOOL3_TRUE`
2532: FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_BOOL3_FALSE`
2533: UNKNOWN, unknown, AUTO and auto all translate to `PETSC_BOOL3_UNKNOWN`
2535: 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`
2536: is equivalent to `-requested_bool3 true`
2538: If the user does not supply the option at all `ivalue` is NOT changed. Thus
2539: you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
2541: .seealso: `PetscOptionsGetBool()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2542: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2543: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2544: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2545: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2546: `PetscOptionsFList()`, `PetscOptionsEList()`
2547: @*/
2548: PetscErrorCode PetscOptionsGetBool3(PetscOptions options, const char pre[], const char name[], PetscBool3 *ivalue, PetscBool *set)
2549: {
2550: const char *value;
2551: PetscBool flag;
2553: PetscFunctionBegin;
2554: PetscAssertPointer(name, 3);
2555: if (ivalue) PetscAssertPointer(ivalue, 4);
2556: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2557: if (flag) { // found the option
2558: PetscBool isAUTO = PETSC_FALSE, isUNKNOWN = PETSC_FALSE;
2560: if (set) *set = PETSC_TRUE;
2561: PetscCall(PetscStrcasecmp("AUTO", value, &isAUTO)); // auto or AUTO
2562: if (!isAUTO) PetscCall(PetscStrcasecmp("UNKNOWN", value, &isUNKNOWN)); // unknown or UNKNOWN
2563: if (isAUTO || isUNKNOWN) {
2564: if (ivalue) *ivalue = PETSC_BOOL3_UNKNOWN;
2565: } else { // handle boolean values (if no value is given, it returns true)
2566: PetscCall(PetscOptionsStringToBool(value, &flag));
2567: if (ivalue) *ivalue = PetscBoolToBool3(flag);
2568: }
2569: } else {
2570: if (set) *set = PETSC_FALSE;
2571: }
2572: PetscFunctionReturn(PETSC_SUCCESS);
2573: }
2575: /*@C
2576: PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2578: Not Collective
2580: Input Parameters:
2581: + options - options database, use `NULL` for default global database
2582: . pre - the string to prepend to the name or `NULL`
2583: . opt - option name
2584: . list - the possible choices (one of these must be selected, anything else is invalid)
2585: - ntext - number of choices
2587: Output Parameters:
2588: + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2589: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2591: Level: intermediate
2593: Notes:
2594: If the user does not supply the option `value` is NOT changed. Thus
2595: you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2597: See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2599: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2600: `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2601: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2602: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2603: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2604: `PetscOptionsFList()`, `PetscOptionsEList()`
2605: @*/
2606: PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const list[], PetscInt ntext, PetscInt *value, PetscBool *set)
2607: {
2608: size_t alen, len = 0, tlen = 0;
2609: char *svalue;
2610: PetscBool aset, flg = PETSC_FALSE;
2612: PetscFunctionBegin;
2613: PetscAssertPointer(opt, 3);
2614: for (PetscInt i = 0; i < ntext; i++) {
2615: PetscCall(PetscStrlen(list[i], &alen));
2616: if (alen > len) len = alen;
2617: tlen += len + 1;
2618: }
2619: len += 5; /* a little extra space for user mistypes */
2620: PetscCall(PetscMalloc1(len, &svalue));
2621: PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2622: if (aset) {
2623: PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
2624: if (!flg) {
2625: char *avail;
2627: PetscCall(PetscMalloc1(tlen, &avail));
2628: avail[0] = '\0';
2629: for (PetscInt i = 0; i < ntext; i++) {
2630: PetscCall(PetscStrlcat(avail, list[i], tlen));
2631: PetscCall(PetscStrlcat(avail, " ", tlen));
2632: }
2633: PetscCall(PetscStrtolower(avail));
2634: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option \"%s\" for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
2635: }
2636: if (set) *set = PETSC_TRUE;
2637: } else if (set) *set = PETSC_FALSE;
2638: PetscCall(PetscFree(svalue));
2639: PetscFunctionReturn(PETSC_SUCCESS);
2640: }
2642: /*@C
2643: PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2645: Not Collective
2647: Input Parameters:
2648: + options - options database, use `NULL` for default global database
2649: . pre - option prefix or `NULL`
2650: . opt - option name
2651: - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2653: Output Parameters:
2654: + value - the value to return
2655: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2657: Level: beginner
2659: Notes:
2660: If the user does not supply the option `value` is NOT changed. Thus
2661: you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2663: `list` is usually something like `PCASMTypes` or some other predefined list of enum names
2665: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2666: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2667: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2668: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2669: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2670: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2671: `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2672: @*/
2673: PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const list[], PetscEnum *value, PetscBool *set) PeNSS
2674: {
2675: PetscInt ntext = 0, tval;
2676: PetscBool fset;
2678: PetscFunctionBegin;
2679: PetscAssertPointer(opt, 3);
2680: 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");
2681: PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2682: ntext -= 3;
2683: PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
2684: /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2685: if (fset) *value = (PetscEnum)tval;
2686: if (set) *set = fset;
2687: PetscFunctionReturn(PETSC_SUCCESS);
2688: }
2690: /*@C
2691: PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2693: Not Collective
2695: Input Parameters:
2696: + options - options database, use `NULL` for default global database
2697: . pre - the string to prepend to the name or `NULL`
2698: - name - the option one is seeking
2700: Output Parameters:
2701: + ivalue - the integer value to return
2702: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2704: Level: beginner
2706: Notes:
2707: If the user does not supply the option `ivalue` is NOT changed. Thus
2708: you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
2710: Accepts the special values `determine`, `decide` and `unlimited`.
2712: Accepts the deprecated value `default`.
2714: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2715: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2716: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2717: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2718: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2719: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2720: `PetscOptionsFList()`, `PetscOptionsEList()`
2721: @*/
2722: PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2723: {
2724: const char *value;
2725: PetscBool flag;
2727: PetscFunctionBegin;
2728: PetscAssertPointer(name, 3);
2729: PetscAssertPointer(ivalue, 4);
2730: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2731: if (flag) {
2732: if (!value) {
2733: if (set) *set = PETSC_FALSE;
2734: } else {
2735: if (set) *set = PETSC_TRUE;
2736: PetscCall(PetscOptionsStringToInt(value, ivalue));
2737: }
2738: } else {
2739: if (set) *set = PETSC_FALSE;
2740: }
2741: PetscFunctionReturn(PETSC_SUCCESS);
2742: }
2744: /*@C
2745: PetscOptionsGetMPIInt - Gets the MPI integer value for a particular option in the database.
2747: Not Collective
2749: Input Parameters:
2750: + options - options database, use `NULL` for default global database
2751: . pre - the string to prepend to the name or `NULL`
2752: - name - the option one is seeking
2754: Output Parameters:
2755: + ivalue - the MPI integer value to return
2756: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2758: Level: beginner
2760: Notes:
2761: If the user does not supply the option `ivalue` is NOT changed. Thus
2762: you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
2764: Accepts the special values `determine`, `decide` and `unlimited`.
2766: Accepts the deprecated value `default`.
2768: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2769: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2770: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2771: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2772: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2773: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2774: `PetscOptionsFList()`, `PetscOptionsEList()`
2775: @*/
2776: PetscErrorCode PetscOptionsGetMPIInt(PetscOptions options, const char pre[], const char name[], PetscMPIInt *ivalue, PetscBool *set)
2777: {
2778: PetscInt value;
2779: PetscBool flag;
2781: PetscFunctionBegin;
2782: PetscCall(PetscOptionsGetInt(options, pre, name, &value, &flag));
2783: if (flag) PetscCall(PetscMPIIntCast(value, ivalue));
2784: if (set) *set = flag;
2785: PetscFunctionReturn(PETSC_SUCCESS);
2786: }
2788: /*@C
2789: PetscOptionsGetReal - Gets the double precision value for a particular
2790: option in the database.
2792: Not Collective
2794: Input Parameters:
2795: + options - options database, use `NULL` for default global database
2796: . pre - string to prepend to each name or `NULL`
2797: - name - the option one is seeking
2799: Output Parameters:
2800: + dvalue - the double value to return
2801: - set - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2803: Level: beginner
2805: Notes:
2806: Accepts the special values `determine`, `decide` and `unlimited`.
2808: Accepts the deprecated value `default`
2810: If the user does not supply the option `dvalue` is NOT changed. Thus
2811: you should ALWAYS initialize `dvalue` if you access it without first checking that the `set` flag is true.
2813: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2814: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2815: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2816: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2817: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2818: `PetscOptionsFList()`, `PetscOptionsEList()`
2819: @*/
2820: PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2821: {
2822: const char *value;
2823: PetscBool flag;
2825: PetscFunctionBegin;
2826: PetscAssertPointer(name, 3);
2827: PetscAssertPointer(dvalue, 4);
2828: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2829: if (flag) {
2830: if (!value) {
2831: if (set) *set = PETSC_FALSE;
2832: } else {
2833: if (set) *set = PETSC_TRUE;
2834: PetscCall(PetscOptionsStringToReal(value, dvalue));
2835: }
2836: } else {
2837: if (set) *set = PETSC_FALSE;
2838: }
2839: PetscFunctionReturn(PETSC_SUCCESS);
2840: }
2842: /*@C
2843: PetscOptionsGetScalar - Gets the scalar value for a particular
2844: option in the database.
2846: Not Collective
2848: Input Parameters:
2849: + options - options database, use `NULL` for default global database
2850: . pre - string to prepend to each name or `NULL`
2851: - name - the option one is seeking
2853: Output Parameters:
2854: + dvalue - the scalar value to return
2855: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2857: Level: beginner
2859: Example Usage:
2860: A complex number 2+3i must be specified with NO spaces
2862: Note:
2863: If the user does not supply the option `dvalue` is NOT changed. Thus
2864: you should ALWAYS initialize `dvalue` if you access it without first checking if the `set` flag is true.
2866: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2867: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2868: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2869: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2870: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2871: `PetscOptionsFList()`, `PetscOptionsEList()`
2872: @*/
2873: PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2874: {
2875: const char *value;
2876: PetscBool flag;
2878: PetscFunctionBegin;
2879: PetscAssertPointer(name, 3);
2880: PetscAssertPointer(dvalue, 4);
2881: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2882: if (flag) {
2883: if (!value) {
2884: if (set) *set = PETSC_FALSE;
2885: } else {
2886: #if !PetscDefined(USE_COMPLEX)
2887: PetscCall(PetscOptionsStringToReal(value, dvalue));
2888: #else
2889: PetscCall(PetscOptionsStringToScalar(value, dvalue));
2890: #endif
2891: if (set) *set = PETSC_TRUE;
2892: }
2893: } else { /* flag */
2894: if (set) *set = PETSC_FALSE;
2895: }
2896: PetscFunctionReturn(PETSC_SUCCESS);
2897: }
2899: /*@C
2900: PetscOptionsGetString - Gets the string value for a particular option in
2901: the database.
2903: Not Collective
2905: Input Parameters:
2906: + options - options database, use `NULL` for default global database
2907: . pre - string to prepend to name or `NULL`
2908: . name - the option one is seeking
2909: - len - maximum length of the string including null termination
2911: Output Parameters:
2912: + string - location to copy string
2913: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2915: Level: beginner
2917: Note:
2918: 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`
2920: If the user does not use the option then `string` is not changed. Thus
2921: you should ALWAYS initialize `string` if you access it without first checking that the `set` flag is true.
2923: Fortran Notes:
2924: The Fortran interface is slightly different from the C/C++
2925: interface. Sample usage in Fortran follows
2926: .vb
2927: character *20 string
2928: PetscErrorCode ierr
2929: PetscBool set
2930: call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2931: .ve
2933: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2934: `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2935: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2936: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2937: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2938: `PetscOptionsFList()`, `PetscOptionsEList()`
2939: @*/
2940: PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set) PeNS
2941: {
2942: const char *value;
2943: PetscBool flag;
2945: PetscFunctionBegin;
2946: PetscAssertPointer(name, 3);
2947: PetscAssertPointer(string, 4);
2948: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2949: if (!flag) {
2950: if (set) *set = PETSC_FALSE;
2951: } else {
2952: if (set) *set = PETSC_TRUE;
2953: if (value) PetscCall(PetscStrncpy(string, value, len));
2954: else PetscCall(PetscArrayzero(string, len));
2955: }
2956: PetscFunctionReturn(PETSC_SUCCESS);
2957: }
2959: /*@C
2960: PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2961: option in the database. The values must be separated with commas with no intervening spaces.
2963: Not Collective
2965: Input Parameters:
2966: + options - options database, use `NULL` for default global database
2967: . pre - string to prepend to each name or `NULL`
2968: - name - the option one is seeking
2970: Output Parameters:
2971: + dvalue - the Boolean values to return
2972: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2973: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2975: Level: beginner
2977: Note:
2978: TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`. FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
2980: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2981: `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2982: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2983: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2984: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2985: `PetscOptionsFList()`, `PetscOptionsEList()`
2986: @*/
2987: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2988: {
2989: const char *svalue;
2990: const char *value;
2991: PetscInt n = 0;
2992: PetscBool flag;
2993: PetscToken token;
2995: PetscFunctionBegin;
2996: PetscAssertPointer(name, 3);
2997: PetscAssertPointer(nmax, 5);
2998: if (*nmax) PetscAssertPointer(dvalue, 4);
3000: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3001: if (!flag || !svalue) {
3002: if (set) *set = PETSC_FALSE;
3003: *nmax = 0;
3004: PetscFunctionReturn(PETSC_SUCCESS);
3005: }
3006: if (set) *set = PETSC_TRUE;
3007: PetscCall(PetscTokenCreate(svalue, ',', &token));
3008: PetscCall(PetscTokenFind(token, &value));
3009: while (value && n < *nmax) {
3010: PetscCall(PetscOptionsStringToBool(value, dvalue));
3011: PetscCall(PetscTokenFind(token, &value));
3012: dvalue++;
3013: n++;
3014: }
3015: PetscCall(PetscTokenDestroy(&token));
3016: *nmax = n;
3017: PetscFunctionReturn(PETSC_SUCCESS);
3018: }
3020: /*@C
3021: PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
3023: Not Collective
3025: Input Parameters:
3026: + options - options database, use `NULL` for default global database
3027: . pre - option prefix or `NULL`
3028: . name - option name
3029: - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
3031: Output Parameters:
3032: + ivalue - the enum values to return
3033: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3034: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3036: Level: beginner
3038: Notes:
3039: The array must be passed as a comma separated list with no spaces between the items.
3041: `list` is usually something like `PCASMTypes` or some other predefined list of enum names.
3043: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
3044: `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3045: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsName()`,
3046: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
3047: `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3048: `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
3049: @*/
3050: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const list[], PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
3051: {
3052: const char *svalue;
3053: const char *value;
3054: PetscInt n = 0;
3055: PetscEnum evalue;
3056: PetscBool flag;
3057: PetscToken token;
3059: PetscFunctionBegin;
3060: PetscAssertPointer(name, 3);
3061: PetscAssertPointer(list, 4);
3062: PetscAssertPointer(nmax, 6);
3063: if (*nmax) PetscAssertPointer(ivalue, 5);
3065: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3066: if (!flag || !svalue) {
3067: if (set) *set = PETSC_FALSE;
3068: *nmax = 0;
3069: PetscFunctionReturn(PETSC_SUCCESS);
3070: }
3071: if (set) *set = PETSC_TRUE;
3072: PetscCall(PetscTokenCreate(svalue, ',', &token));
3073: PetscCall(PetscTokenFind(token, &value));
3074: while (value && n < *nmax) {
3075: PetscCall(PetscEnumFind(list, value, &evalue, &flag));
3076: PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
3077: ivalue[n++] = evalue;
3078: PetscCall(PetscTokenFind(token, &value));
3079: }
3080: PetscCall(PetscTokenDestroy(&token));
3081: *nmax = n;
3082: PetscFunctionReturn(PETSC_SUCCESS);
3083: }
3085: /*@C
3086: PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
3088: Not Collective
3090: Input Parameters:
3091: + options - options database, use `NULL` for default global database
3092: . pre - string to prepend to each name or `NULL`
3093: - name - the option one is seeking
3095: Output Parameters:
3096: + ivalue - the integer values to return
3097: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3098: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3100: Level: beginner
3102: Notes:
3103: The array can be passed as
3104: + a comma separated list - 0,1,2,3,4,5,6,7
3105: . a range (start\-end+1) - 0-8
3106: . a range with given increment (start\-end+1:inc) - 0-7:2
3107: - a combination of values and ranges separated by commas - 0,1-8,8-15:2
3109: There must be no intervening spaces between the values.
3111: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3112: `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3113: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3114: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3115: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3116: `PetscOptionsFList()`, `PetscOptionsEList()`
3117: @*/
3118: PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
3119: {
3120: const char *svalue;
3121: const char *value;
3122: PetscInt n = 0, i, j, start, end, inc, nvalues;
3123: size_t len;
3124: PetscBool flag, foundrange;
3125: PetscToken token;
3127: PetscFunctionBegin;
3128: PetscAssertPointer(name, 3);
3129: PetscAssertPointer(nmax, 5);
3130: if (*nmax) PetscAssertPointer(ivalue, 4);
3132: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3133: if (!flag || !svalue) {
3134: if (set) *set = PETSC_FALSE;
3135: *nmax = 0;
3136: PetscFunctionReturn(PETSC_SUCCESS);
3137: }
3138: if (set) *set = PETSC_TRUE;
3139: PetscCall(PetscTokenCreate(svalue, ',', &token));
3140: PetscCall(PetscTokenFind(token, &value));
3141: while (value && n < *nmax) {
3142: char *iivalue;
3144: /* look for form d-D where d and D are integers */
3145: PetscCall(PetscStrallocpy(value, &iivalue));
3146: foundrange = PETSC_FALSE;
3147: PetscCall(PetscStrlen(iivalue, &len));
3148: if (iivalue[0] == '-') i = 2;
3149: else i = 1;
3150: for (; i < (int)len; i++) {
3151: if (iivalue[i] == '-') {
3152: PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, iivalue);
3153: iivalue[i] = 0;
3155: PetscCall(PetscOptionsStringToInt(iivalue, &start));
3156: inc = 1;
3157: j = i + 1;
3158: for (; j < (int)len; j++) {
3159: if (iivalue[j] == ':') {
3160: iivalue[j] = 0;
3162: PetscCall(PetscOptionsStringToInt(iivalue + j + 1, &inc));
3163: 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);
3164: break;
3165: }
3166: }
3167: PetscCall(PetscOptionsStringToInt(iivalue + i + 1, &end));
3168: 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);
3169: nvalues = (end - start) / inc + (end - start) % inc;
3170: 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);
3171: for (; start < end; start += inc) {
3172: *ivalue = start;
3173: ivalue++;
3174: n++;
3175: }
3176: foundrange = PETSC_TRUE;
3177: break;
3178: }
3179: }
3180: if (!foundrange) {
3181: PetscCall(PetscOptionsStringToInt(value, ivalue));
3182: ivalue++;
3183: n++;
3184: }
3185: PetscCall(PetscFree(iivalue));
3186: PetscCall(PetscTokenFind(token, &value));
3187: }
3188: PetscCall(PetscTokenDestroy(&token));
3189: *nmax = n;
3190: PetscFunctionReturn(PETSC_SUCCESS);
3191: }
3193: /*@C
3194: PetscOptionsGetRealArray - Gets an array of double precision values for a
3195: particular option in the database. The values must be separated with commas with no intervening spaces.
3197: Not Collective
3199: Input Parameters:
3200: + options - options database, use `NULL` for default global database
3201: . pre - string to prepend to each name or `NULL`
3202: - name - the option one is seeking
3204: Output Parameters:
3205: + dvalue - the double values to return
3206: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3207: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3209: Level: beginner
3211: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3212: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3213: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3214: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3215: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3216: `PetscOptionsFList()`, `PetscOptionsEList()`
3217: @*/
3218: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
3219: {
3220: const char *svalue;
3221: const char *value;
3222: PetscInt n = 0;
3223: PetscBool flag;
3224: PetscToken token;
3226: PetscFunctionBegin;
3227: PetscAssertPointer(name, 3);
3228: PetscAssertPointer(nmax, 5);
3229: if (*nmax) PetscAssertPointer(dvalue, 4);
3231: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3232: if (!flag || !svalue) {
3233: if (set) *set = PETSC_FALSE;
3234: *nmax = 0;
3235: PetscFunctionReturn(PETSC_SUCCESS);
3236: }
3237: if (set) *set = PETSC_TRUE;
3238: PetscCall(PetscTokenCreate(svalue, ',', &token));
3239: PetscCall(PetscTokenFind(token, &value));
3240: while (value && n < *nmax) {
3241: PetscCall(PetscOptionsStringToReal(value, dvalue++));
3242: PetscCall(PetscTokenFind(token, &value));
3243: n++;
3244: }
3245: PetscCall(PetscTokenDestroy(&token));
3246: *nmax = n;
3247: PetscFunctionReturn(PETSC_SUCCESS);
3248: }
3250: /*@C
3251: PetscOptionsGetScalarArray - Gets an array of scalars for a
3252: particular option in the database. The values must be separated with commas with no intervening spaces.
3254: Not Collective
3256: Input Parameters:
3257: + options - options database, use `NULL` for default global database
3258: . pre - string to prepend to each name or `NULL`
3259: - name - the option one is seeking
3261: Output Parameters:
3262: + dvalue - the scalar values to return
3263: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3264: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3266: Level: beginner
3268: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3269: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3270: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3271: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3272: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3273: `PetscOptionsFList()`, `PetscOptionsEList()`
3274: @*/
3275: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3276: {
3277: const char *svalue;
3278: const char *value;
3279: PetscInt n = 0;
3280: PetscBool flag;
3281: PetscToken token;
3283: PetscFunctionBegin;
3284: PetscAssertPointer(name, 3);
3285: PetscAssertPointer(nmax, 5);
3286: if (*nmax) PetscAssertPointer(dvalue, 4);
3288: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3289: if (!flag || !svalue) {
3290: if (set) *set = PETSC_FALSE;
3291: *nmax = 0;
3292: PetscFunctionReturn(PETSC_SUCCESS);
3293: }
3294: if (set) *set = PETSC_TRUE;
3295: PetscCall(PetscTokenCreate(svalue, ',', &token));
3296: PetscCall(PetscTokenFind(token, &value));
3297: while (value && n < *nmax) {
3298: PetscCall(PetscOptionsStringToScalar(value, dvalue++));
3299: PetscCall(PetscTokenFind(token, &value));
3300: n++;
3301: }
3302: PetscCall(PetscTokenDestroy(&token));
3303: *nmax = n;
3304: PetscFunctionReturn(PETSC_SUCCESS);
3305: }
3307: /*@C
3308: PetscOptionsGetStringArray - Gets an array of string values for a particular
3309: option in the database. The values must be separated with commas with no intervening spaces.
3311: Not Collective; No Fortran Support
3313: Input Parameters:
3314: + options - options database, use `NULL` for default global database
3315: . pre - string to prepend to name or `NULL`
3316: - name - the option one is seeking
3318: Output Parameters:
3319: + strings - location to copy strings
3320: . nmax - On input maximum number of strings, on output the actual number of strings found
3321: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3323: Level: beginner
3325: Notes:
3326: The `nmax` parameter is used for both input and output.
3328: The user should pass in an array of pointers to `char`, to hold all the
3329: strings returned by this function.
3331: The user is responsible for deallocating the strings that are
3332: returned.
3334: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3335: `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3336: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3337: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3338: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3339: `PetscOptionsFList()`, `PetscOptionsEList()`
3340: @*/
3341: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set) PeNS
3342: {
3343: const char *svalue;
3344: const char *value;
3345: PetscInt n = 0;
3346: PetscBool flag;
3347: PetscToken token;
3349: PetscFunctionBegin;
3350: PetscAssertPointer(name, 3);
3351: PetscAssertPointer(nmax, 5);
3352: if (*nmax) PetscAssertPointer(strings, 4);
3354: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3355: if (!flag || !svalue) {
3356: if (set) *set = PETSC_FALSE;
3357: *nmax = 0;
3358: PetscFunctionReturn(PETSC_SUCCESS);
3359: }
3360: if (set) *set = PETSC_TRUE;
3361: PetscCall(PetscTokenCreate(svalue, ',', &token));
3362: PetscCall(PetscTokenFind(token, &value));
3363: while (value && n < *nmax) {
3364: PetscCall(PetscStrallocpy(value, &strings[n]));
3365: PetscCall(PetscTokenFind(token, &value));
3366: n++;
3367: }
3368: PetscCall(PetscTokenDestroy(&token));
3369: *nmax = n;
3370: PetscFunctionReturn(PETSC_SUCCESS);
3371: }
3373: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3374: {
3375: PetscBool found, quiet;
3376: const char *value;
3377: const char *const quietopt = "-options_suppress_deprecated_warnings";
3378: char msg[4096];
3379: char *prefix = NULL;
3380: PetscOptions options = NULL;
3381: MPI_Comm comm = PETSC_COMM_SELF;
3383: PetscFunctionBegin;
3384: PetscAssertPointer(oldname, 2);
3385: PetscAssertPointer(version, 4);
3386: if (PetscOptionsObject) {
3387: prefix = PetscOptionsObject->prefix;
3388: options = PetscOptionsObject->options;
3389: comm = PetscOptionsObject->comm;
3390: }
3391: PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
3392: if (found) {
3393: if (newname) {
3394: PetscBool newfound;
3396: /* do not overwrite if the new option has been provided */
3397: PetscCall(PetscOptionsFindPair(options, prefix, newname, NULL, &newfound));
3398: if (!newfound) {
3399: if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
3400: PetscCall(PetscOptionsSetValue(options, newname, value));
3401: if (prefix) PetscCall(PetscOptionsPrefixPop(options));
3402: }
3403: PetscCall(PetscOptionsClearValue(options, oldname));
3404: }
3405: quiet = PETSC_FALSE;
3406: PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
3407: if (!quiet) {
3408: PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option -", sizeof(msg)));
3409: PetscCall(PetscStrlcat(msg, prefix, sizeof(msg)));
3410: PetscCall(PetscStrlcat(msg, oldname + 1, sizeof(msg)));
3411: PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3412: PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
3413: PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
3414: if (newname) {
3415: PetscCall(PetscStrlcat(msg, " Use the option -", sizeof(msg)));
3416: PetscCall(PetscStrlcat(msg, prefix, sizeof(msg)));
3417: PetscCall(PetscStrlcat(msg, newname + 1, sizeof(msg)));
3418: PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
3419: }
3420: if (info) {
3421: PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3422: PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
3423: }
3424: PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3425: PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3426: PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
3427: PetscCall(PetscPrintf(comm, "%s", msg));
3428: }
3429: }
3430: PetscFunctionReturn(PETSC_SUCCESS);
3431: }