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 defined(PETSC_HAVE_MALLOC_H)
16: #include <malloc.h>
17: #endif
18: #if defined(PETSC_HAVE_STRINGS_H)
19: #include <strings.h> /* strcasecmp */
20: #endif
22: #if defined(PETSC_HAVE_STRCASECMP)
23: #define PetscOptNameCmp(a, b) strcasecmp(a, b)
24: #elif defined(PETSC_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: MPI_Comm comm = PETSC_COMM_WORLD;
681: int left = PetscMax(argc, 0);
682: const char *const *eargs = args;
684: PetscFunctionBegin;
685: while (left) {
686: PetscBool isfile, isfileyaml, isstringyaml, ispush, ispop, key;
687: PetscCall(PetscStrcasecmp(eargs[0], "-options_file", &isfile));
688: PetscCall(PetscStrcasecmp(eargs[0], "-options_file_yaml", &isfileyaml));
689: PetscCall(PetscStrcasecmp(eargs[0], "-options_string_yaml", &isstringyaml));
690: PetscCall(PetscStrcasecmp(eargs[0], "-prefix_push", &ispush));
691: PetscCall(PetscStrcasecmp(eargs[0], "-prefix_pop", &ispop));
692: PetscCall(PetscOptionsValidKey(eargs[0], &key));
693: if (!key) {
694: eargs++;
695: left--;
696: } else if (isfile) {
697: PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file filename option");
698: PetscCall(PetscOptionsInsertFile(comm, options, eargs[1], PETSC_TRUE));
699: eargs += 2;
700: left -= 2;
701: } else if (isfileyaml) {
702: PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing filename for -options_file_yaml filename option");
703: PetscCall(PetscOptionsInsertFileYAML(comm, options, eargs[1], PETSC_TRUE));
704: eargs += 2;
705: left -= 2;
706: } else if (isstringyaml) {
707: PetscCheck(left > 1 && eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing string for -options_string_yaml string option");
708: PetscCall(PetscOptionsInsertStringYAML_Private(options, eargs[1], PETSC_OPT_CODE));
709: eargs += 2;
710: left -= 2;
711: } else if (ispush) {
712: PetscCheck(left > 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option");
713: PetscCheck(eargs[1][0] != '-', PETSC_COMM_SELF, PETSC_ERR_USER, "Missing prefix for -prefix_push option (prefixes cannot start with '-')");
714: PetscCall(PetscOptionsPrefixPush(options, eargs[1]));
715: eargs += 2;
716: left -= 2;
717: } else if (ispop) {
718: PetscCall(PetscOptionsPrefixPop(options));
719: eargs++;
720: left--;
721: } else {
722: PetscBool nextiskey = PETSC_FALSE;
723: if (left >= 2) PetscCall(PetscOptionsValidKey(eargs[1], &nextiskey));
724: if (left < 2 || nextiskey) {
725: PetscCall(PetscOptionsSetValue_Private(options, eargs[0], NULL, NULL, PETSC_OPT_COMMAND_LINE));
726: eargs++;
727: left--;
728: } else {
729: PetscCall(PetscOptionsSetValue_Private(options, eargs[0], eargs[1], NULL, PETSC_OPT_COMMAND_LINE));
730: eargs += 2;
731: left -= 2;
732: }
733: }
734: }
735: PetscFunctionReturn(PETSC_SUCCESS);
736: }
738: static inline PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt, const char *val[], const PetscBool set[], PetscBool *flg)
739: {
740: PetscFunctionBegin;
741: if (set[opt]) PetscCall(PetscOptionsStringToBool(val[opt], flg));
742: else *flg = PETSC_FALSE;
743: PetscFunctionReturn(PETSC_SUCCESS);
744: }
746: /* Process options with absolute precedence, these are only processed from the command line, not the environment or files */
747: static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options, int argc, char *args[], PetscBool *skip_petscrc, PetscBool *skip_petscrc_set)
748: {
749: const char *const *opt = precedentOptions;
750: const size_t n = PO_NUM;
751: size_t o;
752: int a;
753: const char **val;
754: char **cval;
755: PetscBool *set, unneeded;
757: PetscFunctionBegin;
758: PetscCall(PetscCalloc2(n, &cval, n, &set));
759: val = (const char **)cval;
761: /* Look for options possibly set using PetscOptionsSetValue beforehand */
762: for (o = 0; o < n; o++) PetscCall(PetscOptionsFindPair(options, NULL, opt[o], &val[o], &set[o]));
764: /* Loop through all args to collect last occurring value of each option */
765: for (a = 1; a < argc; a++) {
766: PetscBool valid, eq;
768: PetscCall(PetscOptionsValidKey(args[a], &valid));
769: if (!valid) continue;
770: for (o = 0; o < n; o++) {
771: PetscCall(PetscStrcasecmp(args[a], opt[o], &eq));
772: if (eq) {
773: set[o] = PETSC_TRUE;
774: if (a == argc - 1 || !args[a + 1] || !args[a + 1][0] || args[a + 1][0] == '-') val[o] = NULL;
775: else val[o] = args[a + 1];
776: break;
777: }
778: }
779: }
781: /* Process flags */
782: PetscCall(PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro));
783: if (options->help_intro) options->help = PETSC_TRUE;
784: else PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_HELP, val, set, &options->help));
785: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_CI_ENABLE, val, set, &unneeded));
786: /* need to manage PO_CI_ENABLE option before the PetscOptionsMonitor is turned on, so its setting is not monitored */
787: if (set[PO_CI_ENABLE]) PetscCall(PetscOptionsSetValue_Private(options, opt[PO_CI_ENABLE], val[PO_CI_ENABLE], &a, PETSC_OPT_COMMAND_LINE));
788: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL, val, set, &options->monitorCancel));
789: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val, set, &options->monitorFromOptions));
790: PetscCall(PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val, set, skip_petscrc));
791: *skip_petscrc_set = set[PO_SKIP_PETSCRC];
793: /* Store precedent options in database and mark them as used */
794: for (o = 1; o < n; o++) {
795: if (set[o]) {
796: PetscCall(PetscOptionsSetValue_Private(options, opt[o], val[o], &a, PETSC_OPT_COMMAND_LINE));
797: options->used[a] = PETSC_TRUE;
798: }
799: }
800: PetscCall(PetscFree2(cval, set));
801: options->precedentProcessed = PETSC_TRUE;
802: PetscFunctionReturn(PETSC_SUCCESS);
803: }
805: static inline PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options, const char name[], PetscBool *flg)
806: {
807: PetscFunctionBegin;
808: PetscAssertPointer(flg, 3);
809: *flg = PETSC_FALSE;
810: if (options->precedentProcessed) {
811: for (int i = 0; i < PO_NUM; ++i) {
812: if (!PetscOptNameCmp(precedentOptions[i], name)) {
813: /* check if precedent option has been set already */
814: PetscCall(PetscOptionsFindPair(options, NULL, name, NULL, flg));
815: if (*flg) break;
816: }
817: }
818: }
819: PetscFunctionReturn(PETSC_SUCCESS);
820: }
822: /*@C
823: PetscOptionsInsert - Inserts into the options database from the command line,
824: the environmental variable and a file.
826: Collective on `PETSC_COMM_WORLD`
828: Input Parameters:
829: + options - options database or `NULL` for the default global database
830: . argc - count of number of command line arguments
831: . args - the command line arguments
832: - file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
833: Use `NULL` or empty string to not check for code specific file.
834: Also checks ~/.petscrc, .petscrc and petscrc.
835: Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
837: Options Database Keys:
838: + -options_file filename - read options from a file
839: - -options_file_yaml filename - read options from a YAML file
841: Level: advanced
843: Notes:
844: Since `PetscOptionsInsert()` is automatically called by `PetscInitialize()`,
845: the user does not typically need to call this routine. `PetscOptionsInsert()`
846: can be called several times, adding additional entries into the database.
848: See `PetscInitialize()` for options related to option database monitoring.
850: .seealso: `PetscOptionsDestroy()`, `PetscOptionsView()`, `PetscOptionsInsertString()`, `PetscOptionsInsertFile()`,
851: `PetscInitialize()`
852: @*/
853: PetscErrorCode PetscOptionsInsert(PetscOptions options, int *argc, char ***args, const char file[]) PeNS
854: {
855: MPI_Comm comm = PETSC_COMM_WORLD;
856: PetscMPIInt rank;
857: PetscBool hasArgs = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
858: PetscBool skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
859: char *eoptions = NULL;
860: size_t len = 0;
862: PetscFunctionBegin;
863: PetscCheck(!hasArgs || (args && *args), comm, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
864: PetscCallMPI(MPI_Comm_rank(comm, &rank));
866: if (!options) {
867: PetscCall(PetscOptionsCreateDefault());
868: options = defaultoptions;
869: }
870: if (hasArgs) {
871: /* process options with absolute precedence */
872: PetscCall(PetscOptionsProcessPrecedentFlags(options, *argc, *args, &skipPetscrc, &skipPetscrcSet));
873: PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci", &PetscCIEnabled, NULL));
874: }
875: if (file && file[0]) {
876: PetscCall(PetscOptionsInsertFile(comm, options, file, PETSC_TRUE));
877: /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
878: if (!skipPetscrcSet) PetscCall(PetscOptionsGetBool(options, NULL, "-skip_petscrc", &skipPetscrc, NULL));
879: }
880: if (!skipPetscrc) {
881: char filename[PETSC_MAX_PATH_LEN];
883: PetscCall(PetscGetHomeDirectory(filename, sizeof(filename)));
884: PetscCallMPI(MPI_Bcast(filename, (int)sizeof(filename), MPI_CHAR, 0, comm));
885: if (filename[0]) PetscCall(PetscStrlcat(filename, "/.petscrc", sizeof(filename)));
886: PetscCall(PetscOptionsInsertFile(comm, options, filename, PETSC_FALSE));
887: PetscCall(PetscOptionsInsertFile(comm, options, ".petscrc", PETSC_FALSE));
888: PetscCall(PetscOptionsInsertFile(comm, options, "petscrc", PETSC_FALSE));
889: }
891: /* insert environment options */
892: if (rank == 0) {
893: eoptions = getenv("PETSC_OPTIONS");
894: PetscCall(PetscStrlen(eoptions, &len));
895: }
896: PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
897: if (len) {
898: if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
899: PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, comm));
900: if (rank) eoptions[len] = 0;
901: PetscCall(PetscOptionsInsertString_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
902: if (rank) PetscCall(PetscFree(eoptions));
903: }
905: /* insert YAML environment options */
906: if (rank == 0) {
907: eoptions = getenv("PETSC_OPTIONS_YAML");
908: PetscCall(PetscStrlen(eoptions, &len));
909: }
910: PetscCallMPI(MPI_Bcast(&len, 1, MPIU_SIZE_T, 0, comm));
911: if (len) {
912: if (rank) PetscCall(PetscMalloc1(len + 1, &eoptions));
913: PetscCallMPI(MPI_Bcast(eoptions, (PetscMPIInt)len, MPI_CHAR, 0, comm));
914: if (rank) eoptions[len] = 0;
915: PetscCall(PetscOptionsInsertStringYAML_Private(options, eoptions, PETSC_OPT_ENVIRONMENT));
916: if (rank) PetscCall(PetscFree(eoptions));
917: }
919: /* insert command line options here because they take precedence over arguments in petscrc/environment */
920: if (hasArgs) PetscCall(PetscOptionsInsertArgs(options, *argc - 1, (const char *const *)*args + 1));
921: PetscCall(PetscOptionsGetBool(NULL, NULL, "-petsc_ci_portable_error_output", &PetscCIEnabledPortableErrorOutput, NULL));
922: PetscFunctionReturn(PETSC_SUCCESS);
923: }
925: /* These options are not printed with PetscOptionsView() or PetscOptionsMonitor() when PetscCIEnabled is on */
926: /* TODO: get the list from the test harness, do not have it hardwired here. Maybe from gmakegentest.py */
927: 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"};
929: static PetscBool PetscCIOption(const char *name)
930: {
931: PetscInt idx;
932: PetscBool found;
934: if (!PetscCIEnabled) return PETSC_FALSE;
935: PetscCallAbort(PETSC_COMM_SELF, PetscEListFind(PETSC_STATIC_ARRAY_LENGTH(PetscCIOptions), PetscCIOptions, name, &idx, &found));
936: return found;
937: }
939: /*@
940: PetscOptionsView - Prints the options that have been loaded. This is
941: useful for debugging purposes.
943: Logically Collective, No Fortran Support
945: Input Parameters:
946: + options - options database, use `NULL` for default global database
947: - viewer - must be an `PETSCVIEWERASCII` viewer
949: Options Database Key:
950: . -options_view - Activates `PetscOptionsView()` within `PetscFinalize()`
952: Level: advanced
954: Note:
955: Only the MPI rank 0 of the `MPI_Comm` used to create view prints the option values. Other processes
956: may have different values but they are not printed.
958: .seealso: `PetscOptionsAllUsed()`
959: @*/
960: PetscErrorCode PetscOptionsView(PetscOptions options, PetscViewer viewer)
961: {
962: PetscInt i, N = 0;
963: PetscBool isascii;
965: PetscFunctionBegin;
967: options = options ? options : defaultoptions;
968: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
969: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
970: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only supports ASCII viewer");
972: for (i = 0; i < options->N; i++) {
973: if (PetscCIOption(options->names[i])) continue;
974: N++;
975: }
977: if (!N) {
978: PetscCall(PetscViewerASCIIPrintf(viewer, "#No PETSc Option Table entries\n"));
979: PetscFunctionReturn(PETSC_SUCCESS);
980: }
982: PetscCall(PetscViewerASCIIPrintf(viewer, "#PETSc Option Table entries:\n"));
983: for (i = 0; i < options->N; i++) {
984: if (PetscCIOption(options->names[i])) continue;
985: if (options->values[i]) {
986: PetscCall(PetscViewerASCIIPrintf(viewer, "-%s %s", options->names[i], options->values[i]));
987: } else {
988: PetscCall(PetscViewerASCIIPrintf(viewer, "-%s", options->names[i]));
989: }
990: PetscCall(PetscViewerASCIIPrintf(viewer, " # (source: %s)\n", PetscOptionSources[options->source[i]]));
991: }
992: PetscCall(PetscViewerASCIIPrintf(viewer, "#End of PETSc Option Table entries\n"));
993: PetscFunctionReturn(PETSC_SUCCESS);
994: }
996: /*@
997: PetscOptionsLeftError - Prints a warning listing any options in the default database that were never used
999: Not Collective
1001: Level: developer
1003: Note:
1004: This is intended for use inside PETSc error handlers. Unused options may indicate a program that crashed before it
1005: read them, a spelling mistake, or an option intended for a different context.
1007: .seealso: `PetscOptionsLeft()`, `PetscOptionsAllUsed()`, `PetscOptionsView()`
1008: @*/
1009: PetscErrorCode PetscOptionsLeftError(void)
1010: {
1011: PetscInt i, nopt = 0;
1013: for (i = 0; i < defaultoptions->N; i++) {
1014: if (!defaultoptions->used[i]) {
1015: if (PetscCIOption(defaultoptions->names[i])) continue;
1016: nopt++;
1017: }
1018: }
1019: if (nopt) {
1020: PetscCall((*PetscErrorPrintf)("WARNING! There are unused option(s) set! Could be the program crashed before usage or a spelling mistake, etc!\n"));
1021: for (i = 0; i < defaultoptions->N; i++) {
1022: if (!defaultoptions->used[i]) {
1023: if (PetscCIOption(defaultoptions->names[i])) continue;
1024: 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]]));
1025: else PetscCall((*PetscErrorPrintf)(" Option left: name:-%s (no value) source: %s\n", defaultoptions->names[i], PetscOptionSources[defaultoptions->source[i]]));
1026: }
1027: }
1028: }
1029: return PETSC_SUCCESS;
1030: }
1032: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
1033: {
1034: PetscInt i, N = 0;
1035: PetscOptions options = defaultoptions;
1037: for (i = 0; i < options->N; i++) {
1038: if (PetscCIOption(options->names[i])) continue;
1039: N++;
1040: }
1042: if (N) {
1043: PetscCall((*PetscErrorPrintf)("PETSc Option Table entries:\n"));
1044: } else {
1045: PetscCall((*PetscErrorPrintf)("No PETSc Option Table entries\n"));
1046: }
1047: for (i = 0; i < options->N; i++) {
1048: if (PetscCIOption(options->names[i])) continue;
1049: if (options->values[i]) {
1050: PetscCall((*PetscErrorPrintf)("-%s %s (source: %s)\n", options->names[i], options->values[i], PetscOptionSources[options->source[i]]));
1051: } else {
1052: PetscCall((*PetscErrorPrintf)("-%s (source: %s)\n", options->names[i], PetscOptionSources[options->source[i]]));
1053: }
1054: }
1055: return PETSC_SUCCESS;
1056: }
1058: /*@
1059: PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
1061: Logically Collective
1063: Input Parameters:
1064: + options - options database, or `NULL` for the default global database
1065: - prefix - The string to append to the existing prefix
1067: Options Database Keys:
1068: + -prefix_push some_prefix_ - push the given prefix
1069: - -prefix_pop - pop the last prefix
1071: Level: advanced
1073: Notes:
1074: It is common to use this in conjunction with `-options_file` as in
1075: .vb
1076: -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
1077: .ve
1078: where the files no longer require all options to be prefixed with `-system2_`.
1080: The collectivity of this routine is complex; only the MPI processes that call this routine will
1081: have the affect of these options. If some processes that create objects call this routine and others do
1082: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1083: on different ranks.
1085: .seealso: `PetscOptionsPrefixPop()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
1086: @*/
1087: PetscErrorCode PetscOptionsPrefixPush(PetscOptions options, const char prefix[])
1088: {
1089: size_t n;
1090: PetscInt start;
1091: char key[PETSC_MAX_OPTION_NAME + 1];
1092: PetscBool valid;
1094: PetscFunctionBegin;
1095: PetscAssertPointer(prefix, 2);
1096: options = options ? options : defaultoptions;
1097: 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);
1098: key[0] = '-'; /* keys must start with '-' */
1099: PetscCall(PetscStrncpy(key + 1, prefix, sizeof(key) - 1));
1100: PetscCall(PetscOptionsValidKey(key, &valid));
1101: if (!valid && options->prefixind > 0 && isdigit((int)prefix[0])) valid = PETSC_TRUE; /* If the prefix stack is not empty, make numbers a valid prefix */
1102: 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" : "");
1103: start = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
1104: PetscCall(PetscStrlen(prefix, &n));
1105: PetscCheck(n + 1 <= sizeof(options->prefix) - start, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Maximum prefix length %zu exceeded", sizeof(options->prefix));
1106: PetscCall(PetscArraycpy(options->prefix + start, prefix, n + 1));
1107: options->prefixstack[options->prefixind++] = (int)(start + n);
1108: PetscFunctionReturn(PETSC_SUCCESS);
1109: }
1111: /*@
1112: PetscOptionsPrefixPop - Remove the latest options prefix, see `PetscOptionsPrefixPush()` for details
1114: Logically Collective on the `MPI_Comm` used when called `PetscOptionsPrefixPush()`
1116: Input Parameter:
1117: . options - options database, or `NULL` for the default global database
1119: Level: advanced
1121: .seealso: `PetscOptionsPrefixPush()`, `PetscOptionsPush()`, `PetscOptionsPop()`, `PetscOptionsCreate()`, `PetscOptionsSetValue()`
1122: @*/
1123: PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1124: {
1125: PetscInt offset;
1127: PetscFunctionBegin;
1128: options = options ? options : defaultoptions;
1129: PetscCheck(options->prefixind >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "More prefixes popped than pushed");
1130: options->prefixind--;
1131: offset = options->prefixind ? options->prefixstack[options->prefixind - 1] : 0;
1132: options->prefix[offset] = 0;
1133: PetscFunctionReturn(PETSC_SUCCESS);
1134: }
1136: /*@
1137: PetscOptionsClear - Removes all options form the database leaving it empty.
1139: Logically Collective
1141: Input Parameter:
1142: . options - options database, use `NULL` for the default global database
1144: Level: developer
1146: Note:
1147: The collectivity of this routine is complex; only the MPI processes that call this routine will
1148: have the affect of these options. If some processes that create objects call this routine and others do
1149: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1150: on different ranks.
1152: Developer Note:
1153: Uses `free()` directly because the current option values were set with `malloc()`
1155: .seealso: `PetscOptionsInsert()`
1156: @*/
1157: PetscErrorCode PetscOptionsClear(PetscOptions options)
1158: {
1159: PetscInt i;
1161: PetscFunctionBegin;
1162: options = options ? options : defaultoptions;
1163: if (!options) PetscFunctionReturn(PETSC_SUCCESS);
1165: for (i = 0; i < options->N; i++) {
1166: if (options->names[i]) free(options->names[i]);
1167: if (options->values[i]) free(options->values[i]);
1168: }
1169: options->N = 0;
1170: free(options->names);
1171: free(options->values);
1172: free(options->used);
1173: free(options->source);
1174: options->names = NULL;
1175: options->values = NULL;
1176: options->used = NULL;
1177: options->source = NULL;
1178: options->Nalloc = 0;
1180: for (i = 0; i < options->Na; i++) {
1181: free(options->aliases1[i]);
1182: free(options->aliases2[i]);
1183: }
1184: options->Na = 0;
1185: free(options->aliases1);
1186: free(options->aliases2);
1187: options->aliases1 = options->aliases2 = NULL;
1188: options->Naalloc = 0;
1190: /* destroy hash table */
1191: kh_destroy(HO, options->ht);
1192: options->ht = NULL;
1194: options->prefixind = 0;
1195: options->prefix[0] = 0;
1196: options->help = PETSC_FALSE;
1197: options->help_intro = PETSC_FALSE;
1198: PetscFunctionReturn(PETSC_SUCCESS);
1199: }
1201: /*@
1202: PetscOptionsSetAlias - Makes a key and alias for another key
1204: Logically Collective
1206: Input Parameters:
1207: + options - options database, or `NULL` for default global database
1208: . newname - the alias
1209: - oldname - the name that alias will refer to
1211: Level: advanced
1213: Note:
1214: The collectivity of this routine is complex; only the MPI processes that call this routine will
1215: have the affect of these options. If some processes that create objects call this routine and others do
1216: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1217: on different ranks.
1219: Developer Note:
1220: Uses `malloc()` directly because PETSc may not be initialized yet.
1222: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1223: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1224: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1225: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1226: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1227: `PetscOptionsFList()`, `PetscOptionsEList()`
1228: @*/
1229: PetscErrorCode PetscOptionsSetAlias(PetscOptions options, const char newname[], const char oldname[])
1230: {
1231: size_t len;
1232: PetscBool valid;
1234: PetscFunctionBegin;
1235: PetscAssertPointer(newname, 2);
1236: PetscAssertPointer(oldname, 3);
1237: options = options ? options : defaultoptions;
1238: PetscCall(PetscOptionsValidKey(newname, &valid));
1239: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliased option %s", newname);
1240: PetscCall(PetscOptionsValidKey(oldname, &valid));
1241: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid aliasee option %s", oldname);
1243: if (options->Na == options->Naalloc) {
1244: char **tmpA1, **tmpA2;
1246: options->Naalloc = PetscMax(4, options->Naalloc * 2);
1247: tmpA1 = (char **)malloc(options->Naalloc * sizeof(char *));
1248: tmpA2 = (char **)malloc(options->Naalloc * sizeof(char *));
1249: for (int i = 0; i < options->Na; ++i) {
1250: tmpA1[i] = options->aliases1[i];
1251: tmpA2[i] = options->aliases2[i];
1252: }
1253: free(options->aliases1);
1254: free(options->aliases2);
1255: options->aliases1 = tmpA1;
1256: options->aliases2 = tmpA2;
1257: }
1258: newname++;
1259: oldname++;
1260: PetscCall(PetscStrlen(newname, &len));
1261: options->aliases1[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1262: PetscCall(PetscStrncpy(options->aliases1[options->Na], newname, len + 1));
1263: PetscCall(PetscStrlen(oldname, &len));
1264: options->aliases2[options->Na] = (char *)malloc((len + 1) * sizeof(char));
1265: PetscCall(PetscStrncpy(options->aliases2[options->Na], oldname, len + 1));
1266: ++options->Na;
1267: PetscFunctionReturn(PETSC_SUCCESS);
1268: }
1270: /*@
1271: PetscOptionsSetValue - Sets an option name-value pair in the options
1272: database, overriding whatever is already present.
1274: Logically Collective
1276: Input Parameters:
1277: + options - options database, use `NULL` for the default global database
1278: . name - name of option, this SHOULD have the - prepended
1279: - value - the option value (not used for all options, so can be `NULL`)
1281: Level: intermediate
1283: Note:
1284: This function can be called BEFORE `PetscInitialize()`
1286: The collectivity of this routine is complex; only the MPI processes that call this routine will
1287: have the affect of these options. If some processes that create objects call this routine and others do
1288: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1289: on different ranks.
1291: Developer Note:
1292: Uses `malloc()` directly because PETSc may not be initialized yet.
1294: .seealso: `PetscOptionsInsert()`, `PetscOptionsClearValue()`
1295: @*/
1296: PetscErrorCode PetscOptionsSetValue(PetscOptions options, const char name[], const char value[])
1297: {
1298: PetscFunctionBegin;
1299: PetscCall(PetscOptionsSetValue_Private(options, name, value, NULL, PETSC_OPT_CODE));
1300: PetscFunctionReturn(PETSC_SUCCESS);
1301: }
1303: PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options, const char name[], const char value[], int *pos, PetscOptionSource source)
1304: {
1305: size_t len;
1306: int n, i;
1307: char **names;
1308: char fullname[PETSC_MAX_OPTION_NAME] = "";
1309: PetscBool flg;
1311: PetscFunctionBegin;
1312: if (!options) {
1313: PetscCall(PetscOptionsCreateDefault());
1314: options = defaultoptions;
1315: }
1316: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "name %s must start with '-'", name);
1318: PetscCall(PetscOptionsSkipPrecedent(options, name, &flg));
1319: if (flg) PetscFunctionReturn(PETSC_SUCCESS);
1321: name++; /* skip starting dash */
1323: if (options->prefixind > 0) {
1324: strncpy(fullname, options->prefix, sizeof(fullname));
1325: fullname[sizeof(fullname) - 1] = 0;
1326: strncat(fullname, name, sizeof(fullname) - strlen(fullname) - 1);
1327: fullname[sizeof(fullname) - 1] = 0;
1328: name = fullname;
1329: }
1331: /* check against aliases */
1332: for (i = 0; i < options->Na; i++) {
1333: int result = PetscOptNameCmp(options->aliases1[i], name);
1334: if (!result) {
1335: name = options->aliases2[i];
1336: break;
1337: }
1338: }
1340: /* slow search */
1341: n = options->N;
1342: names = options->names;
1343: for (i = 0; i < options->N; i++) {
1344: int result = PetscOptNameCmp(names[i], name);
1345: if (!result) {
1346: n = i;
1347: goto setvalue;
1348: } else if (result > 0) {
1349: n = i;
1350: break;
1351: }
1352: }
1353: if (options->N == options->Nalloc) {
1354: char **names, **values;
1355: PetscBool *used;
1356: PetscOptionSource *source;
1358: options->Nalloc = PetscMax(10, options->Nalloc * 2);
1359: names = (char **)malloc(options->Nalloc * sizeof(char *));
1360: values = (char **)malloc(options->Nalloc * sizeof(char *));
1361: used = (PetscBool *)malloc(options->Nalloc * sizeof(PetscBool));
1362: source = (PetscOptionSource *)malloc(options->Nalloc * sizeof(PetscOptionSource));
1363: for (int i = 0; i < options->N; ++i) {
1364: names[i] = options->names[i];
1365: values[i] = options->values[i];
1366: used[i] = options->used[i];
1367: source[i] = options->source[i];
1368: }
1369: free(options->names);
1370: free(options->values);
1371: free(options->used);
1372: free(options->source);
1373: options->names = names;
1374: options->values = values;
1375: options->used = used;
1376: options->source = source;
1377: }
1379: /* shift remaining values up 1 */
1380: for (i = options->N; i > n; i--) {
1381: options->names[i] = options->names[i - 1];
1382: options->values[i] = options->values[i - 1];
1383: options->used[i] = options->used[i - 1];
1384: options->source[i] = options->source[i - 1];
1385: }
1386: options->names[n] = NULL;
1387: options->values[n] = NULL;
1388: options->used[n] = PETSC_FALSE;
1389: options->source[n] = PETSC_OPT_CODE;
1390: options->N++;
1392: /* destroy hash table */
1393: kh_destroy(HO, options->ht);
1394: options->ht = NULL;
1396: /* set new name */
1397: len = strlen(name);
1398: options->names[n] = (char *)malloc((len + 1) * sizeof(char));
1399: PetscCheck(options->names[n], PETSC_COMM_SELF, PETSC_ERR_MEM, "Failed to allocate option name");
1400: strcpy(options->names[n], name);
1402: setvalue:
1403: /* set new value */
1404: if (options->values[n]) free(options->values[n]);
1405: len = value ? strlen(value) : 0;
1406: if (len) {
1407: options->values[n] = (char *)malloc((len + 1) * sizeof(char));
1408: if (!options->values[n]) return PETSC_ERR_MEM;
1409: strcpy(options->values[n], value);
1410: options->values[n][len] = '\0';
1411: } else {
1412: options->values[n] = NULL;
1413: }
1414: options->source[n] = source;
1416: /* handle -help so that it can be set from anywhere */
1417: if (!PetscOptNameCmp(name, "help")) {
1418: options->help = PETSC_TRUE;
1419: options->help_intro = (value && !PetscOptNameCmp(value, "intro")) ? PETSC_TRUE : PETSC_FALSE;
1420: options->used[n] = PETSC_TRUE;
1421: }
1423: PetscCall(PetscOptionsMonitor(options, name, value ? value : "", source));
1424: if (pos) *pos = n;
1425: PetscFunctionReturn(PETSC_SUCCESS);
1426: }
1428: /*@
1429: PetscOptionsClearValue - Clears an option name-value pair in the options
1430: database, overriding whatever is already present.
1432: Logically Collective
1434: Input Parameters:
1435: + options - options database, use `NULL` for the default global database
1436: - name - name of option, this SHOULD have the - prepended
1438: Level: intermediate
1440: Note:
1441: The collectivity of this routine is complex; only the MPI processes that call this routine will
1442: have the affect of these options. If some processes that create objects call this routine and others do
1443: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1444: on different ranks.
1446: Developer Note:
1447: Uses `free()` directly because the options have been set with `malloc()`
1449: .seealso: `PetscOptionsInsert()`
1450: @*/
1451: PetscErrorCode PetscOptionsClearValue(PetscOptions options, const char name[])
1452: {
1453: int N, n, i;
1454: char **names;
1456: PetscFunctionBegin;
1457: options = options ? options : defaultoptions;
1458: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1459: if (!PetscOptNameCmp(name, "-help")) options->help = options->help_intro = PETSC_FALSE;
1461: name++; /* skip starting dash */
1463: /* slow search */
1464: N = n = options->N;
1465: names = options->names;
1466: for (i = 0; i < N; i++) {
1467: int result = PetscOptNameCmp(names[i], name);
1468: if (!result) {
1469: n = i;
1470: break;
1471: } else if (result > 0) {
1472: n = N;
1473: break;
1474: }
1475: }
1476: if (n == N) PetscFunctionReturn(PETSC_SUCCESS); /* it was not present */
1478: /* remove name and value */
1479: if (options->names[n]) free(options->names[n]);
1480: if (options->values[n]) free(options->values[n]);
1481: /* shift remaining values down 1 */
1482: for (i = n; i < N - 1; i++) {
1483: options->names[i] = options->names[i + 1];
1484: options->values[i] = options->values[i + 1];
1485: options->used[i] = options->used[i + 1];
1486: options->source[i] = options->source[i + 1];
1487: }
1488: options->N--;
1490: /* destroy hash table */
1491: kh_destroy(HO, options->ht);
1492: options->ht = NULL;
1494: PetscCall(PetscOptionsMonitor(options, name, NULL, PETSC_OPT_CODE));
1495: PetscFunctionReturn(PETSC_SUCCESS);
1496: }
1498: /*@C
1499: PetscOptionsFindPair - Gets an option name-value pair from the options database.
1501: Not Collective
1503: Input Parameters:
1504: + options - options database, use `NULL` for the default global database
1505: . pre - the string to prepend to the name or `NULL`, this SHOULD NOT have the "-" prepended
1506: - name - name of option, this SHOULD have the "-" prepended
1508: Output Parameters:
1509: + value - the option value (optional, not used for all options)
1510: - set - whether the option is set (optional)
1512: Level: developer
1514: Note:
1515: Each process may find different values or no value depending on how options were inserted into the database
1517: .seealso: `PetscOptionsSetValue()`, `PetscOptionsClearValue()`
1518: @*/
1519: PetscErrorCode PetscOptionsFindPair(PetscOptions options, const char pre[], const char name[], const char *value[], PetscBool *set)
1520: {
1521: char buf[PETSC_MAX_OPTION_NAME];
1522: PetscBool matchnumbers = PETSC_TRUE;
1524: PetscFunctionBegin;
1525: if (!options) {
1526: PetscCall(PetscOptionsCreateDefault());
1527: options = defaultoptions;
1528: }
1529: PetscCheck(!pre || !PetscUnlikely(pre[0] == '-'), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1530: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1532: name++; /* skip starting dash */
1534: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1535: if (pre && pre[0]) {
1536: char *ptr = buf;
1537: if (name[0] == '-') {
1538: *ptr++ = '-';
1539: name++;
1540: }
1541: PetscCall(PetscStrncpy(ptr, pre, buf + sizeof(buf) - ptr));
1542: PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
1543: name = buf;
1544: }
1546: if (PetscDefined(USE_DEBUG)) {
1547: PetscBool valid;
1548: char key[PETSC_MAX_OPTION_NAME + 1] = "-";
1549: PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
1550: PetscCall(PetscOptionsValidKey(key, &valid));
1551: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1552: }
1554: if (!options->ht) {
1555: int i, ret;
1556: khiter_t it;
1557: khash_t(HO) *ht;
1558: ht = kh_init(HO);
1559: PetscCheck(ht, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
1560: ret = kh_resize(HO, ht, options->N * 2); /* twice the required size to reduce risk of collisions */
1561: PetscCheck(!ret, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
1562: for (i = 0; i < options->N; i++) {
1563: it = kh_put(HO, ht, options->names[i], &ret);
1564: PetscCheck(ret == 1, PETSC_COMM_SELF, PETSC_ERR_MEM, "Hash table allocation failed");
1565: kh_val(ht, it) = i;
1566: }
1567: options->ht = ht;
1568: }
1570: khash_t(HO) *ht = options->ht;
1571: khiter_t it = kh_get(HO, ht, name);
1572: if (it != kh_end(ht)) {
1573: int i = kh_val(ht, it);
1574: options->used[i] = PETSC_TRUE;
1575: if (value) *value = options->values[i];
1576: if (set) *set = PETSC_TRUE;
1577: PetscFunctionReturn(PETSC_SUCCESS);
1578: }
1580: /*
1581: The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
1582: Maybe this special lookup mode should be enabled on request with a push/pop API.
1583: The feature of matching _%d_ used sparingly in the codebase.
1584: */
1585: if (matchnumbers) {
1586: int i, j, cnt = 0, locs[16], loce[16];
1587: /* determine the location and number of all _%d_ in the key */
1588: for (i = 0; name[i]; i++) {
1589: if (name[i] == '_') {
1590: for (j = i + 1; name[j]; j++) {
1591: if (name[j] >= '0' && name[j] <= '9') continue;
1592: if (name[j] == '_' && j > i + 1) { /* found a number */
1593: locs[cnt] = i + 1;
1594: loce[cnt++] = j + 1;
1595: }
1596: i = j - 1;
1597: break;
1598: }
1599: }
1600: }
1601: for (i = 0; i < cnt; i++) {
1602: PetscBool found;
1603: char opt[PETSC_MAX_OPTION_NAME + 1] = "-", tmp[PETSC_MAX_OPTION_NAME];
1604: PetscCall(PetscStrncpy(tmp, name, PetscMin((size_t)(locs[i] + 1), sizeof(tmp))));
1605: PetscCall(PetscStrlcat(opt, tmp, sizeof(opt)));
1606: PetscCall(PetscStrlcat(opt, name + loce[i], sizeof(opt)));
1607: PetscCall(PetscOptionsFindPair(options, NULL, opt, value, &found));
1608: if (found) {
1609: if (set) *set = PETSC_TRUE;
1610: PetscFunctionReturn(PETSC_SUCCESS);
1611: }
1612: }
1613: }
1615: if (set) *set = PETSC_FALSE;
1616: PetscFunctionReturn(PETSC_SUCCESS);
1617: }
1619: /* Check whether any option begins with pre+name */
1620: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options, const char pre[], const char name[], const char *option[], const char *value[], PetscBool *set)
1621: {
1622: char buf[PETSC_MAX_OPTION_NAME];
1623: int numCnt = 0, locs[16], loce[16];
1625: PetscFunctionBegin;
1626: options = options ? options : defaultoptions;
1627: PetscCheck(!pre || pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Prefix cannot begin with '-': Instead %s", pre);
1628: PetscCheck(name[0] == '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Name must begin with '-': Instead %s", name);
1630: name++; /* skip starting dash */
1632: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1633: if (pre && pre[0]) {
1634: char *ptr = buf;
1635: if (name[0] == '-') {
1636: *ptr++ = '-';
1637: name++;
1638: }
1639: PetscCall(PetscStrncpy(ptr, pre, sizeof(buf) - ((ptr == buf) ? 0 : 1)));
1640: PetscCall(PetscStrlcat(buf, name, sizeof(buf)));
1641: name = buf;
1642: }
1644: if (PetscDefined(USE_DEBUG)) {
1645: PetscBool valid;
1646: char key[PETSC_MAX_OPTION_NAME + 1] = "-";
1647: PetscCall(PetscStrncpy(key + 1, name, sizeof(key) - 1));
1648: PetscCall(PetscOptionsValidKey(key, &valid));
1649: PetscCheck(valid, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid option '%s' obtained from pre='%s' and name='%s'", key, pre ? pre : "", name);
1650: }
1652: /* determine the location and number of all _%d_ in the key */
1653: {
1654: int i, j;
1655: for (i = 0; name[i]; i++) {
1656: if (name[i] == '_') {
1657: for (j = i + 1; name[j]; j++) {
1658: if (name[j] >= '0' && name[j] <= '9') continue;
1659: if (name[j] == '_' && j > i + 1) { /* found a number */
1660: locs[numCnt] = i + 1;
1661: loce[numCnt++] = j + 1;
1662: }
1663: i = j - 1;
1664: break;
1665: }
1666: }
1667: }
1668: }
1670: /* slow search */
1671: for (int c = -1; c < numCnt; ++c) {
1672: char opt[PETSC_MAX_OPTION_NAME + 2] = "";
1673: size_t len;
1675: if (c < 0) {
1676: PetscCall(PetscStrncpy(opt, name, sizeof(opt)));
1677: } else {
1678: PetscCall(PetscStrncpy(opt, name, PetscMin((size_t)(locs[c] + 1), sizeof(opt))));
1679: PetscCall(PetscStrlcat(opt, name + loce[c], sizeof(opt) - 1));
1680: }
1681: PetscCall(PetscStrlen(opt, &len));
1682: for (int i = 0; i < options->N; i++) {
1683: PetscBool match;
1685: PetscCall(PetscStrncmp(options->names[i], opt, len, &match));
1686: if (match) {
1687: options->used[i] = PETSC_TRUE;
1688: if (option) *option = options->names[i];
1689: if (value) *value = options->values[i];
1690: if (set) *set = PETSC_TRUE;
1691: PetscFunctionReturn(PETSC_SUCCESS);
1692: }
1693: }
1694: }
1696: if (set) *set = PETSC_FALSE;
1697: PetscFunctionReturn(PETSC_SUCCESS);
1698: }
1700: /*@
1701: PetscOptionsReject - Generates an error if a certain option is given.
1703: Not Collective
1705: Input Parameters:
1706: + options - options database, use `NULL` for default global database
1707: . pre - the option prefix (may be `NULL`)
1708: . name - the option name one is seeking
1709: - mess - error message (may be `NULL`)
1711: Level: advanced
1713: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`,
1714: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1715: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1716: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1717: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1718: `PetscOptionsFList()`, `PetscOptionsEList()`
1719: @*/
1720: PetscErrorCode PetscOptionsReject(PetscOptions options, const char pre[], const char name[], const char mess[])
1721: {
1722: PetscBool flag = PETSC_FALSE;
1724: PetscFunctionBegin;
1725: PetscCall(PetscOptionsHasName(options, pre, name, &flag));
1726: if (flag) {
1727: PetscCheck(!mess || !mess[0], PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s with %s", pre ? pre : "", name + 1, mess);
1728: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Program has disabled option: -%s%s", pre ? pre : "", name + 1);
1729: }
1730: PetscFunctionReturn(PETSC_SUCCESS);
1731: }
1733: /*@
1734: PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
1736: Not Collective
1738: Input Parameter:
1739: . options - options database, use `NULL` for default global database
1741: Output Parameter:
1742: . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1744: Level: advanced
1746: .seealso: `PetscOptionsHasName()`
1747: @*/
1748: PetscErrorCode PetscOptionsHasHelp(PetscOptions options, PetscBool *set)
1749: {
1750: PetscFunctionBegin;
1751: PetscAssertPointer(set, 2);
1752: options = options ? options : defaultoptions;
1753: *set = options->help;
1754: PetscFunctionReturn(PETSC_SUCCESS);
1755: }
1757: PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options, PetscBool *set)
1758: {
1759: PetscFunctionBegin;
1760: PetscAssertPointer(set, 2);
1761: options = options ? options : defaultoptions;
1762: *set = options->help_intro;
1763: PetscFunctionReturn(PETSC_SUCCESS);
1764: }
1766: /*@
1767: PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or Boolean, even
1768: if its value is set to false.
1770: Not Collective
1772: Input Parameters:
1773: + options - options database, use `NULL` for default global database
1774: . pre - string to prepend to the name or `NULL`
1775: - name - the option one is seeking
1777: Output Parameter:
1778: . set - `PETSC_TRUE` if found else `PETSC_FALSE`.
1780: Level: beginner
1782: Note:
1783: In many cases you probably want to use `PetscOptionsGetBool()` instead of calling this, to allowing toggling values.
1785: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
1786: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
1787: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
1788: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
1789: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
1790: `PetscOptionsFList()`, `PetscOptionsEList()`
1791: @*/
1792: PetscErrorCode PetscOptionsHasName(PetscOptions options, const char pre[], const char name[], PetscBool *set)
1793: {
1794: const char *value;
1795: PetscBool flag;
1797: PetscFunctionBegin;
1798: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
1799: if (set) *set = flag;
1800: PetscFunctionReturn(PETSC_SUCCESS);
1801: }
1803: /*@C
1804: PetscOptionsGetAll - Lists all the options the program was run with in a single string.
1806: Not Collective
1808: Input Parameter:
1809: . options - the options database, use `NULL` for the default global database
1811: Output Parameter:
1812: . copts - pointer where string pointer is stored
1814: Level: advanced
1816: Notes:
1817: The string should be freed with `PetscFree()`
1819: Each process may have different values depending on how the options were inserted into the database
1821: .seealso: `PetscOptionsAllUsed()`, `PetscOptionsView()`, `PetscOptionsPush()`, `PetscOptionsPop()`,
1822: `PetscOptionsLeftGet()`
1823: @*/
1824: PetscErrorCode PetscOptionsGetAll(PetscOptions options, char *copts[]) PeNS
1825: {
1826: PetscInt i;
1827: size_t len = 1, lent = 0;
1828: char *coptions = NULL;
1830: PetscFunctionBegin;
1831: PetscAssertPointer(copts, 2);
1832: options = options ? options : defaultoptions;
1833: /* count the length of the required string */
1834: for (i = 0; i < options->N; i++) {
1835: PetscCall(PetscStrlen(options->names[i], &lent));
1836: len += 2 + lent;
1837: if (options->values[i]) {
1838: PetscCall(PetscStrlen(options->values[i], &lent));
1839: len += 1 + lent;
1840: }
1841: }
1842: PetscCall(PetscMalloc1(len, &coptions));
1843: coptions[0] = 0;
1844: for (i = 0; i < options->N; i++) {
1845: PetscCall(PetscStrlcat(coptions, "-", len));
1846: PetscCall(PetscStrlcat(coptions, options->names[i], len));
1847: PetscCall(PetscStrlcat(coptions, " ", len));
1848: if (options->values[i]) {
1849: PetscCall(PetscStrlcat(coptions, options->values[i], len));
1850: PetscCall(PetscStrlcat(coptions, " ", len));
1851: }
1852: }
1853: *copts = coptions;
1854: PetscFunctionReturn(PETSC_SUCCESS);
1855: }
1857: /*@
1858: PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
1860: Not Collective
1862: Input Parameters:
1863: + options - options database, use `NULL` for default global database
1864: - name - string name of option
1866: Output Parameter:
1867: . used - `PETSC_TRUE` if the option was used, otherwise false, including if option was not found in options database
1869: Level: advanced
1871: Note:
1872: The value returned may be different on each process and depends on which options have been processed
1873: on the given process
1875: .seealso: `PetscOptionsView()`, `PetscOptionsLeft()`, `PetscOptionsAllUsed()`
1876: @*/
1877: PetscErrorCode PetscOptionsUsed(PetscOptions options, const char *name, PetscBool *used)
1878: {
1879: PetscInt i;
1881: PetscFunctionBegin;
1882: PetscAssertPointer(name, 2);
1883: PetscAssertPointer(used, 3);
1884: options = options ? options : defaultoptions;
1885: *used = PETSC_FALSE;
1886: for (i = 0; i < options->N; i++) {
1887: PetscCall(PetscStrcasecmp(options->names[i], name, used));
1888: if (*used) {
1889: *used = options->used[i];
1890: break;
1891: }
1892: }
1893: PetscFunctionReturn(PETSC_SUCCESS);
1894: }
1896: /*@
1897: PetscOptionsAllUsed - Returns a count of the number of options in the
1898: database that have never been selected.
1900: Not Collective
1902: Input Parameter:
1903: . options - options database, use `NULL` for default global database
1905: Output Parameter:
1906: . N - count of options not used
1908: Level: advanced
1910: Note:
1911: The value returned may be different on each process and depends on which options have been processed
1912: on the given process
1914: .seealso: `PetscOptionsView()`
1915: @*/
1916: PetscErrorCode PetscOptionsAllUsed(PetscOptions options, PetscInt *N)
1917: {
1918: PetscInt i, n = 0;
1920: PetscFunctionBegin;
1921: PetscAssertPointer(N, 2);
1922: options = options ? options : defaultoptions;
1923: for (i = 0; i < options->N; i++) {
1924: if (!options->used[i]) n++;
1925: }
1926: *N = n;
1927: PetscFunctionReturn(PETSC_SUCCESS);
1928: }
1930: /*@
1931: PetscOptionsLeft - Prints to screen any options that were set and never used.
1933: Not Collective
1935: Input Parameter:
1936: . options - options database; use `NULL` for default global database
1938: Options Database Key:
1939: . -options_left - activates `PetscOptionsAllUsed()` within `PetscFinalize()`
1941: Level: advanced
1943: Notes:
1944: This is rarely used directly, it is called by `PetscFinalize()` by default (unless
1945: `-options_left false` is specified) to help users determine possible mistakes in their usage of
1946: options. This only prints values on process zero of `PETSC_COMM_WORLD`.
1948: Other processes depending the objects
1949: used may have different options that are left unused.
1951: .seealso: `PetscOptionsAllUsed()`
1952: @*/
1953: PetscErrorCode PetscOptionsLeft(PetscOptions options)
1954: {
1955: PetscInt i;
1956: PetscInt cnt = 0;
1957: PetscOptions toptions;
1959: PetscFunctionBegin;
1960: toptions = options ? options : defaultoptions;
1961: for (i = 0; i < toptions->N; i++) {
1962: if (!toptions->used[i]) {
1963: if (PetscCIOption(toptions->names[i])) continue;
1964: if (toptions->values[i]) {
1965: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s value: %s source: %s\n", toptions->names[i], toptions->values[i], PetscOptionSources[toptions->source[i]]));
1966: } else {
1967: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Option left: name:-%s (no value) source: %s\n", toptions->names[i], PetscOptionSources[toptions->source[i]]));
1968: }
1969: }
1970: }
1971: if (!options) {
1972: toptions = defaultoptions;
1973: while (toptions->previous) {
1974: cnt++;
1975: toptions = toptions->previous;
1976: }
1977: 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));
1978: }
1979: PetscFunctionReturn(PETSC_SUCCESS);
1980: }
1982: /*@C
1983: PetscOptionsLeftGet - Returns all options that were set and never used.
1985: Not Collective
1987: Input Parameter:
1988: . options - options database, use `NULL` for default global database
1990: Output Parameters:
1991: + N - count of options not used
1992: . names - names of options not used
1993: - values - values of options not used
1995: Level: advanced
1997: Notes:
1998: Users should call `PetscOptionsLeftRestore()` to free the memory allocated in this routine
2000: The value returned may be different on each process and depends on which options have been processed
2001: on the given process
2003: .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`
2004: @*/
2005: PetscErrorCode PetscOptionsLeftGet(PetscOptions options, PetscInt *N, char **names[], char **values[])
2006: {
2007: PetscInt i, n;
2009: PetscFunctionBegin;
2010: if (N) PetscAssertPointer(N, 2);
2011: if (names) PetscAssertPointer(names, 3);
2012: if (values) PetscAssertPointer(values, 4);
2013: options = options ? options : defaultoptions;
2015: /* The number of unused PETSc options */
2016: n = 0;
2017: for (i = 0; i < options->N; i++) {
2018: if (PetscCIOption(options->names[i])) continue;
2019: if (!options->used[i]) n++;
2020: }
2021: if (N) *N = n;
2022: if (names) PetscCall(PetscMalloc1(n, names));
2023: if (values) PetscCall(PetscMalloc1(n, values));
2025: n = 0;
2026: if (names || values) {
2027: for (i = 0; i < options->N; i++) {
2028: if (!options->used[i]) {
2029: if (PetscCIOption(options->names[i])) continue;
2030: if (names) (*names)[n] = options->names[i];
2031: if (values) (*values)[n] = options->values[i];
2032: n++;
2033: }
2034: }
2035: }
2036: PetscFunctionReturn(PETSC_SUCCESS);
2037: }
2039: /*@C
2040: PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using `PetscOptionsLeftGet()`.
2042: Not Collective
2044: Input Parameters:
2045: + options - options database, use `NULL` for default global database
2046: . N - count of options not used
2047: . names - names of options not used
2048: - values - values of options not used
2050: Level: advanced
2052: Notes:
2053: The user should pass the same pointer to `N` as they did when calling `PetscOptionsLeftGet()`
2055: .seealso: `PetscOptionsAllUsed()`, `PetscOptionsLeft()`, `PetscOptionsLeftGet()`
2056: @*/
2057: PetscErrorCode PetscOptionsLeftRestore(PetscOptions options, PetscInt *N, char **names[], char **values[])
2058: {
2059: PetscFunctionBegin;
2060: (void)options;
2061: if (N) PetscAssertPointer(N, 2);
2062: if (names) PetscAssertPointer(names, 3);
2063: if (values) PetscAssertPointer(values, 4);
2064: if (N) *N = 0;
2065: if (names) PetscCall(PetscFree(*names));
2066: if (values) PetscCall(PetscFree(*values));
2067: PetscFunctionReturn(PETSC_SUCCESS);
2068: }
2070: /*@C
2071: PetscOptionsMonitorDefault - Print all options set value events using the supplied `PetscViewer`.
2073: Logically Collective
2075: Input Parameters:
2076: + name - option name string
2077: . value - option value string
2078: . source - The source for the option
2079: - ctx - a `PETSCVIEWERASCII` or `NULL`
2081: Level: intermediate
2083: Notes:
2084: If ctx is `NULL`, `PetscPrintf()` is used.
2085: The first MPI process in the `PetscViewer` viewer actually prints the values, other
2086: processes may have different values set
2088: If `PetscCIEnabled` then do not print the test harness options
2090: .seealso: `PetscOptionsMonitorSet()`
2091: @*/
2092: PetscErrorCode PetscOptionsMonitorDefault(const char name[], const char value[], PetscOptionSource source, PetscCtx ctx)
2093: {
2094: PetscFunctionBegin;
2095: if (PetscCIOption(name)) PetscFunctionReturn(PETSC_SUCCESS);
2097: if (ctx) {
2098: PetscViewer viewer = (PetscViewer)ctx;
2099: if (!value) {
2100: PetscCall(PetscViewerASCIIPrintf(viewer, "Removing option: %s\n", name));
2101: } else if (!value[0]) {
2102: PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
2103: } else {
2104: PetscCall(PetscViewerASCIIPrintf(viewer, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
2105: }
2106: } else {
2107: MPI_Comm comm = PETSC_COMM_WORLD;
2108: if (!value) {
2109: PetscCall(PetscPrintf(comm, "Removing option: %s\n", name));
2110: } else if (!value[0]) {
2111: PetscCall(PetscPrintf(comm, "Setting option: %s (no value) (source: %s)\n", name, PetscOptionSources[source]));
2112: } else {
2113: PetscCall(PetscPrintf(comm, "Setting option: %s = %s (source: %s)\n", name, value, PetscOptionSources[source]));
2114: }
2115: }
2116: PetscFunctionReturn(PETSC_SUCCESS);
2117: }
2119: /*@C
2120: PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
2121: modified the PETSc options database.
2123: Not Collective
2125: Input Parameters:
2126: + monitor - pointer to function (if this is `NULL`, it turns off monitoring
2127: . mctx - [optional] context for private data for the monitor routine (use `NULL` if
2128: no context is desired)
2129: - monitordestroy - [optional] routine that frees monitor context (may be `NULL`), see `PetscCtxDestroyFn` for its calling sequence
2131: Calling sequence of `monitor`:
2132: + name - option name string
2133: . value - option value string, a value of `NULL` indicates the option is being removed from the database. A value
2134: of "" indicates the option is in the database but has no value.
2135: . source - option source
2136: - mctx - optional monitoring context, as set by `PetscOptionsMonitorSet()`
2138: Options Database Keys:
2139: + -options_monitor viewer - turn on default monitoring of changes to the options database
2140: - -options_monitor_cancel - turn off any option monitors except the default monitor obtained with `-options_monitor`
2142: Level: intermediate
2144: Notes:
2145: See `PetscInitialize()` for options related to option database monitoring.
2147: The default is to do no monitoring. To print the name and value of options
2148: being inserted into the database, use `PetscOptionsMonitorDefault()` as the monitoring routine,
2149: with a `NULL` monitoring context. Or use the option `-options_monitor viewer`.
2151: Several different monitoring routines may be set by calling
2152: `PetscOptionsMonitorSet()` multiple times; all will be called in the
2153: order in which they were set.
2155: .seealso: `PetscOptionsMonitorDefault()`, `PetscInitialize()`, `PetscCtxDestroyFn`
2156: @*/
2157: PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], PetscOptionSource source, PetscCtx mctx), PetscCtx mctx, PetscCtxDestroyFn *monitordestroy)
2158: {
2159: PetscOptions options = defaultoptions;
2161: PetscFunctionBegin;
2162: if (options->monitorCancel) PetscFunctionReturn(PETSC_SUCCESS);
2163: PetscCheck(options->numbermonitors < MAXOPTIONSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many PetscOptions monitors set");
2164: options->monitor[options->numbermonitors] = monitor;
2165: options->monitordestroy[options->numbermonitors] = monitordestroy;
2166: options->monitorcontext[options->numbermonitors++] = mctx;
2167: PetscFunctionReturn(PETSC_SUCCESS);
2168: }
2170: /*@
2171: PetscOptionsStringToBool - Converts a string to a `PetscBool`
2173: Not Collective
2175: Input Parameter:
2176: . value - the string to convert; may be `NULL` or `""`
2178: Output Parameter:
2179: . a - the resulting `PetscBool`
2181: Level: developer
2183: Note:
2184: Recognizes (case-insensitive) `TRUE`, `YES`, `1`, `on` as `PETSC_TRUE` and `FALSE`, `NO`, `0`, `off` as `PETSC_FALSE`.
2185: An empty or `NULL` string is treated as `PETSC_TRUE`. Any other input generates an error.
2187: .seealso: `PetscOptionsStringToInt()`, `PetscOptionsStringToReal()`, `PetscOptionsStringToScalar()`, `PetscOptionsGetBool()`
2188: @*/
2189: PetscErrorCode PetscOptionsStringToBool(const char value[], PetscBool *a)
2190: {
2191: PetscBool istrue, isfalse;
2192: size_t len;
2194: PetscFunctionBegin;
2195: /* PetscStrlen() returns 0 for NULL or "" */
2196: PetscCall(PetscStrlen(value, &len));
2197: if (!len) {
2198: *a = PETSC_TRUE;
2199: PetscFunctionReturn(PETSC_SUCCESS);
2200: }
2201: PetscCall(PetscStrcasecmp(value, "TRUE", &istrue));
2202: if (istrue) {
2203: *a = PETSC_TRUE;
2204: PetscFunctionReturn(PETSC_SUCCESS);
2205: }
2206: PetscCall(PetscStrcasecmp(value, "YES", &istrue));
2207: if (istrue) {
2208: *a = PETSC_TRUE;
2209: PetscFunctionReturn(PETSC_SUCCESS);
2210: }
2211: PetscCall(PetscStrcasecmp(value, "1", &istrue));
2212: if (istrue) {
2213: *a = PETSC_TRUE;
2214: PetscFunctionReturn(PETSC_SUCCESS);
2215: }
2216: PetscCall(PetscStrcasecmp(value, "on", &istrue));
2217: if (istrue) {
2218: *a = PETSC_TRUE;
2219: PetscFunctionReturn(PETSC_SUCCESS);
2220: }
2221: PetscCall(PetscStrcasecmp(value, "FALSE", &isfalse));
2222: if (isfalse) {
2223: *a = PETSC_FALSE;
2224: PetscFunctionReturn(PETSC_SUCCESS);
2225: }
2226: PetscCall(PetscStrcasecmp(value, "NO", &isfalse));
2227: if (isfalse) {
2228: *a = PETSC_FALSE;
2229: PetscFunctionReturn(PETSC_SUCCESS);
2230: }
2231: PetscCall(PetscStrcasecmp(value, "0", &isfalse));
2232: if (isfalse) {
2233: *a = PETSC_FALSE;
2234: PetscFunctionReturn(PETSC_SUCCESS);
2235: }
2236: PetscCall(PetscStrcasecmp(value, "off", &isfalse));
2237: if (isfalse) {
2238: *a = PETSC_FALSE;
2239: PetscFunctionReturn(PETSC_SUCCESS);
2240: }
2241: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
2242: }
2244: /*@
2245: PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
2247: Not Collective
2249: Input Parameter:
2250: . name - the string to convert
2252: Output Parameter:
2253: . a - the resulting `PetscInt` value
2255: Level: developer
2257: Note:
2258: Recognizes the special strings `PETSC_DEFAULT`, `DEFAULT`, `PETSC_DECIDE`, `DECIDE`, `PETSC_DETERMINE`, `DETERMINE`, `PETSC_UNLIMITED`,
2259: `UNLIMITED`, and `mouse` (which returns `-1`). Otherwise the value is parsed as a base-10 integer.
2261: .seealso: `PetscOptionsStringToReal()`, `PetscOptionsStringToScalar()`, `PetscOptionsStringToBool()`, `PetscOptionsGetInt()`
2262: @*/
2263: PetscErrorCode PetscOptionsStringToInt(const char name[], PetscInt *a)
2264: {
2265: size_t len;
2266: PetscBool decide, tdefault, mouse, unlimited;
2268: PetscFunctionBegin;
2269: PetscCall(PetscStrlen(name, &len));
2270: PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
2272: PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &tdefault));
2273: if (!tdefault) PetscCall(PetscStrcasecmp(name, "DEFAULT", &tdefault));
2274: PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &decide));
2275: if (!decide) PetscCall(PetscStrcasecmp(name, "DECIDE", &decide));
2276: if (!decide) PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &decide));
2277: if (!decide) PetscCall(PetscStrcasecmp(name, "DETERMINE", &decide));
2278: PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &unlimited));
2279: if (!unlimited) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &unlimited));
2280: PetscCall(PetscStrcasecmp(name, "mouse", &mouse));
2282: if (tdefault) *a = PETSC_DEFAULT;
2283: else if (decide) *a = PETSC_DECIDE;
2284: else if (unlimited) *a = PETSC_UNLIMITED;
2285: else if (mouse) *a = -1;
2286: else {
2287: char *endptr;
2288: long strtolval;
2290: strtolval = strtol(name, &endptr, 10);
2291: 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);
2293: #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
2294: (void)strtolval;
2295: *a = atoll(name);
2296: #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
2297: (void)strtolval;
2298: *a = _atoi64(name);
2299: #else
2300: *a = (PetscInt)strtolval;
2301: #endif
2302: }
2303: PetscFunctionReturn(PETSC_SUCCESS);
2304: }
2306: #if defined(PETSC_USE_REAL___FLOAT128)
2307: #include <quadmath.h>
2308: #endif
2310: static PetscErrorCode PetscStrtod(const char name[], PetscReal *a, char **endptr)
2311: {
2312: PetscFunctionBegin;
2313: #if defined(PETSC_USE_REAL___FLOAT128)
2314: *a = strtoflt128(name, endptr);
2315: #else
2316: *a = (PetscReal)strtod(name, endptr);
2317: #endif
2318: PetscFunctionReturn(PETSC_SUCCESS);
2319: }
2321: static PetscErrorCode PetscStrtoz(const char name[], PetscScalar *a, char **endptr, PetscBool *isImaginary)
2322: {
2323: PetscBool hasi = PETSC_FALSE;
2324: char *ptr;
2325: PetscReal strtoval;
2327: PetscFunctionBegin;
2328: PetscCall(PetscStrtod(name, &strtoval, &ptr));
2329: if (ptr == name) {
2330: strtoval = 1.;
2331: hasi = PETSC_TRUE;
2332: if (name[0] == 'i') {
2333: ptr++;
2334: } else if (name[0] == '+' && name[1] == 'i') {
2335: ptr += 2;
2336: } else if (name[0] == '-' && name[1] == 'i') {
2337: strtoval = -1.;
2338: ptr += 2;
2339: }
2340: } else if (*ptr == 'i') {
2341: hasi = PETSC_TRUE;
2342: ptr++;
2343: }
2344: *endptr = ptr;
2345: *isImaginary = hasi;
2346: if (hasi) {
2347: #if !defined(PETSC_USE_COMPLEX)
2348: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s contains imaginary but complex not supported ", name);
2349: #else
2350: *a = PetscCMPLX(0., strtoval);
2351: #endif
2352: } else {
2353: *a = strtoval;
2354: }
2355: PetscFunctionReturn(PETSC_SUCCESS);
2356: }
2358: /*@
2359: PetscOptionsStringToReal - Converts a string to a `PetscReal` value. Handles special cases like `default` and `decide`
2361: Not Collective
2363: Input Parameter:
2364: . name - the string to convert
2366: Output Parameter:
2367: . a - the resulting `PetscReal` value
2369: Level: developer
2371: Note:
2372: Recognizes the special strings `PETSC_DEFAULT`, `DEFAULT`, `PETSC_DECIDE`, `DECIDE`, `PETSC_DETERMINE`, `DETERMINE`,
2373: `PETSC_UNLIMITED`, and `UNLIMITED`. Otherwise the value is parsed as a floating-point number.
2375: .seealso: `PetscOptionsStringToInt()`, `PetscOptionsStringToScalar()`, `PetscOptionsStringToBool()`, `PetscOptionsGetReal()`
2376: @*/
2377: PetscErrorCode PetscOptionsStringToReal(const char name[], PetscReal *a)
2378: {
2379: size_t len;
2380: PetscBool match;
2381: char *endptr;
2383: PetscFunctionBegin;
2384: PetscCall(PetscStrlen(name, &len));
2385: PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "String of length zero has no numerical value");
2387: PetscCall(PetscStrcasecmp(name, "PETSC_DEFAULT", &match));
2388: if (!match) PetscCall(PetscStrcasecmp(name, "DEFAULT", &match));
2389: if (match) {
2390: *a = PETSC_DEFAULT;
2391: PetscFunctionReturn(PETSC_SUCCESS);
2392: }
2394: PetscCall(PetscStrcasecmp(name, "PETSC_DECIDE", &match));
2395: if (!match) PetscCall(PetscStrcasecmp(name, "DECIDE", &match));
2396: if (match) {
2397: *a = PETSC_DECIDE;
2398: PetscFunctionReturn(PETSC_SUCCESS);
2399: }
2401: PetscCall(PetscStrcasecmp(name, "PETSC_DETERMINE", &match));
2402: if (!match) PetscCall(PetscStrcasecmp(name, "DETERMINE", &match));
2403: if (match) {
2404: *a = PETSC_DETERMINE;
2405: PetscFunctionReturn(PETSC_SUCCESS);
2406: }
2408: PetscCall(PetscStrcasecmp(name, "PETSC_UNLIMITED", &match));
2409: if (!match) PetscCall(PetscStrcasecmp(name, "UNLIMITED", &match));
2410: if (match) {
2411: *a = PETSC_UNLIMITED;
2412: PetscFunctionReturn(PETSC_SUCCESS);
2413: }
2415: PetscCall(PetscStrtod(name, a, &endptr));
2416: PetscCheck((size_t)(endptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value", name);
2417: PetscFunctionReturn(PETSC_SUCCESS);
2418: }
2420: /*@
2421: PetscOptionsStringToScalar - Converts a string to a `PetscScalar` value; when PETSc is built with complex scalars, parses an optional imaginary part
2423: Not Collective
2425: Input Parameter:
2426: . name - the string to convert
2428: Output Parameter:
2429: . a - the resulting `PetscScalar` value
2431: Level: developer
2433: Note:
2434: 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.
2436: .seealso: `PetscOptionsStringToInt()`, `PetscOptionsStringToReal()`, `PetscOptionsStringToBool()`, `PetscOptionsGetScalar()`
2437: @*/
2438: PetscErrorCode PetscOptionsStringToScalar(const char name[], PetscScalar *a)
2439: {
2440: PetscBool imag1;
2441: size_t len;
2442: PetscScalar val = 0.;
2443: char *ptr = NULL;
2445: PetscFunctionBegin;
2446: PetscCall(PetscStrlen(name, &len));
2447: PetscCheck(len, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "character string of length zero has no numerical value");
2448: PetscCall(PetscStrtoz(name, &val, &ptr, &imag1));
2449: #if defined(PETSC_USE_COMPLEX)
2450: if ((size_t)(ptr - name) < len) {
2451: PetscBool imag2;
2452: PetscScalar val2;
2454: PetscCall(PetscStrtoz(ptr, &val2, &ptr, &imag2));
2455: if (imag1) PetscCheck(imag2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s: must specify imaginary component second", name);
2456: val = PetscCMPLX(PetscRealPart(val), PetscImaginaryPart(val2));
2457: }
2458: #endif
2459: PetscCheck((size_t)(ptr - name) == len, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Input string %s has no numeric value ", name);
2460: *a = val;
2461: PetscFunctionReturn(PETSC_SUCCESS);
2462: }
2464: /*@C
2465: PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
2466: option in the database.
2468: Not Collective
2470: Input Parameters:
2471: + options - options database, use `NULL` for default global database
2472: . pre - the string to prepend to the name or `NULL`
2473: - name - the option one is seeking
2475: Output Parameters:
2476: + ivalue - the logical value to return
2477: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2479: Level: beginner
2481: Notes:
2482: TRUE, true, YES, yes, ON, on, nostring, and 1 all translate to `PETSC_TRUE`
2483: FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_FALSE`
2485: 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`
2486: is equivalent to `-requested_bool true`
2488: If the user does not supply the option at all `ivalue` is NOT changed. Thus
2489: you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
2491: .seealso: `PetscOptionsGetBool3()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2492: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2493: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2494: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2495: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2496: `PetscOptionsFList()`, `PetscOptionsEList()`
2497: @*/
2498: PetscErrorCode PetscOptionsGetBool(PetscOptions options, const char pre[], const char name[], PetscBool *ivalue, PetscBool *set)
2499: {
2500: const char *value;
2501: PetscBool flag;
2503: PetscFunctionBegin;
2504: PetscAssertPointer(name, 3);
2505: if (ivalue) PetscAssertPointer(ivalue, 4);
2506: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2507: if (flag) {
2508: if (set) *set = PETSC_TRUE;
2509: PetscCall(PetscOptionsStringToBool(value, &flag));
2510: if (ivalue) *ivalue = flag;
2511: } else {
2512: if (set) *set = PETSC_FALSE;
2513: }
2514: PetscFunctionReturn(PETSC_SUCCESS);
2515: }
2517: /*@C
2518: PetscOptionsGetBool3 - Gets the ternary logical (true, false or unknown) value for a particular
2519: option in the database.
2521: Not Collective
2523: Input Parameters:
2524: + options - options database, use `NULL` for default global database
2525: . pre - the string to prepend to the name or `NULL`
2526: - name - the option one is seeking
2528: Output Parameters:
2529: + ivalue - the ternary logical value to return
2530: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2532: Level: beginner
2534: Notes:
2535: TRUE, true, YES, yes, ON, on, nostring and 1 all translate to `PETSC_BOOL3_TRUE`
2536: FALSE, false, NO, no, OFF, off and 0 all translate to `PETSC_BOOL3_FALSE`
2537: UNKNOWN, unknown, AUTO and auto all translate to `PETSC_BOOL3_UNKNOWN`
2539: 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`
2540: is equivalent to `-requested_bool3 true`
2542: If the user does not supply the option at all `ivalue` is NOT changed. Thus
2543: you should ALWAYS initialize `ivalue` if you access it without first checking that the `set` flag is true.
2545: .seealso: `PetscOptionsGetBool()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2546: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsGetInt()`, `PetscOptionsBool()`,
2547: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2548: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2549: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2550: `PetscOptionsFList()`, `PetscOptionsEList()`
2551: @*/
2552: PetscErrorCode PetscOptionsGetBool3(PetscOptions options, const char pre[], const char name[], PetscBool3 *ivalue, PetscBool *set)
2553: {
2554: const char *value;
2555: PetscBool flag;
2557: PetscFunctionBegin;
2558: PetscAssertPointer(name, 3);
2559: if (ivalue) PetscAssertPointer(ivalue, 4);
2560: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2561: if (flag) { // found the option
2562: PetscBool isAUTO = PETSC_FALSE, isUNKNOWN = PETSC_FALSE;
2564: if (set) *set = PETSC_TRUE;
2565: PetscCall(PetscStrcasecmp("AUTO", value, &isAUTO)); // auto or AUTO
2566: if (!isAUTO) PetscCall(PetscStrcasecmp("UNKNOWN", value, &isUNKNOWN)); // unknown or UNKNOWN
2567: if (isAUTO || isUNKNOWN) {
2568: if (ivalue) *ivalue = PETSC_BOOL3_UNKNOWN;
2569: } else { // handle boolean values (if no value is given, it returns true)
2570: PetscCall(PetscOptionsStringToBool(value, &flag));
2571: if (ivalue) *ivalue = PetscBoolToBool3(flag);
2572: }
2573: } else {
2574: if (set) *set = PETSC_FALSE;
2575: }
2576: PetscFunctionReturn(PETSC_SUCCESS);
2577: }
2579: /*@C
2580: PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2582: Not Collective
2584: Input Parameters:
2585: + options - options database, use `NULL` for default global database
2586: . pre - the string to prepend to the name or `NULL`
2587: . opt - option name
2588: . list - the possible choices (one of these must be selected, anything else is invalid)
2589: - ntext - number of choices
2591: Output Parameters:
2592: + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2593: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2595: Level: intermediate
2597: Notes:
2598: If the user does not supply the option `value` is NOT changed. Thus
2599: you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2601: See `PetscOptionsFList()` for when the choices are given in a `PetscFunctionList`
2603: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2604: `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2605: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2606: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2607: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2608: `PetscOptionsFList()`, `PetscOptionsEList()`
2609: @*/
2610: PetscErrorCode PetscOptionsGetEList(PetscOptions options, const char pre[], const char opt[], const char *const list[], PetscInt ntext, PetscInt *value, PetscBool *set)
2611: {
2612: size_t alen, len = 0, tlen = 0;
2613: char *svalue;
2614: PetscBool aset, flg = PETSC_FALSE;
2615: PetscInt i;
2617: PetscFunctionBegin;
2618: PetscAssertPointer(opt, 3);
2619: for (i = 0; i < ntext; i++) {
2620: PetscCall(PetscStrlen(list[i], &alen));
2621: if (alen > len) len = alen;
2622: tlen += len + 1;
2623: }
2624: len += 5; /* a little extra space for user mistypes */
2625: PetscCall(PetscMalloc1(len, &svalue));
2626: PetscCall(PetscOptionsGetString(options, pre, opt, svalue, len, &aset));
2627: if (aset) {
2628: PetscCall(PetscEListFind(ntext, list, svalue, value, &flg));
2629: if (!flg) {
2630: char *avail;
2632: PetscCall(PetscMalloc1(tlen, &avail));
2633: avail[0] = '\0';
2634: for (i = 0; i < ntext; i++) {
2635: PetscCall(PetscStrlcat(avail, list[i], tlen));
2636: PetscCall(PetscStrlcat(avail, " ", tlen));
2637: }
2638: PetscCall(PetscStrtolower(avail));
2639: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown option \"%s\" for -%s%s. Available options: %s", svalue, pre ? pre : "", opt + 1, avail);
2640: }
2641: if (set) *set = PETSC_TRUE;
2642: } else if (set) *set = PETSC_FALSE;
2643: PetscCall(PetscFree(svalue));
2644: PetscFunctionReturn(PETSC_SUCCESS);
2645: }
2647: /*@C
2648: PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2650: Not Collective
2652: Input Parameters:
2653: + options - options database, use `NULL` for default global database
2654: . pre - option prefix or `NULL`
2655: . opt - option name
2656: - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2658: Output Parameters:
2659: + value - the value to return
2660: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2662: Level: beginner
2664: Notes:
2665: If the user does not supply the option `value` is NOT changed. Thus
2666: you should ALWAYS initialize `value` if you access it without first checking that the `set` flag is true.
2668: `list` is usually something like `PCASMTypes` or some other predefined list of enum names
2670: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
2671: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2672: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2673: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2674: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2675: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2676: `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
2677: @*/
2678: PetscErrorCode PetscOptionsGetEnum(PetscOptions options, const char pre[], const char opt[], const char *const list[], PetscEnum *value, PetscBool *set) PeNSS
2679: {
2680: PetscInt ntext = 0, tval;
2681: PetscBool fset;
2683: PetscFunctionBegin;
2684: PetscAssertPointer(opt, 3);
2685: 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");
2686: PetscCheck(ntext >= 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least two entries: typename and type prefix");
2687: ntext -= 3;
2688: PetscCall(PetscOptionsGetEList(options, pre, opt, list, ntext, &tval, &fset));
2689: /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2690: if (fset) *value = (PetscEnum)tval;
2691: if (set) *set = fset;
2692: PetscFunctionReturn(PETSC_SUCCESS);
2693: }
2695: /*@C
2696: PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2698: Not Collective
2700: Input Parameters:
2701: + options - options database, use `NULL` for default global database
2702: . pre - the string to prepend to the name or `NULL`
2703: - name - the option one is seeking
2705: Output Parameters:
2706: + ivalue - the integer value to return
2707: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2709: Level: beginner
2711: Notes:
2712: If the user does not supply the option `ivalue` is NOT changed. Thus
2713: you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
2715: Accepts the special values `determine`, `decide` and `unlimited`.
2717: Accepts the deprecated value `default`.
2719: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2720: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2721: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2722: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2723: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2724: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2725: `PetscOptionsFList()`, `PetscOptionsEList()`
2726: @*/
2727: PetscErrorCode PetscOptionsGetInt(PetscOptions options, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
2728: {
2729: const char *value;
2730: PetscBool flag;
2732: PetscFunctionBegin;
2733: PetscAssertPointer(name, 3);
2734: PetscAssertPointer(ivalue, 4);
2735: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2736: if (flag) {
2737: if (!value) {
2738: if (set) *set = PETSC_FALSE;
2739: } else {
2740: if (set) *set = PETSC_TRUE;
2741: PetscCall(PetscOptionsStringToInt(value, ivalue));
2742: }
2743: } else {
2744: if (set) *set = PETSC_FALSE;
2745: }
2746: PetscFunctionReturn(PETSC_SUCCESS);
2747: }
2749: /*@C
2750: PetscOptionsGetMPIInt - Gets the MPI integer value for a particular option in the database.
2752: Not Collective
2754: Input Parameters:
2755: + options - options database, use `NULL` for default global database
2756: . pre - the string to prepend to the name or `NULL`
2757: - name - the option one is seeking
2759: Output Parameters:
2760: + ivalue - the MPI integer value to return
2761: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2763: Level: beginner
2765: Notes:
2766: If the user does not supply the option `ivalue` is NOT changed. Thus
2767: you should ALWAYS initialize the `ivalue` if you access it without first checking that the `set` flag is true.
2769: Accepts the special values `determine`, `decide` and `unlimited`.
2771: Accepts the deprecated value `default`.
2773: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
2774: `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2775: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
2776: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2777: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2778: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2779: `PetscOptionsFList()`, `PetscOptionsEList()`
2780: @*/
2781: PetscErrorCode PetscOptionsGetMPIInt(PetscOptions options, const char pre[], const char name[], PetscMPIInt *ivalue, PetscBool *set)
2782: {
2783: PetscInt value;
2784: PetscBool flag;
2786: PetscFunctionBegin;
2787: PetscCall(PetscOptionsGetInt(options, pre, name, &value, &flag));
2788: if (flag) PetscCall(PetscMPIIntCast(value, ivalue));
2789: if (set) *set = flag;
2790: PetscFunctionReturn(PETSC_SUCCESS);
2791: }
2793: /*@C
2794: PetscOptionsGetReal - Gets the double precision value for a particular
2795: option in the database.
2797: Not Collective
2799: Input Parameters:
2800: + options - options database, use `NULL` for default global database
2801: . pre - string to prepend to each name or `NULL`
2802: - name - the option one is seeking
2804: Output Parameters:
2805: + dvalue - the double value to return
2806: - set - `PETSC_TRUE` if found, `PETSC_FALSE` if not found
2808: Level: beginner
2810: Notes:
2811: Accepts the special values `determine`, `decide` and `unlimited`.
2813: Accepts the deprecated value `default`
2815: If the user does not supply the option `dvalue` is NOT changed. Thus
2816: you should ALWAYS initialize `dvalue` if you access it without first checking that the `set` flag is true.
2818: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2819: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2820: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2821: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2822: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2823: `PetscOptionsFList()`, `PetscOptionsEList()`
2824: @*/
2825: PetscErrorCode PetscOptionsGetReal(PetscOptions options, const char pre[], const char name[], PetscReal *dvalue, PetscBool *set)
2826: {
2827: const char *value;
2828: PetscBool flag;
2830: PetscFunctionBegin;
2831: PetscAssertPointer(name, 3);
2832: PetscAssertPointer(dvalue, 4);
2833: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2834: if (flag) {
2835: if (!value) {
2836: if (set) *set = PETSC_FALSE;
2837: } else {
2838: if (set) *set = PETSC_TRUE;
2839: PetscCall(PetscOptionsStringToReal(value, dvalue));
2840: }
2841: } else {
2842: if (set) *set = PETSC_FALSE;
2843: }
2844: PetscFunctionReturn(PETSC_SUCCESS);
2845: }
2847: /*@C
2848: PetscOptionsGetScalar - Gets the scalar value for a particular
2849: option in the database.
2851: Not Collective
2853: Input Parameters:
2854: + options - options database, use `NULL` for default global database
2855: . pre - string to prepend to each name or `NULL`
2856: - name - the option one is seeking
2858: Output Parameters:
2859: + dvalue - the scalar value to return
2860: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2862: Level: beginner
2864: Example Usage:
2865: A complex number 2+3i must be specified with NO spaces
2867: Note:
2868: If the user does not supply the option `dvalue` is NOT changed. Thus
2869: you should ALWAYS initialize `dvalue` if you access it without first checking if the `set` flag is true.
2871: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2872: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2873: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2874: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2875: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2876: `PetscOptionsFList()`, `PetscOptionsEList()`
2877: @*/
2878: PetscErrorCode PetscOptionsGetScalar(PetscOptions options, const char pre[], const char name[], PetscScalar *dvalue, PetscBool *set)
2879: {
2880: const char *value;
2881: PetscBool flag;
2883: PetscFunctionBegin;
2884: PetscAssertPointer(name, 3);
2885: PetscAssertPointer(dvalue, 4);
2886: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2887: if (flag) {
2888: if (!value) {
2889: if (set) *set = PETSC_FALSE;
2890: } else {
2891: #if !defined(PETSC_USE_COMPLEX)
2892: PetscCall(PetscOptionsStringToReal(value, dvalue));
2893: #else
2894: PetscCall(PetscOptionsStringToScalar(value, dvalue));
2895: #endif
2896: if (set) *set = PETSC_TRUE;
2897: }
2898: } else { /* flag */
2899: if (set) *set = PETSC_FALSE;
2900: }
2901: PetscFunctionReturn(PETSC_SUCCESS);
2902: }
2904: /*@C
2905: PetscOptionsGetString - Gets the string value for a particular option in
2906: the database.
2908: Not Collective
2910: Input Parameters:
2911: + options - options database, use `NULL` for default global database
2912: . pre - string to prepend to name or `NULL`
2913: . name - the option one is seeking
2914: - len - maximum length of the string including null termination
2916: Output Parameters:
2917: + string - location to copy string
2918: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2920: Level: beginner
2922: Note:
2923: 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`
2925: If the user does not use the option then `string` is not changed. Thus
2926: you should ALWAYS initialize `string` if you access it without first checking that the `set` flag is true.
2928: Fortran Notes:
2929: The Fortran interface is slightly different from the C/C++
2930: interface. Sample usage in Fortran follows
2931: .vb
2932: character *20 string
2933: PetscErrorCode ierr
2934: PetscBool set
2935: call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2936: .ve
2938: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
2939: `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2940: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2941: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2942: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2943: `PetscOptionsFList()`, `PetscOptionsEList()`
2944: @*/
2945: PetscErrorCode PetscOptionsGetString(PetscOptions options, const char pre[], const char name[], char string[], size_t len, PetscBool *set) PeNS
2946: {
2947: const char *value;
2948: PetscBool flag;
2950: PetscFunctionBegin;
2951: PetscAssertPointer(name, 3);
2952: PetscAssertPointer(string, 4);
2953: PetscCall(PetscOptionsFindPair(options, pre, name, &value, &flag));
2954: if (!flag) {
2955: if (set) *set = PETSC_FALSE;
2956: } else {
2957: if (set) *set = PETSC_TRUE;
2958: if (value) PetscCall(PetscStrncpy(string, value, len));
2959: else PetscCall(PetscArrayzero(string, len));
2960: }
2961: PetscFunctionReturn(PETSC_SUCCESS);
2962: }
2964: /*@C
2965: PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2966: option in the database. The values must be separated with commas with no intervening spaces.
2968: Not Collective
2970: Input Parameters:
2971: + options - options database, use `NULL` for default global database
2972: . pre - string to prepend to each name or `NULL`
2973: - name - the option one is seeking
2975: Output Parameters:
2976: + dvalue - the Boolean values to return
2977: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
2978: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
2980: Level: beginner
2982: Note:
2983: TRUE, true, YES, yes, nostring, and 1 all translate to `PETSC_TRUE`. FALSE, false, NO, no, and 0 all translate to `PETSC_FALSE`
2985: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
2986: `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
2987: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
2988: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
2989: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
2990: `PetscOptionsFList()`, `PetscOptionsEList()`
2991: @*/
2992: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options, const char pre[], const char name[], PetscBool dvalue[], PetscInt *nmax, PetscBool *set)
2993: {
2994: const char *svalue;
2995: const char *value;
2996: PetscInt n = 0;
2997: PetscBool flag;
2998: PetscToken token;
3000: PetscFunctionBegin;
3001: PetscAssertPointer(name, 3);
3002: PetscAssertPointer(nmax, 5);
3003: if (*nmax) PetscAssertPointer(dvalue, 4);
3005: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3006: if (!flag || !svalue) {
3007: if (set) *set = PETSC_FALSE;
3008: *nmax = 0;
3009: PetscFunctionReturn(PETSC_SUCCESS);
3010: }
3011: if (set) *set = PETSC_TRUE;
3012: PetscCall(PetscTokenCreate(svalue, ',', &token));
3013: PetscCall(PetscTokenFind(token, &value));
3014: while (value && n < *nmax) {
3015: PetscCall(PetscOptionsStringToBool(value, dvalue));
3016: PetscCall(PetscTokenFind(token, &value));
3017: dvalue++;
3018: n++;
3019: }
3020: PetscCall(PetscTokenDestroy(&token));
3021: *nmax = n;
3022: PetscFunctionReturn(PETSC_SUCCESS);
3023: }
3025: /*@C
3026: PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
3028: Not Collective
3030: Input Parameters:
3031: + options - options database, use `NULL` for default global database
3032: . pre - option prefix or `NULL`
3033: . name - option name
3034: - list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
3036: Output Parameters:
3037: + ivalue - the enum values to return
3038: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3039: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3041: Level: beginner
3043: Notes:
3044: The array must be passed as a comma separated list with no spaces between the items.
3046: `list` is usually something like `PCASMTypes` or some other predefined list of enum names.
3048: .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`,
3049: `PetscOptionsGetEnum()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3050: `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsName()`,
3051: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, `PetscOptionsStringArray()`, `PetscOptionsRealArray()`,
3052: `PetscOptionsScalar()`, `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3053: `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsGetEList()`, `PetscOptionsEnum()`
3054: @*/
3055: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options, const char pre[], const char name[], const char *const list[], PetscEnum ivalue[], PetscInt *nmax, PetscBool *set)
3056: {
3057: const char *svalue;
3058: const char *value;
3059: PetscInt n = 0;
3060: PetscEnum evalue;
3061: PetscBool flag;
3062: PetscToken token;
3064: PetscFunctionBegin;
3065: PetscAssertPointer(name, 3);
3066: PetscAssertPointer(list, 4);
3067: PetscAssertPointer(nmax, 6);
3068: if (*nmax) PetscAssertPointer(ivalue, 5);
3070: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3071: if (!flag || !svalue) {
3072: if (set) *set = PETSC_FALSE;
3073: *nmax = 0;
3074: PetscFunctionReturn(PETSC_SUCCESS);
3075: }
3076: if (set) *set = PETSC_TRUE;
3077: PetscCall(PetscTokenCreate(svalue, ',', &token));
3078: PetscCall(PetscTokenFind(token, &value));
3079: while (value && n < *nmax) {
3080: PetscCall(PetscEnumFind(list, value, &evalue, &flag));
3081: PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_USER, "Unknown enum value '%s' for -%s%s", svalue, pre ? pre : "", name + 1);
3082: ivalue[n++] = evalue;
3083: PetscCall(PetscTokenFind(token, &value));
3084: }
3085: PetscCall(PetscTokenDestroy(&token));
3086: *nmax = n;
3087: PetscFunctionReturn(PETSC_SUCCESS);
3088: }
3090: /*@C
3091: PetscOptionsGetIntArray - Gets an array of integer values for a particular option in the database.
3093: Not Collective
3095: Input Parameters:
3096: + options - options database, use `NULL` for default global database
3097: . pre - string to prepend to each name or `NULL`
3098: - name - the option one is seeking
3100: Output Parameters:
3101: + ivalue - the integer values to return
3102: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3103: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3105: Level: beginner
3107: Notes:
3108: The array can be passed as
3109: + a comma separated list - 0,1,2,3,4,5,6,7
3110: . a range (start\-end+1) - 0-8
3111: . a range with given increment (start\-end+1:inc) - 0-7:2
3112: - a combination of values and ranges separated by commas - 0,1-8,8-15:2
3114: There must be no intervening spaces between the values.
3116: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3117: `PetscOptionsGetString()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3118: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3119: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3120: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3121: `PetscOptionsFList()`, `PetscOptionsEList()`
3122: @*/
3123: PetscErrorCode PetscOptionsGetIntArray(PetscOptions options, const char pre[], const char name[], PetscInt ivalue[], PetscInt *nmax, PetscBool *set)
3124: {
3125: const char *svalue;
3126: const char *value;
3127: PetscInt n = 0, i, j, start, end, inc, nvalues;
3128: size_t len;
3129: PetscBool flag, foundrange;
3130: PetscToken token;
3132: PetscFunctionBegin;
3133: PetscAssertPointer(name, 3);
3134: PetscAssertPointer(nmax, 5);
3135: if (*nmax) PetscAssertPointer(ivalue, 4);
3137: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3138: if (!flag || !svalue) {
3139: if (set) *set = PETSC_FALSE;
3140: *nmax = 0;
3141: PetscFunctionReturn(PETSC_SUCCESS);
3142: }
3143: if (set) *set = PETSC_TRUE;
3144: PetscCall(PetscTokenCreate(svalue, ',', &token));
3145: PetscCall(PetscTokenFind(token, &value));
3146: while (value && n < *nmax) {
3147: char *iivalue;
3149: /* look for form d-D where d and D are integers */
3150: PetscCall(PetscStrallocpy(value, &iivalue));
3151: foundrange = PETSC_FALSE;
3152: PetscCall(PetscStrlen(iivalue, &len));
3153: if (iivalue[0] == '-') i = 2;
3154: else i = 1;
3155: for (; i < (int)len; i++) {
3156: if (iivalue[i] == '-') {
3157: PetscCheck(i != (int)len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, iivalue);
3158: iivalue[i] = 0;
3160: PetscCall(PetscOptionsStringToInt(iivalue, &start));
3161: inc = 1;
3162: j = i + 1;
3163: for (; j < (int)len; j++) {
3164: if (iivalue[j] == ':') {
3165: iivalue[j] = 0;
3167: PetscCall(PetscOptionsStringToInt(iivalue + j + 1, &inc));
3168: 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);
3169: break;
3170: }
3171: }
3172: PetscCall(PetscOptionsStringToInt(iivalue + i + 1, &end));
3173: 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);
3174: nvalues = (end - start) / inc + (end - start) % inc;
3175: 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);
3176: for (; start < end; start += inc) {
3177: *ivalue = start;
3178: ivalue++;
3179: n++;
3180: }
3181: foundrange = PETSC_TRUE;
3182: break;
3183: }
3184: }
3185: if (!foundrange) {
3186: PetscCall(PetscOptionsStringToInt(value, ivalue));
3187: ivalue++;
3188: n++;
3189: }
3190: PetscCall(PetscFree(iivalue));
3191: PetscCall(PetscTokenFind(token, &value));
3192: }
3193: PetscCall(PetscTokenDestroy(&token));
3194: *nmax = n;
3195: PetscFunctionReturn(PETSC_SUCCESS);
3196: }
3198: /*@C
3199: PetscOptionsGetRealArray - Gets an array of double precision values for a
3200: particular option in the database. The values must be separated with commas with no intervening spaces.
3202: Not Collective
3204: Input Parameters:
3205: + options - options database, use `NULL` for default global database
3206: . pre - string to prepend to each name or `NULL`
3207: - name - the option one is seeking
3209: Output Parameters:
3210: + dvalue - the double values to return
3211: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3212: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3214: Level: beginner
3216: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3217: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3218: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3219: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3220: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3221: `PetscOptionsFList()`, `PetscOptionsEList()`
3222: @*/
3223: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options, const char pre[], const char name[], PetscReal dvalue[], PetscInt *nmax, PetscBool *set)
3224: {
3225: const char *svalue;
3226: const char *value;
3227: PetscInt n = 0;
3228: PetscBool flag;
3229: PetscToken token;
3231: PetscFunctionBegin;
3232: PetscAssertPointer(name, 3);
3233: PetscAssertPointer(nmax, 5);
3234: if (*nmax) PetscAssertPointer(dvalue, 4);
3236: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3237: if (!flag || !svalue) {
3238: if (set) *set = PETSC_FALSE;
3239: *nmax = 0;
3240: PetscFunctionReturn(PETSC_SUCCESS);
3241: }
3242: if (set) *set = PETSC_TRUE;
3243: PetscCall(PetscTokenCreate(svalue, ',', &token));
3244: PetscCall(PetscTokenFind(token, &value));
3245: while (value && n < *nmax) {
3246: PetscCall(PetscOptionsStringToReal(value, dvalue++));
3247: PetscCall(PetscTokenFind(token, &value));
3248: n++;
3249: }
3250: PetscCall(PetscTokenDestroy(&token));
3251: *nmax = n;
3252: PetscFunctionReturn(PETSC_SUCCESS);
3253: }
3255: /*@C
3256: PetscOptionsGetScalarArray - Gets an array of scalars for a
3257: particular option in the database. The values must be separated with commas with no intervening spaces.
3259: Not Collective
3261: Input Parameters:
3262: + options - options database, use `NULL` for default global database
3263: . pre - string to prepend to each name or `NULL`
3264: - name - the option one is seeking
3266: Output Parameters:
3267: + dvalue - the scalar values to return
3268: . nmax - On input maximum number of values to retrieve, on output the actual number of values retrieved
3269: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3271: Level: beginner
3273: .seealso: `PetscOptionsGetInt()`, `PetscOptionsHasName()`,
3274: `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
3275: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3276: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3277: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3278: `PetscOptionsFList()`, `PetscOptionsEList()`
3279: @*/
3280: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options, const char pre[], const char name[], PetscScalar dvalue[], PetscInt *nmax, PetscBool *set)
3281: {
3282: const char *svalue;
3283: const char *value;
3284: PetscInt n = 0;
3285: PetscBool flag;
3286: PetscToken token;
3288: PetscFunctionBegin;
3289: PetscAssertPointer(name, 3);
3290: PetscAssertPointer(nmax, 5);
3291: if (*nmax) PetscAssertPointer(dvalue, 4);
3293: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3294: if (!flag || !svalue) {
3295: if (set) *set = PETSC_FALSE;
3296: *nmax = 0;
3297: PetscFunctionReturn(PETSC_SUCCESS);
3298: }
3299: if (set) *set = PETSC_TRUE;
3300: PetscCall(PetscTokenCreate(svalue, ',', &token));
3301: PetscCall(PetscTokenFind(token, &value));
3302: while (value && n < *nmax) {
3303: PetscCall(PetscOptionsStringToScalar(value, dvalue++));
3304: PetscCall(PetscTokenFind(token, &value));
3305: n++;
3306: }
3307: PetscCall(PetscTokenDestroy(&token));
3308: *nmax = n;
3309: PetscFunctionReturn(PETSC_SUCCESS);
3310: }
3312: /*@C
3313: PetscOptionsGetStringArray - Gets an array of string values for a particular
3314: option in the database. The values must be separated with commas with no intervening spaces.
3316: Not Collective; No Fortran Support
3318: Input Parameters:
3319: + options - options database, use `NULL` for default global database
3320: . pre - string to prepend to name or `NULL`
3321: - name - the option one is seeking
3323: Output Parameters:
3324: + strings - location to copy strings
3325: . nmax - On input maximum number of strings, on output the actual number of strings found
3326: - set - `PETSC_TRUE` if found, else `PETSC_FALSE`
3328: Level: beginner
3330: Notes:
3331: The `nmax` parameter is used for both input and output.
3333: The user should pass in an array of pointers to `char`, to hold all the
3334: strings returned by this function.
3336: The user is responsible for deallocating the strings that are
3337: returned.
3339: .seealso: `PetscOptionsGetInt()`, `PetscOptionsGetReal()`,
3340: `PetscOptionsHasName()`, `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
3341: `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
3342: `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
3343: `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
3344: `PetscOptionsFList()`, `PetscOptionsEList()`
3345: @*/
3346: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options, const char pre[], const char name[], char *strings[], PetscInt *nmax, PetscBool *set) PeNS
3347: {
3348: const char *svalue;
3349: const char *value;
3350: PetscInt n = 0;
3351: PetscBool flag;
3352: PetscToken token;
3354: PetscFunctionBegin;
3355: PetscAssertPointer(name, 3);
3356: PetscAssertPointer(nmax, 5);
3357: if (*nmax) PetscAssertPointer(strings, 4);
3359: PetscCall(PetscOptionsFindPair(options, pre, name, &svalue, &flag));
3360: if (!flag || !svalue) {
3361: if (set) *set = PETSC_FALSE;
3362: *nmax = 0;
3363: PetscFunctionReturn(PETSC_SUCCESS);
3364: }
3365: if (set) *set = PETSC_TRUE;
3366: PetscCall(PetscTokenCreate(svalue, ',', &token));
3367: PetscCall(PetscTokenFind(token, &value));
3368: while (value && n < *nmax) {
3369: PetscCall(PetscStrallocpy(value, &strings[n]));
3370: PetscCall(PetscTokenFind(token, &value));
3371: n++;
3372: }
3373: PetscCall(PetscTokenDestroy(&token));
3374: *nmax = n;
3375: PetscFunctionReturn(PETSC_SUCCESS);
3376: }
3378: /*@C
3379: PetscOptionsDeprecated_Private - mark an option as deprecated, optionally replacing it with `newname`
3381: Prints a deprecation warning, unless an option is supplied to suppress.
3383: Logically Collective
3385: Input Parameters:
3386: + PetscOptionsObject - string to prepend to name or `NULL`
3387: . oldname - the old, deprecated option
3388: . newname - the new option, or `NULL` if option is purely removed
3389: . version - a string describing the version of first deprecation, e.g. "3.9"
3390: - info - additional information string, or `NULL`.
3392: Options Database Key:
3393: . -options_suppress_deprecated_warnings - do not print deprecation warnings
3395: Level: developer
3397: Notes:
3398: If `newname` is provided then the options database will automatically check the database for `oldname`.
3400: The old call `PetscOptionsXXX`(`oldname`) should be removed from the source code when both (1) the call to `PetscOptionsDeprecated()` occurs before the
3401: new call to `PetscOptionsXXX`(`newname`) and (2) the argument handling of the new call to `PetscOptionsXXX`(`newname`) is identical to the previous call.
3402: See `PTScotch_PartGraph_Seq()` for an example of when (1) fails and `SNESTestJacobian()` where an example of (2) fails.
3404: Must be called between `PetscOptionsBegin()` (or `PetscObjectOptionsBegin()`) and `PetscOptionsEnd()`.
3405: Only the process of rank zero that owns the `PetscOptionsItems` are argument (managed by `PetscOptionsBegin()` or
3406: `PetscObjectOptionsBegin()` prints the information
3407: If newname is provided, the old option is replaced. Otherwise, it remains
3408: in the options database.
3409: If an option is not replaced, the info argument should be used to advise the user
3410: on how to proceed.
3411: There is a limit on the length of the warning printed, so very long strings
3412: provided as info may be truncated.
3414: .seealso: `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsScalar()`, `PetscOptionsBool()`, `PetscOptionsString()`, `PetscOptionsSetValue()`
3415: @*/
3416: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems PetscOptionsObject, const char oldname[], const char newname[], const char version[], const char info[])
3417: {
3418: PetscBool found, quiet;
3419: const char *value;
3420: const char *const quietopt = "-options_suppress_deprecated_warnings";
3421: char msg[4096];
3422: char *prefix = NULL;
3423: PetscOptions options = NULL;
3424: MPI_Comm comm = PETSC_COMM_SELF;
3426: PetscFunctionBegin;
3427: PetscAssertPointer(oldname, 2);
3428: PetscAssertPointer(version, 4);
3429: if (PetscOptionsObject) {
3430: prefix = PetscOptionsObject->prefix;
3431: options = PetscOptionsObject->options;
3432: comm = PetscOptionsObject->comm;
3433: }
3434: PetscCall(PetscOptionsFindPair(options, prefix, oldname, &value, &found));
3435: if (found) {
3436: if (newname) {
3437: PetscBool newfound;
3439: /* do not overwrite if the new option has been provided */
3440: PetscCall(PetscOptionsFindPair(options, prefix, newname, NULL, &newfound));
3441: if (!newfound) {
3442: if (prefix) PetscCall(PetscOptionsPrefixPush(options, prefix));
3443: PetscCall(PetscOptionsSetValue(options, newname, value));
3444: if (prefix) PetscCall(PetscOptionsPrefixPop(options));
3445: }
3446: PetscCall(PetscOptionsClearValue(options, oldname));
3447: }
3448: quiet = PETSC_FALSE;
3449: PetscCall(PetscOptionsGetBool(options, NULL, quietopt, &quiet, NULL));
3450: if (!quiet) {
3451: PetscCall(PetscStrncpy(msg, "** PETSc DEPRECATION WARNING ** : the option -", sizeof(msg)));
3452: PetscCall(PetscStrlcat(msg, prefix, sizeof(msg)));
3453: PetscCall(PetscStrlcat(msg, oldname + 1, sizeof(msg)));
3454: PetscCall(PetscStrlcat(msg, " is deprecated as of version ", sizeof(msg)));
3455: PetscCall(PetscStrlcat(msg, version, sizeof(msg)));
3456: PetscCall(PetscStrlcat(msg, " and will be removed in a future release.\n", sizeof(msg)));
3457: if (newname) {
3458: PetscCall(PetscStrlcat(msg, " Use the option -", sizeof(msg)));
3459: PetscCall(PetscStrlcat(msg, prefix, sizeof(msg)));
3460: PetscCall(PetscStrlcat(msg, newname + 1, sizeof(msg)));
3461: PetscCall(PetscStrlcat(msg, " instead.", sizeof(msg)));
3462: }
3463: if (info) {
3464: PetscCall(PetscStrlcat(msg, " ", sizeof(msg)));
3465: PetscCall(PetscStrlcat(msg, info, sizeof(msg)));
3466: }
3467: PetscCall(PetscStrlcat(msg, " (Silence this warning with ", sizeof(msg)));
3468: PetscCall(PetscStrlcat(msg, quietopt, sizeof(msg)));
3469: PetscCall(PetscStrlcat(msg, ")\n", sizeof(msg)));
3470: PetscCall(PetscPrintf(comm, "%s", msg));
3471: }
3472: }
3473: PetscFunctionReturn(PETSC_SUCCESS);
3474: }