Actual source code: options.c
petsc-3.14.6 2021-03-30
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
21: #if defined(PETSC_HAVE_YAML)
22: #include <yaml.h>
23: #endif
25: #if defined(PETSC_HAVE_STRCASECMP)
26: #define PetscOptNameCmp(a,b) strcasecmp(a,b)
27: #elif defined(PETSC_HAVE_STRICMP)
28: #define PetscOptNameCmp(a,b) stricmp(a,b)
29: #else
30: #define PetscOptNameCmp(a,b) Error_strcasecmp_not_found
31: #endif
33: #include <petsc/private/hashtable.h>
35: /* This assumes ASCII encoding and ignores locale settings */
36: /* Using tolower() is about 2X slower in microbenchmarks */
37: PETSC_STATIC_INLINE int PetscToLower(int c)
38: {
39: return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
40: }
42: /* Bob Jenkins's one at a time hash function (case-insensitive) */
43: PETSC_STATIC_INLINE unsigned int PetscOptHash(const char key[])
44: {
45: unsigned int hash = 0;
46: while (*key) {
47: hash += PetscToLower(*key++);
48: hash += hash << 10;
49: hash ^= hash >> 6;
50: }
51: hash += hash << 3;
52: hash ^= hash >> 11;
53: hash += hash << 15;
54: return hash;
55: }
57: PETSC_STATIC_INLINE int PetscOptEqual(const char a[],const char b[])
58: {
59: return !PetscOptNameCmp(a,b);
60: }
62: KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
64: /*
65: This table holds all the options set by the user. For simplicity, we use a static size database
66: */
67: #define MAXOPTNAME 512
68: #define MAXOPTIONS 512
69: #define MAXALIASES 25
70: #define MAXPREFIXES 25
71: #define MAXOPTIONSMONITORS 5
73: struct _n_PetscOptions {
74: PetscOptions previous;
75: int N; /* number of options */
76: char *names[MAXOPTIONS]; /* option names */
77: char *values[MAXOPTIONS]; /* option values */
78: PetscBool used[MAXOPTIONS]; /* flag option use */
79: PetscBool precedentProcessed;
81: /* Hash table */
82: khash_t(HO) *ht;
84: /* Prefixes */
85: int prefixind;
86: int prefixstack[MAXPREFIXES];
87: char prefix[MAXOPTNAME];
89: /* Aliases */
90: int Naliases; /* number or aliases */
91: char *aliases1[MAXALIASES]; /* aliased */
92: char *aliases2[MAXALIASES]; /* aliasee */
94: /* Help */
95: PetscBool help; /* flag whether "-help" is in the database */
96: PetscBool help_intro; /* flag whether "-help intro" is in the database */
98: /* Monitors */
99: PetscBool monitorFromOptions, monitorCancel;
100: PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[],const char[],void*); /* returns control to user after */
101: PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void**); /* */
102: void *monitorcontext[MAXOPTIONSMONITORS]; /* to pass arbitrary user data into monitor */
103: PetscInt numbermonitors; /* to, for instance, detect options being set */
104: };
106: static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
108: /* list of options which preceed others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
109: static const char *precedentOptions[] = {"-options_monitor","-options_monitor_cancel","-help","-skip_petscrc","-options_file_yaml","-options_string_yaml"};
110: enum PetscPrecedentOption {PO_OPTIONS_MONITOR,PO_OPTIONS_MONITOR_CANCEL,PO_HELP,PO_SKIP_PETSCRC,PO_OPTIONS_FILE_YAML,PO_OPTIONS_STRING_YAML,PO_NUM};
112: static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions,const char[],const char[],int*);
114: /*
115: Options events monitor
116: */
117: static PetscErrorCode PetscOptionsMonitor(PetscOptions options,const char name[],const char value[])
118: {
119: PetscInt i;
122: if (!PetscErrorHandlingInitialized) return 0;
124: if (!value) value = "";
125: if (options->monitorFromOptions) {
126: PetscOptionsMonitorDefault(name,value,NULL);
127: }
128: for (i=0; i<options->numbermonitors; i++) {
129: (*options->monitor[i])(name,value,options->monitorcontext[i]);
130: }
131: return(0);
132: }
134: /*@
135: PetscOptionsCreate - Creates an empty options database.
137: Logically collective
139: Output Parameter:
140: . options - Options database object
142: Level: advanced
144: Developer Note: We may want eventually to pass a MPI_Comm to determine the ownership of the object
146: .seealso: PetscOptionsDestroy(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsInsert(), PetscOptionsSetValue()
147: @*/
148: PetscErrorCode PetscOptionsCreate(PetscOptions *options)
149: {
150: if (!options) return PETSC_ERR_ARG_NULL;
151: *options = (PetscOptions)calloc(1,sizeof(**options));
152: if (!*options) return PETSC_ERR_MEM;
153: return 0;
154: }
156: /*@
157: PetscOptionsDestroy - Destroys an option database.
159: Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
161: Input Parameter:
162: . options - the PetscOptions object
164: Level: advanced
166: .seealso: PetscOptionsInsert(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsInsert(), PetscOptionsSetValue()
167: @*/
168: PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
169: {
172: if (!*options) return 0;
173: if ((*options)->previous) SETERRQ(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()");
174: PetscOptionsClear(*options);if (ierr) return ierr;
175: /* XXX what about monitors ? */
176: free(*options);
177: *options = NULL;
178: return(0);
179: }
181: /*
182: PetscOptionsCreateDefault - Creates the default global options database
183: */
184: PetscErrorCode PetscOptionsCreateDefault(void)
185: {
188: if (!defaultoptions) {
189: PetscOptionsCreate(&defaultoptions);if (ierr) return ierr;
190: }
191: return 0;
192: }
194: /*@
195: PetscOptionsPush - Push a new PetscOptions object as the default provider of options
196: Allows using different parts of a code to use different options databases
198: Logically Collective
200: Input Parameter:
201: . opt - the options obtained with PetscOptionsCreate()
203: Notes:
204: Use PetscOptionsPop() to return to the previous default options database
206: The collectivity of this routine is complex; only the MPI processes that call this routine will
207: have the affect of these options. If some processes that create objects call this routine and others do
208: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
209: on different ranks.
211: Level: advanced
213: .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsInsert(), PetscOptionsSetValue(), PetscOptionsLeft()
215: @*/
216: PetscErrorCode PetscOptionsPush(PetscOptions opt)
217: {
221: PetscOptionsCreateDefault();
222: opt->previous = defaultoptions;
223: defaultoptions = opt;
224: return(0);
225: }
227: /*@
228: PetscOptionsPop - Pop the most recent PetscOptionsPush() to return to the previous default options
230: Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
232: Notes:
233: Use PetscOptionsPop() to return to the previous default options database
234: Allows using different parts of a code to use different options databases
236: Level: advanced
238: .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsInsert(), PetscOptionsSetValue(), PetscOptionsLeft()
240: @*/
241: PetscErrorCode PetscOptionsPop(void)
242: {
243: PetscOptions current = defaultoptions;
246: if (!defaultoptions) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing default options");
247: if (!defaultoptions->previous) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PetscOptionsPop() called too many times");
248: defaultoptions = defaultoptions->previous;
249: current->previous = NULL;
250: return(0);
251: }
253: /*
254: PetscOptionsDestroyDefault - Destroys the default global options database
255: */
256: PetscErrorCode PetscOptionsDestroyDefault(void)
257: {
259: PetscOptions tmp;
261: if (!defaultoptions) return 0;
262: /* Destroy any options that the user forgot to pop */
263: while (defaultoptions->previous) {
264: tmp = defaultoptions;
265: PetscOptionsPop();
266: PetscOptionsDestroy(&tmp);
267: }
268: PetscOptionsDestroy(&defaultoptions);if (ierr) return ierr;
269: return 0;
270: }
272: /*@C
273: PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
275: Not collective
277: Input Parameter:
278: . key - string to check if valid
280: Output Parameter:
281: . valid - PETSC_TRUE if a valid key
283: Level: intermediate
284: @*/
285: PetscErrorCode PetscOptionsValidKey(const char key[],PetscBool *valid)
286: {
287: char *ptr;
292: *valid = PETSC_FALSE;
293: if (!key) return(0);
294: if (key[0] != '-') return(0);
295: if (key[1] == '-') key++;
296: if (!isalpha((int)key[1])) return(0);
297: (void) strtod(key,&ptr);
298: if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) return(0);
299: *valid = PETSC_TRUE;
300: return(0);
301: }
303: /*@C
304: PetscOptionsInsertString - Inserts options into the database from a string
306: Logically Collective
308: Input Parameter:
309: + options - options object
310: - in_str - string that contains options separated by blanks
312: Level: intermediate
314: The collectivity of this routine is complex; only the MPI processes that call this routine will
315: have the affect of these options. If some processes that create objects call this routine and others do
316: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
317: on different ranks.
319: Contributed by Boyana Norris
321: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
322: PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
323: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
324: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
325: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
326: PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile()
327: @*/
328: PetscErrorCode PetscOptionsInsertString(PetscOptions options,const char in_str[])
329: {
330: char *first,*second;
332: PetscToken token;
333: PetscBool key,ispush,ispop,isopts;
336: PetscTokenCreate(in_str,' ',&token);
337: PetscTokenFind(token,&first);
338: while (first) {
339: PetscStrcasecmp(first,"-prefix_push",&ispush);
340: PetscStrcasecmp(first,"-prefix_pop",&ispop);
341: PetscStrcasecmp(first,"-options_file",&isopts);
342: PetscOptionsValidKey(first,&key);
343: if (ispush) {
344: PetscTokenFind(token,&second);
345: PetscOptionsPrefixPush(options,second);
346: PetscTokenFind(token,&first);
347: } else if (ispop) {
348: PetscOptionsPrefixPop(options);
349: PetscTokenFind(token,&first);
350: } else if (isopts) {
351: PetscTokenFind(token,&second);
352: PetscOptionsInsertFile(PETSC_COMM_SELF,options,second,PETSC_TRUE);
353: PetscTokenFind(token,&first);
354: } else if (key) {
355: PetscTokenFind(token,&second);
356: PetscOptionsValidKey(second,&key);
357: if (!key) {
358: PetscOptionsSetValue(options,first,second);
359: PetscTokenFind(token,&first);
360: } else {
361: PetscOptionsSetValue(options,first,NULL);
362: first = second;
363: }
364: } else {
365: PetscTokenFind(token,&first);
366: }
367: }
368: PetscTokenDestroy(&token);
369: return(0);
370: }
372: /*
373: Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
374: */
375: static char *Petscgetline(FILE * f)
376: {
377: size_t size = 0;
378: size_t len = 0;
379: size_t last = 0;
380: char *buf = NULL;
382: if (feof(f)) return NULL;
383: do {
384: size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
385: buf = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
386: /* Actually do the read. Note that fgets puts a terminal '\0' on the
387: end of the string, so we make sure we overwrite this */
388: if (!fgets(buf+len,1024,f)) buf[len]=0;
389: PetscStrlen(buf,&len);
390: last = len - 1;
391: } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
392: if (len) return buf;
393: free(buf);
394: return NULL;
395: }
397: /*@C
398: PetscOptionsInsertFile - Inserts options into the database from a file.
400: Collective
402: Input Parameter:
403: + comm - the processes that will share the options (usually PETSC_COMM_WORLD)
404: . options - options database, use NULL for default global database
405: . file - name of file
406: - require - if PETSC_TRUE will generate an error if the file does not exist
409: Notes:
410: Use # for lines that are comments and which should be ignored.
411: Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
412: 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
413: calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().
414: The collectivity of this routine is complex; only the MPI processes in comm will
415: have the affect of these options. If some processes that create objects call this routine and others do
416: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
417: on different ranks.
419: Level: developer
421: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
422: PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
423: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
424: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
425: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
426: PetscOptionsFList(), PetscOptionsEList()
428: @*/
429: PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
430: {
431: char *string,fname[PETSC_MAX_PATH_LEN],*vstring = NULL,*astring = NULL,*packed = NULL;
432: char *tokens[4];
434: size_t i,len,bytes;
435: FILE *fd;
436: PetscToken token=NULL;
437: int err;
438: char *cmatch;
439: const char cmt='#';
440: PetscInt line=1;
441: PetscMPIInt rank,cnt=0,acnt=0,counts[2];
442: PetscBool isdir,alias=PETSC_FALSE,valid;
445: MPI_Comm_rank(comm,&rank);
446: PetscMemzero(tokens,sizeof(tokens));
447: if (!rank) {
448: cnt = 0;
449: acnt = 0;
451: PetscFixFilename(file,fname);
452: fd = fopen(fname,"r");
453: PetscTestDirectory(fname,'r',&isdir);
454: if (isdir && require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Specified options file %s is a directory",fname);
455: if (fd && !isdir) {
456: PetscSegBuffer vseg,aseg;
457: PetscSegBufferCreate(1,4000,&vseg);
458: PetscSegBufferCreate(1,2000,&aseg);
460: /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
461: PetscInfo1(NULL,"Opened options file %s\n",file);
463: while ((string = Petscgetline(fd))) {
464: /* eliminate comments from each line */
465: PetscStrchr(string,cmt,&cmatch);
466: if (cmatch) *cmatch = 0;
467: PetscStrlen(string,&len);
468: /* replace tabs, ^M, \n with " " */
469: for (i=0; i<len; i++) {
470: if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
471: string[i] = ' ';
472: }
473: }
474: PetscTokenCreate(string,' ',&token);
475: PetscTokenFind(token,&tokens[0]);
476: if (!tokens[0]) {
477: goto destroy;
478: } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
479: PetscTokenFind(token,&tokens[0]);
480: }
481: for (i=1; i<4; i++) {
482: PetscTokenFind(token,&tokens[i]);
483: }
484: if (!tokens[0]) {
485: goto destroy;
486: } else if (tokens[0][0] == '-') {
487: PetscOptionsValidKey(tokens[0],&valid);
488: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: invalid option %s",fname,line,tokens[0]);
489: PetscStrlen(tokens[0],&len);
490: PetscSegBufferGet(vseg,len+1,&vstring);
491: PetscArraycpy(vstring,tokens[0],len);
492: vstring[len] = ' ';
493: if (tokens[1]) {
494: PetscOptionsValidKey(tokens[1],&valid);
495: if (valid) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: cannot specify two options per line (%s %s)",fname,line,tokens[0],tokens[1]);
496: PetscStrlen(tokens[1],&len);
497: PetscSegBufferGet(vseg,len+3,&vstring);
498: vstring[0] = '"';
499: PetscArraycpy(vstring+1,tokens[1],len);
500: vstring[len+1] = '"';
501: vstring[len+2] = ' ';
502: }
503: } else {
504: PetscStrcasecmp(tokens[0],"alias",&alias);
505: if (alias) {
506: PetscOptionsValidKey(tokens[1],&valid);
507: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: invalid aliased option %s",fname,line,tokens[1]);
508: if (!tokens[2]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: alias missing for %s",fname,line,tokens[1]);
509: PetscOptionsValidKey(tokens[2],&valid);
510: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: invalid aliasee option %s",fname,line,tokens[2]);
511: PetscStrlen(tokens[1],&len);
512: PetscSegBufferGet(aseg,len+1,&astring);
513: PetscArraycpy(astring,tokens[1],len);
514: astring[len] = ' ';
516: PetscStrlen(tokens[2],&len);
517: PetscSegBufferGet(aseg,len+1,&astring);
518: PetscArraycpy(astring,tokens[2],len);
519: astring[len] = ' ';
520: } else SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown first token in options file %s line %D: %s",fname,line,tokens[0]);
521: }
522: {
523: const char *extraToken = alias ? tokens[3] : tokens[2];
524: if (extraToken) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: extra token %s",fname,line,extraToken);
525: }
526: destroy:
527: free(string);
528: PetscTokenDestroy(&token);
529: alias = PETSC_FALSE;
530: line++;
531: }
532: err = fclose(fd);
533: if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file %s",fname);
534: PetscSegBufferGetSize(aseg,&bytes); /* size without null termination */
535: PetscMPIIntCast(bytes,&acnt);
536: PetscSegBufferGet(aseg,1,&astring);
537: astring[0] = 0;
538: PetscSegBufferGetSize(vseg,&bytes); /* size without null termination */
539: PetscMPIIntCast(bytes,&cnt);
540: PetscSegBufferGet(vseg,1,&vstring);
541: vstring[0] = 0;
542: PetscMalloc1(2+acnt+cnt,&packed);
543: PetscSegBufferExtractTo(aseg,packed);
544: PetscSegBufferExtractTo(vseg,packed+acnt+1);
545: PetscSegBufferDestroy(&aseg);
546: PetscSegBufferDestroy(&vseg);
547: } else if (require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open options file %s",fname);
548: }
550: counts[0] = acnt;
551: counts[1] = cnt;
552: err = MPI_Bcast(counts,2,MPI_INT,0,comm);
553: if (err) SETERRQ(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://www.mcs.anl.gov/petsc/documentation/faq.html");
554: acnt = counts[0];
555: cnt = counts[1];
556: if (rank) {
557: PetscMalloc1(2+acnt+cnt,&packed);
558: }
559: if (acnt || cnt) {
560: MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm);
561: astring = packed;
562: vstring = packed + acnt + 1;
563: }
565: if (acnt) {
566: PetscTokenCreate(astring,' ',&token);
567: PetscTokenFind(token,&tokens[0]);
568: while (tokens[0]) {
569: PetscTokenFind(token,&tokens[1]);
570: PetscOptionsSetAlias(options,tokens[0],tokens[1]);
571: PetscTokenFind(token,&tokens[0]);
572: }
573: PetscTokenDestroy(&token);
574: }
576: if (cnt) {
577: PetscOptionsInsertString(options,vstring);
578: }
579: PetscFree(packed);
580: return(0);
581: }
583: static PetscErrorCode PetscOptionsInsertArgs(PetscOptions options,int argc,char *args[])
584: {
586: int left = argc - 1;
587: char **eargs = args + 1;
590: while (left) {
591: PetscBool isoptions_file,isprefixpush,isprefixpop,isp4,tisp4,isp4yourname,isp4rmrank,key;
592: PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);
593: PetscStrcasecmp(eargs[0],"-prefix_push",&isprefixpush);
594: PetscStrcasecmp(eargs[0],"-prefix_pop",&isprefixpop);
595: PetscStrcasecmp(eargs[0],"-p4pg",&isp4);
596: PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);
597: PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);
598: PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);
599: isp4 = (PetscBool) (isp4 || tisp4);
600: PetscStrcasecmp(eargs[0],"-np",&tisp4);
601: isp4 = (PetscBool) (isp4 || tisp4);
602: PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);
603: PetscOptionsValidKey(eargs[0],&key);
605: if (!key) {
606: eargs++; left--;
607: } else if (isoptions_file) {
608: if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
609: if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
610: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,eargs[1],PETSC_TRUE);
611: eargs += 2; left -= 2;
612: } else if (isprefixpush) {
613: if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
614: if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
615: PetscOptionsPrefixPush(options,eargs[1]);
616: eargs += 2; left -= 2;
617: } else if (isprefixpop) {
618: PetscOptionsPrefixPop(options);
619: eargs++; left--;
621: /*
622: These are "bad" options that MPICH, etc put on the command line
623: we strip them out here.
624: */
625: } else if (tisp4 || isp4rmrank) {
626: eargs += 1; left -= 1;
627: } else if (isp4 || isp4yourname) {
628: eargs += 2; left -= 2;
629: } else {
630: PetscBool nextiskey = PETSC_FALSE;
631: if (left >= 2) {PetscOptionsValidKey(eargs[1],&nextiskey);}
632: if (left < 2 || nextiskey) {
633: PetscOptionsSetValue(options,eargs[0],NULL);
634: eargs++; left--;
635: } else {
636: PetscOptionsSetValue(options,eargs[0],eargs[1]);
637: eargs += 2; left -= 2;
638: }
639: }
640: }
641: return(0);
642: }
644: PETSC_STATIC_INLINE PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt,const char *val[],PetscBool set[],PetscBool *flg)
645: {
649: if (set[opt]) {
650: PetscOptionsStringToBool(val[opt],flg);
651: } else *flg = PETSC_FALSE;
652: return(0);
653: }
655: /* Process options with absolute precedence */
656: static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options,int argc,char *args[],PetscBool *skip_petscrc,PetscBool *skip_petscrc_set)
657: {
658: const char* const *opt = precedentOptions;
659: const size_t n = PO_NUM;
660: size_t o;
661: int a;
662: const char **val;
663: PetscBool *set;
664: PetscErrorCode ierr;
667: PetscCalloc2(n,&val,n,&set);
669: /* Look for options possibly set using PetscOptionsSetValue beforehand */
670: for (o=0; o<n; o++) {
671: PetscOptionsFindPair(options,NULL,opt[o],&val[o],&set[o]);
672: }
674: /* Loop through all args to collect last occuring value of each option */
675: for (a=1; a<argc; a++) {
676: PetscBool valid, eq;
678: PetscOptionsValidKey(args[a],&valid);
679: if (!valid) continue;
680: for (o=0; o<n; o++) {
681: PetscStrcasecmp(args[a],opt[o],&eq);
682: if (eq) {
683: set[o] = PETSC_TRUE;
684: if (a == argc-1 || !args[a+1] || !args[a+1][0] || args[a+1][0] == '-') val[o] = NULL;
685: else val[o] = args[a+1];
686: break;
687: }
688: }
689: }
691: /* Process flags */
692: PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro);
693: if (options->help_intro) options->help = PETSC_TRUE;
694: else {PetscOptionsStringToBoolIfSet_Private(PO_HELP, val,set,&options->help);}
695: PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL,val,set,&options->monitorCancel);
696: PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val,set,&options->monitorFromOptions);
697: PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val,set,skip_petscrc);
698: *skip_petscrc_set = set[PO_SKIP_PETSCRC];
700: /* Store precedent options in database and mark them as used */
701: for (o=0; o<n; o++) {
702: if (set[o]) {
703: int pos;
705: PetscOptionsSetValue_Private(options,opt[o],val[o],&pos);
706: options->used[pos] = PETSC_TRUE;
707: }
708: }
710: PetscFree2(val,set);
711: options->precedentProcessed = PETSC_TRUE;
712: return(0);
713: }
715: PETSC_STATIC_INLINE PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options,const char name[],PetscBool *flg)
716: {
717: int i;
720: *flg = PETSC_FALSE;
721: if (options->precedentProcessed) {
722: for (i=0; i<PO_NUM; i++) {
723: if (!PetscOptNameCmp(precedentOptions[i],name)) {
724: /* check if precedent option has been set already */
725: PetscOptionsFindPair(options,NULL,name,NULL,flg);
726: if (*flg) break;
727: }
728: }
729: }
730: return(0);
731: }
733: /*@C
734: PetscOptionsInsert - Inserts into the options database from the command line,
735: the environmental variable and a file.
737: Collective on PETSC_COMM_WORLD
739: Input Parameters:
740: + options - options database or NULL for the default global database
741: . argc - count of number of command line arguments
742: . args - the command line arguments
743: - file - [optional] PETSc database file, also checks ~/.petscrc, .petscrc and petscrc.
744: Use NULL to not check for code specific file.
745: Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
747: Note:
748: Since PetscOptionsInsert() is automatically called by PetscInitialize(),
749: the user does not typically need to call this routine. PetscOptionsInsert()
750: can be called several times, adding additional entries into the database.
752: Options Database Keys:
753: . -options_file <filename> - read options from a file
755: See PetscInitialize() for options related to option database monitoring.
757: Level: advanced
759: .seealso: PetscOptionsDestroy(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
760: PetscInitialize()
761: @*/
762: PetscErrorCode PetscOptionsInsert(PetscOptions options,int *argc,char ***args,const char file[])
763: {
765: PetscMPIInt rank;
766: char filename[PETSC_MAX_PATH_LEN];
767: PetscBool hasArgs = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
768: PetscBool skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
772: if (hasArgs && !(args && *args)) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_NULL, "*argc > 1 but *args not given");
773: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
775: if (!options) {
776: PetscOptionsCreateDefault();
777: options = defaultoptions;
778: }
779: if (hasArgs) {
780: /* process options with absolute precedence */
781: PetscOptionsProcessPrecedentFlags(options,*argc,*args,&skipPetscrc,&skipPetscrcSet);
782: }
783: if (file && file[0]) {
784: PetscStrreplace(PETSC_COMM_WORLD,file,filename,PETSC_MAX_PATH_LEN);
785: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,filename,PETSC_TRUE);
786: /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
787: if (!skipPetscrcSet) {PetscOptionsGetBool(options,NULL,"-skip_petscrc",&skipPetscrc,NULL);}
788: }
789: if (!skipPetscrc) {
790: PetscGetHomeDirectory(filename,PETSC_MAX_PATH_LEN-16);
791: /* PetscOptionsInsertFile() does a fopen() on rank0 only - so only rank0 HomeDir value is relavent */
792: if (filename[0]) { PetscStrcat(filename,"/.petscrc"); }
793: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,filename,PETSC_FALSE);
794: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,".petscrc",PETSC_FALSE);
795: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,"petscrc",PETSC_FALSE);
796: }
798: /* insert environment options */
799: {
800: char *eoptions = NULL;
801: size_t len = 0;
802: if (!rank) {
803: eoptions = (char*)getenv("PETSC_OPTIONS");
804: PetscStrlen(eoptions,&len);
805: MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
806: } else {
807: MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
808: if (len) {
809: PetscMalloc1(len+1,&eoptions);
810: }
811: }
812: if (len) {
813: MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
814: if (rank) eoptions[len] = 0;
815: PetscOptionsInsertString(options,eoptions);
816: if (rank) {PetscFree(eoptions);}
817: }
818: }
820: #if defined(PETSC_HAVE_YAML)
821: {
822: char *eoptions = NULL;
823: size_t len = 0;
824: if (!rank) {
825: eoptions = (char*)getenv("PETSC_OPTIONS_YAML");
826: PetscStrlen(eoptions,&len);
827: MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
828: } else {
829: MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
830: if (len) {
831: PetscMalloc1(len+1,&eoptions);
832: }
833: }
834: if (len) {
835: MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
836: if (rank) eoptions[len] = 0;
837: PetscOptionsInsertStringYAML(options,eoptions);
838: if (rank) {PetscFree(eoptions);}
839: }
840: }
841: {
842: char yaml_file[PETSC_MAX_PATH_LEN];
843: char yaml_string[BUFSIZ];
844: PetscBool yaml_flg;
845: PetscOptionsGetString(NULL,NULL,"-options_file_yaml",yaml_file,sizeof(yaml_file),&yaml_flg);
846: if (yaml_flg) {
847: PetscOptionsInsertFileYAML(PETSC_COMM_WORLD,yaml_file,PETSC_TRUE);
848: }
849: PetscOptionsGetString(NULL,NULL,"-options_string_yaml",yaml_string,sizeof(yaml_string),&yaml_flg);
850: if (yaml_flg) {
851: PetscOptionsInsertStringYAML(NULL,yaml_string);
852: }
853: }
854: #endif
856: /* insert command line options here because they take precedence over arguments in petscrc/environment */
857: if (hasArgs) {PetscOptionsInsertArgs(options,*argc,*args);}
858: return(0);
859: }
861: /*@C
862: PetscOptionsView - Prints the options that have been loaded. This is
863: useful for debugging purposes.
865: Logically Collective on PetscViewer
867: Input Parameter:
868: + options - options database, use NULL for default global database
869: - viewer - must be an PETSCVIEWERASCII viewer
871: Options Database Key:
872: . -options_view - Activates PetscOptionsView() within PetscFinalize()
874: Notes:
875: Only the rank zero process of MPI_Comm used to create view prints the option values. Other processes
876: may have different values but they are not printed.
878: Level: advanced
880: .seealso: PetscOptionsAllUsed()
881: @*/
882: PetscErrorCode PetscOptionsView(PetscOptions options,PetscViewer viewer)
883: {
885: PetscInt i;
886: PetscBool isascii;
890: options = options ? options : defaultoptions;
891: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
892: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
893: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
895: if (!options->N) {
896: PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");
897: return(0);
898: }
900: PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");
901: for (i=0; i<options->N; i++) {
902: if (options->values[i]) {
903: PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);
904: } else {
905: PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);
906: }
907: }
908: PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");
909: return(0);
910: }
912: /*
913: Called by error handlers to print options used in run
914: */
915: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
916: {
917: PetscInt i;
918: PetscOptions options = defaultoptions;
921: if (options->N) {
922: (*PetscErrorPrintf)("PETSc Option Table entries:\n");
923: } else {
924: (*PetscErrorPrintf)("No PETSc Option Table entries\n");
925: }
926: for (i=0; i<options->N; i++) {
927: if (options->values[i]) {
928: (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]);
929: } else {
930: (*PetscErrorPrintf)("-%s\n",options->names[i]);
931: }
932: }
933: return(0);
934: }
936: /*@C
937: PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
939: Logically Collective
941: Input Parameter:
942: + options - options database, or NULL for the default global database
943: - prefix - The string to append to the existing prefix
945: Options Database Keys:
946: + -prefix_push <some_prefix_> - push the given prefix
947: - -prefix_pop - pop the last prefix
949: Notes:
950: It is common to use this in conjunction with -options_file as in
952: $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
954: where the files no longer require all options to be prefixed with -system2_.
956: The collectivity of this routine is complex; only the MPI processes that call this routine will
957: have the affect of these options. If some processes that create objects call this routine and others do
958: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
959: on different ranks.
961: Level: advanced
963: .seealso: PetscOptionsPrefixPop(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue()
964: @*/
965: PetscErrorCode PetscOptionsPrefixPush(PetscOptions options,const char prefix[])
966: {
968: size_t n;
969: PetscInt start;
970: char key[MAXOPTNAME+1];
971: PetscBool valid;
975: options = options ? options : defaultoptions;
976: if (options->prefixind >= MAXPREFIXES) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum depth of prefix stack %d exceeded, recompile \n src/sys/objects/options.c with larger value for MAXPREFIXES",MAXPREFIXES);
977: key[0] = '-'; /* keys must start with '-' */
978: PetscStrncpy(key+1,prefix,sizeof(key)-1);
979: PetscOptionsValidKey(key,&valid);
980: if (!valid && options->prefixind > 0 && isdigit((int)prefix[0])) valid = PETSC_TRUE; /* If the prefix stack is not empty, make numbers a valid prefix */
981: if (!valid) SETERRQ2(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":"");
982: start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
983: PetscStrlen(prefix,&n);
984: if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
985: PetscArraycpy(options->prefix+start,prefix,n+1);
986: options->prefixstack[options->prefixind++] = start+n;
987: return(0);
988: }
990: /*@C
991: PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details
993: Logically Collective on the MPI_Comm that called PetscOptionsPrefixPush()
995: Input Parameters:
996: . options - options database, or NULL for the default global database
998: Level: advanced
1000: .seealso: PetscOptionsPrefixPush(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue()
1001: @*/
1002: PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1003: {
1004: PetscInt offset;
1007: options = options ? options : defaultoptions;
1008: if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
1009: options->prefixind--;
1010: offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
1011: options->prefix[offset] = 0;
1012: return(0);
1013: }
1015: /*@C
1016: PetscOptionsClear - Removes all options form the database leaving it empty.
1018: Logically Collective
1020: Input Parameters:
1021: . options - options database, use NULL for the default global database
1023: The collectivity of this routine is complex; only the MPI processes that call this routine will
1024: have the affect of these options. If some processes that create objects call this routine and others do
1025: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1026: on different ranks.
1028: Level: developer
1030: .seealso: PetscOptionsInsert()
1031: @*/
1032: PetscErrorCode PetscOptionsClear(PetscOptions options)
1033: {
1034: PetscInt i;
1036: options = options ? options : defaultoptions;
1037: if (!options) return 0;
1039: for (i=0; i<options->N; i++) {
1040: if (options->names[i]) free(options->names[i]);
1041: if (options->values[i]) free(options->values[i]);
1042: }
1043: options->N = 0;
1045: for (i=0; i<options->Naliases; i++) {
1046: free(options->aliases1[i]);
1047: free(options->aliases2[i]);
1048: }
1049: options->Naliases = 0;
1051: /* destroy hash table */
1052: kh_destroy(HO,options->ht);
1053: options->ht = NULL;
1055: options->prefixind = 0;
1056: options->prefix[0] = 0;
1057: options->help = PETSC_FALSE;
1058: return 0;
1059: }
1061: /*@C
1062: PetscOptionsSetAlias - Makes a key and alias for another key
1064: Logically Collective
1066: Input Parameters:
1067: + options - options database, or NULL for default global database
1068: . newname - the alias
1069: - oldname - the name that alias will refer to
1071: Level: advanced
1073: The collectivity of this routine is complex; only the MPI processes that call this routine will
1074: have the affect of these options. If some processes that create objects call this routine and others do
1075: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1076: on different ranks.
1078: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1079: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
1080: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1081: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1082: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1083: PetscOptionsFList(), PetscOptionsEList()
1084: @*/
1085: PetscErrorCode PetscOptionsSetAlias(PetscOptions options,const char newname[],const char oldname[])
1086: {
1087: PetscInt n;
1088: size_t len;
1089: PetscBool valid;
1095: options = options ? options : defaultoptions;
1096: PetscOptionsValidKey(newname,&valid);
1097: if (!valid) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliased option %s",newname);
1098: PetscOptionsValidKey(oldname,&valid);
1099: if (!valid) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliasee option %s",oldname);
1101: n = options->Naliases;
1102: if (n >= MAXALIASES) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MEM,"You have defined to many PETSc options aliases, limit %d recompile \n src/sys/objects/options.c with larger value for MAXALIASES",MAXALIASES);
1104: newname++; oldname++;
1105: PetscStrlen(newname,&len);
1106: options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
1107: PetscStrcpy(options->aliases1[n],newname);
1108: PetscStrlen(oldname,&len);
1109: options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
1110: PetscStrcpy(options->aliases2[n],oldname);
1111: options->Naliases++;
1112: return(0);
1113: }
1115: /*@C
1116: PetscOptionsSetValue - Sets an option name-value pair in the options
1117: database, overriding whatever is already present.
1119: Logically Collective
1121: Input Parameters:
1122: + options - options database, use NULL for the default global database
1123: . name - name of option, this SHOULD have the - prepended
1124: - value - the option value (not used for all options, so can be NULL)
1126: Level: intermediate
1128: Note:
1129: This function can be called BEFORE PetscInitialize()
1131: The collectivity of this routine is complex; only the MPI processes that call this routine will
1132: have the affect of these options. If some processes that create objects call this routine and others do
1133: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1134: on different ranks.
1136: Developers Note: Uses malloc() directly because PETSc may not be initialized yet.
1138: .seealso: PetscOptionsInsert(), PetscOptionsClearValue()
1139: @*/
1140: PetscErrorCode PetscOptionsSetValue(PetscOptions options,const char name[],const char value[])
1141: {
1142: return PetscOptionsSetValue_Private(options,name,value,NULL);
1143: }
1145: static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options,const char name[],const char value[],int *pos)
1146: {
1147: size_t len;
1148: int N,n,i;
1149: char **names;
1150: char fullname[MAXOPTNAME] = "";
1151: PetscBool flg;
1154: if (!options) {
1155: PetscOptionsCreateDefault();if (ierr) return ierr;
1156: options = defaultoptions;
1157: }
1159: if (name[0] != '-') return PETSC_ERR_ARG_OUTOFRANGE;
1161: PetscOptionsSkipPrecedent(options,name,&flg);
1162: if (flg) return 0;
1164: name++; /* skip starting dash */
1166: if (options->prefixind > 0) {
1167: strncpy(fullname,options->prefix,sizeof(fullname));
1168: fullname[sizeof(fullname)-1] = 0;
1169: strncat(fullname,name,sizeof(fullname)-strlen(fullname)-1);
1170: fullname[sizeof(fullname)-1] = 0;
1171: name = fullname;
1172: }
1174: /* check against aliases */
1175: N = options->Naliases;
1176: for (i=0; i<N; i++) {
1177: int result = PetscOptNameCmp(options->aliases1[i],name);
1178: if (!result) { name = options->aliases2[i]; break; }
1179: }
1181: /* slow search */
1182: N = n = options->N;
1183: names = options->names;
1184: for (i=0; i<N; i++) {
1185: int result = PetscOptNameCmp(names[i],name);
1186: if (!result) {
1187: n = i; goto setvalue;
1188: } else if (result > 0) {
1189: n = i; break;
1190: }
1191: }
1192: if (N >= MAXOPTIONS) return PETSC_ERR_MEM;
1193: /* shift remaining values up 1 */
1194: for (i=N; i>n; i--) {
1195: options->names[i] = options->names[i-1];
1196: options->values[i] = options->values[i-1];
1197: options->used[i] = options->used[i-1];
1198: }
1199: options->names[n] = NULL;
1200: options->values[n] = NULL;
1201: options->used[n] = PETSC_FALSE;
1202: options->N++;
1204: /* destroy hash table */
1205: kh_destroy(HO,options->ht);
1206: options->ht = NULL;
1208: /* set new name */
1209: len = strlen(name);
1210: options->names[n] = (char*)malloc((len+1)*sizeof(char));
1211: if (!options->names[n]) return PETSC_ERR_MEM;
1212: strcpy(options->names[n],name);
1214: setvalue:
1215: /* set new value */
1216: if (options->values[n]) free(options->values[n]);
1217: len = value ? strlen(value) : 0;
1218: if (len) {
1219: options->values[n] = (char*)malloc((len+1)*sizeof(char));
1220: if (!options->values[n]) return PETSC_ERR_MEM;
1221: strcpy(options->values[n],value);
1222: } else {
1223: options->values[n] = NULL;
1224: }
1226: /* handle -help so that it can be set from anywhere */
1227: if (!PetscOptNameCmp(name,"help")) {
1228: options->help = PETSC_TRUE;
1229: PetscStrcasecmp(value, "intro", &options->help_intro);
1230: options->used[n] = PETSC_TRUE;
1231: }
1233: if (PetscErrorHandlingInitialized) {
1234: PetscOptionsMonitor(options,name,value);
1235: }
1236: if (pos) *pos = n;
1237: return 0;
1238: }
1240: /*@C
1241: PetscOptionsClearValue - Clears an option name-value pair in the options
1242: database, overriding whatever is already present.
1244: Logically Collective
1246: Input Parameter:
1247: + options - options database, use NULL for the default global database
1248: - name - name of option, this SHOULD have the - prepended
1250: Level: intermediate
1252: The collectivity of this routine is complex; only the MPI processes that call this routine will
1253: have the affect of these options. If some processes that create objects call this routine and others do
1254: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1255: on different ranks.
1257: .seealso: PetscOptionsInsert()
1258: @*/
1259: PetscErrorCode PetscOptionsClearValue(PetscOptions options,const char name[])
1260: {
1261: int N,n,i;
1262: char **names;
1266: options = options ? options : defaultoptions;
1267: if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1268: if (!PetscOptNameCmp(name,"-help")) options->help = options->help_intro = PETSC_FALSE;
1270: name++; /* skip starting dash */
1272: /* slow search */
1273: N = n = options->N;
1274: names = options->names;
1275: for (i=0; i<N; i++) {
1276: int result = PetscOptNameCmp(names[i],name);
1277: if (!result) {
1278: n = i; break;
1279: } else if (result > 0) {
1280: n = N; break;
1281: }
1282: }
1283: if (n == N) return(0); /* it was not present */
1285: /* remove name and value */
1286: if (options->names[n]) free(options->names[n]);
1287: if (options->values[n]) free(options->values[n]);
1288: /* shift remaining values down 1 */
1289: for (i=n; i<N-1; i++) {
1290: options->names[i] = options->names[i+1];
1291: options->values[i] = options->values[i+1];
1292: options->used[i] = options->used[i+1];
1293: }
1294: options->N--;
1296: /* destroy hash table */
1297: kh_destroy(HO,options->ht);
1298: options->ht = NULL;
1300: PetscOptionsMonitor(options,name,NULL);
1301: return(0);
1302: }
1304: /*@C
1305: PetscOptionsFindPair - Gets an option name-value pair from the options database.
1307: Not Collective
1309: Input Parameters:
1310: + options - options database, use NULL for the default global database
1311: . pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
1312: - name - name of option, this SHOULD have the "-" prepended
1314: Output Parameters:
1315: + value - the option value (optional, not used for all options)
1316: - set - whether the option is set (optional)
1318: Notes:
1319: Each process may find different values or no value depending on how options were inserted into the database
1321: Level: developer
1323: .seealso: PetscOptionsSetValue(), PetscOptionsClearValue()
1324: @*/
1325: PetscErrorCode PetscOptionsFindPair(PetscOptions options,const char pre[],const char name[],const char *value[],PetscBool *set)
1326: {
1327: char buf[MAXOPTNAME];
1328: PetscBool usehashtable = PETSC_TRUE;
1329: PetscBool matchnumbers = PETSC_TRUE;
1333: options = options ? options : defaultoptions;
1334: if (pre && PetscUnlikely(pre[0] == '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1335: if (PetscUnlikely(name[0] != '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1337: name++; /* skip starting dash */
1339: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1340: if (pre && pre[0]) {
1341: char *ptr = buf;
1342: if (name[0] == '-') { *ptr++ = '-'; name++; }
1343: PetscStrncpy(ptr,pre,buf+sizeof(buf)-ptr);
1344: PetscStrlcat(buf,name,sizeof(buf));
1345: name = buf;
1346: }
1348: if (PetscDefined(USE_DEBUG)) {
1349: PetscBool valid;
1350: char key[MAXOPTNAME+1] = "-";
1351: PetscStrncpy(key+1,name,sizeof(key)-1);
1352: PetscOptionsValidKey(key,&valid);
1353: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1354: }
1356: if (!options->ht && usehashtable) {
1357: int i,ret;
1358: khiter_t it;
1359: khash_t(HO) *ht;
1360: ht = kh_init(HO);
1361: if (PetscUnlikely(!ht)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1362: ret = kh_resize(HO,ht,options->N*2); /* twice the required size to reduce risk of collisions */
1363: if (PetscUnlikely(ret)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1364: for (i=0; i<options->N; i++) {
1365: it = kh_put(HO,ht,options->names[i],&ret);
1366: if (PetscUnlikely(ret != 1)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1367: kh_val(ht,it) = i;
1368: }
1369: options->ht = ht;
1370: }
1372: if (usehashtable)
1373: { /* fast search */
1374: khash_t(HO) *ht = options->ht;
1375: khiter_t it = kh_get(HO,ht,name);
1376: if (it != kh_end(ht)) {
1377: int i = kh_val(ht,it);
1378: options->used[i] = PETSC_TRUE;
1379: if (value) *value = options->values[i];
1380: if (set) *set = PETSC_TRUE;
1381: return(0);
1382: }
1383: } else
1384: { /* slow search */
1385: int i, N = options->N;
1386: for (i=0; i<N; i++) {
1387: int result = PetscOptNameCmp(options->names[i],name);
1388: if (!result) {
1389: options->used[i] = PETSC_TRUE;
1390: if (value) *value = options->values[i];
1391: if (set) *set = PETSC_TRUE;
1392: return(0);
1393: } else if (result > 0) {
1394: break;
1395: }
1396: }
1397: }
1399: /*
1400: The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
1401: Maybe this special lookup mode should be enabled on request with a push/pop API.
1402: The feature of matching _%d_ used sparingly in the codebase.
1403: */
1404: if (matchnumbers) {
1405: int i,j,cnt = 0,locs[16],loce[16];
1406: /* determine the location and number of all _%d_ in the key */
1407: for (i=0; name[i]; i++) {
1408: if (name[i] == '_') {
1409: for (j=i+1; name[j]; j++) {
1410: if (name[j] >= '0' && name[j] <= '9') continue;
1411: if (name[j] == '_' && j > i+1) { /* found a number */
1412: locs[cnt] = i+1;
1413: loce[cnt++] = j+1;
1414: }
1415: i = j-1;
1416: break;
1417: }
1418: }
1419: }
1420: for (i=0; i<cnt; i++) {
1421: PetscBool found;
1422: char opt[MAXOPTNAME+1] = "-", tmp[MAXOPTNAME];
1423: PetscStrncpy(tmp,name,PetscMin((size_t)(locs[i]+1),sizeof(tmp)));
1424: PetscStrlcat(opt,tmp,sizeof(opt));
1425: PetscStrlcat(opt,name+loce[i],sizeof(opt));
1426: PetscOptionsFindPair(options,NULL,opt,value,&found);
1427: if (found) {if (set) *set = PETSC_TRUE; return(0);}
1428: }
1429: }
1431: if (set) *set = PETSC_FALSE;
1432: return(0);
1433: }
1435: /* Check whether any option begins with pre+name */
1436: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options,const char pre[], const char name[],const char *value[],PetscBool *set)
1437: {
1438: char buf[MAXOPTNAME];
1439: int numCnt = 0, locs[16],loce[16];
1443: options = options ? options : defaultoptions;
1444: if (pre && pre[0] == '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1445: if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1447: name++; /* skip starting dash */
1449: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1450: if (pre && pre[0]) {
1451: char *ptr = buf;
1452: if (name[0] == '-') { *ptr++ = '-'; name++; }
1453: PetscStrncpy(ptr,pre,sizeof(buf)+(size_t)(ptr-buf));
1454: PetscStrlcat(buf,name,sizeof(buf));
1455: name = buf;
1456: }
1458: if (PetscDefined(USE_DEBUG)) {
1459: PetscBool valid;
1460: char key[MAXOPTNAME+1] = "-";
1461: PetscStrncpy(key+1,name,sizeof(key)-1);
1462: PetscOptionsValidKey(key,&valid);
1463: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1464: }
1466: /* determine the location and number of all _%d_ in the key */
1467: {
1468: int i,j;
1469: for (i=0; name[i]; i++) {
1470: if (name[i] == '_') {
1471: for (j=i+1; name[j]; j++) {
1472: if (name[j] >= '0' && name[j] <= '9') continue;
1473: if (name[j] == '_' && j > i+1) { /* found a number */
1474: locs[numCnt] = i+1;
1475: loce[numCnt++] = j+1;
1476: }
1477: i = j-1;
1478: break;
1479: }
1480: }
1481: }
1482: }
1484: { /* slow search */
1485: int c, i;
1486: size_t len;
1487: PetscBool match;
1489: for (c = -1; c < numCnt; ++c) {
1490: char opt[MAXOPTNAME+1] = "", tmp[MAXOPTNAME];
1492: if (c < 0) {
1493: PetscStrcpy(opt,name);
1494: } else {
1495: PetscStrncpy(tmp,name,PetscMin((size_t)(locs[c]+1),sizeof(tmp)));
1496: PetscStrlcat(opt,tmp,sizeof(opt));
1497: PetscStrlcat(opt,name+loce[c],sizeof(opt));
1498: }
1499: PetscStrlen(opt,&len);
1500: for (i=0; i<options->N; i++) {
1501: PetscStrncmp(options->names[i],opt,len,&match);
1502: if (match) {
1503: options->used[i] = PETSC_TRUE;
1504: if (value) *value = options->values[i];
1505: if (set) *set = PETSC_TRUE;
1506: return(0);
1507: }
1508: }
1509: }
1510: }
1512: if (set) *set = PETSC_FALSE;
1513: return(0);
1514: }
1516: /*@C
1517: PetscOptionsReject - Generates an error if a certain option is given.
1519: Not Collective
1521: Input Parameters:
1522: + options - options database, use NULL for default global database
1523: . pre - the option prefix (may be NULL)
1524: . name - the option name one is seeking
1525: - mess - error message (may be NULL)
1527: Level: advanced
1529: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1530: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1531: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1532: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1533: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1534: PetscOptionsFList(), PetscOptionsEList()
1535: @*/
1536: PetscErrorCode PetscOptionsReject(PetscOptions options,const char pre[],const char name[],const char mess[])
1537: {
1539: PetscBool flag = PETSC_FALSE;
1542: PetscOptionsHasName(options,pre,name,&flag);
1543: if (flag) {
1544: if (mess && mess[0]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s with %s",pre?pre:"",name+1,mess);
1545: else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s",pre?pre:"",name+1);
1546: }
1547: return(0);
1548: }
1550: /*@C
1551: PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
1553: Not Collective
1555: Input Parameters:
1556: . options - options database, use NULL for default global database
1558: Output Parameters:
1559: . set - PETSC_TRUE if found else PETSC_FALSE.
1561: Level: advanced
1563: .seealso: PetscOptionsHasName()
1564: @*/
1565: PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set)
1566: {
1569: options = options ? options : defaultoptions;
1570: *set = options->help;
1571: return(0);
1572: }
1574: PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options,PetscBool *set)
1575: {
1578: options = options ? options : defaultoptions;
1579: *set = options->help_intro;
1580: return(0);
1581: }
1583: /*@C
1584: PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or boolean, even
1585: its value is set to false.
1587: Not Collective
1589: Input Parameters:
1590: + options - options database, use NULL for default global database
1591: . pre - string to prepend to the name or NULL
1592: - name - the option one is seeking
1594: Output Parameters:
1595: . set - PETSC_TRUE if found else PETSC_FALSE.
1597: Level: beginner
1599: Notes:
1600: In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.
1602: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1603: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1604: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1605: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1606: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1607: PetscOptionsFList(), PetscOptionsEList()
1608: @*/
1609: PetscErrorCode PetscOptionsHasName(PetscOptions options,const char pre[],const char name[],PetscBool *set)
1610: {
1611: const char *value;
1613: PetscBool flag;
1616: PetscOptionsFindPair(options,pre,name,&value,&flag);
1617: if (set) *set = flag;
1618: return(0);
1619: }
1621: /*@C
1622: PetscOptionsGetAll - Lists all the options the program was run with in a single string.
1624: Not Collective
1626: Input Parameter:
1627: . options - the options database, use NULL for the default global database
1629: Output Parameter:
1630: . copts - pointer where string pointer is stored
1632: Notes:
1633: The array and each entry in the array should be freed with PetscFree()
1634: Each process may have different values depending on how the options were inserted into the database
1636: Level: advanced
1638: .seealso: PetscOptionsAllUsed(), PetscOptionsView(), PetscOptionsPush(), PetscOptionsPop()
1639: @*/
1640: PetscErrorCode PetscOptionsGetAll(PetscOptions options,char *copts[])
1641: {
1643: PetscInt i;
1644: size_t len = 1,lent = 0;
1645: char *coptions = NULL;
1649: options = options ? options : defaultoptions;
1650: /* count the length of the required string */
1651: for (i=0; i<options->N; i++) {
1652: PetscStrlen(options->names[i],&lent);
1653: len += 2 + lent;
1654: if (options->values[i]) {
1655: PetscStrlen(options->values[i],&lent);
1656: len += 1 + lent;
1657: }
1658: }
1659: PetscMalloc1(len,&coptions);
1660: coptions[0] = 0;
1661: for (i=0; i<options->N; i++) {
1662: PetscStrcat(coptions,"-");
1663: PetscStrcat(coptions,options->names[i]);
1664: PetscStrcat(coptions," ");
1665: if (options->values[i]) {
1666: PetscStrcat(coptions,options->values[i]);
1667: PetscStrcat(coptions," ");
1668: }
1669: }
1670: *copts = coptions;
1671: return(0);
1672: }
1674: /*@C
1675: PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
1677: Not Collective
1679: Input Parameter:
1680: + options - options database, use NULL for default global database
1681: - name - string name of option
1683: Output Parameter:
1684: . used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database
1686: Level: advanced
1688: Notes:
1689: The value returned may be different on each process and depends on which options have been processed
1690: on the given process
1692: .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
1693: @*/
1694: PetscErrorCode PetscOptionsUsed(PetscOptions options,const char *name,PetscBool *used)
1695: {
1696: PetscInt i;
1702: options = options ? options : defaultoptions;
1703: *used = PETSC_FALSE;
1704: for (i=0; i<options->N; i++) {
1705: PetscStrcasecmp(options->names[i],name,used);
1706: if (*used) {
1707: *used = options->used[i];
1708: break;
1709: }
1710: }
1711: return(0);
1712: }
1714: /*@
1715: PetscOptionsAllUsed - Returns a count of the number of options in the
1716: database that have never been selected.
1718: Not Collective
1720: Input Parameter:
1721: . options - options database, use NULL for default global database
1723: Output Parameter:
1724: . N - count of options not used
1726: Level: advanced
1728: Notes:
1729: The value returned may be different on each process and depends on which options have been processed
1730: on the given process
1732: .seealso: PetscOptionsView()
1733: @*/
1734: PetscErrorCode PetscOptionsAllUsed(PetscOptions options,PetscInt *N)
1735: {
1736: PetscInt i,n = 0;
1740: options = options ? options : defaultoptions;
1741: for (i=0; i<options->N; i++) {
1742: if (!options->used[i]) n++;
1743: }
1744: *N = n;
1745: return(0);
1746: }
1748: /*@
1749: PetscOptionsLeft - Prints to screen any options that were set and never used.
1751: Not Collective
1753: Input Parameter:
1754: . options - options database; use NULL for default global database
1756: Options Database Key:
1757: . -options_left - activates PetscOptionsAllUsed() within PetscFinalize()
1759: Notes:
1760: This is rarely used directly, it is called by PetscFinalize() in debug more or if -options_left
1761: is passed otherwise to help users determine possible mistakes in their usage of options. This
1762: only prints values on process zero of PETSC_COMM_WORLD. Other processes depending the objects
1763: used may have different options that are left unused.
1765: Level: advanced
1767: .seealso: PetscOptionsAllUsed()
1768: @*/
1769: PetscErrorCode PetscOptionsLeft(PetscOptions options)
1770: {
1772: PetscInt i;
1773: PetscInt cnt = 0;
1774: PetscOptions toptions;
1777: toptions = options ? options : defaultoptions;
1778: for (i=0; i<toptions->N; i++) {
1779: if (!toptions->used[i]) {
1780: if (toptions->values[i]) {
1781: PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",toptions->names[i],toptions->values[i]);
1782: } else {
1783: PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",toptions->names[i]);
1784: }
1785: }
1786: }
1787: if (!options) {
1788: toptions = defaultoptions;
1789: while (toptions->previous) {
1790: cnt++;
1791: toptions = toptions->previous;
1792: }
1793: if (cnt) {
1794: PetscPrintf(PETSC_COMM_WORLD,"Option left: You may have forgotten some calls to PetscOptionsPop(),\n PetscOptionsPop() has been called %D less times than PetscOptionsPush()\n",cnt);
1795: }
1796: }
1797: return(0);
1798: }
1800: /*@C
1801: PetscOptionsLeftGet - Returns all options that were set and never used.
1803: Not Collective
1805: Input Parameter:
1806: . options - options database, use NULL for default global database
1808: Output Parameter:
1809: + N - count of options not used
1810: . names - names of options not used
1811: - values - values of options not used
1813: Level: advanced
1815: Notes:
1816: Users should call PetscOptionsLeftRestore() to free the memory allocated in this routine
1817: Notes: The value returned may be different on each process and depends on which options have been processed
1818: on the given process
1820: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft()
1821: @*/
1822: PetscErrorCode PetscOptionsLeftGet(PetscOptions options,PetscInt *N,char **names[],char **values[])
1823: {
1825: PetscInt i,n;
1831: options = options ? options : defaultoptions;
1833: /* The number of unused PETSc options */
1834: n = 0;
1835: for (i=0; i<options->N; i++) {
1836: if (!options->used[i]) n++;
1837: }
1838: if (N) { *N = n; }
1839: if (names) { PetscMalloc1(n,names); }
1840: if (values) { PetscMalloc1(n,values); }
1842: n = 0;
1843: if (names || values) {
1844: for (i=0; i<options->N; i++) {
1845: if (!options->used[i]) {
1846: if (names) (*names)[n] = options->names[i];
1847: if (values) (*values)[n] = options->values[i];
1848: n++;
1849: }
1850: }
1851: }
1852: return(0);
1853: }
1855: /*@C
1856: PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using PetscOptionsLeftGet.
1858: Not Collective
1860: Input Parameter:
1861: + options - options database, use NULL for default global database
1862: . names - names of options not used
1863: - values - values of options not used
1865: Level: advanced
1867: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft(), PetscOptionsLeftGet()
1868: @*/
1869: PetscErrorCode PetscOptionsLeftRestore(PetscOptions options,PetscInt *N,char **names[],char **values[])
1870: {
1877: if (N) { *N = 0; }
1878: if (names) { PetscFree(*names); }
1879: if (values) { PetscFree(*values); }
1880: return(0);
1881: }
1883: /*@C
1884: PetscOptionsMonitorDefault - Print all options set value events using the supplied PetscViewer.
1886: Logically Collective on ctx
1888: Input Parameters:
1889: + name - option name string
1890: . value - option value string
1891: - ctx - an ASCII viewer or NULL
1893: Level: intermediate
1895: Notes:
1896: If ctx=NULL, PetscPrintf() is used.
1897: The first MPI rank in the PetscViewer viewer actually prints the values, other
1898: processes may have different values set
1900: .seealso: PetscOptionsMonitorSet()
1901: @*/
1902: PetscErrorCode PetscOptionsMonitorDefault(const char name[],const char value[],void *ctx)
1903: {
1907: if (ctx) {
1908: PetscViewer viewer = (PetscViewer)ctx;
1909: if (!value) {
1910: PetscViewerASCIIPrintf(viewer,"Removing option: %s\n",name,value);
1911: } else if (!value[0]) {
1912: PetscViewerASCIIPrintf(viewer,"Setting option: %s (no value)\n",name);
1913: } else {
1914: PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
1915: }
1916: } else {
1917: MPI_Comm comm = PETSC_COMM_WORLD;
1918: if (!value) {
1919: PetscPrintf(comm,"Removing option: %s\n",name,value);
1920: } else if (!value[0]) {
1921: PetscPrintf(comm,"Setting option: %s (no value)\n",name);
1922: } else {
1923: PetscPrintf(comm,"Setting option: %s = %s\n",name,value);
1924: }
1925: }
1926: return(0);
1927: }
1929: /*@C
1930: PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
1931: modified the PETSc options database.
1933: Not Collective
1935: Input Parameters:
1936: + monitor - pointer to function (if this is NULL, it turns off monitoring
1937: . mctx - [optional] context for private data for the
1938: monitor routine (use NULL if no context is desired)
1939: - monitordestroy - [optional] routine that frees monitor context
1940: (may be NULL)
1942: Calling Sequence of monitor:
1943: $ monitor (const char name[], const char value[], void *mctx)
1945: + name - option name string
1946: . value - option value string
1947: - mctx - optional monitoring context, as set by PetscOptionsMonitorSet()
1949: Options Database Keys:
1950: See PetscInitialize() for options related to option database monitoring.
1952: Notes:
1953: The default is to do nothing. To print the name and value of options
1954: being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
1955: with a null monitoring context.
1957: Several different monitoring routines may be set by calling
1958: PetscOptionsMonitorSet() multiple times; all will be called in the
1959: order in which they were set.
1961: Level: intermediate
1963: .seealso: PetscOptionsMonitorDefault(), PetscInitialize()
1964: @*/
1965: PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
1966: {
1967: PetscOptions options = defaultoptions;
1970: if (options->monitorCancel) return(0);
1971: if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
1972: options->monitor[options->numbermonitors] = monitor;
1973: options->monitordestroy[options->numbermonitors] = monitordestroy;
1974: options->monitorcontext[options->numbermonitors++] = (void*)mctx;
1975: return(0);
1976: }
1978: /*
1979: PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
1980: Empty string is considered as true.
1981: */
1982: PetscErrorCode PetscOptionsStringToBool(const char value[],PetscBool *a)
1983: {
1984: PetscBool istrue,isfalse;
1985: size_t len;
1989: /* PetscStrlen() returns 0 for NULL or "" */
1990: PetscStrlen(value,&len);
1991: if (!len) {*a = PETSC_TRUE; return(0);}
1992: PetscStrcasecmp(value,"TRUE",&istrue);
1993: if (istrue) {*a = PETSC_TRUE; return(0);}
1994: PetscStrcasecmp(value,"YES",&istrue);
1995: if (istrue) {*a = PETSC_TRUE; return(0);}
1996: PetscStrcasecmp(value,"1",&istrue);
1997: if (istrue) {*a = PETSC_TRUE; return(0);}
1998: PetscStrcasecmp(value,"on",&istrue);
1999: if (istrue) {*a = PETSC_TRUE; return(0);}
2000: PetscStrcasecmp(value,"FALSE",&isfalse);
2001: if (isfalse) {*a = PETSC_FALSE; return(0);}
2002: PetscStrcasecmp(value,"NO",&isfalse);
2003: if (isfalse) {*a = PETSC_FALSE; return(0);}
2004: PetscStrcasecmp(value,"0",&isfalse);
2005: if (isfalse) {*a = PETSC_FALSE; return(0);}
2006: PetscStrcasecmp(value,"off",&isfalse);
2007: if (isfalse) {*a = PETSC_FALSE; return(0);}
2008: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value);
2009: }
2011: /*
2012: PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
2013: */
2014: PetscErrorCode PetscOptionsStringToInt(const char name[],PetscInt *a)
2015: {
2017: size_t len;
2018: PetscBool decide,tdefault,mouse;
2021: PetscStrlen(name,&len);
2022: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
2024: PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
2025: if (!tdefault) {
2026: PetscStrcasecmp(name,"DEFAULT",&tdefault);
2027: }
2028: PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
2029: if (!decide) {
2030: PetscStrcasecmp(name,"DECIDE",&decide);
2031: }
2032: PetscStrcasecmp(name,"mouse",&mouse);
2034: if (tdefault) *a = PETSC_DEFAULT;
2035: else if (decide) *a = PETSC_DECIDE;
2036: else if (mouse) *a = -1;
2037: else {
2038: char *endptr;
2039: long strtolval;
2041: strtolval = strtol(name,&endptr,10);
2042: if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);
2044: #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
2045: (void) strtolval;
2046: *a = atoll(name);
2047: #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
2048: (void) strtolval;
2049: *a = _atoi64(name);
2050: #else
2051: *a = (PetscInt)strtolval;
2052: #endif
2053: }
2054: return(0);
2055: }
2057: #if defined(PETSC_USE_REAL___FLOAT128)
2058: #include <quadmath.h>
2059: #endif
2061: static PetscErrorCode PetscStrtod(const char name[],PetscReal *a,char **endptr)
2062: {
2064: #if defined(PETSC_USE_REAL___FLOAT128)
2065: *a = strtoflt128(name,endptr);
2066: #else
2067: *a = (PetscReal)strtod(name,endptr);
2068: #endif
2069: return(0);
2070: }
2072: static PetscErrorCode PetscStrtoz(const char name[],PetscScalar *a,char **endptr,PetscBool *isImaginary)
2073: {
2074: PetscBool hasi = PETSC_FALSE;
2075: char *ptr;
2076: PetscReal strtoval;
2080: PetscStrtod(name,&strtoval,&ptr);
2081: if (ptr == name) {
2082: strtoval = 1.;
2083: hasi = PETSC_TRUE;
2084: if (name[0] == 'i') {
2085: ptr++;
2086: } else if (name[0] == '+' && name[1] == 'i') {
2087: ptr += 2;
2088: } else if (name[0] == '-' && name[1] == 'i') {
2089: strtoval = -1.;
2090: ptr += 2;
2091: }
2092: } else if (*ptr == 'i') {
2093: hasi = PETSC_TRUE;
2094: ptr++;
2095: }
2096: *endptr = ptr;
2097: *isImaginary = hasi;
2098: if (hasi) {
2099: #if !defined(PETSC_USE_COMPLEX)
2100: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s contains imaginary but complex not supported ",name);
2101: #else
2102: *a = PetscCMPLX(0.,strtoval);
2103: #endif
2104: } else {
2105: *a = strtoval;
2106: }
2107: return(0);
2108: }
2110: /*
2111: Converts a string to PetscReal value. Handles special cases like "default" and "decide"
2112: */
2113: PetscErrorCode PetscOptionsStringToReal(const char name[],PetscReal *a)
2114: {
2115: size_t len;
2116: PetscBool match;
2117: char *endptr;
2121: PetscStrlen(name,&len);
2122: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"String of length zero has no numerical value");
2124: PetscStrcasecmp(name,"PETSC_DEFAULT",&match);
2125: if (!match) {
2126: PetscStrcasecmp(name,"DEFAULT",&match);
2127: }
2128: if (match) {*a = PETSC_DEFAULT; return(0);}
2130: PetscStrcasecmp(name,"PETSC_DECIDE",&match);
2131: if (!match) {
2132: PetscStrcasecmp(name,"DECIDE",&match);
2133: }
2134: if (match) {*a = PETSC_DECIDE; return(0);}
2136: PetscStrtod(name,a,&endptr);
2137: if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value",name);
2138: return(0);
2139: }
2141: PetscErrorCode PetscOptionsStringToScalar(const char name[],PetscScalar *a)
2142: {
2143: PetscBool imag1;
2144: size_t len;
2145: PetscScalar val = 0.;
2146: char *ptr = NULL;
2150: PetscStrlen(name,&len);
2151: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
2152: PetscStrtoz(name,&val,&ptr,&imag1);
2153: #if defined(PETSC_USE_COMPLEX)
2154: if ((size_t) (ptr - name) < len) {
2155: PetscBool imag2;
2156: PetscScalar val2;
2158: PetscStrtoz(ptr,&val2,&ptr,&imag2);
2159: if (imag1 || !imag2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s: must specify imaginary component second",name);
2160: val = PetscCMPLX(PetscRealPart(val),PetscImaginaryPart(val2));
2161: }
2162: #endif
2163: if ((size_t) (ptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
2164: *a = val;
2165: return(0);
2166: }
2168: /*@C
2169: PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
2170: option in the database.
2172: Not Collective
2174: Input Parameters:
2175: + options - options database, use NULL for default global database
2176: . pre - the string to prepend to the name or NULL
2177: - name - the option one is seeking
2179: Output Parameter:
2180: + ivalue - the logical value to return
2181: - set - PETSC_TRUE if found, else PETSC_FALSE
2183: Level: beginner
2185: Notes:
2186: TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
2187: FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
2189: 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
2190: is equivalent to -requested_bool true
2192: If the user does not supply the option at all ivalue is NOT changed. Thus
2193: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2195: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
2196: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
2197: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2198: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2199: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2200: PetscOptionsFList(), PetscOptionsEList()
2201: @*/
2202: PetscErrorCode PetscOptionsGetBool(PetscOptions options,const char pre[],const char name[],PetscBool *ivalue,PetscBool *set)
2203: {
2204: const char *value;
2205: PetscBool flag;
2211: PetscOptionsFindPair(options,pre,name,&value,&flag);
2212: if (flag) {
2213: if (set) *set = PETSC_TRUE;
2214: PetscOptionsStringToBool(value, &flag);
2215: if (ivalue) *ivalue = flag;
2216: } else {
2217: if (set) *set = PETSC_FALSE;
2218: }
2219: return(0);
2220: }
2222: /*@C
2223: PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2225: Not Collective
2227: Input Parameters:
2228: + options - options database, use NULL for default global database
2229: . pre - the string to prepend to the name or NULL
2230: . opt - option name
2231: . list - the possible choices (one of these must be selected, anything else is invalid)
2232: - ntext - number of choices
2234: Output Parameter:
2235: + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2236: - set - PETSC_TRUE if found, else PETSC_FALSE
2238: Level: intermediate
2240: Notes:
2241: If the user does not supply the option value is NOT changed. Thus
2242: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2244: See PetscOptionsFList() for when the choices are given in a PetscFunctionList()
2246: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2247: PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2248: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2249: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2250: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2251: PetscOptionsFList(), PetscOptionsEList()
2252: @*/
2253: PetscErrorCode PetscOptionsGetEList(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool *set)
2254: {
2256: size_t alen,len = 0, tlen = 0;
2257: char *svalue;
2258: PetscBool aset,flg = PETSC_FALSE;
2259: PetscInt i;
2263: for (i=0; i<ntext; i++) {
2264: PetscStrlen(list[i],&alen);
2265: if (alen > len) len = alen;
2266: tlen += len + 1;
2267: }
2268: len += 5; /* a little extra space for user mistypes */
2269: PetscMalloc1(len,&svalue);
2270: PetscOptionsGetString(options,pre,opt,svalue,len,&aset);
2271: if (aset) {
2272: PetscEListFind(ntext,list,svalue,value,&flg);
2273: if (!flg) {
2274: char *avail,*pavl;
2276: PetscMalloc1(tlen,&avail);
2277: pavl = avail;
2278: for (i=0; i<ntext; i++) {
2279: PetscStrlen(list[i],&alen);
2280: PetscStrcpy(pavl,list[i]);
2281: pavl += alen;
2282: PetscStrcpy(pavl," ");
2283: pavl += 1;
2284: }
2285: PetscStrtolower(avail);
2286: SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s. Available options: %s",svalue,pre ? pre : "",opt+1,avail);
2287: }
2288: if (set) *set = PETSC_TRUE;
2289: } else if (set) *set = PETSC_FALSE;
2290: PetscFree(svalue);
2291: return(0);
2292: }
2294: /*@C
2295: PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2297: Not Collective
2299: Input Parameters:
2300: + options - options database, use NULL for default global database
2301: . pre - option prefix or NULL
2302: . opt - option name
2303: . list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2304: - defaultv - the default (current) value
2306: Output Parameter:
2307: + value - the value to return
2308: - set - PETSC_TRUE if found, else PETSC_FALSE
2310: Level: beginner
2312: Notes:
2313: If the user does not supply the option value is NOT changed. Thus
2314: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2316: List is usually something like PCASMTypes or some other predefined list of enum names
2318: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2319: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2320: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2321: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2322: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2323: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2324: PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2325: @*/
2326: PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set)
2327: {
2329: PetscInt ntext = 0,tval;
2330: PetscBool fset;
2334: while (list[ntext++]) {
2335: if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
2336: }
2337: if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
2338: ntext -= 3;
2339: PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset);
2340: /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2341: if (fset) *value = (PetscEnum)tval;
2342: if (set) *set = fset;
2343: return(0);
2344: }
2346: /*@C
2347: PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2349: Not Collective
2351: Input Parameters:
2352: + options - options database, use NULL for default global database
2353: . pre - the string to prepend to the name or NULL
2354: - name - the option one is seeking
2356: Output Parameter:
2357: + ivalue - the integer value to return
2358: - set - PETSC_TRUE if found, else PETSC_FALSE
2360: Level: beginner
2362: Notes:
2363: If the user does not supply the option ivalue is NOT changed. Thus
2364: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2366: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
2367: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2368: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2369: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2370: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2371: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2372: PetscOptionsFList(), PetscOptionsEList()
2373: @*/
2374: PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set)
2375: {
2376: const char *value;
2378: PetscBool flag;
2383: PetscOptionsFindPair(options,pre,name,&value,&flag);
2384: if (flag) {
2385: if (!value) {
2386: if (set) *set = PETSC_FALSE;
2387: } else {
2388: if (set) *set = PETSC_TRUE;
2389: PetscOptionsStringToInt(value,ivalue);
2390: }
2391: } else {
2392: if (set) *set = PETSC_FALSE;
2393: }
2394: return(0);
2395: }
2397: /*@C
2398: PetscOptionsGetReal - Gets the double precision value for a particular
2399: option in the database.
2401: Not Collective
2403: Input Parameters:
2404: + options - options database, use NULL for default global database
2405: . pre - string to prepend to each name or NULL
2406: - name - the option one is seeking
2408: Output Parameter:
2409: + dvalue - the double value to return
2410: - set - PETSC_TRUE if found, PETSC_FALSE if not found
2412: Notes:
2413: If the user does not supply the option dvalue is NOT changed. Thus
2414: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2416: Level: beginner
2418: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2419: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
2420: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2421: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2422: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2423: PetscOptionsFList(), PetscOptionsEList()
2424: @*/
2425: PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set)
2426: {
2427: const char *value;
2428: PetscBool flag;
2434: PetscOptionsFindPair(options,pre,name,&value,&flag);
2435: if (flag) {
2436: if (!value) {
2437: if (set) *set = PETSC_FALSE;
2438: } else {
2439: if (set) *set = PETSC_TRUE;
2440: PetscOptionsStringToReal(value,dvalue);
2441: }
2442: } else {
2443: if (set) *set = PETSC_FALSE;
2444: }
2445: return(0);
2446: }
2448: /*@C
2449: PetscOptionsGetScalar - Gets the scalar value for a particular
2450: option in the database.
2452: Not Collective
2454: Input Parameters:
2455: + options - options database, use NULL for default global database
2456: . pre - string to prepend to each name or NULL
2457: - name - the option one is seeking
2459: Output Parameter:
2460: + dvalue - the double value to return
2461: - set - PETSC_TRUE if found, else PETSC_FALSE
2463: Level: beginner
2465: Usage:
2466: A complex number 2+3i must be specified with NO spaces
2468: Notes:
2469: If the user does not supply the option dvalue is NOT changed. Thus
2470: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2472: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2473: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2474: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2475: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2476: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2477: PetscOptionsFList(), PetscOptionsEList()
2478: @*/
2479: PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set)
2480: {
2481: const char *value;
2482: PetscBool flag;
2488: PetscOptionsFindPair(options,pre,name,&value,&flag);
2489: if (flag) {
2490: if (!value) {
2491: if (set) *set = PETSC_FALSE;
2492: } else {
2493: #if !defined(PETSC_USE_COMPLEX)
2494: PetscOptionsStringToReal(value,dvalue);
2495: #else
2496: PetscOptionsStringToScalar(value,dvalue);
2497: #endif
2498: if (set) *set = PETSC_TRUE;
2499: }
2500: } else { /* flag */
2501: if (set) *set = PETSC_FALSE;
2502: }
2503: return(0);
2504: }
2506: /*@C
2507: PetscOptionsGetString - Gets the string value for a particular option in
2508: the database.
2510: Not Collective
2512: Input Parameters:
2513: + options - options database, use NULL for default global database
2514: . pre - string to prepend to name or NULL
2515: . name - the option one is seeking
2516: - len - maximum length of the string including null termination
2518: Output Parameters:
2519: + string - location to copy string
2520: - set - PETSC_TRUE if found, else PETSC_FALSE
2522: Level: beginner
2524: Fortran Note:
2525: The Fortran interface is slightly different from the C/C++
2526: interface (len is not used). Sample usage in Fortran follows
2527: .vb
2528: character *20 string
2529: PetscErrorCode ierr
2530: PetscBool set
2531: call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2532: .ve
2534: Notes:
2535: 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
2537: If the user does not use the option then the string is not changed. Thus
2538: you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
2540: Note:
2541: Even if the user provided no string (for example -optionname -someotheroption) the flag is set to PETSC_TRUE (and the string is fulled with nulls).
2543: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2544: PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2545: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2546: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2547: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2548: PetscOptionsFList(), PetscOptionsEList()
2549: @*/
2550: PetscErrorCode PetscOptionsGetString(PetscOptions options,const char pre[],const char name[],char string[],size_t len,PetscBool *set)
2551: {
2552: const char *value;
2553: PetscBool flag;
2559: PetscOptionsFindPair(options,pre,name,&value,&flag);
2560: if (!flag) {
2561: if (set) *set = PETSC_FALSE;
2562: } else {
2563: if (set) *set = PETSC_TRUE;
2564: if (value) {
2565: PetscStrncpy(string,value,len);
2566: } else {
2567: PetscArrayzero(string,len);
2568: }
2569: }
2570: return(0);
2571: }
2573: char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[])
2574: {
2575: const char *value;
2576: PetscBool flag;
2580: PetscOptionsFindPair(options,pre,name,&value,&flag);if (ierr) PetscFunctionReturn(NULL);
2581: if (flag) PetscFunctionReturn((char*)value);
2582: else PetscFunctionReturn(NULL);
2583: }
2585: /*@C
2586: PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2587: option in the database. The values must be separated with commas with
2588: no intervening spaces.
2590: Not Collective
2592: Input Parameters:
2593: + options - options database, use NULL for default global database
2594: . pre - string to prepend to each name or NULL
2595: . name - the option one is seeking
2596: - nmax - maximum number of values to retrieve
2598: Output Parameter:
2599: + dvalue - the integer values to return
2600: . nmax - actual number of values retreived
2601: - set - PETSC_TRUE if found, else PETSC_FALSE
2603: Level: beginner
2605: Notes:
2606: TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
2607: FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
2609: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2610: PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2611: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2612: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2613: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2614: PetscOptionsFList(), PetscOptionsEList()
2615: @*/
2616: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set)
2617: {
2618: const char *svalue;
2619: char *value;
2621: PetscInt n = 0;
2622: PetscBool flag;
2623: PetscToken token;
2630: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2631: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2632: if (set) *set = PETSC_TRUE;
2633: PetscTokenCreate(svalue,',',&token);
2634: PetscTokenFind(token,&value);
2635: while (value && n < *nmax) {
2636: PetscOptionsStringToBool(value,dvalue);
2637: PetscTokenFind(token,&value);
2638: dvalue++;
2639: n++;
2640: }
2641: PetscTokenDestroy(&token);
2642: *nmax = n;
2643: return(0);
2644: }
2646: /*@C
2647: PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
2649: Not Collective
2651: Input Parameters:
2652: + options - options database, use NULL for default global database
2653: . pre - option prefix or NULL
2654: . name - option name
2655: . list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2656: - nmax - maximum number of values to retrieve
2658: Output Parameters:
2659: + ivalue - the enum values to return
2660: . nmax - actual number of values retreived
2661: - set - PETSC_TRUE if found, else PETSC_FALSE
2663: Level: beginner
2665: Notes:
2666: The array must be passed as a comma separated list.
2668: There must be no intervening spaces between the values.
2670: list is usually something like PCASMTypes or some other predefined list of enum names.
2672: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2673: PetscOptionsGetEnum(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2674: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(),
2675: PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(),
2676: PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2677: PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2678: @*/
2679: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set)
2680: {
2681: const char *svalue;
2682: char *value;
2683: PetscInt n = 0;
2684: PetscEnum evalue;
2685: PetscBool flag;
2686: PetscToken token;
2695: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2696: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2697: if (set) *set = PETSC_TRUE;
2698: PetscTokenCreate(svalue,',',&token);
2699: PetscTokenFind(token,&value);
2700: while (value && n < *nmax) {
2701: PetscEnumFind(list,value,&evalue,&flag);
2702: if (!flag) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
2703: ivalue[n++] = evalue;
2704: PetscTokenFind(token,&value);
2705: }
2706: PetscTokenDestroy(&token);
2707: *nmax = n;
2708: return(0);
2709: }
2711: /*@C
2712: PetscOptionsGetIntArray - Gets an array of integer values for a particular
2713: option in the database.
2715: Not Collective
2717: Input Parameters:
2718: + options - options database, use NULL for default global database
2719: . pre - string to prepend to each name or NULL
2720: . name - the option one is seeking
2721: - nmax - maximum number of values to retrieve
2723: Output Parameter:
2724: + ivalue - the integer values to return
2725: . nmax - actual number of values retreived
2726: - set - PETSC_TRUE if found, else PETSC_FALSE
2728: Level: beginner
2730: Notes:
2731: The array can be passed as
2732: a comma separated list: 0,1,2,3,4,5,6,7
2733: a range (start-end+1): 0-8
2734: a range with given increment (start-end+1:inc): 0-7:2
2735: a combination of values and ranges separated by commas: 0,1-8,8-15:2
2737: There must be no intervening spaces between the values.
2739: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2740: PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2741: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2742: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2743: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2744: PetscOptionsFList(), PetscOptionsEList()
2745: @*/
2746: PetscErrorCode PetscOptionsGetIntArray(PetscOptions options,const char pre[],const char name[],PetscInt ivalue[],PetscInt *nmax,PetscBool *set)
2747: {
2748: const char *svalue;
2749: char *value;
2751: PetscInt n = 0,i,j,start,end,inc,nvalues;
2752: size_t len;
2753: PetscBool flag,foundrange;
2754: PetscToken token;
2761: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2762: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2763: if (set) *set = PETSC_TRUE;
2764: PetscTokenCreate(svalue,',',&token);
2765: PetscTokenFind(token,&value);
2766: while (value && n < *nmax) {
2767: /* look for form d-D where d and D are integers */
2768: foundrange = PETSC_FALSE;
2769: PetscStrlen(value,&len);
2770: if (value[0] == '-') i=2;
2771: else i=1;
2772: for (;i<(int)len; i++) {
2773: if (value[i] == '-') {
2774: if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
2775: value[i] = 0;
2777: PetscOptionsStringToInt(value,&start);
2778: inc = 1;
2779: j = i+1;
2780: for (;j<(int)len; j++) {
2781: if (value[j] == ':') {
2782: value[j] = 0;
2784: PetscOptionsStringToInt(value+j+1,&inc);
2785: if (inc <= 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry,%s cannot have negative increment",n,value+j+1);
2786: break;
2787: }
2788: }
2789: PetscOptionsStringToInt(value+i+1,&end);
2790: if (end <= start) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry, %s-%s cannot have decreasing list",n,value,value+i+1);
2791: nvalues = (end-start)/inc + (end-start)%inc;
2792: if (n + nvalues > *nmax) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry, not enough space left in array (%D) to contain entire range from %D to %D",n,*nmax-n,start,end);
2793: for (;start<end; start+=inc) {
2794: *ivalue = start; ivalue++;n++;
2795: }
2796: foundrange = PETSC_TRUE;
2797: break;
2798: }
2799: }
2800: if (!foundrange) {
2801: PetscOptionsStringToInt(value,ivalue);
2802: ivalue++;
2803: n++;
2804: }
2805: PetscTokenFind(token,&value);
2806: }
2807: PetscTokenDestroy(&token);
2808: *nmax = n;
2809: return(0);
2810: }
2812: /*@C
2813: PetscOptionsGetRealArray - Gets an array of double precision values for a
2814: particular option in the database. The values must be separated with
2815: commas with no intervening spaces.
2817: Not Collective
2819: Input Parameters:
2820: + options - options database, use NULL for default global database
2821: . pre - string to prepend to each name or NULL
2822: . name - the option one is seeking
2823: - nmax - maximum number of values to retrieve
2825: Output Parameters:
2826: + dvalue - the double values to return
2827: . nmax - actual number of values retreived
2828: - set - PETSC_TRUE if found, else PETSC_FALSE
2830: Level: beginner
2832: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2833: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2834: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2835: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2836: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2837: PetscOptionsFList(), PetscOptionsEList()
2838: @*/
2839: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set)
2840: {
2841: const char *svalue;
2842: char *value;
2844: PetscInt n = 0;
2845: PetscBool flag;
2846: PetscToken token;
2853: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2854: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2855: if (set) *set = PETSC_TRUE;
2856: PetscTokenCreate(svalue,',',&token);
2857: PetscTokenFind(token,&value);
2858: while (value && n < *nmax) {
2859: PetscOptionsStringToReal(value,dvalue++);
2860: PetscTokenFind(token,&value);
2861: n++;
2862: }
2863: PetscTokenDestroy(&token);
2864: *nmax = n;
2865: return(0);
2866: }
2868: /*@C
2869: PetscOptionsGetScalarArray - Gets an array of scalars for a
2870: particular option in the database. The values must be separated with
2871: commas with no intervening spaces.
2873: Not Collective
2875: Input Parameters:
2876: + options - options database, use NULL for default global database
2877: . pre - string to prepend to each name or NULL
2878: . name - the option one is seeking
2879: - nmax - maximum number of values to retrieve
2881: Output Parameters:
2882: + dvalue - the scalar values to return
2883: . nmax - actual number of values retreived
2884: - set - PETSC_TRUE if found, else PETSC_FALSE
2886: Level: beginner
2888: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2889: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2890: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2891: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2892: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2893: PetscOptionsFList(), PetscOptionsEList()
2894: @*/
2895: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set)
2896: {
2897: const char *svalue;
2898: char *value;
2900: PetscInt n = 0;
2901: PetscBool flag;
2902: PetscToken token;
2909: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2910: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2911: if (set) *set = PETSC_TRUE;
2912: PetscTokenCreate(svalue,',',&token);
2913: PetscTokenFind(token,&value);
2914: while (value && n < *nmax) {
2915: PetscOptionsStringToScalar(value,dvalue++);
2916: PetscTokenFind(token,&value);
2917: n++;
2918: }
2919: PetscTokenDestroy(&token);
2920: *nmax = n;
2921: return(0);
2922: }
2924: /*@C
2925: PetscOptionsGetStringArray - Gets an array of string values for a particular
2926: option in the database. The values must be separated with commas with
2927: no intervening spaces.
2929: Not Collective
2931: Input Parameters:
2932: + options - options database, use NULL for default global database
2933: . pre - string to prepend to name or NULL
2934: . name - the option one is seeking
2935: - nmax - maximum number of strings
2937: Output Parameters:
2938: + strings - location to copy strings
2939: . nmax - the number of strings found
2940: - set - PETSC_TRUE if found, else PETSC_FALSE
2942: Level: beginner
2944: Notes:
2945: The nmax parameter is used for both input and output.
2947: The user should pass in an array of pointers to char, to hold all the
2948: strings returned by this function.
2950: The user is responsible for deallocating the strings that are
2951: returned. The Fortran interface for this routine is not supported.
2953: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2954: PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2955: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2956: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2957: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2958: PetscOptionsFList(), PetscOptionsEList()
2959: @*/
2960: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set)
2961: {
2962: const char *svalue;
2963: char *value;
2965: PetscInt n = 0;
2966: PetscBool flag;
2967: PetscToken token;
2974: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2975: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2976: if (set) *set = PETSC_TRUE;
2977: PetscTokenCreate(svalue,',',&token);
2978: PetscTokenFind(token,&value);
2979: while (value && n < *nmax) {
2980: PetscStrallocpy(value,&strings[n]);
2981: PetscTokenFind(token,&value);
2982: n++;
2983: }
2984: PetscTokenDestroy(&token);
2985: *nmax = n;
2986: return(0);
2987: }
2989: /*@C
2990: PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one
2992: Prints a deprecation warning, unless an option is supplied to suppress.
2994: Logically Collective
2996: Input Parameters:
2997: + pre - string to prepend to name or NULL
2998: . oldname - the old, deprecated option
2999: . newname - the new option, or NULL if option is purely removed
3000: . version - a string describing the version of first deprecation, e.g. "3.9"
3001: - info - additional information string, or NULL.
3003: Options Database Keys:
3004: . -options_suppress_deprecated_warnings - do not print deprecation warnings
3006: Notes:
3007: Must be called between PetscOptionsBegin() (or PetscObjectOptionsBegin()) and PetscOptionsEnd().
3008: Only the proces of rank zero that owns the PetscOptionsItems are argument (managed by PetscOptionsBegin() or
3009: PetscObjectOptionsBegin() prints the information
3010: If newname is provided, the old option is replaced. Otherwise, it remains
3011: in the options database.
3012: If an option is not replaced, the info argument should be used to advise the user
3013: on how to proceed.
3014: There is a limit on the length of the warning printed, so very long strings
3015: provided as info may be truncated.
3017: Level: developer
3019: .seealso: PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsScalar(), PetscOptionsBool(), PetscOptionsString(), PetscOptionsSetValue()
3021: @*/
3022: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[])
3023: {
3024: PetscErrorCode ierr;
3025: PetscBool found,quiet;
3026: const char *value;
3027: const char * const quietopt="-options_suppress_deprecated_warnings";
3028: char msg[4096];
3029: char *prefix = NULL;
3030: PetscOptions options = NULL;
3031: MPI_Comm comm = PETSC_COMM_SELF;
3036: if (PetscOptionsObject) {
3037: prefix = PetscOptionsObject->prefix;
3038: options = PetscOptionsObject->options;
3039: comm = PetscOptionsObject->comm;
3040: }
3041: PetscOptionsFindPair(options,prefix,oldname,&value,&found);
3042: if (found) {
3043: if (newname) {
3044: if (prefix) {
3045: PetscOptionsPrefixPush(options,prefix);
3046: }
3047: PetscOptionsSetValue(options,newname,value);
3048: if (prefix) {
3049: PetscOptionsPrefixPop(options);
3050: }
3051: PetscOptionsClearValue(options,oldname);
3052: }
3053: quiet = PETSC_FALSE;
3054: PetscOptionsGetBool(options,NULL,quietopt,&quiet,NULL);
3055: if (!quiet) {
3056: PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option ");
3057: PetscStrcat(msg,oldname);
3058: PetscStrcat(msg," is deprecated as of version ");
3059: PetscStrcat(msg,version);
3060: PetscStrcat(msg," and will be removed in a future release.");
3061: if (newname) {
3062: PetscStrcat(msg," Please use the option ");
3063: PetscStrcat(msg,newname);
3064: PetscStrcat(msg," instead.");
3065: }
3066: if (info) {
3067: PetscStrcat(msg," ");
3068: PetscStrcat(msg,info);
3069: }
3070: PetscStrcat(msg," (Silence this warning with ");
3071: PetscStrcat(msg,quietopt);
3072: PetscStrcat(msg,")\n");
3073: PetscPrintf(comm,msg);
3074: }
3075: }
3076: return(0);
3077: }