Actual source code: options.c
1: /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
2: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for atoll() */
4: /*
5: These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
6: This provides the low-level interface, the high level interface is in aoptions.c
8: Some routines use regular malloc and free because it cannot know what malloc is requested with the
9: options database until it has already processed the input.
10: */
12: #include <petsc/private/petscimpl.h>
13: #include <petscviewer.h>
14: #include <ctype.h>
15: #if defined(PETSC_HAVE_MALLOC_H)
16: #include <malloc.h>
17: #endif
18: #if defined(PETSC_HAVE_STRINGS_H)
19: # include <strings.h> /* strcasecmp */
20: #endif
22: #if defined(PETSC_HAVE_STRCASECMP)
23: #define PetscOptNameCmp(a,b) strcasecmp(a,b)
24: #elif defined(PETSC_HAVE_STRICMP)
25: #define PetscOptNameCmp(a,b) stricmp(a,b)
26: #else
27: #define PetscOptNameCmp(a,b) Error_strcasecmp_not_found
28: #endif
30: #include <petsc/private/hashtable.h>
32: /* This assumes ASCII encoding and ignores locale settings */
33: /* Using tolower() is about 2X slower in microbenchmarks */
34: PETSC_STATIC_INLINE int PetscToLower(int c)
35: {
36: return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
37: }
39: /* Bob Jenkins's one at a time hash function (case-insensitive) */
40: PETSC_STATIC_INLINE unsigned int PetscOptHash(const char key[])
41: {
42: unsigned int hash = 0;
43: while (*key) {
44: hash += PetscToLower(*key++);
45: hash += hash << 10;
46: hash ^= hash >> 6;
47: }
48: hash += hash << 3;
49: hash ^= hash >> 11;
50: hash += hash << 15;
51: return hash;
52: }
54: PETSC_STATIC_INLINE int PetscOptEqual(const char a[],const char b[])
55: {
56: return !PetscOptNameCmp(a,b);
57: }
59: KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
61: /*
62: This table holds all the options set by the user. For simplicity, we use a static size database
63: */
64: #define MAXOPTNAME PETSC_MAX_OPTION_NAME
65: #define MAXOPTIONS 512
66: #define MAXALIASES 25
67: #define MAXPREFIXES 25
68: #define MAXOPTIONSMONITORS 5
70: struct _n_PetscOptions {
71: PetscOptions previous;
72: int N; /* number of options */
73: char *names[MAXOPTIONS]; /* option names */
74: char *values[MAXOPTIONS]; /* option values */
75: PetscBool used[MAXOPTIONS]; /* flag option use */
76: PetscBool precedentProcessed;
78: /* Hash table */
79: khash_t(HO) *ht;
81: /* Prefixes */
82: int prefixind;
83: int prefixstack[MAXPREFIXES];
84: char prefix[MAXOPTNAME];
86: /* Aliases */
87: int Naliases; /* number or aliases */
88: char *aliases1[MAXALIASES]; /* aliased */
89: char *aliases2[MAXALIASES]; /* aliasee */
91: /* Help */
92: PetscBool help; /* flag whether "-help" is in the database */
93: PetscBool help_intro; /* flag whether "-help intro" is in the database */
95: /* Monitors */
96: PetscBool monitorFromOptions, monitorCancel;
97: PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[],const char[],void*); /* returns control to user after */
98: PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void**); /* */
99: void *monitorcontext[MAXOPTIONSMONITORS]; /* to pass arbitrary user data into monitor */
100: PetscInt numbermonitors; /* to, for instance, detect options being set */
101: };
103: static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */
105: /* list of options which preceed others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */
106: static const char *precedentOptions[] = {"-options_monitor","-options_monitor_cancel","-help","-skip_petscrc"};
107: enum PetscPrecedentOption {PO_OPTIONS_MONITOR,PO_OPTIONS_MONITOR_CANCEL,PO_HELP,PO_SKIP_PETSCRC,PO_NUM};
109: static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions,const char[],const char[],int*);
111: /*
112: Options events monitor
113: */
114: static PetscErrorCode PetscOptionsMonitor(PetscOptions options,const char name[],const char value[])
115: {
116: PetscInt i;
119: if (!PetscErrorHandlingInitialized) return 0;
121: if (!value) value = "";
122: if (options->monitorFromOptions) {
123: PetscOptionsMonitorDefault(name,value,NULL);
124: }
125: for (i=0; i<options->numbermonitors; i++) {
126: (*options->monitor[i])(name,value,options->monitorcontext[i]);
127: }
128: return(0);
129: }
131: /*@
132: PetscOptionsCreate - Creates an empty options database.
134: Logically collective
136: Output Parameter:
137: . options - Options database object
139: Level: advanced
141: Developer Note: We may want eventually to pass a MPI_Comm to determine the ownership of the object
143: .seealso: PetscOptionsDestroy(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsInsert(), PetscOptionsSetValue()
144: @*/
145: PetscErrorCode PetscOptionsCreate(PetscOptions *options)
146: {
147: if (!options) return PETSC_ERR_ARG_NULL;
148: *options = (PetscOptions)calloc(1,sizeof(**options));
149: if (!*options) return PETSC_ERR_MEM;
150: return 0;
151: }
153: /*@
154: PetscOptionsDestroy - Destroys an option database.
156: Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
158: Input Parameter:
159: . options - the PetscOptions object
161: Level: advanced
163: .seealso: PetscOptionsInsert(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsInsert(), PetscOptionsSetValue()
164: @*/
165: PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
166: {
169: if (!*options) return 0;
170: 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()");
171: PetscOptionsClear(*options);if (ierr) return ierr;
172: /* XXX what about monitors ? */
173: free(*options);
174: *options = NULL;
175: return(0);
176: }
178: /*
179: PetscOptionsCreateDefault - Creates the default global options database
180: */
181: PetscErrorCode PetscOptionsCreateDefault(void)
182: {
185: if (!defaultoptions) {
186: PetscOptionsCreate(&defaultoptions);if (ierr) return ierr;
187: }
188: return 0;
189: }
191: /*@
192: PetscOptionsPush - Push a new PetscOptions object as the default provider of options
193: Allows using different parts of a code to use different options databases
195: Logically Collective
197: Input Parameter:
198: . opt - the options obtained with PetscOptionsCreate()
200: Notes:
201: Use PetscOptionsPop() to return to the previous default options database
203: The collectivity of this routine is complex; only the MPI processes that call this routine will
204: have the affect of these options. If some processes that create objects call this routine and others do
205: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
206: on different ranks.
208: Level: advanced
210: .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsInsert(), PetscOptionsSetValue(), PetscOptionsLeft()
212: @*/
213: PetscErrorCode PetscOptionsPush(PetscOptions opt)
214: {
218: PetscOptionsCreateDefault();
219: opt->previous = defaultoptions;
220: defaultoptions = opt;
221: return(0);
222: }
224: /*@
225: PetscOptionsPop - Pop the most recent PetscOptionsPush() to return to the previous default options
227: Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
229: Notes:
230: Use PetscOptionsPop() to return to the previous default options database
231: Allows using different parts of a code to use different options databases
233: Level: advanced
235: .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsInsert(), PetscOptionsSetValue(), PetscOptionsLeft()
237: @*/
238: PetscErrorCode PetscOptionsPop(void)
239: {
240: PetscOptions current = defaultoptions;
243: if (!defaultoptions) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing default options");
244: if (!defaultoptions->previous) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PetscOptionsPop() called too many times");
245: defaultoptions = defaultoptions->previous;
246: current->previous = NULL;
247: return(0);
248: }
250: /*
251: PetscOptionsDestroyDefault - Destroys the default global options database
252: */
253: PetscErrorCode PetscOptionsDestroyDefault(void)
254: {
256: PetscOptions tmp;
258: if (!defaultoptions) return 0;
259: /* Destroy any options that the user forgot to pop */
260: while (defaultoptions->previous) {
261: tmp = defaultoptions;
262: PetscOptionsPop();
263: PetscOptionsDestroy(&tmp);
264: }
265: PetscOptionsDestroy(&defaultoptions);if (ierr) return ierr;
266: return 0;
267: }
269: /*@C
270: PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
272: Not collective
274: Input Parameter:
275: . key - string to check if valid
277: Output Parameter:
278: . valid - PETSC_TRUE if a valid key
280: Level: intermediate
281: @*/
282: PetscErrorCode PetscOptionsValidKey(const char key[],PetscBool *valid)
283: {
284: char *ptr;
289: *valid = PETSC_FALSE;
290: if (!key) return(0);
291: if (key[0] != '-') return(0);
292: if (key[1] == '-') key++;
293: if (!isalpha((int)key[1])) return(0);
294: (void) strtod(key,&ptr);
295: if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) return(0);
296: *valid = PETSC_TRUE;
297: return(0);
298: }
300: /*@C
301: PetscOptionsInsertString - Inserts options into the database from a string
303: Logically Collective
305: Input Parameter:
306: + options - options object
307: - in_str - string that contains options separated by blanks
309: Level: intermediate
311: The collectivity of this routine is complex; only the MPI processes that call this routine will
312: have the affect of these options. If some processes that create objects call this routine and others do
313: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
314: on different ranks.
316: Contributed by Boyana Norris
318: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
319: PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
320: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
321: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
322: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
323: PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile()
324: @*/
325: PetscErrorCode PetscOptionsInsertString(PetscOptions options,const char in_str[])
326: {
327: MPI_Comm comm = PETSC_COMM_SELF;
329: char *first,*second;
330: PetscToken token;
333: PetscTokenCreate(in_str,' ',&token);
334: PetscTokenFind(token,&first);
335: while (first) {
336: PetscBool isfile,isfileyaml,isstringyaml,ispush,ispop,key;
337: PetscStrcasecmp(first,"-options_file",&isfile);
338: PetscStrcasecmp(first,"-options_file_yaml",&isfileyaml);
339: PetscStrcasecmp(first,"-options_string_yaml",&isstringyaml);
340: PetscStrcasecmp(first,"-prefix_push",&ispush);
341: PetscStrcasecmp(first,"-prefix_pop",&ispop);
342: PetscOptionsValidKey(first,&key);
343: if (!key) {
344: PetscTokenFind(token,&first);
345: } else if (isfile) {
346: PetscTokenFind(token,&second);
347: PetscOptionsInsertFile(comm,options,second,PETSC_TRUE);
348: PetscTokenFind(token,&first);
349: } else if (isfileyaml) {
350: PetscTokenFind(token,&second);
351: PetscOptionsInsertFileYAML(comm,options,second,PETSC_TRUE);
352: PetscTokenFind(token,&first);
353: } else if (isstringyaml) {
354: PetscTokenFind(token,&second);
355: PetscOptionsInsertStringYAML(options,second);
356: PetscTokenFind(token,&first);
357: } else if (ispush) {
358: PetscTokenFind(token,&second);
359: PetscOptionsPrefixPush(options,second);
360: PetscTokenFind(token,&first);
361: } else if (ispop) {
362: PetscOptionsPrefixPop(options);
363: PetscTokenFind(token,&first);
364: } else {
365: PetscTokenFind(token,&second);
366: PetscOptionsValidKey(second,&key);
367: if (!key) {
368: PetscOptionsSetValue(options,first,second);
369: PetscTokenFind(token,&first);
370: } else {
371: PetscOptionsSetValue(options,first,NULL);
372: first = second;
373: }
374: }
375: }
376: PetscTokenDestroy(&token);
377: return(0);
378: }
380: /*
381: Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
382: */
383: static char *Petscgetline(FILE * f)
384: {
385: size_t size = 0;
386: size_t len = 0;
387: size_t last = 0;
388: char *buf = NULL;
390: if (feof(f)) return NULL;
391: do {
392: size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
393: buf = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
394: /* Actually do the read. Note that fgets puts a terminal '\0' on the
395: end of the string, so we make sure we overwrite this */
396: if (!fgets(buf+len,1024,f)) buf[len]=0;
397: PetscStrlen(buf,&len);
398: last = len - 1;
399: } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
400: if (len) return buf;
401: free(buf);
402: return NULL;
403: }
405: static PetscErrorCode PetscOptionsFilename(MPI_Comm comm,const char file[],char filename[PETSC_MAX_PATH_LEN],PetscBool *yaml)
406: {
407: char fname[PETSC_MAX_PATH_LEN+8],path[PETSC_MAX_PATH_LEN+8],*tail;
410: *yaml = PETSC_FALSE;
412: PetscStrreplace(comm,file,fname,sizeof(fname));
413: PetscFixFilename(fname,path);
414: PetscStrendswith(path,":yaml",yaml);
415: if (*yaml) {
416: PetscStrrchr(path,':',&tail);
417: tail[-1] = 0; /* remove ":yaml" suffix from path */
418: }
419: PetscStrncpy(filename,path,PETSC_MAX_PATH_LEN);
420: /* check for standard YAML and JSON filename extensions */
421: if (!*yaml) {PetscStrendswith(filename,".yaml",yaml);}
422: if (!*yaml) {PetscStrendswith(filename,".yml", yaml);}
423: if (!*yaml) {PetscStrendswith(filename,".json",yaml);}
424: if (!*yaml) { /* check file contents */
425: PetscMPIInt rank;
426: MPI_Comm_rank(comm,&rank);
427: if (!rank) {
428: FILE *fh = fopen(filename,"r");
429: if (fh) {
430: char buf[6] = "";
431: if (fread(buf,1,6,fh) > 0) {
432: PetscStrncmp(buf,"%YAML ",6,yaml); /* check for '%YAML' tag */
433: if (!*yaml) {PetscStrncmp(buf,"---",3,yaml);} /* check for document start */
434: }
435: (void)fclose(fh);
436: }
437: }
438: MPI_Bcast(yaml,1,MPIU_BOOL,0,comm);
439: }
440: return(0);
441: }
443: static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
444: {
445: char *string,*vstring = NULL,*astring = NULL,*packed = NULL;
446: char *tokens[4];
448: size_t i,len,bytes;
449: FILE *fd;
450: PetscToken token=NULL;
451: int err;
452: char *cmatch;
453: const char cmt='#';
454: PetscInt line=1;
455: PetscMPIInt rank,cnt=0,acnt=0,counts[2];
456: PetscBool isdir,alias=PETSC_FALSE,valid;
460: PetscMemzero(tokens,sizeof(tokens));
461: MPI_Comm_rank(comm,&rank);
462: if (!rank) {
463: char fpath[PETSC_MAX_PATH_LEN];
464: char fname[PETSC_MAX_PATH_LEN];
466: PetscStrreplace(PETSC_COMM_SELF,file,fpath,sizeof(fpath));
467: PetscFixFilename(fpath,fname);
469: fd = fopen(fname,"r");
470: PetscTestDirectory(fname,'r',&isdir);
471: if (isdir && require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Specified options file %s is a directory",fname);
472: if (fd && !isdir) {
473: PetscSegBuffer vseg,aseg;
474: PetscSegBufferCreate(1,4000,&vseg);
475: PetscSegBufferCreate(1,2000,&aseg);
477: /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
478: PetscInfo1(NULL,"Opened options file %s\n",file);
480: while ((string = Petscgetline(fd))) {
481: /* eliminate comments from each line */
482: PetscStrchr(string,cmt,&cmatch);
483: if (cmatch) *cmatch = 0;
484: PetscStrlen(string,&len);
485: /* replace tabs, ^M, \n with " " */
486: for (i=0; i<len; i++) {
487: if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
488: string[i] = ' ';
489: }
490: }
491: PetscTokenCreate(string,' ',&token);
492: PetscTokenFind(token,&tokens[0]);
493: if (!tokens[0]) {
494: goto destroy;
495: } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */
496: PetscTokenFind(token,&tokens[0]);
497: }
498: for (i=1; i<4; i++) {
499: PetscTokenFind(token,&tokens[i]);
500: }
501: if (!tokens[0]) {
502: goto destroy;
503: } else if (tokens[0][0] == '-') {
504: PetscOptionsValidKey(tokens[0],&valid);
505: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: invalid option %s",fname,line,tokens[0]);
506: PetscStrlen(tokens[0],&len);
507: PetscSegBufferGet(vseg,len+1,&vstring);
508: PetscArraycpy(vstring,tokens[0],len);
509: vstring[len] = ' ';
510: if (tokens[1]) {
511: PetscOptionsValidKey(tokens[1],&valid);
512: 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]);
513: PetscStrlen(tokens[1],&len);
514: PetscSegBufferGet(vseg,len+3,&vstring);
515: vstring[0] = '"';
516: PetscArraycpy(vstring+1,tokens[1],len);
517: vstring[len+1] = '"';
518: vstring[len+2] = ' ';
519: }
520: } else {
521: PetscStrcasecmp(tokens[0],"alias",&alias);
522: if (alias) {
523: PetscOptionsValidKey(tokens[1],&valid);
524: 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]);
525: 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]);
526: PetscOptionsValidKey(tokens[2],&valid);
527: 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]);
528: PetscStrlen(tokens[1],&len);
529: PetscSegBufferGet(aseg,len+1,&astring);
530: PetscArraycpy(astring,tokens[1],len);
531: astring[len] = ' ';
533: PetscStrlen(tokens[2],&len);
534: PetscSegBufferGet(aseg,len+1,&astring);
535: PetscArraycpy(astring,tokens[2],len);
536: astring[len] = ' ';
537: } else SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown first token in options file %s line %D: %s",fname,line,tokens[0]);
538: }
539: {
540: const char *extraToken = alias ? tokens[3] : tokens[2];
541: if (extraToken) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: extra token %s",fname,line,extraToken);
542: }
543: destroy:
544: free(string);
545: PetscTokenDestroy(&token);
546: alias = PETSC_FALSE;
547: line++;
548: }
549: err = fclose(fd);
550: if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file %s",fname);
551: PetscSegBufferGetSize(aseg,&bytes); /* size without null termination */
552: PetscMPIIntCast(bytes,&acnt);
553: PetscSegBufferGet(aseg,1,&astring);
554: astring[0] = 0;
555: PetscSegBufferGetSize(vseg,&bytes); /* size without null termination */
556: PetscMPIIntCast(bytes,&cnt);
557: PetscSegBufferGet(vseg,1,&vstring);
558: vstring[0] = 0;
559: PetscMalloc1(2+acnt+cnt,&packed);
560: PetscSegBufferExtractTo(aseg,packed);
561: PetscSegBufferExtractTo(vseg,packed+acnt+1);
562: PetscSegBufferDestroy(&aseg);
563: PetscSegBufferDestroy(&vseg);
564: } else if (require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open options file %s",fname);
565: }
567: counts[0] = acnt;
568: counts[1] = cnt;
569: err = MPI_Bcast(counts,2,MPI_INT,0,comm);
570: 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://petsc.org/release/faq/");
571: acnt = counts[0];
572: cnt = counts[1];
573: if (rank) {
574: PetscMalloc1(2+acnt+cnt,&packed);
575: }
576: if (acnt || cnt) {
577: MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm);
578: astring = packed;
579: vstring = packed + acnt + 1;
580: }
582: if (acnt) {
583: PetscTokenCreate(astring,' ',&token);
584: PetscTokenFind(token,&tokens[0]);
585: while (tokens[0]) {
586: PetscTokenFind(token,&tokens[1]);
587: PetscOptionsSetAlias(options,tokens[0],tokens[1]);
588: PetscTokenFind(token,&tokens[0]);
589: }
590: PetscTokenDestroy(&token);
591: }
593: if (cnt) {
594: PetscOptionsInsertString(options,vstring);
595: }
596: PetscFree(packed);
597: return(0);
598: }
600: /*@C
601: PetscOptionsInsertFile - Inserts options into the database from a file.
603: Collective
605: Input Parameter:
606: + comm - the processes that will share the options (usually PETSC_COMM_WORLD)
607: . options - options database, use NULL for default global database
608: . file - name of file,
609: ".yml" and ".yaml" filename extensions are inserted as YAML options,
610: append ":yaml" to filename to force YAML options.
611: - require - if PETSC_TRUE will generate an error if the file does not exist
614: Notes:
615: Use # for lines that are comments and which should be ignored.
616: Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
617: 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
618: calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().
619: The collectivity of this routine is complex; only the MPI processes in comm will
620: have the affect of these options. If some processes that create objects call this routine and others do
621: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
622: on different ranks.
624: Level: developer
626: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
627: PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
628: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
629: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
630: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
631: PetscOptionsFList(), PetscOptionsEList()
633: @*/
634: PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
635: {
636: char filename[PETSC_MAX_PATH_LEN];
637: PetscBool yaml;
641: PetscOptionsFilename(comm,file,filename,&yaml);
642: if (yaml) {
643: PetscOptionsInsertFileYAML(comm,options,filename,require);
644: } else {
645: PetscOptionsInsertFilePetsc(comm,options,filename,require);
646: }
647: return(0);
648: }
650: /*@C
651: PetscOptionsInsertArgs - Inserts options into the database from a array of strings
653: Logically Collective
655: Input Parameter:
656: + options - options object
657: . argc - the array lenght
658: - args - the string array
660: Level: intermediate
662: .seealso: PetscOptions, PetscOptionsInsertString(), PetscOptionsInsertFile()
663: @*/
664: PetscErrorCode PetscOptionsInsertArgs(PetscOptions options,int argc,char *args[])
665: {
666: MPI_Comm comm = PETSC_COMM_WORLD;
668: int left = PetscMax(argc,0);
669: char *const *eargs = args;
672: while (left) {
673: PetscBool isfile,isfileyaml,isstringyaml,ispush,ispop,key;
674: PetscStrcasecmp(eargs[0],"-options_file",&isfile);
675: PetscStrcasecmp(eargs[0],"-options_file_yaml",&isfileyaml);
676: PetscStrcasecmp(eargs[0],"-options_string_yaml",&isstringyaml);
677: PetscStrcasecmp(eargs[0],"-prefix_push",&ispush);
678: PetscStrcasecmp(eargs[0],"-prefix_pop",&ispop);
679: PetscOptionsValidKey(eargs[0],&key);
680: if (!key) {
681: eargs++; left--;
682: } else if (isfile) {
683: if (left <= 1 || eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
684: PetscOptionsInsertFile(comm,options,eargs[1],PETSC_TRUE);
685: eargs += 2; left -= 2;
686: } else if (isfileyaml) {
687: if (left <= 1 || eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file_yaml filename option");
688: PetscOptionsInsertFileYAML(comm,options,eargs[1],PETSC_TRUE);
689: eargs += 2; left -= 2;
690: } else if (isstringyaml) {
691: if (left <= 1 || eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing string for -options_string_yaml string option");
692: PetscOptionsInsertStringYAML(options,eargs[1]);
693: eargs += 2; left -= 2;
694: } else if (ispush) {
695: if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
696: if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
697: PetscOptionsPrefixPush(options,eargs[1]);
698: eargs += 2; left -= 2;
699: } else if (ispop) {
700: PetscOptionsPrefixPop(options);
701: eargs++; left--;
702: } else {
703: PetscBool nextiskey = PETSC_FALSE;
704: if (left >= 2) {PetscOptionsValidKey(eargs[1],&nextiskey);}
705: if (left < 2 || nextiskey) {
706: PetscOptionsSetValue(options,eargs[0],NULL);
707: eargs++; left--;
708: } else {
709: PetscOptionsSetValue(options,eargs[0],eargs[1]);
710: eargs += 2; left -= 2;
711: }
712: }
713: }
714: return(0);
715: }
717: PETSC_STATIC_INLINE PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt,const char *val[],PetscBool set[],PetscBool *flg)
718: {
722: if (set[opt]) {
723: PetscOptionsStringToBool(val[opt],flg);
724: } else *flg = PETSC_FALSE;
725: return(0);
726: }
728: /* Process options with absolute precedence */
729: static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options,int argc,char *args[],PetscBool *skip_petscrc,PetscBool *skip_petscrc_set)
730: {
731: const char* const *opt = precedentOptions;
732: const size_t n = PO_NUM;
733: size_t o;
734: int a;
735: const char **val;
736: PetscBool *set;
737: PetscErrorCode ierr;
740: PetscCalloc2(n,&val,n,&set);
742: /* Look for options possibly set using PetscOptionsSetValue beforehand */
743: for (o=0; o<n; o++) {
744: PetscOptionsFindPair(options,NULL,opt[o],&val[o],&set[o]);
745: }
747: /* Loop through all args to collect last occuring value of each option */
748: for (a=1; a<argc; a++) {
749: PetscBool valid, eq;
751: PetscOptionsValidKey(args[a],&valid);
752: if (!valid) continue;
753: for (o=0; o<n; o++) {
754: PetscStrcasecmp(args[a],opt[o],&eq);
755: if (eq) {
756: set[o] = PETSC_TRUE;
757: if (a == argc-1 || !args[a+1] || !args[a+1][0] || args[a+1][0] == '-') val[o] = NULL;
758: else val[o] = args[a+1];
759: break;
760: }
761: }
762: }
764: /* Process flags */
765: PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro);
766: if (options->help_intro) options->help = PETSC_TRUE;
767: else {PetscOptionsStringToBoolIfSet_Private(PO_HELP, val,set,&options->help);}
768: PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL,val,set,&options->monitorCancel);
769: PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val,set,&options->monitorFromOptions);
770: PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val,set,skip_petscrc);
771: *skip_petscrc_set = set[PO_SKIP_PETSCRC];
773: /* Store precedent options in database and mark them as used */
774: for (o=0; o<n; o++) {
775: if (set[o]) {
776: PetscOptionsSetValue_Private(options,opt[o],val[o],&a);
777: options->used[a] = PETSC_TRUE;
778: }
779: }
781: PetscFree2(val,set);
782: options->precedentProcessed = PETSC_TRUE;
783: return(0);
784: }
786: PETSC_STATIC_INLINE PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options,const char name[],PetscBool *flg)
787: {
788: int i;
791: *flg = PETSC_FALSE;
792: if (options->precedentProcessed) {
793: for (i=0; i<PO_NUM; i++) {
794: if (!PetscOptNameCmp(precedentOptions[i],name)) {
795: /* check if precedent option has been set already */
796: PetscOptionsFindPair(options,NULL,name,NULL,flg);if (ierr) return ierr;
797: if (*flg) break;
798: }
799: }
800: }
801: return 0;
802: }
804: /*@C
805: PetscOptionsInsert - Inserts into the options database from the command line,
806: the environmental variable and a file.
808: Collective on PETSC_COMM_WORLD
810: Input Parameters:
811: + options - options database or NULL for the default global database
812: . argc - count of number of command line arguments
813: . args - the command line arguments
814: - file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
815: Use NULL or empty string to not check for code specific file.
816: Also checks ~/.petscrc, .petscrc and petscrc.
817: Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
819: Note:
820: Since PetscOptionsInsert() is automatically called by PetscInitialize(),
821: the user does not typically need to call this routine. PetscOptionsInsert()
822: can be called several times, adding additional entries into the database.
824: Options Database Keys:
825: + -options_file <filename> - read options from a file
826: - -options_file_yaml <filename> - read options from a YAML file
828: See PetscInitialize() for options related to option database monitoring.
830: Level: advanced
832: .seealso: PetscOptionsDestroy(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
833: PetscInitialize()
834: @*/
835: PetscErrorCode PetscOptionsInsert(PetscOptions options,int *argc,char ***args,const char file[])
836: {
837: MPI_Comm comm = PETSC_COMM_WORLD;
839: PetscMPIInt rank;
840: PetscBool hasArgs = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE;
841: PetscBool skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE;
844: if (hasArgs && !(args && *args)) SETERRQ(comm,PETSC_ERR_ARG_NULL,"*argc > 1 but *args not given");
845: MPI_Comm_rank(comm,&rank);
847: if (!options) {
848: PetscOptionsCreateDefault();
849: options = defaultoptions;
850: }
851: if (hasArgs) {
852: /* process options with absolute precedence */
853: PetscOptionsProcessPrecedentFlags(options,*argc,*args,&skipPetscrc,&skipPetscrcSet);
854: }
855: if (file && file[0]) {
856: PetscOptionsInsertFile(comm,options,file,PETSC_TRUE);
857: /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */
858: if (!skipPetscrcSet) {PetscOptionsGetBool(options,NULL,"-skip_petscrc",&skipPetscrc,NULL);}
859: }
860: if (!skipPetscrc) {
861: char filename[PETSC_MAX_PATH_LEN];
862: PetscGetHomeDirectory(filename,sizeof(filename));
863: MPI_Bcast(filename,(int)sizeof(filename),MPI_CHAR,0,comm);
864: if (filename[0]) {PetscStrcat(filename,"/.petscrc");}
865: PetscOptionsInsertFile(comm,options,filename,PETSC_FALSE);
866: PetscOptionsInsertFile(comm,options,".petscrc",PETSC_FALSE);
867: PetscOptionsInsertFile(comm,options,"petscrc",PETSC_FALSE);
868: }
870: /* insert environment options */
871: {
872: char *eoptions = NULL;
873: size_t len = 0;
874: if (!rank) {
875: eoptions = (char*)getenv("PETSC_OPTIONS");
876: PetscStrlen(eoptions,&len);
877: }
878: MPI_Bcast(&len,1,MPIU_SIZE_T,0,comm);
879: if (len) {
880: if (rank) {PetscMalloc1(len+1,&eoptions);}
881: MPI_Bcast(eoptions,len,MPI_CHAR,0,comm);
882: if (rank) eoptions[len] = 0;
883: PetscOptionsInsertString(options,eoptions);
884: if (rank) {PetscFree(eoptions);}
885: }
886: }
888: /* insert YAML environment options */
889: {
890: char *eoptions = NULL;
891: size_t len = 0;
892: if (!rank) {
893: eoptions = (char*)getenv("PETSC_OPTIONS_YAML");
894: PetscStrlen(eoptions,&len);
895: }
896: MPI_Bcast(&len,1,MPIU_SIZE_T,0,comm);
897: if (len) {
898: if (rank) {PetscMalloc1(len+1,&eoptions);}
899: MPI_Bcast(eoptions,len,MPI_CHAR,0,comm);
900: if (rank) eoptions[len] = 0;
901: PetscOptionsInsertStringYAML(options,eoptions);
902: if (rank) {PetscFree(eoptions);}
903: }
904: }
906: /* insert command line options here because they take precedence over arguments in petscrc/environment */
907: if (hasArgs) {PetscOptionsInsertArgs(options,*argc-1,*args+1);}
908: return(0);
909: }
911: /*@C
912: PetscOptionsView - Prints the options that have been loaded. This is
913: useful for debugging purposes.
915: Logically Collective on PetscViewer
917: Input Parameter:
918: + options - options database, use NULL for default global database
919: - viewer - must be an PETSCVIEWERASCII viewer
921: Options Database Key:
922: . -options_view - Activates PetscOptionsView() within PetscFinalize()
924: Notes:
925: Only the rank zero process of MPI_Comm used to create view prints the option values. Other processes
926: may have different values but they are not printed.
928: Level: advanced
930: .seealso: PetscOptionsAllUsed()
931: @*/
932: PetscErrorCode PetscOptionsView(PetscOptions options,PetscViewer viewer)
933: {
935: PetscInt i;
936: PetscBool isascii;
940: options = options ? options : defaultoptions;
941: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
942: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
943: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
945: if (!options->N) {
946: PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");
947: return(0);
948: }
950: PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");
951: for (i=0; i<options->N; i++) {
952: if (options->values[i]) {
953: PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);
954: } else {
955: PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);
956: }
957: }
958: PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");
959: return(0);
960: }
962: /*
963: Called by error handlers to print options used in run
964: */
965: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
966: {
967: PetscInt i;
968: PetscOptions options = defaultoptions;
971: if (options->N) {
972: (*PetscErrorPrintf)("PETSc Option Table entries:\n");
973: } else {
974: (*PetscErrorPrintf)("No PETSc Option Table entries\n");
975: }
976: for (i=0; i<options->N; i++) {
977: if (options->values[i]) {
978: (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]);
979: } else {
980: (*PetscErrorPrintf)("-%s\n",options->names[i]);
981: }
982: }
983: return(0);
984: }
986: /*@C
987: PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
989: Logically Collective
991: Input Parameter:
992: + options - options database, or NULL for the default global database
993: - prefix - The string to append to the existing prefix
995: Options Database Keys:
996: + -prefix_push <some_prefix_> - push the given prefix
997: - -prefix_pop - pop the last prefix
999: Notes:
1000: It is common to use this in conjunction with -options_file as in
1002: $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
1004: where the files no longer require all options to be prefixed with -system2_.
1006: The collectivity of this routine is complex; only the MPI processes that call this routine will
1007: have the affect of these options. If some processes that create objects call this routine and others do
1008: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1009: on different ranks.
1011: Level: advanced
1013: .seealso: PetscOptionsPrefixPop(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue()
1014: @*/
1015: PetscErrorCode PetscOptionsPrefixPush(PetscOptions options,const char prefix[])
1016: {
1018: size_t n;
1019: PetscInt start;
1020: char key[MAXOPTNAME+1];
1021: PetscBool valid;
1025: options = options ? options : defaultoptions;
1026: 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);
1027: key[0] = '-'; /* keys must start with '-' */
1028: PetscStrncpy(key+1,prefix,sizeof(key)-1);
1029: PetscOptionsValidKey(key,&valid);
1030: if (!valid && options->prefixind > 0 && isdigit((int)prefix[0])) valid = PETSC_TRUE; /* If the prefix stack is not empty, make numbers a valid prefix */
1031: 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":"");
1032: start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
1033: PetscStrlen(prefix,&n);
1034: if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
1035: PetscArraycpy(options->prefix+start,prefix,n+1);
1036: options->prefixstack[options->prefixind++] = start+n;
1037: return(0);
1038: }
1040: /*@C
1041: PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details
1043: Logically Collective on the MPI_Comm that called PetscOptionsPrefixPush()
1045: Input Parameters:
1046: . options - options database, or NULL for the default global database
1048: Level: advanced
1050: .seealso: PetscOptionsPrefixPush(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue()
1051: @*/
1052: PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
1053: {
1054: PetscInt offset;
1057: options = options ? options : defaultoptions;
1058: if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
1059: options->prefixind--;
1060: offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
1061: options->prefix[offset] = 0;
1062: return(0);
1063: }
1065: /*@C
1066: PetscOptionsClear - Removes all options form the database leaving it empty.
1068: Logically Collective
1070: Input Parameters:
1071: . options - options database, use NULL for the default global database
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: Level: developer
1080: .seealso: PetscOptionsInsert()
1081: @*/
1082: PetscErrorCode PetscOptionsClear(PetscOptions options)
1083: {
1084: PetscInt i;
1086: options = options ? options : defaultoptions;
1087: if (!options) return 0;
1089: for (i=0; i<options->N; i++) {
1090: if (options->names[i]) free(options->names[i]);
1091: if (options->values[i]) free(options->values[i]);
1092: }
1093: options->N = 0;
1095: for (i=0; i<options->Naliases; i++) {
1096: free(options->aliases1[i]);
1097: free(options->aliases2[i]);
1098: }
1099: options->Naliases = 0;
1101: /* destroy hash table */
1102: kh_destroy(HO,options->ht);
1103: options->ht = NULL;
1105: options->prefixind = 0;
1106: options->prefix[0] = 0;
1107: options->help = PETSC_FALSE;
1108: return 0;
1109: }
1111: /*@C
1112: PetscOptionsSetAlias - Makes a key and alias for another key
1114: Logically Collective
1116: Input Parameters:
1117: + options - options database, or NULL for default global database
1118: . newname - the alias
1119: - oldname - the name that alias will refer to
1121: Level: advanced
1123: The collectivity of this routine is complex; only the MPI processes that call this routine will
1124: have the affect of these options. If some processes that create objects call this routine and others do
1125: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1126: on different ranks.
1128: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1129: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
1130: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1131: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1132: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1133: PetscOptionsFList(), PetscOptionsEList()
1134: @*/
1135: PetscErrorCode PetscOptionsSetAlias(PetscOptions options,const char newname[],const char oldname[])
1136: {
1137: PetscInt n;
1138: size_t len;
1139: PetscBool valid;
1145: options = options ? options : defaultoptions;
1146: PetscOptionsValidKey(newname,&valid);
1147: if (!valid) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliased option %s",newname);
1148: PetscOptionsValidKey(oldname,&valid);
1149: if (!valid) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliasee option %s",oldname);
1151: n = options->Naliases;
1152: 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);
1154: newname++; oldname++;
1155: PetscStrlen(newname,&len);
1156: options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
1157: PetscStrcpy(options->aliases1[n],newname);
1158: PetscStrlen(oldname,&len);
1159: options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
1160: PetscStrcpy(options->aliases2[n],oldname);
1161: options->Naliases++;
1162: return(0);
1163: }
1165: /*@C
1166: PetscOptionsSetValue - Sets an option name-value pair in the options
1167: database, overriding whatever is already present.
1169: Logically Collective
1171: Input Parameters:
1172: + options - options database, use NULL for the default global database
1173: . name - name of option, this SHOULD have the - prepended
1174: - value - the option value (not used for all options, so can be NULL)
1176: Level: intermediate
1178: Note:
1179: This function can be called BEFORE PetscInitialize()
1181: The collectivity of this routine is complex; only the MPI processes that call this routine will
1182: have the affect of these options. If some processes that create objects call this routine and others do
1183: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1184: on different ranks.
1186: Developers Note: Uses malloc() directly because PETSc may not be initialized yet.
1188: .seealso: PetscOptionsInsert(), PetscOptionsClearValue()
1189: @*/
1190: PetscErrorCode PetscOptionsSetValue(PetscOptions options,const char name[],const char value[])
1191: {
1192: return PetscOptionsSetValue_Private(options,name,value,NULL);
1193: }
1195: static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options,const char name[],const char value[],int *pos)
1196: {
1197: size_t len;
1198: int N,n,i;
1199: char **names;
1200: char fullname[MAXOPTNAME] = "";
1201: PetscBool flg;
1204: if (!options) {
1205: PetscOptionsCreateDefault();if (ierr) return ierr;
1206: options = defaultoptions;
1207: }
1209: if (name[0] != '-') return PETSC_ERR_ARG_OUTOFRANGE;
1211: PetscOptionsSkipPrecedent(options,name,&flg);if (ierr) return ierr;
1212: if (flg) return 0;
1214: name++; /* skip starting dash */
1216: if (options->prefixind > 0) {
1217: strncpy(fullname,options->prefix,sizeof(fullname));
1218: fullname[sizeof(fullname)-1] = 0;
1219: strncat(fullname,name,sizeof(fullname)-strlen(fullname)-1);
1220: fullname[sizeof(fullname)-1] = 0;
1221: name = fullname;
1222: }
1224: /* check against aliases */
1225: N = options->Naliases;
1226: for (i=0; i<N; i++) {
1227: int result = PetscOptNameCmp(options->aliases1[i],name);
1228: if (!result) { name = options->aliases2[i]; break; }
1229: }
1231: /* slow search */
1232: N = n = options->N;
1233: names = options->names;
1234: for (i=0; i<N; i++) {
1235: int result = PetscOptNameCmp(names[i],name);
1236: if (!result) {
1237: n = i; goto setvalue;
1238: } else if (result > 0) {
1239: n = i; break;
1240: }
1241: }
1242: if (N >= MAXOPTIONS) return PETSC_ERR_MEM;
1243: /* shift remaining values up 1 */
1244: for (i=N; i>n; i--) {
1245: options->names[i] = options->names[i-1];
1246: options->values[i] = options->values[i-1];
1247: options->used[i] = options->used[i-1];
1248: }
1249: options->names[n] = NULL;
1250: options->values[n] = NULL;
1251: options->used[n] = PETSC_FALSE;
1252: options->N++;
1254: /* destroy hash table */
1255: kh_destroy(HO,options->ht);
1256: options->ht = NULL;
1258: /* set new name */
1259: len = strlen(name);
1260: options->names[n] = (char*)malloc((len+1)*sizeof(char));
1261: if (!options->names[n]) return PETSC_ERR_MEM;
1262: strcpy(options->names[n],name);
1264: setvalue:
1265: /* set new value */
1266: if (options->values[n]) free(options->values[n]);
1267: len = value ? strlen(value) : 0;
1268: if (len) {
1269: options->values[n] = (char*)malloc((len+1)*sizeof(char));
1270: if (!options->values[n]) return PETSC_ERR_MEM;
1271: strcpy(options->values[n],value);
1272: } else {
1273: options->values[n] = NULL;
1274: }
1276: /* handle -help so that it can be set from anywhere */
1277: if (!PetscOptNameCmp(name,"help")) {
1278: options->help = PETSC_TRUE;
1279: options->help_intro = (value && !PetscOptNameCmp(value,"intro")) ? PETSC_TRUE : PETSC_FALSE;
1280: options->used[n] = PETSC_TRUE;
1281: }
1283: if (PetscErrorHandlingInitialized) {
1284: PetscOptionsMonitor(options,name,value);
1285: }
1286: if (pos) *pos = n;
1287: return 0;
1288: }
1290: /*@C
1291: PetscOptionsClearValue - Clears an option name-value pair in the options
1292: database, overriding whatever is already present.
1294: Logically Collective
1296: Input Parameter:
1297: + options - options database, use NULL for the default global database
1298: - name - name of option, this SHOULD have the - prepended
1300: Level: intermediate
1302: The collectivity of this routine is complex; only the MPI processes that call this routine will
1303: have the affect of these options. If some processes that create objects call this routine and others do
1304: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1305: on different ranks.
1307: .seealso: PetscOptionsInsert()
1308: @*/
1309: PetscErrorCode PetscOptionsClearValue(PetscOptions options,const char name[])
1310: {
1311: int N,n,i;
1312: char **names;
1316: options = options ? options : defaultoptions;
1317: if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1318: if (!PetscOptNameCmp(name,"-help")) options->help = options->help_intro = PETSC_FALSE;
1320: name++; /* skip starting dash */
1322: /* slow search */
1323: N = n = options->N;
1324: names = options->names;
1325: for (i=0; i<N; i++) {
1326: int result = PetscOptNameCmp(names[i],name);
1327: if (!result) {
1328: n = i; break;
1329: } else if (result > 0) {
1330: n = N; break;
1331: }
1332: }
1333: if (n == N) return(0); /* it was not present */
1335: /* remove name and value */
1336: if (options->names[n]) free(options->names[n]);
1337: if (options->values[n]) free(options->values[n]);
1338: /* shift remaining values down 1 */
1339: for (i=n; i<N-1; i++) {
1340: options->names[i] = options->names[i+1];
1341: options->values[i] = options->values[i+1];
1342: options->used[i] = options->used[i+1];
1343: }
1344: options->N--;
1346: /* destroy hash table */
1347: kh_destroy(HO,options->ht);
1348: options->ht = NULL;
1350: PetscOptionsMonitor(options,name,NULL);
1351: return(0);
1352: }
1354: /*@C
1355: PetscOptionsFindPair - Gets an option name-value pair from the options database.
1357: Not Collective
1359: Input Parameters:
1360: + options - options database, use NULL for the default global database
1361: . pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
1362: - name - name of option, this SHOULD have the "-" prepended
1364: Output Parameters:
1365: + value - the option value (optional, not used for all options)
1366: - set - whether the option is set (optional)
1368: Notes:
1369: Each process may find different values or no value depending on how options were inserted into the database
1371: Level: developer
1373: .seealso: PetscOptionsSetValue(), PetscOptionsClearValue()
1374: @*/
1375: PetscErrorCode PetscOptionsFindPair(PetscOptions options,const char pre[],const char name[],const char *value[],PetscBool *set)
1376: {
1377: char buf[MAXOPTNAME];
1378: PetscBool usehashtable = PETSC_TRUE;
1379: PetscBool matchnumbers = PETSC_TRUE;
1383: options = options ? options : defaultoptions;
1384: if (pre && PetscUnlikely(pre[0] == '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1385: if (PetscUnlikely(name[0] != '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1387: name++; /* skip starting dash */
1389: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1390: if (pre && pre[0]) {
1391: char *ptr = buf;
1392: if (name[0] == '-') { *ptr++ = '-'; name++; }
1393: PetscStrncpy(ptr,pre,buf+sizeof(buf)-ptr);
1394: PetscStrlcat(buf,name,sizeof(buf));
1395: name = buf;
1396: }
1398: if (PetscDefined(USE_DEBUG)) {
1399: PetscBool valid;
1400: char key[MAXOPTNAME+1] = "-";
1401: PetscStrncpy(key+1,name,sizeof(key)-1);
1402: PetscOptionsValidKey(key,&valid);
1403: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1404: }
1406: if (!options->ht && usehashtable) {
1407: int i,ret;
1408: khiter_t it;
1409: khash_t(HO) *ht;
1410: ht = kh_init(HO);
1411: if (PetscUnlikely(!ht)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1412: ret = kh_resize(HO,ht,options->N*2); /* twice the required size to reduce risk of collisions */
1413: if (PetscUnlikely(ret)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1414: for (i=0; i<options->N; i++) {
1415: it = kh_put(HO,ht,options->names[i],&ret);
1416: if (PetscUnlikely(ret != 1)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1417: kh_val(ht,it) = i;
1418: }
1419: options->ht = ht;
1420: }
1422: if (usehashtable)
1423: { /* fast search */
1424: khash_t(HO) *ht = options->ht;
1425: khiter_t it = kh_get(HO,ht,name);
1426: if (it != kh_end(ht)) {
1427: int i = kh_val(ht,it);
1428: options->used[i] = PETSC_TRUE;
1429: if (value) *value = options->values[i];
1430: if (set) *set = PETSC_TRUE;
1431: return(0);
1432: }
1433: } else
1434: { /* slow search */
1435: int i, N = options->N;
1436: for (i=0; i<N; i++) {
1437: int result = PetscOptNameCmp(options->names[i],name);
1438: if (!result) {
1439: options->used[i] = PETSC_TRUE;
1440: if (value) *value = options->values[i];
1441: if (set) *set = PETSC_TRUE;
1442: return(0);
1443: } else if (result > 0) {
1444: break;
1445: }
1446: }
1447: }
1449: /*
1450: The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
1451: Maybe this special lookup mode should be enabled on request with a push/pop API.
1452: The feature of matching _%d_ used sparingly in the codebase.
1453: */
1454: if (matchnumbers) {
1455: int i,j,cnt = 0,locs[16],loce[16];
1456: /* determine the location and number of all _%d_ in the key */
1457: for (i=0; name[i]; i++) {
1458: if (name[i] == '_') {
1459: for (j=i+1; name[j]; j++) {
1460: if (name[j] >= '0' && name[j] <= '9') continue;
1461: if (name[j] == '_' && j > i+1) { /* found a number */
1462: locs[cnt] = i+1;
1463: loce[cnt++] = j+1;
1464: }
1465: i = j-1;
1466: break;
1467: }
1468: }
1469: }
1470: for (i=0; i<cnt; i++) {
1471: PetscBool found;
1472: char opt[MAXOPTNAME+1] = "-", tmp[MAXOPTNAME];
1473: PetscStrncpy(tmp,name,PetscMin((size_t)(locs[i]+1),sizeof(tmp)));
1474: PetscStrlcat(opt,tmp,sizeof(opt));
1475: PetscStrlcat(opt,name+loce[i],sizeof(opt));
1476: PetscOptionsFindPair(options,NULL,opt,value,&found);
1477: if (found) {if (set) *set = PETSC_TRUE; return(0);}
1478: }
1479: }
1481: if (set) *set = PETSC_FALSE;
1482: return(0);
1483: }
1485: /* Check whether any option begins with pre+name */
1486: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options,const char pre[], const char name[],const char *value[],PetscBool *set)
1487: {
1488: char buf[MAXOPTNAME];
1489: int numCnt = 0, locs[16],loce[16];
1493: options = options ? options : defaultoptions;
1494: if (pre && pre[0] == '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1495: if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1497: name++; /* skip starting dash */
1499: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1500: if (pre && pre[0]) {
1501: char *ptr = buf;
1502: if (name[0] == '-') { *ptr++ = '-'; name++; }
1503: PetscStrncpy(ptr,pre,sizeof(buf)+(size_t)(ptr-buf));
1504: PetscStrlcat(buf,name,sizeof(buf));
1505: name = buf;
1506: }
1508: if (PetscDefined(USE_DEBUG)) {
1509: PetscBool valid;
1510: char key[MAXOPTNAME+1] = "-";
1511: PetscStrncpy(key+1,name,sizeof(key)-1);
1512: PetscOptionsValidKey(key,&valid);
1513: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1514: }
1516: /* determine the location and number of all _%d_ in the key */
1517: {
1518: int i,j;
1519: for (i=0; name[i]; i++) {
1520: if (name[i] == '_') {
1521: for (j=i+1; name[j]; j++) {
1522: if (name[j] >= '0' && name[j] <= '9') continue;
1523: if (name[j] == '_' && j > i+1) { /* found a number */
1524: locs[numCnt] = i+1;
1525: loce[numCnt++] = j+1;
1526: }
1527: i = j-1;
1528: break;
1529: }
1530: }
1531: }
1532: }
1534: { /* slow search */
1535: int c, i;
1536: size_t len;
1537: PetscBool match;
1539: for (c = -1; c < numCnt; ++c) {
1540: char opt[MAXOPTNAME+1] = "", tmp[MAXOPTNAME];
1542: if (c < 0) {
1543: PetscStrcpy(opt,name);
1544: } else {
1545: PetscStrncpy(tmp,name,PetscMin((size_t)(locs[c]+1),sizeof(tmp)));
1546: PetscStrlcat(opt,tmp,sizeof(opt));
1547: PetscStrlcat(opt,name+loce[c],sizeof(opt));
1548: }
1549: PetscStrlen(opt,&len);
1550: for (i=0; i<options->N; i++) {
1551: PetscStrncmp(options->names[i],opt,len,&match);
1552: if (match) {
1553: options->used[i] = PETSC_TRUE;
1554: if (value) *value = options->values[i];
1555: if (set) *set = PETSC_TRUE;
1556: return(0);
1557: }
1558: }
1559: }
1560: }
1562: if (set) *set = PETSC_FALSE;
1563: return(0);
1564: }
1566: /*@C
1567: PetscOptionsReject - Generates an error if a certain option is given.
1569: Not Collective
1571: Input Parameters:
1572: + options - options database, use NULL for default global database
1573: . pre - the option prefix (may be NULL)
1574: . name - the option name one is seeking
1575: - mess - error message (may be NULL)
1577: Level: advanced
1579: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1580: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1581: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1582: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1583: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1584: PetscOptionsFList(), PetscOptionsEList()
1585: @*/
1586: PetscErrorCode PetscOptionsReject(PetscOptions options,const char pre[],const char name[],const char mess[])
1587: {
1589: PetscBool flag = PETSC_FALSE;
1592: PetscOptionsHasName(options,pre,name,&flag);
1593: if (flag) {
1594: 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);
1595: else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s",pre?pre:"",name+1);
1596: }
1597: return(0);
1598: }
1600: /*@C
1601: PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
1603: Not Collective
1605: Input Parameters:
1606: . options - options database, use NULL for default global database
1608: Output Parameters:
1609: . set - PETSC_TRUE if found else PETSC_FALSE.
1611: Level: advanced
1613: .seealso: PetscOptionsHasName()
1614: @*/
1615: PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set)
1616: {
1619: options = options ? options : defaultoptions;
1620: *set = options->help;
1621: return(0);
1622: }
1624: PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options,PetscBool *set)
1625: {
1628: options = options ? options : defaultoptions;
1629: *set = options->help_intro;
1630: return(0);
1631: }
1633: /*@C
1634: PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or boolean, even
1635: its value is set to false.
1637: Not Collective
1639: Input Parameters:
1640: + options - options database, use NULL for default global database
1641: . pre - string to prepend to the name or NULL
1642: - name - the option one is seeking
1644: Output Parameters:
1645: . set - PETSC_TRUE if found else PETSC_FALSE.
1647: Level: beginner
1649: Notes:
1650: In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.
1652: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1653: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1654: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1655: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1656: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1657: PetscOptionsFList(), PetscOptionsEList()
1658: @*/
1659: PetscErrorCode PetscOptionsHasName(PetscOptions options,const char pre[],const char name[],PetscBool *set)
1660: {
1661: const char *value;
1663: PetscBool flag;
1666: PetscOptionsFindPair(options,pre,name,&value,&flag);
1667: if (set) *set = flag;
1668: return(0);
1669: }
1671: /*@C
1672: PetscOptionsGetAll - Lists all the options the program was run with in a single string.
1674: Not Collective
1676: Input Parameter:
1677: . options - the options database, use NULL for the default global database
1679: Output Parameter:
1680: . copts - pointer where string pointer is stored
1682: Notes:
1683: The array and each entry in the array should be freed with PetscFree()
1684: Each process may have different values depending on how the options were inserted into the database
1686: Level: advanced
1688: .seealso: PetscOptionsAllUsed(), PetscOptionsView(), PetscOptionsPush(), PetscOptionsPop()
1689: @*/
1690: PetscErrorCode PetscOptionsGetAll(PetscOptions options,char *copts[])
1691: {
1693: PetscInt i;
1694: size_t len = 1,lent = 0;
1695: char *coptions = NULL;
1699: options = options ? options : defaultoptions;
1700: /* count the length of the required string */
1701: for (i=0; i<options->N; i++) {
1702: PetscStrlen(options->names[i],&lent);
1703: len += 2 + lent;
1704: if (options->values[i]) {
1705: PetscStrlen(options->values[i],&lent);
1706: len += 1 + lent;
1707: }
1708: }
1709: PetscMalloc1(len,&coptions);
1710: coptions[0] = 0;
1711: for (i=0; i<options->N; i++) {
1712: PetscStrcat(coptions,"-");
1713: PetscStrcat(coptions,options->names[i]);
1714: PetscStrcat(coptions," ");
1715: if (options->values[i]) {
1716: PetscStrcat(coptions,options->values[i]);
1717: PetscStrcat(coptions," ");
1718: }
1719: }
1720: *copts = coptions;
1721: return(0);
1722: }
1724: /*@C
1725: PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
1727: Not Collective
1729: Input Parameter:
1730: + options - options database, use NULL for default global database
1731: - name - string name of option
1733: Output Parameter:
1734: . used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database
1736: Level: advanced
1738: Notes:
1739: The value returned may be different on each process and depends on which options have been processed
1740: on the given process
1742: .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
1743: @*/
1744: PetscErrorCode PetscOptionsUsed(PetscOptions options,const char *name,PetscBool *used)
1745: {
1746: PetscInt i;
1752: options = options ? options : defaultoptions;
1753: *used = PETSC_FALSE;
1754: for (i=0; i<options->N; i++) {
1755: PetscStrcasecmp(options->names[i],name,used);
1756: if (*used) {
1757: *used = options->used[i];
1758: break;
1759: }
1760: }
1761: return(0);
1762: }
1764: /*@
1765: PetscOptionsAllUsed - Returns a count of the number of options in the
1766: database that have never been selected.
1768: Not Collective
1770: Input Parameter:
1771: . options - options database, use NULL for default global database
1773: Output Parameter:
1774: . N - count of options not used
1776: Level: advanced
1778: Notes:
1779: The value returned may be different on each process and depends on which options have been processed
1780: on the given process
1782: .seealso: PetscOptionsView()
1783: @*/
1784: PetscErrorCode PetscOptionsAllUsed(PetscOptions options,PetscInt *N)
1785: {
1786: PetscInt i,n = 0;
1790: options = options ? options : defaultoptions;
1791: for (i=0; i<options->N; i++) {
1792: if (!options->used[i]) n++;
1793: }
1794: *N = n;
1795: return(0);
1796: }
1798: /*@
1799: PetscOptionsLeft - Prints to screen any options that were set and never used.
1801: Not Collective
1803: Input Parameter:
1804: . options - options database; use NULL for default global database
1806: Options Database Key:
1807: . -options_left - activates PetscOptionsAllUsed() within PetscFinalize()
1809: Notes:
1810: This is rarely used directly, it is called by PetscFinalize() in debug more or if -options_left
1811: is passed otherwise to help users determine possible mistakes in their usage of options. This
1812: only prints values on process zero of PETSC_COMM_WORLD. Other processes depending the objects
1813: used may have different options that are left unused.
1815: Level: advanced
1817: .seealso: PetscOptionsAllUsed()
1818: @*/
1819: PetscErrorCode PetscOptionsLeft(PetscOptions options)
1820: {
1822: PetscInt i;
1823: PetscInt cnt = 0;
1824: PetscOptions toptions;
1827: toptions = options ? options : defaultoptions;
1828: for (i=0; i<toptions->N; i++) {
1829: if (!toptions->used[i]) {
1830: if (toptions->values[i]) {
1831: PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",toptions->names[i],toptions->values[i]);
1832: } else {
1833: PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",toptions->names[i]);
1834: }
1835: }
1836: }
1837: if (!options) {
1838: toptions = defaultoptions;
1839: while (toptions->previous) {
1840: cnt++;
1841: toptions = toptions->previous;
1842: }
1843: if (cnt) {
1844: 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);
1845: }
1846: }
1847: return(0);
1848: }
1850: /*@C
1851: PetscOptionsLeftGet - Returns all options that were set and never used.
1853: Not Collective
1855: Input Parameter:
1856: . options - options database, use NULL for default global database
1858: Output Parameter:
1859: + N - count of options not used
1860: . names - names of options not used
1861: - values - values of options not used
1863: Level: advanced
1865: Notes:
1866: Users should call PetscOptionsLeftRestore() to free the memory allocated in this routine
1867: Notes: The value returned may be different on each process and depends on which options have been processed
1868: on the given process
1870: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft()
1871: @*/
1872: PetscErrorCode PetscOptionsLeftGet(PetscOptions options,PetscInt *N,char **names[],char **values[])
1873: {
1875: PetscInt i,n;
1881: options = options ? options : defaultoptions;
1883: /* The number of unused PETSc options */
1884: n = 0;
1885: for (i=0; i<options->N; i++) {
1886: if (!options->used[i]) n++;
1887: }
1888: if (N) { *N = n; }
1889: if (names) { PetscMalloc1(n,names); }
1890: if (values) { PetscMalloc1(n,values); }
1892: n = 0;
1893: if (names || values) {
1894: for (i=0; i<options->N; i++) {
1895: if (!options->used[i]) {
1896: if (names) (*names)[n] = options->names[i];
1897: if (values) (*values)[n] = options->values[i];
1898: n++;
1899: }
1900: }
1901: }
1902: return(0);
1903: }
1905: /*@C
1906: PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using PetscOptionsLeftGet.
1908: Not Collective
1910: Input Parameter:
1911: + options - options database, use NULL for default global database
1912: . names - names of options not used
1913: - values - values of options not used
1915: Level: advanced
1917: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft(), PetscOptionsLeftGet()
1918: @*/
1919: PetscErrorCode PetscOptionsLeftRestore(PetscOptions options,PetscInt *N,char **names[],char **values[])
1920: {
1927: if (N) { *N = 0; }
1928: if (names) { PetscFree(*names); }
1929: if (values) { PetscFree(*values); }
1930: return(0);
1931: }
1933: /*@C
1934: PetscOptionsMonitorDefault - Print all options set value events using the supplied PetscViewer.
1936: Logically Collective on ctx
1938: Input Parameters:
1939: + name - option name string
1940: . value - option value string
1941: - ctx - an ASCII viewer or NULL
1943: Level: intermediate
1945: Notes:
1946: If ctx=NULL, PetscPrintf() is used.
1947: The first MPI rank in the PetscViewer viewer actually prints the values, other
1948: processes may have different values set
1950: .seealso: PetscOptionsMonitorSet()
1951: @*/
1952: PetscErrorCode PetscOptionsMonitorDefault(const char name[],const char value[],void *ctx)
1953: {
1957: if (ctx) {
1958: PetscViewer viewer = (PetscViewer)ctx;
1959: if (!value) {
1960: PetscViewerASCIIPrintf(viewer,"Removing option: %s\n",name,value);
1961: } else if (!value[0]) {
1962: PetscViewerASCIIPrintf(viewer,"Setting option: %s (no value)\n",name);
1963: } else {
1964: PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
1965: }
1966: } else {
1967: MPI_Comm comm = PETSC_COMM_WORLD;
1968: if (!value) {
1969: PetscPrintf(comm,"Removing option: %s\n",name,value);
1970: } else if (!value[0]) {
1971: PetscPrintf(comm,"Setting option: %s (no value)\n",name);
1972: } else {
1973: PetscPrintf(comm,"Setting option: %s = %s\n",name,value);
1974: }
1975: }
1976: return(0);
1977: }
1979: /*@C
1980: PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
1981: modified the PETSc options database.
1983: Not Collective
1985: Input Parameters:
1986: + monitor - pointer to function (if this is NULL, it turns off monitoring
1987: . mctx - [optional] context for private data for the
1988: monitor routine (use NULL if no context is desired)
1989: - monitordestroy - [optional] routine that frees monitor context
1990: (may be NULL)
1992: Calling Sequence of monitor:
1993: $ monitor (const char name[], const char value[], void *mctx)
1995: + name - option name string
1996: . value - option value string
1997: - mctx - optional monitoring context, as set by PetscOptionsMonitorSet()
1999: Options Database Keys:
2000: See PetscInitialize() for options related to option database monitoring.
2002: Notes:
2003: The default is to do nothing. To print the name and value of options
2004: being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
2005: with a null monitoring context.
2007: Several different monitoring routines may be set by calling
2008: PetscOptionsMonitorSet() multiple times; all will be called in the
2009: order in which they were set.
2011: Level: intermediate
2013: .seealso: PetscOptionsMonitorDefault(), PetscInitialize()
2014: @*/
2015: PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
2016: {
2017: PetscOptions options = defaultoptions;
2020: if (options->monitorCancel) return(0);
2021: if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
2022: options->monitor[options->numbermonitors] = monitor;
2023: options->monitordestroy[options->numbermonitors] = monitordestroy;
2024: options->monitorcontext[options->numbermonitors++] = (void*)mctx;
2025: return(0);
2026: }
2028: /*
2029: PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
2030: Empty string is considered as true.
2031: */
2032: PetscErrorCode PetscOptionsStringToBool(const char value[],PetscBool *a)
2033: {
2034: PetscBool istrue,isfalse;
2035: size_t len;
2039: /* PetscStrlen() returns 0 for NULL or "" */
2040: PetscStrlen(value,&len);
2041: if (!len) {*a = PETSC_TRUE; return(0);}
2042: PetscStrcasecmp(value,"TRUE",&istrue);
2043: if (istrue) {*a = PETSC_TRUE; return(0);}
2044: PetscStrcasecmp(value,"YES",&istrue);
2045: if (istrue) {*a = PETSC_TRUE; return(0);}
2046: PetscStrcasecmp(value,"1",&istrue);
2047: if (istrue) {*a = PETSC_TRUE; return(0);}
2048: PetscStrcasecmp(value,"on",&istrue);
2049: if (istrue) {*a = PETSC_TRUE; return(0);}
2050: PetscStrcasecmp(value,"FALSE",&isfalse);
2051: if (isfalse) {*a = PETSC_FALSE; return(0);}
2052: PetscStrcasecmp(value,"NO",&isfalse);
2053: if (isfalse) {*a = PETSC_FALSE; return(0);}
2054: PetscStrcasecmp(value,"0",&isfalse);
2055: if (isfalse) {*a = PETSC_FALSE; return(0);}
2056: PetscStrcasecmp(value,"off",&isfalse);
2057: if (isfalse) {*a = PETSC_FALSE; return(0);}
2058: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value);
2059: }
2061: /*
2062: PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
2063: */
2064: PetscErrorCode PetscOptionsStringToInt(const char name[],PetscInt *a)
2065: {
2067: size_t len;
2068: PetscBool decide,tdefault,mouse;
2071: PetscStrlen(name,&len);
2072: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
2074: PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
2075: if (!tdefault) {
2076: PetscStrcasecmp(name,"DEFAULT",&tdefault);
2077: }
2078: PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
2079: if (!decide) {
2080: PetscStrcasecmp(name,"DECIDE",&decide);
2081: }
2082: PetscStrcasecmp(name,"mouse",&mouse);
2084: if (tdefault) *a = PETSC_DEFAULT;
2085: else if (decide) *a = PETSC_DECIDE;
2086: else if (mouse) *a = -1;
2087: else {
2088: char *endptr;
2089: long strtolval;
2091: strtolval = strtol(name,&endptr,10);
2092: 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);
2094: #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
2095: (void) strtolval;
2096: *a = atoll(name);
2097: #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
2098: (void) strtolval;
2099: *a = _atoi64(name);
2100: #else
2101: *a = (PetscInt)strtolval;
2102: #endif
2103: }
2104: return(0);
2105: }
2107: #if defined(PETSC_USE_REAL___FLOAT128)
2108: #include <quadmath.h>
2109: #endif
2111: static PetscErrorCode PetscStrtod(const char name[],PetscReal *a,char **endptr)
2112: {
2114: #if defined(PETSC_USE_REAL___FLOAT128)
2115: *a = strtoflt128(name,endptr);
2116: #else
2117: *a = (PetscReal)strtod(name,endptr);
2118: #endif
2119: return(0);
2120: }
2122: static PetscErrorCode PetscStrtoz(const char name[],PetscScalar *a,char **endptr,PetscBool *isImaginary)
2123: {
2124: PetscBool hasi = PETSC_FALSE;
2125: char *ptr;
2126: PetscReal strtoval;
2130: PetscStrtod(name,&strtoval,&ptr);
2131: if (ptr == name) {
2132: strtoval = 1.;
2133: hasi = PETSC_TRUE;
2134: if (name[0] == 'i') {
2135: ptr++;
2136: } else if (name[0] == '+' && name[1] == 'i') {
2137: ptr += 2;
2138: } else if (name[0] == '-' && name[1] == 'i') {
2139: strtoval = -1.;
2140: ptr += 2;
2141: }
2142: } else if (*ptr == 'i') {
2143: hasi = PETSC_TRUE;
2144: ptr++;
2145: }
2146: *endptr = ptr;
2147: *isImaginary = hasi;
2148: if (hasi) {
2149: #if !defined(PETSC_USE_COMPLEX)
2150: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s contains imaginary but complex not supported ",name);
2151: #else
2152: *a = PetscCMPLX(0.,strtoval);
2153: #endif
2154: } else {
2155: *a = strtoval;
2156: }
2157: return(0);
2158: }
2160: /*
2161: Converts a string to PetscReal value. Handles special cases like "default" and "decide"
2162: */
2163: PetscErrorCode PetscOptionsStringToReal(const char name[],PetscReal *a)
2164: {
2165: size_t len;
2166: PetscBool match;
2167: char *endptr;
2171: PetscStrlen(name,&len);
2172: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"String of length zero has no numerical value");
2174: PetscStrcasecmp(name,"PETSC_DEFAULT",&match);
2175: if (!match) {
2176: PetscStrcasecmp(name,"DEFAULT",&match);
2177: }
2178: if (match) {*a = PETSC_DEFAULT; return(0);}
2180: PetscStrcasecmp(name,"PETSC_DECIDE",&match);
2181: if (!match) {
2182: PetscStrcasecmp(name,"DECIDE",&match);
2183: }
2184: if (match) {*a = PETSC_DECIDE; return(0);}
2186: PetscStrtod(name,a,&endptr);
2187: if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value",name);
2188: return(0);
2189: }
2191: PetscErrorCode PetscOptionsStringToScalar(const char name[],PetscScalar *a)
2192: {
2193: PetscBool imag1;
2194: size_t len;
2195: PetscScalar val = 0.;
2196: char *ptr = NULL;
2200: PetscStrlen(name,&len);
2201: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
2202: PetscStrtoz(name,&val,&ptr,&imag1);
2203: #if defined(PETSC_USE_COMPLEX)
2204: if ((size_t) (ptr - name) < len) {
2205: PetscBool imag2;
2206: PetscScalar val2;
2208: PetscStrtoz(ptr,&val2,&ptr,&imag2);
2209: if (imag1 || !imag2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s: must specify imaginary component second",name);
2210: val = PetscCMPLX(PetscRealPart(val),PetscImaginaryPart(val2));
2211: }
2212: #endif
2213: if ((size_t) (ptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
2214: *a = val;
2215: return(0);
2216: }
2218: /*@C
2219: PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
2220: option in the database.
2222: Not Collective
2224: Input Parameters:
2225: + options - options database, use NULL for default global database
2226: . pre - the string to prepend to the name or NULL
2227: - name - the option one is seeking
2229: Output Parameter:
2230: + ivalue - the logical value to return
2231: - set - PETSC_TRUE if found, else PETSC_FALSE
2233: Level: beginner
2235: Notes:
2236: TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
2237: FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
2239: 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
2240: is equivalent to -requested_bool true
2242: If the user does not supply the option at all ivalue is NOT changed. Thus
2243: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2245: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
2246: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
2247: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2248: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2249: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2250: PetscOptionsFList(), PetscOptionsEList()
2251: @*/
2252: PetscErrorCode PetscOptionsGetBool(PetscOptions options,const char pre[],const char name[],PetscBool *ivalue,PetscBool *set)
2253: {
2254: const char *value;
2255: PetscBool flag;
2261: PetscOptionsFindPair(options,pre,name,&value,&flag);
2262: if (flag) {
2263: if (set) *set = PETSC_TRUE;
2264: PetscOptionsStringToBool(value, &flag);
2265: if (ivalue) *ivalue = flag;
2266: } else {
2267: if (set) *set = PETSC_FALSE;
2268: }
2269: return(0);
2270: }
2272: /*@C
2273: PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2275: Not Collective
2277: Input Parameters:
2278: + options - options database, use NULL for default global database
2279: . pre - the string to prepend to the name or NULL
2280: . opt - option name
2281: . list - the possible choices (one of these must be selected, anything else is invalid)
2282: - ntext - number of choices
2284: Output Parameter:
2285: + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2286: - set - PETSC_TRUE if found, else PETSC_FALSE
2288: Level: intermediate
2290: Notes:
2291: If the user does not supply the option value is NOT changed. Thus
2292: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2294: See PetscOptionsFList() for when the choices are given in a PetscFunctionList()
2296: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2297: PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2298: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2299: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2300: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2301: PetscOptionsFList(), PetscOptionsEList()
2302: @*/
2303: PetscErrorCode PetscOptionsGetEList(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool *set)
2304: {
2306: size_t alen,len = 0, tlen = 0;
2307: char *svalue;
2308: PetscBool aset,flg = PETSC_FALSE;
2309: PetscInt i;
2313: for (i=0; i<ntext; i++) {
2314: PetscStrlen(list[i],&alen);
2315: if (alen > len) len = alen;
2316: tlen += len + 1;
2317: }
2318: len += 5; /* a little extra space for user mistypes */
2319: PetscMalloc1(len,&svalue);
2320: PetscOptionsGetString(options,pre,opt,svalue,len,&aset);
2321: if (aset) {
2322: PetscEListFind(ntext,list,svalue,value,&flg);
2323: if (!flg) {
2324: char *avail,*pavl;
2326: PetscMalloc1(tlen,&avail);
2327: pavl = avail;
2328: for (i=0; i<ntext; i++) {
2329: PetscStrlen(list[i],&alen);
2330: PetscStrcpy(pavl,list[i]);
2331: pavl += alen;
2332: PetscStrcpy(pavl," ");
2333: pavl += 1;
2334: }
2335: PetscStrtolower(avail);
2336: SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s. Available options: %s",svalue,pre ? pre : "",opt+1,avail);
2337: }
2338: if (set) *set = PETSC_TRUE;
2339: } else if (set) *set = PETSC_FALSE;
2340: PetscFree(svalue);
2341: return(0);
2342: }
2344: /*@C
2345: PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2347: Not Collective
2349: Input Parameters:
2350: + options - options database, use NULL for default global database
2351: . pre - option prefix or NULL
2352: . opt - option name
2353: . list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2354: - defaultv - the default (current) value
2356: Output Parameter:
2357: + value - the 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 value 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: List is usually something like PCASMTypes or some other predefined list of enum names
2368: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2369: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2370: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2371: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2372: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2373: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2374: PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2375: @*/
2376: PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set)
2377: {
2379: PetscInt ntext = 0,tval;
2380: PetscBool fset;
2384: while (list[ntext++]) {
2385: if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
2386: }
2387: if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
2388: ntext -= 3;
2389: PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset);
2390: /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2391: if (fset) *value = (PetscEnum)tval;
2392: if (set) *set = fset;
2393: return(0);
2394: }
2396: /*@C
2397: PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2399: Not Collective
2401: Input Parameters:
2402: + options - options database, use NULL for default global database
2403: . pre - the string to prepend to the name or NULL
2404: - name - the option one is seeking
2406: Output Parameter:
2407: + ivalue - the integer value to return
2408: - set - PETSC_TRUE if found, else PETSC_FALSE
2410: Level: beginner
2412: Notes:
2413: If the user does not supply the option ivalue 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: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
2417: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2418: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2419: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2420: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2421: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2422: PetscOptionsFList(), PetscOptionsEList()
2423: @*/
2424: PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set)
2425: {
2426: const char *value;
2428: PetscBool flag;
2433: PetscOptionsFindPair(options,pre,name,&value,&flag);
2434: if (flag) {
2435: if (!value) {
2436: if (set) *set = PETSC_FALSE;
2437: } else {
2438: if (set) *set = PETSC_TRUE;
2439: PetscOptionsStringToInt(value,ivalue);
2440: }
2441: } else {
2442: if (set) *set = PETSC_FALSE;
2443: }
2444: return(0);
2445: }
2447: /*@C
2448: PetscOptionsGetReal - Gets the double precision value for a particular
2449: option in the database.
2451: Not Collective
2453: Input Parameters:
2454: + options - options database, use NULL for default global database
2455: . pre - string to prepend to each name or NULL
2456: - name - the option one is seeking
2458: Output Parameter:
2459: + dvalue - the double value to return
2460: - set - PETSC_TRUE if found, PETSC_FALSE if not found
2462: Notes:
2463: If the user does not supply the option dvalue is NOT changed. Thus
2464: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2466: Level: beginner
2468: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2469: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
2470: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2471: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2472: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2473: PetscOptionsFList(), PetscOptionsEList()
2474: @*/
2475: PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set)
2476: {
2477: const char *value;
2478: PetscBool flag;
2484: PetscOptionsFindPair(options,pre,name,&value,&flag);
2485: if (flag) {
2486: if (!value) {
2487: if (set) *set = PETSC_FALSE;
2488: } else {
2489: if (set) *set = PETSC_TRUE;
2490: PetscOptionsStringToReal(value,dvalue);
2491: }
2492: } else {
2493: if (set) *set = PETSC_FALSE;
2494: }
2495: return(0);
2496: }
2498: /*@C
2499: PetscOptionsGetScalar - Gets the scalar value for a particular
2500: option in the database.
2502: Not Collective
2504: Input Parameters:
2505: + options - options database, use NULL for default global database
2506: . pre - string to prepend to each name or NULL
2507: - name - the option one is seeking
2509: Output Parameter:
2510: + dvalue - the double value to return
2511: - set - PETSC_TRUE if found, else PETSC_FALSE
2513: Level: beginner
2515: Usage:
2516: A complex number 2+3i must be specified with NO spaces
2518: Notes:
2519: If the user does not supply the option dvalue is NOT changed. Thus
2520: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2522: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2523: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2524: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2525: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2526: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2527: PetscOptionsFList(), PetscOptionsEList()
2528: @*/
2529: PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set)
2530: {
2531: const char *value;
2532: PetscBool flag;
2538: PetscOptionsFindPair(options,pre,name,&value,&flag);
2539: if (flag) {
2540: if (!value) {
2541: if (set) *set = PETSC_FALSE;
2542: } else {
2543: #if !defined(PETSC_USE_COMPLEX)
2544: PetscOptionsStringToReal(value,dvalue);
2545: #else
2546: PetscOptionsStringToScalar(value,dvalue);
2547: #endif
2548: if (set) *set = PETSC_TRUE;
2549: }
2550: } else { /* flag */
2551: if (set) *set = PETSC_FALSE;
2552: }
2553: return(0);
2554: }
2556: /*@C
2557: PetscOptionsGetString - Gets the string value for a particular option in
2558: the database.
2560: Not Collective
2562: Input Parameters:
2563: + options - options database, use NULL for default global database
2564: . pre - string to prepend to name or NULL
2565: . name - the option one is seeking
2566: - len - maximum length of the string including null termination
2568: Output Parameters:
2569: + string - location to copy string
2570: - set - PETSC_TRUE if found, else PETSC_FALSE
2572: Level: beginner
2574: Fortran Note:
2575: The Fortran interface is slightly different from the C/C++
2576: interface (len is not used). Sample usage in Fortran follows
2577: .vb
2578: character *20 string
2579: PetscErrorCode ierr
2580: PetscBool set
2581: call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2582: .ve
2584: Notes:
2585: 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
2587: If the user does not use the option then the string is not changed. Thus
2588: you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
2590: Note:
2591: 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).
2593: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2594: PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2595: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2596: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2597: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2598: PetscOptionsFList(), PetscOptionsEList()
2599: @*/
2600: PetscErrorCode PetscOptionsGetString(PetscOptions options,const char pre[],const char name[],char string[],size_t len,PetscBool *set)
2601: {
2602: const char *value;
2603: PetscBool flag;
2609: PetscOptionsFindPair(options,pre,name,&value,&flag);
2610: if (!flag) {
2611: if (set) *set = PETSC_FALSE;
2612: } else {
2613: if (set) *set = PETSC_TRUE;
2614: if (value) {
2615: PetscStrncpy(string,value,len);
2616: } else {
2617: PetscArrayzero(string,len);
2618: }
2619: }
2620: return(0);
2621: }
2623: char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[])
2624: {
2625: const char *value;
2626: PetscBool flag;
2630: PetscOptionsFindPair(options,pre,name,&value,&flag);if (ierr) PetscFunctionReturn(NULL);
2631: if (flag) PetscFunctionReturn((char*)value);
2632: else PetscFunctionReturn(NULL);
2633: }
2635: /*@C
2636: PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2637: option in the database. The values must be separated with commas with
2638: no intervening spaces.
2640: Not Collective
2642: Input Parameters:
2643: + options - options database, use NULL for default global database
2644: . pre - string to prepend to each name or NULL
2645: . name - the option one is seeking
2646: - nmax - maximum number of values to retrieve
2648: Output Parameter:
2649: + dvalue - the integer values to return
2650: . nmax - actual number of values retreived
2651: - set - PETSC_TRUE if found, else PETSC_FALSE
2653: Level: beginner
2655: Notes:
2656: TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
2657: FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
2659: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2660: PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2661: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2662: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2663: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2664: PetscOptionsFList(), PetscOptionsEList()
2665: @*/
2666: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set)
2667: {
2668: const char *svalue;
2669: char *value;
2671: PetscInt n = 0;
2672: PetscBool flag;
2673: PetscToken token;
2680: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2681: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2682: if (set) *set = PETSC_TRUE;
2683: PetscTokenCreate(svalue,',',&token);
2684: PetscTokenFind(token,&value);
2685: while (value && n < *nmax) {
2686: PetscOptionsStringToBool(value,dvalue);
2687: PetscTokenFind(token,&value);
2688: dvalue++;
2689: n++;
2690: }
2691: PetscTokenDestroy(&token);
2692: *nmax = n;
2693: return(0);
2694: }
2696: /*@C
2697: PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
2699: Not Collective
2701: Input Parameters:
2702: + options - options database, use NULL for default global database
2703: . pre - option prefix or NULL
2704: . name - option name
2705: . list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2706: - nmax - maximum number of values to retrieve
2708: Output Parameters:
2709: + ivalue - the enum values to return
2710: . nmax - actual number of values retreived
2711: - set - PETSC_TRUE if found, else PETSC_FALSE
2713: Level: beginner
2715: Notes:
2716: The array must be passed as a comma separated list.
2718: There must be no intervening spaces between the values.
2720: list is usually something like PCASMTypes or some other predefined list of enum names.
2722: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2723: PetscOptionsGetEnum(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2724: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(),
2725: PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(),
2726: PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2727: PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2728: @*/
2729: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set)
2730: {
2731: const char *svalue;
2732: char *value;
2733: PetscInt n = 0;
2734: PetscEnum evalue;
2735: PetscBool flag;
2736: PetscToken token;
2745: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2746: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2747: if (set) *set = PETSC_TRUE;
2748: PetscTokenCreate(svalue,',',&token);
2749: PetscTokenFind(token,&value);
2750: while (value && n < *nmax) {
2751: PetscEnumFind(list,value,&evalue,&flag);
2752: if (!flag) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
2753: ivalue[n++] = evalue;
2754: PetscTokenFind(token,&value);
2755: }
2756: PetscTokenDestroy(&token);
2757: *nmax = n;
2758: return(0);
2759: }
2761: /*@C
2762: PetscOptionsGetIntArray - Gets an array of integer values for a particular
2763: option in the database.
2765: Not Collective
2767: Input Parameters:
2768: + options - options database, use NULL for default global database
2769: . pre - string to prepend to each name or NULL
2770: . name - the option one is seeking
2771: - nmax - maximum number of values to retrieve
2773: Output Parameter:
2774: + ivalue - the integer values to return
2775: . nmax - actual number of values retreived
2776: - set - PETSC_TRUE if found, else PETSC_FALSE
2778: Level: beginner
2780: Notes:
2781: The array can be passed as
2782: a comma separated list: 0,1,2,3,4,5,6,7
2783: a range (start-end+1): 0-8
2784: a range with given increment (start-end+1:inc): 0-7:2
2785: a combination of values and ranges separated by commas: 0,1-8,8-15:2
2787: There must be no intervening spaces between the values.
2789: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2790: PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2791: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2792: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2793: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2794: PetscOptionsFList(), PetscOptionsEList()
2795: @*/
2796: PetscErrorCode PetscOptionsGetIntArray(PetscOptions options,const char pre[],const char name[],PetscInt ivalue[],PetscInt *nmax,PetscBool *set)
2797: {
2798: const char *svalue;
2799: char *value;
2801: PetscInt n = 0,i,j,start,end,inc,nvalues;
2802: size_t len;
2803: PetscBool flag,foundrange;
2804: PetscToken token;
2811: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2812: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2813: if (set) *set = PETSC_TRUE;
2814: PetscTokenCreate(svalue,',',&token);
2815: PetscTokenFind(token,&value);
2816: while (value && n < *nmax) {
2817: /* look for form d-D where d and D are integers */
2818: foundrange = PETSC_FALSE;
2819: PetscStrlen(value,&len);
2820: if (value[0] == '-') i=2;
2821: else i=1;
2822: for (;i<(int)len; i++) {
2823: if (value[i] == '-') {
2824: if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
2825: value[i] = 0;
2827: PetscOptionsStringToInt(value,&start);
2828: inc = 1;
2829: j = i+1;
2830: for (;j<(int)len; j++) {
2831: if (value[j] == ':') {
2832: value[j] = 0;
2834: PetscOptionsStringToInt(value+j+1,&inc);
2835: 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);
2836: break;
2837: }
2838: }
2839: PetscOptionsStringToInt(value+i+1,&end);
2840: 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);
2841: nvalues = (end-start)/inc + (end-start)%inc;
2842: 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);
2843: for (;start<end; start+=inc) {
2844: *ivalue = start; ivalue++;n++;
2845: }
2846: foundrange = PETSC_TRUE;
2847: break;
2848: }
2849: }
2850: if (!foundrange) {
2851: PetscOptionsStringToInt(value,ivalue);
2852: ivalue++;
2853: n++;
2854: }
2855: PetscTokenFind(token,&value);
2856: }
2857: PetscTokenDestroy(&token);
2858: *nmax = n;
2859: return(0);
2860: }
2862: /*@C
2863: PetscOptionsGetRealArray - Gets an array of double precision values for a
2864: particular option in the database. The values must be separated with
2865: commas with no intervening spaces.
2867: Not Collective
2869: Input Parameters:
2870: + options - options database, use NULL for default global database
2871: . pre - string to prepend to each name or NULL
2872: . name - the option one is seeking
2873: - nmax - maximum number of values to retrieve
2875: Output Parameters:
2876: + dvalue - the double values to return
2877: . nmax - actual number of values retreived
2878: - set - PETSC_TRUE if found, else PETSC_FALSE
2880: Level: beginner
2882: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2883: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2884: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2885: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2886: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2887: PetscOptionsFList(), PetscOptionsEList()
2888: @*/
2889: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set)
2890: {
2891: const char *svalue;
2892: char *value;
2894: PetscInt n = 0;
2895: PetscBool flag;
2896: PetscToken token;
2903: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2904: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2905: if (set) *set = PETSC_TRUE;
2906: PetscTokenCreate(svalue,',',&token);
2907: PetscTokenFind(token,&value);
2908: while (value && n < *nmax) {
2909: PetscOptionsStringToReal(value,dvalue++);
2910: PetscTokenFind(token,&value);
2911: n++;
2912: }
2913: PetscTokenDestroy(&token);
2914: *nmax = n;
2915: return(0);
2916: }
2918: /*@C
2919: PetscOptionsGetScalarArray - Gets an array of scalars for a
2920: particular option in the database. The values must be separated with
2921: commas with no intervening spaces.
2923: Not Collective
2925: Input Parameters:
2926: + options - options database, use NULL for default global database
2927: . pre - string to prepend to each name or NULL
2928: . name - the option one is seeking
2929: - nmax - maximum number of values to retrieve
2931: Output Parameters:
2932: + dvalue - the scalar values to return
2933: . nmax - actual number of values retreived
2934: - set - PETSC_TRUE if found, else PETSC_FALSE
2936: Level: beginner
2938: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2939: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2940: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2941: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2942: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2943: PetscOptionsFList(), PetscOptionsEList()
2944: @*/
2945: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set)
2946: {
2947: const char *svalue;
2948: char *value;
2950: PetscInt n = 0;
2951: PetscBool flag;
2952: PetscToken token;
2959: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2960: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2961: if (set) *set = PETSC_TRUE;
2962: PetscTokenCreate(svalue,',',&token);
2963: PetscTokenFind(token,&value);
2964: while (value && n < *nmax) {
2965: PetscOptionsStringToScalar(value,dvalue++);
2966: PetscTokenFind(token,&value);
2967: n++;
2968: }
2969: PetscTokenDestroy(&token);
2970: *nmax = n;
2971: return(0);
2972: }
2974: /*@C
2975: PetscOptionsGetStringArray - Gets an array of string values for a particular
2976: option in the database. The values must be separated with commas with
2977: no intervening spaces.
2979: Not Collective
2981: Input Parameters:
2982: + options - options database, use NULL for default global database
2983: . pre - string to prepend to name or NULL
2984: . name - the option one is seeking
2985: - nmax - maximum number of strings
2987: Output Parameters:
2988: + strings - location to copy strings
2989: . nmax - the number of strings found
2990: - set - PETSC_TRUE if found, else PETSC_FALSE
2992: Level: beginner
2994: Notes:
2995: The nmax parameter is used for both input and output.
2997: The user should pass in an array of pointers to char, to hold all the
2998: strings returned by this function.
3000: The user is responsible for deallocating the strings that are
3001: returned. The Fortran interface for this routine is not supported.
3003: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
3004: PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
3005: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
3006: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
3007: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
3008: PetscOptionsFList(), PetscOptionsEList()
3009: @*/
3010: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set)
3011: {
3012: const char *svalue;
3013: char *value;
3015: PetscInt n = 0;
3016: PetscBool flag;
3017: PetscToken token;
3024: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
3025: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
3026: if (set) *set = PETSC_TRUE;
3027: PetscTokenCreate(svalue,',',&token);
3028: PetscTokenFind(token,&value);
3029: while (value && n < *nmax) {
3030: PetscStrallocpy(value,&strings[n]);
3031: PetscTokenFind(token,&value);
3032: n++;
3033: }
3034: PetscTokenDestroy(&token);
3035: *nmax = n;
3036: return(0);
3037: }
3039: /*@C
3040: PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one
3042: Prints a deprecation warning, unless an option is supplied to suppress.
3044: Logically Collective
3046: Input Parameters:
3047: + pre - string to prepend to name or NULL
3048: . oldname - the old, deprecated option
3049: . newname - the new option, or NULL if option is purely removed
3050: . version - a string describing the version of first deprecation, e.g. "3.9"
3051: - info - additional information string, or NULL.
3053: Options Database Keys:
3054: . -options_suppress_deprecated_warnings - do not print deprecation warnings
3056: Notes:
3057: Must be called between PetscOptionsBegin() (or PetscObjectOptionsBegin()) and PetscOptionsEnd().
3058: Only the proces of rank zero that owns the PetscOptionsItems are argument (managed by PetscOptionsBegin() or
3059: PetscObjectOptionsBegin() prints the information
3060: If newname is provided, the old option is replaced. Otherwise, it remains
3061: in the options database.
3062: If an option is not replaced, the info argument should be used to advise the user
3063: on how to proceed.
3064: There is a limit on the length of the warning printed, so very long strings
3065: provided as info may be truncated.
3067: Level: developer
3069: .seealso: PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsScalar(), PetscOptionsBool(), PetscOptionsString(), PetscOptionsSetValue()
3071: @*/
3072: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[])
3073: {
3074: PetscErrorCode ierr;
3075: PetscBool found,quiet;
3076: const char *value;
3077: const char * const quietopt="-options_suppress_deprecated_warnings";
3078: char msg[4096];
3079: char *prefix = NULL;
3080: PetscOptions options = NULL;
3081: MPI_Comm comm = PETSC_COMM_SELF;
3086: if (PetscOptionsObject) {
3087: prefix = PetscOptionsObject->prefix;
3088: options = PetscOptionsObject->options;
3089: comm = PetscOptionsObject->comm;
3090: }
3091: PetscOptionsFindPair(options,prefix,oldname,&value,&found);
3092: if (found) {
3093: if (newname) {
3094: if (prefix) {
3095: PetscOptionsPrefixPush(options,prefix);
3096: }
3097: PetscOptionsSetValue(options,newname,value);
3098: if (prefix) {
3099: PetscOptionsPrefixPop(options);
3100: }
3101: PetscOptionsClearValue(options,oldname);
3102: }
3103: quiet = PETSC_FALSE;
3104: PetscOptionsGetBool(options,NULL,quietopt,&quiet,NULL);
3105: if (!quiet) {
3106: PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option ");
3107: PetscStrcat(msg,oldname);
3108: PetscStrcat(msg," is deprecated as of version ");
3109: PetscStrcat(msg,version);
3110: PetscStrcat(msg," and will be removed in a future release.");
3111: if (newname) {
3112: PetscStrcat(msg," Please use the option ");
3113: PetscStrcat(msg,newname);
3114: PetscStrcat(msg," instead.");
3115: }
3116: if (info) {
3117: PetscStrcat(msg," ");
3118: PetscStrcat(msg,info);
3119: }
3120: PetscStrcat(msg," (Silence this warning with ");
3121: PetscStrcat(msg,quietopt);
3122: PetscStrcat(msg,")\n");
3123: PetscPrintf(comm,msg);
3124: }
3125: }
3126: return(0);
3127: }