Actual source code: options.c
petsc-3.12.5 2020-03-29
1: /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
2: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for atoll() */
4: /*
5: These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
6: This provides the low-level interface, the high level interface is in aoptions.c
8: Some routines use regular malloc and free because it cannot know what malloc is requested with the
9: options database until it has already processed the input.
10: */
12: #include <petsc/private/petscimpl.h>
13: #include <petscviewer.h>
14: #include <ctype.h>
15: #if defined(PETSC_HAVE_MALLOC_H)
16: #include <malloc.h>
17: #endif
18: #if defined(PETSC_HAVE_STRINGS_H)
19: # include <strings.h> /* strcasecmp */
20: #endif
21: #if defined(PETSC_HAVE_YAML)
22: #include <yaml.h>
23: #endif
25: #if defined(PETSC_HAVE_STRCASECMP)
26: #define PetscOptNameCmp(a,b) strcasecmp(a,b)
27: #elif defined(PETSC_HAVE_STRICMP)
28: #define PetscOptNameCmp(a,b) stricmp(a,b)
29: #else
30: #define PetscOptNameCmp(a,b) Error_strcasecmp_not_found
31: #endif
33: #include <petsc/private/hashtable.h>
35: /* This assumes ASCII encoding and ignores locale settings */
36: /* Using tolower() is about 2X slower in microbenchmarks */
37: PETSC_STATIC_INLINE int PetscToLower(int c)
38: {
39: return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c;
40: }
42: /* Bob Jenkins's one at a time hash function (case-insensitive) */
43: PETSC_STATIC_INLINE unsigned int PetscOptHash(const char key[])
44: {
45: unsigned int hash = 0;
46: while (*key) {
47: hash += PetscToLower(*key++);
48: hash += hash << 10;
49: hash ^= hash >> 6;
50: }
51: hash += hash << 3;
52: hash ^= hash >> 11;
53: hash += hash << 15;
54: return hash;
55: }
57: PETSC_STATIC_INLINE int PetscOptEqual(const char a[],const char b[])
58: {
59: return !PetscOptNameCmp(a,b);
60: }
62: KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual)
64: /*
65: This table holds all the options set by the user. For simplicity, we use a static size database
66: */
67: #define MAXOPTNAME 512
68: #define MAXOPTIONS 512
69: #define MAXALIASES 25
70: #define MAXPREFIXES 25
71: #define MAXOPTIONSMONITORS 5
73: struct _n_PetscOptions {
74: PetscOptions previous;
75: int N; /* number of options */
76: char *names[MAXOPTIONS]; /* option names */
77: char *values[MAXOPTIONS]; /* option values */
78: PetscBool used[MAXOPTIONS]; /* flag option use */
80: /* Hash table */
81: khash_t(HO) *ht;
83: /* Prefixes */
84: int prefixind;
85: int prefixstack[MAXPREFIXES];
86: char prefix[MAXOPTNAME];
88: /* Aliases */
89: int Naliases; /* number or aliases */
90: char *aliases1[MAXALIASES]; /* aliased */
91: char *aliases2[MAXALIASES]; /* aliasee */
93: /* Help */
94: PetscBool help; /* flag whether "-help" is in the database */
96: /* Monitors */
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: /*
106: Options events monitor
107: */
108: static PetscErrorCode PetscOptionsMonitor(PetscOptions options,const char name[],const char value[])
109: {
110: PetscInt i;
113: if (!PetscInitializeCalled) return 0;
115: for (i=0; i<options->numbermonitors; i++) {
116: (*options->monitor[i])(name,value,options->monitorcontext[i]);
117: }
118: return(0);
119: }
121: /*@
122: PetscOptionsCreate - Creates an empty options database.
124: Logically collective
126: Output Parameter:
127: . options - Options database object
129: Level: advanced
131: Developer Note: We may want eventually to pass a MPI_Comm to determine the ownership of the object
133: .seealso: PetscOptionsDestroy(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsInsert(), PetscOptionsSetValue()
134: @*/
135: PetscErrorCode PetscOptionsCreate(PetscOptions *options)
136: {
137: if (!options) return PETSC_ERR_ARG_NULL;
138: *options = (PetscOptions)calloc(1,sizeof(**options));
139: if (!*options) return PETSC_ERR_MEM;
140: return 0;
141: }
143: /*@
144: PetscOptionsDestroy - Destroys an option database.
146: Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
148: Input Parameter:
149: . options - the PetscOptions object
151: Level: advanced
153: .seealso: PetscOptionsInsert(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsInsert(), PetscOptionsSetValue()
154: @*/
155: PetscErrorCode PetscOptionsDestroy(PetscOptions *options)
156: {
159: if (!*options) return 0;
160: 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()");
161: PetscOptionsClear(*options);if (ierr) return ierr;
162: /* XXX what about monitors ? */
163: free(*options);
164: *options = NULL;
165: return(0);
166: }
168: /*
169: PetscOptionsCreateDefault - Creates the default global options database
170: */
171: PetscErrorCode PetscOptionsCreateDefault(void)
172: {
175: if (!defaultoptions) {
176: PetscOptionsCreate(&defaultoptions);if (ierr) return ierr;
177: }
178: return 0;
179: }
181: /*@
182: PetscOptionsPush - Push a new PetscOptions object as the default provider of options
183: Allows using different parts of a code to use different options databases
185: Logically Collective
187: Input Parameter:
188: . opt - the options obtained with PetscOptionsCreate()
190: Notes:
191: Use PetscOptionsPop() to return to the previous default options database
193: The collectivity of this routine is complex; only the MPI processes that call this routine will
194: have the affect of these options. If some processes that create objects call this routine and others do
195: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
196: on different ranks.
198: Level: advanced
200: .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionDestroy(), PetscOptionsInsert(), PetscOptionsSetValue(),
201: PetscOptionsLeft()
203: @*/
204: PetscErrorCode PetscOptionsPush(PetscOptions opt)
205: {
209: if (!defaultoptions) {
210: PetscOptionsCreateDefault();
211: }
212: opt->previous = defaultoptions;
213: defaultoptions = opt;
214: return(0);
215: }
217: /*@
218: PetscOptionsPop - Pop the most recent PetscOptionsPush() to return to the previous default options
220: Logically collective on whatever communicator was associated with the call to PetscOptionsCreate()
222: Notes:
223: Use PetscOptionsPop() to return to the previous default options database
224: Allows using different parts of a code to use different options databases
226: Level: advanced
228: .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionDestroy(), PetscOptionsInsert(), PetscOptionsSetValue(),
229: PetscOptionsLeft()
231: @*/
232: PetscErrorCode PetscOptionsPop(void)
233: {
234: PetscOptions current = defaultoptions;
237: if (!defaultoptions) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing default options");
238: if (!defaultoptions->previous) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PetscOptionsPop() called too many times");
239: defaultoptions = defaultoptions->previous;
240: current->previous = NULL;
241: return(0);
242: }
244: /*
245: PetscOptionsDestroyDefault - Destroys the default global options database
246: */
247: PetscErrorCode PetscOptionsDestroyDefault(void)
248: {
250: PetscOptions tmp;
252: /* Destroy any options that the user forgot to pop */
253: while (defaultoptions->previous) {
254: tmp = defaultoptions;
255: PetscOptionsPop();
256: PetscOptionsDestroy(&tmp);
257: }
258: PetscOptionsDestroy(&defaultoptions);if (ierr) return ierr;
259: return 0;
260: }
262: /*@C
263: PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.
265: Not collective
267: Input Parameter:
268: . key - string to check if valid
270: Output Parameter:
271: . valid - PETSC_TRUE if a valid key
273: Level: intermediate
274: @*/
275: PetscErrorCode PetscOptionsValidKey(const char key[],PetscBool *valid)
276: {
277: char *ptr;
282: *valid = PETSC_FALSE;
283: if (!key) return(0);
284: if (key[0] != '-') return(0);
285: if (key[1] == '-') key++;
286: if (!isalpha((int)key[1])) return(0);
287: (void) strtod(key,&ptr);
288: if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) return(0);
289: *valid = PETSC_TRUE;
290: return(0);
291: }
293: /*@C
294: PetscOptionsInsertString - Inserts options into the database from a string
296: Logically Collective
298: Input Parameter:
299: . in_str - string that contains options separated by blanks
301: Level: intermediate
303: The collectivity of this routine is complex; only the MPI processes that call this routine will
304: have the affect of these options. If some processes that create objects call this routine and others do
305: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
306: on different ranks.
308: Contributed by Boyana Norris
310: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
311: PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
312: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
313: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
314: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
315: PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile()
316: @*/
317: PetscErrorCode PetscOptionsInsertString(PetscOptions options,const char in_str[])
318: {
319: char *first,*second;
321: PetscToken token;
322: PetscBool key,ispush,ispop,isopts;
325: PetscTokenCreate(in_str,' ',&token);
326: PetscTokenFind(token,&first);
327: while (first) {
328: PetscStrcasecmp(first,"-prefix_push",&ispush);
329: PetscStrcasecmp(first,"-prefix_pop",&ispop);
330: PetscStrcasecmp(first,"-options_file",&isopts);
331: PetscOptionsValidKey(first,&key);
332: if (ispush) {
333: PetscTokenFind(token,&second);
334: PetscOptionsPrefixPush(options,second);
335: PetscTokenFind(token,&first);
336: } else if (ispop) {
337: PetscOptionsPrefixPop(options);
338: PetscTokenFind(token,&first);
339: } else if (isopts) {
340: PetscTokenFind(token,&second);
341: PetscOptionsInsertFile(PETSC_COMM_SELF,options,second,PETSC_TRUE);
342: PetscTokenFind(token,&first);
343: } else if (key) {
344: PetscTokenFind(token,&second);
345: PetscOptionsValidKey(second,&key);
346: if (!key) {
347: PetscOptionsSetValue(options,first,second);
348: PetscTokenFind(token,&first);
349: } else {
350: PetscOptionsSetValue(options,first,NULL);
351: first = second;
352: }
353: } else {
354: PetscTokenFind(token,&first);
355: }
356: }
357: PetscTokenDestroy(&token);
358: return(0);
359: }
361: /*
362: Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
363: */
364: static char *Petscgetline(FILE * f)
365: {
366: size_t size = 0;
367: size_t len = 0;
368: size_t last = 0;
369: char *buf = NULL;
371: if (feof(f)) return 0;
372: do {
373: size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
374: buf = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
375: /* Actually do the read. Note that fgets puts a terminal '\0' on the
376: end of the string, so we make sure we overwrite this */
377: if (!fgets(buf+len,1024,f)) buf[len]=0;
378: PetscStrlen(buf,&len);
379: last = len - 1;
380: } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
381: if (len) return buf;
382: free(buf);
383: return 0;
384: }
386: /*@C
387: PetscOptionsInsertFile - Inserts options into the database from a file.
389: Collective
391: Input Parameter:
392: + comm - the processes that will share the options (usually PETSC_COMM_WORLD)
393: . options - options database, use NULL for default global database
394: . file - name of file
395: - require - if PETSC_TRUE will generate an error if the file does not exist
398: Notes:
399: Use # for lines that are comments and which should be ignored.
400: Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
401: 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
402: calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().
403: The collectivity of this routine is complex; only the MPI processes in comm will
404: have the affect of these options. If some processes that create objects call this routine and others do
405: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
406: on different ranks.
408: Level: developer
410: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
411: PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
412: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
413: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
414: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
415: PetscOptionsFList(), PetscOptionsEList()
417: @*/
418: PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
419: {
420: char *string,fname[PETSC_MAX_PATH_LEN],*first,*second,*third,*vstring = 0,*astring = 0,*packed = 0;
422: size_t i,len,bytes;
423: FILE *fd;
424: PetscToken token;
425: int err;
426: char cmt[1]={'#'},*cmatch;
427: PetscMPIInt rank,cnt=0,acnt=0,counts[2];
428: PetscBool isdir;
431: MPI_Comm_rank(comm,&rank);
432: if (!rank) {
433: cnt = 0;
434: acnt = 0;
436: PetscFixFilename(file,fname);
437: fd = fopen(fname,"r");
438: PetscTestDirectory(fname,'r',&isdir);
439: if (isdir && require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Specified options file %s is a directory",fname);
440: if (fd && !isdir) {
441: PetscSegBuffer vseg,aseg;
442: PetscSegBufferCreate(1,4000,&vseg);
443: PetscSegBufferCreate(1,2000,&aseg);
445: /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
446: PetscInfo1(0,"Opened options file %s\n",file);
448: while ((string = Petscgetline(fd))) {
449: /* eliminate comments from each line */
450: for (i=0; i<1; i++) {
451: PetscStrchr(string,cmt[i],&cmatch);
452: if (cmatch) *cmatch = 0;
453: }
454: PetscStrlen(string,&len);
455: /* replace tabs, ^M, \n with " " */
456: for (i=0; i<len; i++) {
457: if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
458: string[i] = ' ';
459: }
460: }
461: PetscTokenCreate(string,' ',&token);
462: PetscTokenFind(token,&first);
463: if (!first) {
464: goto destroy;
465: } else if (!first[0]) { /* if first token is empty spaces, redo first token */
466: PetscTokenFind(token,&first);
467: }
468: PetscTokenFind(token,&second);
469: if (!first) {
470: goto destroy;
471: } else if (first[0] == '-') {
472: PetscStrlen(first,&len);
473: PetscSegBufferGet(vseg,len+1,&vstring);
474: PetscArraycpy(vstring,first,len);
475: vstring[len] = ' ';
476: if (second) {
477: PetscStrlen(second,&len);
478: PetscSegBufferGet(vseg,len+3,&vstring);
479: vstring[0] = '"';
480: PetscArraycpy(vstring+1,second,len);
481: vstring[len+1] = '"';
482: vstring[len+2] = ' ';
483: }
484: } else {
485: PetscBool match;
487: PetscStrcasecmp(first,"alias",&match);
488: if (match) {
489: PetscTokenFind(token,&third);
490: if (!third) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file:alias missing (%s)",second);
491: PetscStrlen(second,&len);
492: PetscSegBufferGet(aseg,len+1,&astring);
493: PetscArraycpy(astring,second,len);
494: astring[len] = ' ';
496: PetscStrlen(third,&len);
497: PetscSegBufferGet(aseg,len+1,&astring);
498: PetscArraycpy(astring,third,len);
499: astring[len] = ' ';
500: } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown statement in options file: (%s)",string);
501: }
502: destroy:
503: free(string);
504: PetscTokenDestroy(&token);
505: }
506: err = fclose(fd);
507: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
508: PetscSegBufferGetSize(aseg,&bytes); /* size without null termination */
509: PetscMPIIntCast(bytes,&acnt);
510: PetscSegBufferGet(aseg,1,&astring);
511: astring[0] = 0;
512: PetscSegBufferGetSize(vseg,&bytes); /* size without null termination */
513: PetscMPIIntCast(bytes,&cnt);
514: PetscSegBufferGet(vseg,1,&vstring);
515: vstring[0] = 0;
516: PetscMalloc1(2+acnt+cnt,&packed);
517: PetscSegBufferExtractTo(aseg,packed);
518: PetscSegBufferExtractTo(vseg,packed+acnt+1);
519: PetscSegBufferDestroy(&aseg);
520: PetscSegBufferDestroy(&vseg);
521: } else if (require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open Options File %s",fname);
522: }
524: counts[0] = acnt;
525: counts[1] = cnt;
526: MPI_Bcast(counts,2,MPI_INT,0,comm);
527: acnt = counts[0];
528: cnt = counts[1];
529: if (rank) {
530: PetscMalloc1(2+acnt+cnt,&packed);
531: }
532: if (acnt || cnt) {
533: MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm);
534: astring = packed;
535: vstring = packed + acnt + 1;
536: }
538: if (acnt) {
539: PetscToken token;
540: char *first,*second;
542: PetscTokenCreate(astring,' ',&token);
543: PetscTokenFind(token,&first);
544: while (first) {
545: PetscTokenFind(token,&second);
546: PetscOptionsSetAlias(options,first,second);
547: PetscTokenFind(token,&first);
548: }
549: PetscTokenDestroy(&token);
550: }
552: if (cnt) {
553: PetscOptionsInsertString(options,vstring);
554: }
555: PetscFree(packed);
556: return(0);
557: }
559: static PetscErrorCode PetscOptionsInsertArgs(PetscOptions options,int argc,char *args[])
560: {
562: int left = argc - 1;
563: char **eargs = args + 1;
566: while (left) {
567: PetscBool isoptions_file,isprefixpush,isprefixpop,isp4,tisp4,isp4yourname,isp4rmrank,key;
568: PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);
569: PetscStrcasecmp(eargs[0],"-prefix_push",&isprefixpush);
570: PetscStrcasecmp(eargs[0],"-prefix_pop",&isprefixpop);
571: PetscStrcasecmp(eargs[0],"-p4pg",&isp4);
572: PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);
573: PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);
574: PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);
575: isp4 = (PetscBool) (isp4 || tisp4);
576: PetscStrcasecmp(eargs[0],"-np",&tisp4);
577: isp4 = (PetscBool) (isp4 || tisp4);
578: PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);
579: PetscOptionsValidKey(eargs[0],&key);
581: if (!key) {
582: eargs++; left--;
583: } else if (isoptions_file) {
584: if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
585: if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
586: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,eargs[1],PETSC_TRUE);
587: eargs += 2; left -= 2;
588: } else if (isprefixpush) {
589: if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
590: if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
591: PetscOptionsPrefixPush(options,eargs[1]);
592: eargs += 2; left -= 2;
593: } else if (isprefixpop) {
594: PetscOptionsPrefixPop(options);
595: eargs++; left--;
597: /*
598: These are "bad" options that MPICH, etc put on the command line
599: we strip them out here.
600: */
601: } else if (tisp4 || isp4rmrank) {
602: eargs += 1; left -= 1;
603: } else if (isp4 || isp4yourname) {
604: eargs += 2; left -= 2;
605: } else {
606: PetscBool nextiskey = PETSC_FALSE;
607: if (left >= 2) {PetscOptionsValidKey(eargs[1],&nextiskey);}
608: if (left < 2 || nextiskey) {
609: PetscOptionsSetValue(options,eargs[0],NULL);
610: eargs++; left--;
611: } else {
612: PetscOptionsSetValue(options,eargs[0],eargs[1]);
613: eargs += 2; left -= 2;
614: }
615: }
616: }
617: return(0);
618: }
621: /*@C
622: PetscOptionsInsert - Inserts into the options database from the command line,
623: the environmental variable and a file.
625: Collective on PETSC_COMM_WORLD
627: Input Parameters:
628: + options - options database or NULL for the default global database
629: . argc - count of number of command line arguments
630: . args - the command line arguments
631: - file - optional filename, defaults to ~username/.petscrc
633: Note:
634: Since PetscOptionsInsert() is automatically called by PetscInitialize(),
635: the user does not typically need to call this routine. PetscOptionsInsert()
636: can be called several times, adding additional entries into the database.
638: Options Database Keys:
639: + -options_monitor <optional filename> - print options names and values as they are set
640: - -options_file <filename> - read options from a file
642: Level: advanced
644: .seealso: PetscOptionsDestroy(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
645: PetscInitialize()
646: @*/
647: PetscErrorCode PetscOptionsInsert(PetscOptions options,int *argc,char ***args,const char file[])
648: {
650: PetscMPIInt rank;
651: char filename[PETSC_MAX_PATH_LEN];
652: PetscBool flag = PETSC_FALSE;
656: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
658: if (file && file[0]) {
659: PetscStrreplace(PETSC_COMM_WORLD,file,filename,PETSC_MAX_PATH_LEN);
660: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,filename,PETSC_TRUE);
661: }
662: /*
663: We want to be able to give -skip_petscrc on the command line, but need to parse it first. Since the command line
664: should take precedence, we insert it twice. It would be sufficient to just scan for -skip_petscrc.
665: */
666: if (argc && args && *argc) {PetscOptionsInsertArgs(options,*argc,*args);}
667: PetscOptionsGetBool(NULL,NULL,"-skip_petscrc",&flag,NULL);
668: if (!flag) {
669: PetscGetHomeDirectory(filename,PETSC_MAX_PATH_LEN-16);
670: /* PetscOptionsInsertFile() does a fopen() on rank0 only - so only rank0 HomeDir value is relavent */
671: if (filename[0]) { PetscStrcat(filename,"/.petscrc"); }
672: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,filename,PETSC_FALSE);
673: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,".petscrc",PETSC_FALSE);
674: PetscOptionsInsertFile(PETSC_COMM_WORLD,options,"petscrc",PETSC_FALSE);
675: }
677: /* insert environment options */
678: {
679: char *eoptions = NULL;
680: size_t len = 0;
681: if (!rank) {
682: eoptions = (char*)getenv("PETSC_OPTIONS");
683: PetscStrlen(eoptions,&len);
684: MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
685: } else {
686: MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
687: if (len) {
688: PetscMalloc1(len+1,&eoptions);
689: }
690: }
691: if (len) {
692: MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
693: if (rank) eoptions[len] = 0;
694: PetscOptionsInsertString(options,eoptions);
695: if (rank) {PetscFree(eoptions);}
696: }
697: }
699: #if defined(PETSC_HAVE_YAML)
700: {
701: char yaml_file[PETSC_MAX_PATH_LEN];
702: PetscBool yaml_flg;
703: PetscOptionsGetString(NULL,NULL,"-options_file_yaml",yaml_file,PETSC_MAX_PATH_LEN,&yaml_flg);
704: if (yaml_flg) {
705: PetscOptionsInsertFileYAML(PETSC_COMM_WORLD,yaml_file,PETSC_TRUE);
706: }
707: }
708: #endif
710: /* insert command line options again because they take precedence over arguments in petscrc/environment */
711: if (argc && args && *argc) {PetscOptionsInsertArgs(options,*argc,*args);}
712: return(0);
713: }
715: /*@C
716: PetscOptionsView - Prints the options that have been loaded. This is
717: useful for debugging purposes.
719: Logically Collective on PetscViewer
721: Input Parameter:
722: + options - options database, use NULL for default global database
723: - viewer - must be an PETSCVIEWERASCII viewer
725: Options Database Key:
726: . -options_view - Activates PetscOptionsView() within PetscFinalize()
728: Notes:
729: Only the rank zero process of MPI_Comm used to create view prints the option values. Other processes
730: may have different values but they are not printed.
732: Level: advanced
734: .seealso: PetscOptionsAllUsed()
735: @*/
736: PetscErrorCode PetscOptionsView(PetscOptions options,PetscViewer viewer)
737: {
739: PetscInt i;
740: PetscBool isascii;
744: options = options ? options : defaultoptions;
745: if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
746: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
747: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");
749: if (!options->N) {
750: PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");
751: return(0);
752: }
754: PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");
755: for (i=0; i<options->N; i++) {
756: if (options->values[i]) {
757: PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);
758: } else {
759: PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);
760: }
761: }
762: PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");
763: return(0);
764: }
766: /*
767: Called by error handlers to print options used in run
768: */
769: PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void)
770: {
771: PetscInt i;
772: PetscOptions options = defaultoptions;
775: if (options->N) {
776: (*PetscErrorPrintf)("PETSc Option Table entries:\n");
777: } else {
778: (*PetscErrorPrintf)("No PETSc Option Table entries\n");
779: }
780: for (i=0; i<options->N; i++) {
781: if (options->values[i]) {
782: (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]);
783: } else {
784: (*PetscErrorPrintf)("-%s\n",options->names[i]);
785: }
786: }
787: return(0);
788: }
790: /*@C
791: PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.
793: Logically Collective
795: Input Parameter:
796: + options - options database, or NULL for the default global database
797: - prefix - The string to append to the existing prefix
799: Options Database Keys:
800: + -prefix_push <some_prefix_> - push the given prefix
801: - -prefix_pop - pop the last prefix
803: Notes:
804: It is common to use this in conjunction with -options_file as in
806: $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop
808: where the files no longer require all options to be prefixed with -system2_.
810: The collectivity of this routine is complex; only the MPI processes that call this routine will
811: have the affect of these options. If some processes that create objects call this routine and others do
812: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
813: on different ranks.
815: Level: advanced
817: .seealso: PetscOptionsPrefixPop(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue()
818: @*/
819: PetscErrorCode PetscOptionsPrefixPush(PetscOptions options,const char prefix[])
820: {
822: size_t n;
823: PetscInt start;
824: char key[MAXOPTNAME+1];
825: PetscBool valid;
829: options = options ? options : defaultoptions;
830: 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);
831: key[0] = '-'; /* keys must start with '-' */
832: PetscStrncpy(key+1,prefix,sizeof(key)-1);
833: PetscOptionsValidKey(key,&valid);
834: if (!valid) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Given prefix \"%s\" not valid (the first character must be a letter, do not include leading '-')",prefix);
835: start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
836: PetscStrlen(prefix,&n);
837: if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
838: PetscArraycpy(options->prefix+start,prefix,n+1);
839: options->prefixstack[options->prefixind++] = start+n;
840: return(0);
841: }
843: /*@C
844: PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details
846: Logically Collective on the MPI_Comm that called PetscOptionsPrefixPush()
848: Input Parameters:
849: . options - options database, or NULL for the default global database
851: Level: advanced
853: .seealso: PetscOptionsPrefixPush(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue()
854: @*/
855: PetscErrorCode PetscOptionsPrefixPop(PetscOptions options)
856: {
857: PetscInt offset;
860: options = options ? options : defaultoptions;
861: if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
862: options->prefixind--;
863: offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
864: options->prefix[offset] = 0;
865: return(0);
866: }
868: /*@C
869: PetscOptionsClear - Removes all options form the database leaving it empty.
871: Logically Collective
873: Input Parameters:
874: . options - options database, use NULL for the default global database
876: The collectivity of this routine is complex; only the MPI processes that call this routine will
877: have the affect of these options. If some processes that create objects call this routine and others do
878: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
879: on different ranks.
881: Level: developer
883: .seealso: PetscOptionsInsert()
884: @*/
885: PetscErrorCode PetscOptionsClear(PetscOptions options)
886: {
887: PetscInt i;
889: options = options ? options : defaultoptions;
890: if (!options) return 0;
892: for (i=0; i<options->N; i++) {
893: if (options->names[i]) free(options->names[i]);
894: if (options->values[i]) free(options->values[i]);
895: }
896: options->N = 0;
898: for (i=0; i<options->Naliases; i++) {
899: free(options->aliases1[i]);
900: free(options->aliases2[i]);
901: }
902: options->Naliases = 0;
904: /* destroy hash table */
905: kh_destroy(HO,options->ht);
906: options->ht = NULL;
908: options->prefixind = 0;
909: options->prefix[0] = 0;
910: options->help = PETSC_FALSE;
911: return 0;
912: }
914: /*@C
915: PetscOptionsSetAlias - Makes a key and alias for another key
917: Logically Collective
919: Input Parameters:
920: + options - options database, or NULL for default global database
921: . newname - the alias
922: - oldname - the name that alias will refer to
924: Level: advanced
926: The collectivity of this routine is complex; only the MPI processes that call this routine will
927: have the affect of these options. If some processes that create objects call this routine and others do
928: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
929: on different ranks.
931: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
932: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
933: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
934: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
935: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
936: PetscOptionsFList(), PetscOptionsEList()
937: @*/
938: PetscErrorCode PetscOptionsSetAlias(PetscOptions options,const char newname[],const char oldname[])
939: {
940: PetscInt n;
941: size_t len;
947: options = options ? options : defaultoptions;
948: if (newname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliased must start with '-': Instead %s",newname);
949: if (oldname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliasee must start with '-': Instead %s",oldname);
951: n = options->Naliases;
952: 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);
954: newname++; oldname++;
955: PetscStrlen(newname,&len);
956: options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
957: PetscStrcpy(options->aliases1[n],newname);
958: PetscStrlen(oldname,&len);
959: options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
960: PetscStrcpy(options->aliases2[n],oldname);
961: options->Naliases++;
962: return(0);
963: }
965: /*@C
966: PetscOptionsSetValue - Sets an option name-value pair in the options
967: database, overriding whatever is already present.
969: Logically Collective
971: Input Parameters:
972: + options - options database, use NULL for the default global database
973: . name - name of option, this SHOULD have the - prepended
974: - value - the option value (not used for all options, so can be NULL)
976: Level: intermediate
978: Note:
979: This function can be called BEFORE PetscInitialize()
981: The collectivity of this routine is complex; only the MPI processes that call this routine will
982: have the affect of these options. If some processes that create objects call this routine and others do
983: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
984: on different ranks.
986: Developers Note: Uses malloc() directly because PETSc may not be initialized yet.
988: .seealso: PetscOptionsInsert(), PetscOptionsClearValue()
989: @*/
990: PetscErrorCode PetscOptionsSetValue(PetscOptions options,const char name[],const char value[])
991: {
992: size_t len;
993: int N,n,i;
994: char **names;
995: char fullname[MAXOPTNAME] = "";
998: if (!options && !defaultoptions) {
999: PetscOptionsCreateDefault();if (ierr) return ierr;
1000: }
1001: options = options ? options : defaultoptions;
1003: if (name[0] != '-') return PETSC_ERR_ARG_OUTOFRANGE;
1005: /* this is so that -h and -help are equivalent (p4 does not like -help)*/
1006: if (!strcmp(name,"-h")) name = "-help";
1007: if (!PetscOptNameCmp(name,"-help")) options->help = PETSC_TRUE;
1009: name++; /* skip starting dash */
1011: if (options->prefixind > 0) {
1012: strncpy(fullname,options->prefix,sizeof(fullname));
1013: fullname[sizeof(fullname)-1] = 0;
1014: strncat(fullname,name,sizeof(fullname)-strlen(fullname)-1);
1015: fullname[sizeof(fullname)-1] = 0;
1016: name = fullname;
1017: }
1019: /* check against aliases */
1020: N = options->Naliases;
1021: for (i=0; i<N; i++) {
1022: int result = PetscOptNameCmp(options->aliases1[i],name);
1023: if (!result) { name = options->aliases2[i]; break; }
1024: }
1026: /* slow search */
1027: N = n = options->N;
1028: names = options->names;
1029: for (i=0; i<N; i++) {
1030: int result = PetscOptNameCmp(names[i],name);
1031: if (!result) {
1032: n = i; goto setvalue;
1033: } else if (result > 0) {
1034: n = i; break;
1035: }
1036: }
1037: if (N >= MAXOPTIONS) return PETSC_ERR_MEM;
1038: /* shift remaining values up 1 */
1039: for (i=N; i>n; i--) {
1040: options->names[i] = options->names[i-1];
1041: options->values[i] = options->values[i-1];
1042: options->used[i] = options->used[i-1];
1043: }
1044: options->names[n] = NULL;
1045: options->values[n] = NULL;
1046: options->used[n] = PETSC_FALSE;
1047: options->N++;
1049: /* destroy hash table */
1050: kh_destroy(HO,options->ht);
1051: options->ht = NULL;
1053: /* set new name */
1054: len = strlen(name);
1055: options->names[n] = (char*)malloc((len+1)*sizeof(char));
1056: if (!options->names[n]) return PETSC_ERR_MEM;
1057: strcpy(options->names[n],name);
1059: setvalue:
1060: /* set new value */
1061: if (options->values[n]) free(options->values[n]);
1062: len = value ? strlen(value) : 0;
1063: if (len) {
1064: options->values[n] = (char*)malloc((len+1)*sizeof(char));
1065: if (!options->values[n]) return PETSC_ERR_MEM;
1066: strcpy(options->values[n],value);
1067: } else {
1068: options->values[n] = NULL;
1069: }
1071: PetscOptionsMonitor(options,name,value?value:"");if (ierr) return ierr;
1072: return 0;
1073: }
1075: /*@C
1076: PetscOptionsClearValue - Clears an option name-value pair in the options
1077: database, overriding whatever is already present.
1079: Logically Collective
1081: Input Parameter:
1082: + options - options database, use NULL for the default global database
1083: - name - name of option, this SHOULD have the - prepended
1085: Level: intermediate
1087: The collectivity of this routine is complex; only the MPI processes that call this routine will
1088: have the affect of these options. If some processes that create objects call this routine and others do
1089: not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options
1090: on different ranks.
1092: .seealso: PetscOptionsInsert()
1093: @*/
1094: PetscErrorCode PetscOptionsClearValue(PetscOptions options,const char name[])
1095: {
1096: int N,n,i;
1097: char **names;
1101: options = options ? options : defaultoptions;
1102: if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1104: /* this is so that -h and -help are equivalent (p4 does not like -help)*/
1105: if (!strcmp(name,"-h")) name = "-help";
1106: if (!PetscOptNameCmp(name,"-help")) options->help = PETSC_FALSE;
1108: name++; /* skip starting dash */
1110: /* slow search */
1111: N = n = options->N;
1112: names = options->names;
1113: for (i=0; i<N; i++) {
1114: int result = PetscOptNameCmp(names[i],name);
1115: if (!result) {
1116: n = i; break;
1117: } else if (result > 0) {
1118: n = N; break;
1119: }
1120: }
1121: if (n == N) return(0); /* it was not present */
1123: /* remove name and value */
1124: if (options->names[n]) free(options->names[n]);
1125: if (options->values[n]) free(options->values[n]);
1126: /* shift remaining values down 1 */
1127: for (i=n; i<N-1; i++) {
1128: options->names[i] = options->names[i+1];
1129: options->values[i] = options->values[i+1];
1130: options->used[i] = options->used[i+1];
1131: }
1132: options->N--;
1134: /* destroy hash table */
1135: kh_destroy(HO,options->ht);
1136: options->ht = NULL;
1138: PetscOptionsMonitor(options,name,NULL);
1139: return(0);
1140: }
1142: /*@C
1143: PetscOptionsFindPair - Gets an option name-value pair from the options database.
1145: Not Collective
1147: Input Parameters:
1148: + options - options database, use NULL for the default global database
1149: . pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended
1150: - name - name of option, this SHOULD have the "-" prepended
1152: Output Parameters:
1153: + value - the option value (optional, not used for all options)
1154: - set - whether the option is set (optional)
1156: Notes:
1157: Each process may find different values or no value depending on how options were inserted into the database
1159: Level: developer
1161: .seealso: PetscOptionsSetValue(), PetscOptionsClearValue()
1162: @*/
1163: PetscErrorCode PetscOptionsFindPair(PetscOptions options,const char pre[],const char name[],const char *value[],PetscBool *set)
1164: {
1165: char buf[MAXOPTNAME];
1166: PetscBool usehashtable = PETSC_TRUE;
1167: PetscBool matchnumbers = PETSC_TRUE;
1171: options = options ? options : defaultoptions;
1172: if (pre && PetscUnlikely(pre[0] == '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1173: if (PetscUnlikely(name[0] != '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1175: name++; /* skip starting dash */
1177: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1178: if (pre && pre[0]) {
1179: char *ptr = buf;
1180: if (name[0] == '-') { *ptr++ = '-'; name++; }
1181: PetscStrncpy(ptr,pre,buf+sizeof(buf)-ptr);
1182: PetscStrlcat(buf,name,sizeof(buf));
1183: name = buf;
1184: }
1186: #if defined(PETSC_USE_DEBUG)
1187: {
1188: PetscBool valid;
1189: char key[MAXOPTNAME+1] = "-";
1190: PetscStrncpy(key+1,name,sizeof(key)-1);
1191: PetscOptionsValidKey(key,&valid);
1192: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1193: }
1194: #endif
1196: if (!options->ht && usehashtable) {
1197: int i,ret;
1198: khiter_t it;
1199: khash_t(HO) *ht;
1200: ht = kh_init(HO);
1201: if (PetscUnlikely(!ht)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1202: ret = kh_resize(HO,ht,options->N*2); /* twice the required size to reduce risk of collisions */
1203: if (PetscUnlikely(ret)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1204: for (i=0; i<options->N; i++) {
1205: it = kh_put(HO,ht,options->names[i],&ret);
1206: if (PetscUnlikely(ret != 1)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed");
1207: kh_val(ht,it) = i;
1208: }
1209: options->ht = ht;
1210: }
1212: if (usehashtable)
1213: { /* fast search */
1214: khash_t(HO) *ht = options->ht;
1215: khiter_t it = kh_get(HO,ht,name);
1216: if (it != kh_end(ht)) {
1217: int i = kh_val(ht,it);
1218: options->used[i] = PETSC_TRUE;
1219: if (value) *value = options->values[i];
1220: if (set) *set = PETSC_TRUE;
1221: return(0);
1222: }
1223: } else
1224: { /* slow search */
1225: int i, N = options->N;
1226: for (i=0; i<N; i++) {
1227: int result = PetscOptNameCmp(options->names[i],name);
1228: if (!result) {
1229: options->used[i] = PETSC_TRUE;
1230: if (value) *value = options->values[i];
1231: if (set) *set = PETSC_TRUE;
1232: return(0);
1233: } else if (result > 0) {
1234: break;
1235: }
1236: }
1237: }
1239: /*
1240: The following block slows down all lookups in the most frequent path (most lookups are unsuccessful).
1241: Maybe this special lookup mode should be enabled on request with a push/pop API.
1242: The feature of matching _%d_ used sparingly in the codebase.
1243: */
1244: if (matchnumbers) {
1245: int i,j,cnt = 0,locs[16],loce[16];
1246: /* determine the location and number of all _%d_ in the key */
1247: for (i=0; name[i]; i++) {
1248: if (name[i] == '_') {
1249: for (j=i+1; name[j]; j++) {
1250: if (name[j] >= '0' && name[j] <= '9') continue;
1251: if (name[j] == '_' && j > i+1) { /* found a number */
1252: locs[cnt] = i+1;
1253: loce[cnt++] = j+1;
1254: }
1255: i = j-1;
1256: break;
1257: }
1258: }
1259: }
1260: for (i=0; i<cnt; i++) {
1261: PetscBool found;
1262: char opt[MAXOPTNAME+1] = "-", tmp[MAXOPTNAME];
1263: PetscStrncpy(tmp,name,PetscMin((size_t)(locs[i]+1),sizeof(tmp)));
1264: PetscStrlcat(opt,tmp,sizeof(opt));
1265: PetscStrlcat(opt,name+loce[i],sizeof(opt));
1266: PetscOptionsFindPair(options,NULL,opt,value,&found);
1267: if (found) {if (set) *set = PETSC_TRUE; return(0);}
1268: }
1269: }
1271: if (set) *set = PETSC_FALSE;
1272: return(0);
1273: }
1275: /* Check whether any option begins with pre+name */
1276: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options,const char pre[], const char name[],const char *value[],PetscBool *set)
1277: {
1278: char buf[MAXOPTNAME];
1279: int numCnt = 0, locs[16],loce[16];
1283: options = options ? options : defaultoptions;
1284: if (pre && pre[0] == '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre);
1285: if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name);
1287: name++; /* skip starting dash */
1289: /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1290: if (pre && pre[0]) {
1291: char *ptr = buf;
1292: if (name[0] == '-') { *ptr++ = '-'; name++; }
1293: PetscStrncpy(ptr,pre,sizeof(buf)+(size_t)(ptr-buf));
1294: PetscStrlcat(buf,name,sizeof(buf));
1295: name = buf;
1296: }
1298: #if defined(PETSC_USE_DEBUG)
1299: {
1300: PetscBool valid;
1301: char key[MAXOPTNAME+1] = "-";
1302: PetscStrncpy(key+1,name,sizeof(key)-1);
1303: PetscOptionsValidKey(key,&valid);
1304: if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1305: }
1306: #endif
1308: /* determine the location and number of all _%d_ in the key */
1309: {
1310: int i,j;
1311: for (i=0; name[i]; i++) {
1312: if (name[i] == '_') {
1313: for (j=i+1; name[j]; j++) {
1314: if (name[j] >= '0' && name[j] <= '9') continue;
1315: if (name[j] == '_' && j > i+1) { /* found a number */
1316: locs[numCnt] = i+1;
1317: loce[numCnt++] = j+1;
1318: }
1319: i = j-1;
1320: break;
1321: }
1322: }
1323: }
1324: }
1326: { /* slow search */
1327: int c, i;
1328: size_t len;
1329: PetscBool match;
1331: for (c = -1; c < numCnt; ++c) {
1332: char opt[MAXOPTNAME+1] = "", tmp[MAXOPTNAME];
1334: if (c < 0) {
1335: PetscStrcpy(opt,name);
1336: } else {
1337: PetscStrncpy(tmp,name,PetscMin((size_t)(locs[c]+1),sizeof(tmp)));
1338: PetscStrlcat(opt,tmp,sizeof(opt));
1339: PetscStrlcat(opt,name+loce[c],sizeof(opt));
1340: }
1341: PetscStrlen(opt,&len);
1342: for (i=0; i<options->N; i++) {
1343: PetscStrncmp(options->names[i],opt,len,&match);
1344: if (match) {
1345: options->used[i] = PETSC_TRUE;
1346: if (value) *value = options->values[i];
1347: if (set) *set = PETSC_TRUE;
1348: return(0);
1349: }
1350: }
1351: }
1352: }
1354: if (set) *set = PETSC_FALSE;
1355: return(0);
1356: }
1358: /*@C
1359: PetscOptionsReject - Generates an error if a certain option is given.
1361: Not Collective
1363: Input Parameters:
1364: + options - options database, use NULL for default global database
1365: . pre - the option prefix (may be NULL)
1366: . name - the option name one is seeking
1367: - mess - error message (may be NULL)
1369: Level: advanced
1371: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1372: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1373: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1374: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1375: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1376: PetscOptionsFList(), PetscOptionsEList()
1377: @*/
1378: PetscErrorCode PetscOptionsReject(PetscOptions options,const char pre[],const char name[],const char mess[])
1379: {
1381: PetscBool flag = PETSC_FALSE;
1384: PetscOptionsHasName(options,pre,name,&flag);
1385: if (flag) {
1386: 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);
1387: else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s",pre?pre:"",name+1);
1388: }
1389: return(0);
1390: }
1392: /*@C
1393: PetscOptionsHasHelp - Determines whether the "-help" option is in the database.
1395: Not Collective
1397: Input Parameters:
1398: . options - options database, use NULL for default global database
1400: Output Parameters:
1401: . set - PETSC_TRUE if found else PETSC_FALSE.
1403: Level: advanced
1405: .seealso: PetscOptionsHasName()
1406: @*/
1407: PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set)
1408: {
1411: options = options ? options : defaultoptions;
1412: *set = options->help;
1413: return(0);
1414: }
1416: /*@C
1417: PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or boolean, even
1418: its value is set to false.
1420: Not Collective
1422: Input Parameters:
1423: + options - options database, use NULL for default global database
1424: . pre - string to prepend to the name or NULL
1425: - name - the option one is seeking
1427: Output Parameters:
1428: . set - PETSC_TRUE if found else PETSC_FALSE.
1430: Level: beginner
1432: Notes:
1433: Name cannot be simply "-h".
1435: In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.
1437: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1438: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1439: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1440: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1441: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1442: PetscOptionsFList(), PetscOptionsEList()
1443: @*/
1444: PetscErrorCode PetscOptionsHasName(PetscOptions options,const char pre[],const char name[],PetscBool *set)
1445: {
1446: const char *value;
1448: PetscBool flag;
1451: PetscOptionsFindPair(options,pre,name,&value,&flag);
1452: if (set) *set = flag;
1453: return(0);
1454: }
1456: /*@C
1457: PetscOptionsGetAll - Lists all the options the program was run with in a single string.
1459: Not Collective
1461: Input Paramter:
1462: . options - the options database, use NULL for the default global database
1464: Output Parameter:
1465: . copts - pointer where string pointer is stored
1467: Notes:
1468: The array and each entry in the array should be freed with PetscFree()
1469: Each process may have different values depending on how the options were inserted into the database
1471: Level: advanced
1473: .seealso: PetscOptionsAllUsed(), PetscOptionsView(), PetscOptionsPush(), PetscOptionsPop()
1474: @*/
1475: PetscErrorCode PetscOptionsGetAll(PetscOptions options,char *copts[])
1476: {
1478: PetscInt i;
1479: size_t len = 1,lent = 0;
1480: char *coptions = NULL;
1484: options = options ? options : defaultoptions;
1485: /* count the length of the required string */
1486: for (i=0; i<options->N; i++) {
1487: PetscStrlen(options->names[i],&lent);
1488: len += 2 + lent;
1489: if (options->values[i]) {
1490: PetscStrlen(options->values[i],&lent);
1491: len += 1 + lent;
1492: }
1493: }
1494: PetscMalloc1(len,&coptions);
1495: coptions[0] = 0;
1496: for (i=0; i<options->N; i++) {
1497: PetscStrcat(coptions,"-");
1498: PetscStrcat(coptions,options->names[i]);
1499: PetscStrcat(coptions," ");
1500: if (options->values[i]) {
1501: PetscStrcat(coptions,options->values[i]);
1502: PetscStrcat(coptions," ");
1503: }
1504: }
1505: *copts = coptions;
1506: return(0);
1507: }
1509: /*@C
1510: PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database
1512: Not Collective
1514: Input Parameter:
1515: + options - options database, use NULL for default global database
1516: - name - string name of option
1518: Output Parameter:
1519: . used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database
1521: Level: advanced
1523: Notes:
1524: The value returned may be different on each process and depends on which options have been processed
1525: on the given process
1527: .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
1528: @*/
1529: PetscErrorCode PetscOptionsUsed(PetscOptions options,const char *name,PetscBool *used)
1530: {
1531: PetscInt i;
1537: options = options ? options : defaultoptions;
1538: *used = PETSC_FALSE;
1539: for (i=0; i<options->N; i++) {
1540: PetscStrcmp(options->names[i],name,used);
1541: if (*used) {
1542: *used = options->used[i];
1543: break;
1544: }
1545: }
1546: return(0);
1547: }
1549: /*@
1550: PetscOptionsAllUsed - Returns a count of the number of options in the
1551: database that have never been selected.
1553: Not Collective
1555: Input Parameter:
1556: . options - options database, use NULL for default global database
1558: Output Parameter:
1559: . N - count of options not used
1561: Level: advanced
1563: Notes:
1564: The value returned may be different on each process and depends on which options have been processed
1565: on the given process
1567: .seealso: PetscOptionsView()
1568: @*/
1569: PetscErrorCode PetscOptionsAllUsed(PetscOptions options,PetscInt *N)
1570: {
1571: PetscInt i,n = 0;
1575: options = options ? options : defaultoptions;
1576: for (i=0; i<options->N; i++) {
1577: if (!options->used[i]) n++;
1578: }
1579: *N = n;
1580: return(0);
1581: }
1583: /*@
1584: PetscOptionsLeft - Prints to screen any options that were set and never used.
1586: Not Collective
1588: Input Parameter:
1589: . options - options database; use NULL for default global database
1591: Options Database Key:
1592: . -options_left - Activates OptionsAllUsed() within PetscFinalize()
1594: Notes:
1595: This is rarely used directly, it is called by PetscFinalize() in debug more or if -options_left
1596: is passed otherwise to help users determine possible mistakes in their usage of options. This
1597: only prints values on process zero of PETSC_COMM_WORLD. Other processes depending the objects
1598: used may have different options that are left unused.
1600: Level: advanced
1602: .seealso: PetscOptionsAllUsed()
1603: @*/
1604: PetscErrorCode PetscOptionsLeft(PetscOptions options)
1605: {
1607: PetscInt i;
1608: PetscInt cnt = 0;
1609: PetscOptions toptions;
1612: toptions = options ? options : defaultoptions;
1613: for (i=0; i<toptions->N; i++) {
1614: if (!toptions->used[i]) {
1615: if (toptions->values[i]) {
1616: PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",toptions->names[i],toptions->values[i]);
1617: } else {
1618: PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",toptions->names[i]);
1619: }
1620: }
1621: }
1622: if (!options) {
1623: toptions = defaultoptions;
1624: while (toptions->previous) {
1625: cnt++;
1626: toptions = toptions->previous;
1627: }
1628: if (cnt) {
1629: 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);
1630: }
1631: }
1632: return(0);
1633: }
1635: /*@C
1636: PetscOptionsLeftGet - Returns all options that were set and never used.
1638: Not Collective
1640: Input Parameter:
1641: . options - options database, use NULL for default global database
1643: Output Parameter:
1644: + N - count of options not used
1645: . names - names of options not used
1646: - values - values of options not used
1648: Level: advanced
1650: Notes:
1651: Users should call PetscOptionsLeftRestore() to free the memory allocated in this routine
1652: Notes: The value returned may be different on each process and depends on which options have been processed
1653: on the given process
1655: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft()
1656: @*/
1657: PetscErrorCode PetscOptionsLeftGet(PetscOptions options,PetscInt *N,char **names[],char **values[])
1658: {
1660: PetscInt i,n;
1666: options = options ? options : defaultoptions;
1668: /* The number of unused PETSc options */
1669: n = 0;
1670: for (i=0; i<options->N; i++) {
1671: if (!options->used[i]) n++;
1672: }
1673: if (N) { *N = n; }
1674: if (names) { PetscMalloc1(n,names); }
1675: if (values) { PetscMalloc1(n,values); }
1677: n = 0;
1678: if (names || values) {
1679: for (i=0; i<options->N; i++) {
1680: if (!options->used[i]) {
1681: if (names) (*names)[n] = options->names[i];
1682: if (values) (*values)[n] = options->values[i];
1683: n++;
1684: }
1685: }
1686: }
1687: return(0);
1688: }
1690: /*@C
1691: PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using PetscOptionsLeftGet.
1693: Not Collective
1695: Input Parameter:
1696: + options - options database, use NULL for default global database
1697: . names - names of options not used
1698: - values - values of options not used
1700: Level: advanced
1702: .seealso: PetscOptionsAllUsed(), PetscOptionsLeft(), PetscOptionsLeftGet()
1703: @*/
1704: PetscErrorCode PetscOptionsLeftRestore(PetscOptions options,PetscInt *N,char **names[],char **values[])
1705: {
1712: if (N) { *N = 0; }
1713: if (names) { PetscFree(*names); }
1714: if (values) { PetscFree(*values); }
1715: return(0);
1716: }
1718: /*@C
1719: PetscOptionsSetFromOptions - Sets options related to the handling of options in PETSc
1721: Collective on PETSC_COMM_WORLD
1723: Input Parameter:
1724: . options - options database, use NULL for default global database
1726: Options Database Keys:
1727: + -options_monitor <optional filename> - prints the names and values of all runtime options as they are set. The monitor functionality is not
1728: available for options set through a file, environment variable, or on
1729: the command line. Only options set after PetscInitialize() completes will
1730: be monitored.
1731: - -options_monitor_cancel - cancel all options database monitors
1733: Notes:
1734: To see all options, run your program with the -help option
1736: Level: intermediate
1738: @*/
1739: PetscErrorCode PetscOptionsSetFromOptions(PetscOptions options)
1740: {
1741: PetscBool flgc = PETSC_FALSE,flgm;
1743: char monfilename[PETSC_MAX_PATH_LEN];
1744: PetscViewer monviewer;
1747: /*
1748: The options argument is currently ignored since we currently maintain only a single options database
1750: options = options ? options : defaultoptions;
1751: */
1752: PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for handling options","PetscOptions");
1753: PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);
1754: PetscOptionsBool("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",flgc,&flgc,NULL);
1755: PetscOptionsEnd();
1756: if (flgm) {
1757: PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);
1758: PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
1759: }
1760: if (flgc) { PetscOptionsMonitorCancel(); }
1761: return(0);
1762: }
1764: /*@C
1765: PetscOptionsMonitorDefault - Print all options set value events.
1767: Logically Collective on ctx
1769: Input Parameters:
1770: + name - option name string
1771: . value - option value string
1772: - ctx - an ASCII viewer
1774: Level: intermediate
1776: Notes:
1777: The first MPI rank in the PetscViewer viewer actually prints the values, other
1778: processes may have different values set
1780: .seealso: PetscOptionsMonitorSet()
1781: @*/
1782: PetscErrorCode PetscOptionsMonitorDefault(const char name[],const char value[],void *ctx)
1783: {
1785: PetscViewer viewer = (PetscViewer)ctx;
1788: if (!value) {
1789: PetscViewerASCIIPrintf(viewer,"Removing option: %s\n",name,value);
1790: } else if (!value[0]) {
1791: PetscViewerASCIIPrintf(viewer,"Setting option: %s (no value)\n",name);
1792: } else {
1793: PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
1794: }
1795: return(0);
1796: }
1798: /*@C
1799: PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
1800: modified the PETSc options database.
1802: Not Collective
1804: Input Parameters:
1805: + monitor - pointer to function (if this is NULL, it turns off monitoring
1806: . mctx - [optional] context for private data for the
1807: monitor routine (use NULL if no context is desired)
1808: - monitordestroy - [optional] routine that frees monitor context
1809: (may be NULL)
1811: Calling Sequence of monitor:
1812: $ monitor (const char name[], const char value[], void *mctx)
1814: + name - option name string
1815: . value - option value string
1816: - mctx - optional monitoring context, as set by PetscOptionsMonitorSet()
1818: Options Database Keys:
1819: + -options_monitor - sets PetscOptionsMonitorDefault()
1820: - -options_monitor_cancel - cancels all monitors that have
1821: been hardwired into a code by
1822: calls to PetscOptionsMonitorSet(), but
1823: does not cancel those set via
1824: the options database.
1826: Notes:
1827: The default is to do nothing. To print the name and value of options
1828: being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
1829: with a null monitoring context.
1831: Several different monitoring routines may be set by calling
1832: PetscOptionsMonitorSet() multiple times; all will be called in the
1833: order in which they were set.
1835: Level: beginner
1837: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
1838: @*/
1839: PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
1840: {
1841: PetscOptions options = defaultoptions;
1844: if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
1845: options->monitor[options->numbermonitors] = monitor;
1846: options->monitordestroy[options->numbermonitors] = monitordestroy;
1847: options->monitorcontext[options->numbermonitors++] = (void*)mctx;
1848: return(0);
1849: }
1851: /*@
1852: PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.
1854: Not Collective
1856: Options Database Key:
1857: . -options_monitor_cancel - Cancels all monitors that have
1858: been hardwired into a code by calls to PetscOptionsMonitorSet(),
1859: but does not cancel those set via the options database.
1861: Level: intermediate
1863: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
1864: @*/
1865: PetscErrorCode PetscOptionsMonitorCancel(void)
1866: {
1868: PetscInt i;
1869: PetscOptions options = defaultoptions;
1872: for (i=0; i<options->numbermonitors; i++) {
1873: if (options->monitordestroy[i]) {
1874: (*options->monitordestroy[i])(&options->monitorcontext[i]);
1875: }
1876: }
1877: options->numbermonitors = 0;
1878: return(0);
1879: }
1881: /*
1882: PetscOptionsStringToBool - Converts string to PetscBool , handles cases like "yes", "no", "true", "false", "0", "1", "off", "on".
1883: */
1884: PetscErrorCode PetscOptionsStringToBool(const char value[],PetscBool *a)
1885: {
1886: PetscBool istrue,isfalse;
1887: size_t len;
1891: PetscStrlen(value,&len);
1892: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Character string of length zero has no logical value");
1893: PetscStrcasecmp(value,"TRUE",&istrue);
1894: if (istrue) {*a = PETSC_TRUE; return(0);}
1895: PetscStrcasecmp(value,"YES",&istrue);
1896: if (istrue) {*a = PETSC_TRUE; return(0);}
1897: PetscStrcasecmp(value,"1",&istrue);
1898: if (istrue) {*a = PETSC_TRUE; return(0);}
1899: PetscStrcasecmp(value,"on",&istrue);
1900: if (istrue) {*a = PETSC_TRUE; return(0);}
1901: PetscStrcasecmp(value,"FALSE",&isfalse);
1902: if (isfalse) {*a = PETSC_FALSE; return(0);}
1903: PetscStrcasecmp(value,"NO",&isfalse);
1904: if (isfalse) {*a = PETSC_FALSE; return(0);}
1905: PetscStrcasecmp(value,"0",&isfalse);
1906: if (isfalse) {*a = PETSC_FALSE; return(0);}
1907: PetscStrcasecmp(value,"off",&isfalse);
1908: if (isfalse) {*a = PETSC_FALSE; return(0);}
1909: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value);
1910: }
1912: /*
1913: PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
1914: */
1915: PetscErrorCode PetscOptionsStringToInt(const char name[],PetscInt *a)
1916: {
1918: size_t len;
1919: PetscBool decide,tdefault,mouse;
1922: PetscStrlen(name,&len);
1923: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
1925: PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
1926: if (!tdefault) {
1927: PetscStrcasecmp(name,"DEFAULT",&tdefault);
1928: }
1929: PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
1930: if (!decide) {
1931: PetscStrcasecmp(name,"DECIDE",&decide);
1932: }
1933: PetscStrcasecmp(name,"mouse",&mouse);
1935: if (tdefault) *a = PETSC_DEFAULT;
1936: else if (decide) *a = PETSC_DECIDE;
1937: else if (mouse) *a = -1;
1938: else {
1939: char *endptr;
1940: long strtolval;
1942: strtolval = strtol(name,&endptr,10);
1943: 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);
1945: #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
1946: (void) strtolval;
1947: *a = atoll(name);
1948: #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
1949: (void) strtolval;
1950: *a = _atoi64(name);
1951: #else
1952: *a = (PetscInt)strtolval;
1953: #endif
1954: }
1955: return(0);
1956: }
1958: #if defined(PETSC_USE_REAL___FLOAT128)
1959: #include <quadmath.h>
1960: #endif
1962: static PetscErrorCode PetscStrtod(const char name[],PetscReal *a,char **endptr)
1963: {
1965: #if defined(PETSC_USE_REAL___FLOAT128)
1966: *a = strtoflt128(name,endptr);
1967: #else
1968: *a = (PetscReal)strtod(name,endptr);
1969: #endif
1970: return(0);
1971: }
1973: static PetscErrorCode PetscStrtoz(const char name[],PetscScalar *a,char **endptr,PetscBool *isImaginary)
1974: {
1975: PetscBool hasi = PETSC_FALSE;
1976: char *ptr;
1977: PetscReal strtoval;
1981: PetscStrtod(name,&strtoval,&ptr);
1982: if (ptr == name) {
1983: strtoval = 1.;
1984: hasi = PETSC_TRUE;
1985: if (name[0] == 'i') {
1986: ptr++;
1987: } else if (name[0] == '+' && name[1] == 'i') {
1988: ptr += 2;
1989: } else if (name[0] == '-' && name[1] == 'i') {
1990: strtoval = -1.;
1991: ptr += 2;
1992: }
1993: } else if (*ptr == 'i') {
1994: hasi = PETSC_TRUE;
1995: ptr++;
1996: }
1997: *endptr = ptr;
1998: *isImaginary = hasi;
1999: if (hasi) {
2000: #if !defined(PETSC_USE_COMPLEX)
2001: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s contains imaginary but complex not supported ",name);
2002: #else
2003: *a = PetscCMPLX(0.,strtoval);
2004: #endif
2005: } else {
2006: *a = strtoval;
2007: }
2008: return(0);
2009: }
2011: /*
2012: Converts a string to PetscReal value. Handles special cases like "default" and "decide"
2013: */
2014: PetscErrorCode PetscOptionsStringToReal(const char name[],PetscReal *a)
2015: {
2016: size_t len;
2017: PetscBool match;
2018: char *endptr;
2022: PetscStrlen(name,&len);
2023: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"String of length zero has no numerical value");
2025: PetscStrcasecmp(name,"PETSC_DEFAULT",&match);
2026: if (!match) {
2027: PetscStrcasecmp(name,"DEFAULT",&match);
2028: }
2029: if (match) {*a = PETSC_DEFAULT; return(0);}
2031: PetscStrcasecmp(name,"PETSC_DECIDE",&match);
2032: if (!match) {
2033: PetscStrcasecmp(name,"DECIDE",&match);
2034: }
2035: if (match) {*a = PETSC_DECIDE; return(0);}
2037: PetscStrtod(name,a,&endptr);
2038: if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value",name);
2039: return(0);
2040: }
2042: PetscErrorCode PetscOptionsStringToScalar(const char name[],PetscScalar *a)
2043: {
2044: PetscBool imag1;
2045: size_t len;
2046: PetscScalar val = 0.;
2047: char *ptr = NULL;
2051: PetscStrlen(name,&len);
2052: if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");
2053: PetscStrtoz(name,&val,&ptr,&imag1);
2054: #if defined(PETSC_USE_COMPLEX)
2055: if ((size_t) (ptr - name) < len) {
2056: PetscBool imag2;
2057: PetscScalar val2;
2059: PetscStrtoz(ptr,&val2,&ptr,&imag2);
2060: if (imag1 || !imag2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s: must specify imaginary component second",name);
2061: val = PetscCMPLX(PetscRealPart(val),PetscImaginaryPart(val2));
2062: }
2063: #endif
2064: if ((size_t) (ptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
2065: *a = val;
2066: return(0);
2067: }
2069: /*@C
2070: PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
2071: option in the database.
2073: Not Collective
2075: Input Parameters:
2076: + options - options database, use NULL for default global database
2077: . pre - the string to prepend to the name or NULL
2078: - name - the option one is seeking
2080: Output Parameter:
2081: + ivalue - the logical value to return
2082: - set - PETSC_TRUE if found, else PETSC_FALSE
2084: Level: beginner
2086: Notes:
2087: TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
2088: FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
2090: 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
2091: is equivalent to -requested_bool true
2093: If the user does not supply the option at all ivalue is NOT changed. Thus
2094: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2096: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
2097: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
2098: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2099: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2100: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2101: PetscOptionsFList(), PetscOptionsEList()
2102: @*/
2103: PetscErrorCode PetscOptionsGetBool(PetscOptions options,const char pre[],const char name[],PetscBool *ivalue,PetscBool *set)
2104: {
2105: const char *value;
2106: PetscBool flag;
2112: PetscOptionsFindPair(options,pre,name,&value,&flag);
2113: if (flag) {
2114: if (set) *set = PETSC_TRUE;
2115: if (!value) {
2116: if (ivalue) *ivalue = PETSC_TRUE;
2117: } else {
2118: PetscOptionsStringToBool(value, &flag);
2119: if (ivalue) *ivalue = flag;
2120: }
2121: } else {
2122: if (set) *set = PETSC_FALSE;
2123: }
2124: return(0);
2125: }
2127: /*@C
2128: PetscOptionsGetEList - Puts a list of option values that a single one may be selected from
2130: Not Collective
2132: Input Parameters:
2133: + options - options database, use NULL for default global database
2134: . pre - the string to prepend to the name or NULL
2135: . opt - option name
2136: . list - the possible choices (one of these must be selected, anything else is invalid)
2137: - ntext - number of choices
2139: Output Parameter:
2140: + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed)
2141: - set - PETSC_TRUE if found, else PETSC_FALSE
2143: Level: intermediate
2145: Notes:
2146: If the user does not supply the option value is NOT changed. Thus
2147: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2149: See PetscOptionsFList() for when the choices are given in a PetscFunctionList()
2151: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2152: PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2153: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2154: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2155: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2156: PetscOptionsFList(), PetscOptionsEList()
2157: @*/
2158: PetscErrorCode PetscOptionsGetEList(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool *set)
2159: {
2161: size_t alen,len = 0;
2162: char *svalue;
2163: PetscBool aset,flg = PETSC_FALSE;
2164: PetscInt i;
2168: for (i=0; i<ntext; i++) {
2169: PetscStrlen(list[i],&alen);
2170: if (alen > len) len = alen;
2171: }
2172: len += 5; /* a little extra space for user mistypes */
2173: PetscMalloc1(len,&svalue);
2174: PetscOptionsGetString(options,pre,opt,svalue,len,&aset);
2175: if (aset) {
2176: PetscEListFind(ntext,list,svalue,value,&flg);
2177: if (!flg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre ? pre : "",opt+1);
2178: if (set) *set = PETSC_TRUE;
2179: } else if (set) *set = PETSC_FALSE;
2180: PetscFree(svalue);
2181: return(0);
2182: }
2184: /*@C
2185: PetscOptionsGetEnum - Gets the enum value for a particular option in the database.
2187: Not Collective
2189: Input Parameters:
2190: + options - options database, use NULL for default global database
2191: . pre - option prefix or NULL
2192: . opt - option name
2193: . list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2194: - defaultv - the default (current) value
2196: Output Parameter:
2197: + value - the value to return
2198: - set - PETSC_TRUE if found, else PETSC_FALSE
2200: Level: beginner
2202: Notes:
2203: If the user does not supply the option value is NOT changed. Thus
2204: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2206: List is usually something like PCASMTypes or some other predefined list of enum names
2208: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2209: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2210: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2211: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2212: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2213: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2214: PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2215: @*/
2216: PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set)
2217: {
2219: PetscInt ntext = 0,tval;
2220: PetscBool fset;
2224: while (list[ntext++]) {
2225: if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
2226: }
2227: if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
2228: ntext -= 3;
2229: PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset);
2230: /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
2231: if (fset) *value = (PetscEnum)tval;
2232: if (set) *set = fset;
2233: return(0);
2234: }
2236: /*@C
2237: PetscOptionsGetInt - Gets the integer value for a particular option in the database.
2239: Not Collective
2241: Input Parameters:
2242: + options - options database, use NULL for default global database
2243: . pre - the string to prepend to the name or NULL
2244: - name - the option one is seeking
2246: Output Parameter:
2247: + ivalue - the integer value to return
2248: - set - PETSC_TRUE if found, else PETSC_FALSE
2250: Level: beginner
2252: Notes:
2253: If the user does not supply the option ivalue is NOT changed. Thus
2254: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2256: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
2257: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2258: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
2259: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2260: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2261: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2262: PetscOptionsFList(), PetscOptionsEList()
2263: @*/
2264: PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set)
2265: {
2266: const char *value;
2268: PetscBool flag;
2273: PetscOptionsFindPair(options,pre,name,&value,&flag);
2274: if (flag) {
2275: if (!value) {
2276: if (set) *set = PETSC_FALSE;
2277: } else {
2278: if (set) *set = PETSC_TRUE;
2279: PetscOptionsStringToInt(value,ivalue);
2280: }
2281: } else {
2282: if (set) *set = PETSC_FALSE;
2283: }
2284: return(0);
2285: }
2287: /*@C
2288: PetscOptionsGetReal - Gets the double precision value for a particular
2289: option in the database.
2291: Not Collective
2293: Input Parameters:
2294: + options - options database, use NULL for default global database
2295: . pre - string to prepend to each name or NULL
2296: - name - the option one is seeking
2298: Output Parameter:
2299: + dvalue - the double value to return
2300: - set - PETSC_TRUE if found, PETSC_FALSE if not found
2302: Notes:
2303: If the user does not supply the option dvalue is NOT changed. Thus
2304: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2306: Level: beginner
2308: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2309: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
2310: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2311: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2312: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2313: PetscOptionsFList(), PetscOptionsEList()
2314: @*/
2315: PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set)
2316: {
2317: const char *value;
2318: PetscBool flag;
2324: PetscOptionsFindPair(options,pre,name,&value,&flag);
2325: if (flag) {
2326: if (!value) {
2327: if (set) *set = PETSC_FALSE;
2328: } else {
2329: if (set) *set = PETSC_TRUE;
2330: PetscOptionsStringToReal(value,dvalue);
2331: }
2332: } else {
2333: if (set) *set = PETSC_FALSE;
2334: }
2335: return(0);
2336: }
2338: /*@C
2339: PetscOptionsGetScalar - Gets the scalar value for a particular
2340: option in the database.
2342: Not Collective
2344: Input Parameters:
2345: + options - options database, use NULL for default global database
2346: . pre - string to prepend to each name or NULL
2347: - name - the option one is seeking
2349: Output Parameter:
2350: + dvalue - the double value to return
2351: - set - PETSC_TRUE if found, else PETSC_FALSE
2353: Level: beginner
2355: Usage:
2356: A complex number 2+3i must be specified with NO spaces
2358: Notes:
2359: If the user does not supply the option dvalue is NOT changed. Thus
2360: you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true.
2362: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2363: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2364: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2365: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2366: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2367: PetscOptionsFList(), PetscOptionsEList()
2368: @*/
2369: PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set)
2370: {
2371: const char *value;
2372: PetscBool flag;
2378: PetscOptionsFindPair(options,pre,name,&value,&flag);
2379: if (flag) {
2380: if (!value) {
2381: if (set) *set = PETSC_FALSE;
2382: } else {
2383: #if !defined(PETSC_USE_COMPLEX)
2384: PetscOptionsStringToReal(value,dvalue);
2385: #else
2386: PetscOptionsStringToScalar(value,dvalue);
2387: #endif
2388: if (set) *set = PETSC_TRUE;
2389: }
2390: } else { /* flag */
2391: if (set) *set = PETSC_FALSE;
2392: }
2393: return(0);
2394: }
2396: /*@C
2397: PetscOptionsGetString - Gets the string value for a particular option in
2398: the database.
2400: Not Collective
2402: Input Parameters:
2403: + options - options database, use NULL for default global database
2404: . pre - string to prepend to name or NULL
2405: . name - the option one is seeking
2406: - len - maximum length of the string including null termination
2408: Output Parameters:
2409: + string - location to copy string
2410: - set - PETSC_TRUE if found, else PETSC_FALSE
2412: Level: beginner
2414: Fortran Note:
2415: The Fortran interface is slightly different from the C/C++
2416: interface (len is not used). Sample usage in Fortran follows
2417: .vb
2418: character *20 string
2419: PetscErrorCode ierr
2420: PetscBool set
2421: call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr)
2422: .ve
2424: Notes:
2425: 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
2427: If the user does not use the option then the string is not changed. Thus
2428: you should ALWAYS initialize the string if you access it without first checking if the set flag is true.
2430: Note:
2431: 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).
2433: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2434: PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2435: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2436: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2437: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2438: PetscOptionsFList(), PetscOptionsEList()
2439: @*/
2440: PetscErrorCode PetscOptionsGetString(PetscOptions options,const char pre[],const char name[],char string[],size_t len,PetscBool *set)
2441: {
2442: const char *value;
2443: PetscBool flag;
2449: PetscOptionsFindPair(options,pre,name,&value,&flag);
2450: if (!flag) {
2451: if (set) *set = PETSC_FALSE;
2452: } else {
2453: if (set) *set = PETSC_TRUE;
2454: if (value) {
2455: PetscStrncpy(string,value,len);
2456: } else {
2457: PetscArrayzero(string,len);
2458: }
2459: }
2460: return(0);
2461: }
2463: char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[])
2464: {
2465: const char *value;
2466: PetscBool flag;
2470: PetscOptionsFindPair(options,pre,name,&value,&flag);if (ierr) return(0);
2471: if (flag) PetscFunctionReturn((char*)value);
2472: else return(0);
2473: }
2475: /*@C
2476: PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
2477: option in the database. The values must be separated with commas with
2478: no intervening spaces.
2480: Not Collective
2482: Input Parameters:
2483: + options - options database, use NULL for default global database
2484: . pre - string to prepend to each name or NULL
2485: . name - the option one is seeking
2486: - nmax - maximum number of values to retrieve
2488: Output Parameter:
2489: + dvalue - the integer values to return
2490: . nmax - actual number of values retreived
2491: - set - PETSC_TRUE if found, else PETSC_FALSE
2493: Level: beginner
2495: Notes:
2496: TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
2497: FALSE, false, NO, no, and 0 all translate to PETSC_FALSE
2499: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2500: PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2501: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2502: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2503: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2504: PetscOptionsFList(), PetscOptionsEList()
2505: @*/
2506: PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set)
2507: {
2508: const char *svalue;
2509: char *value;
2511: PetscInt n = 0;
2512: PetscBool flag;
2513: PetscToken token;
2520: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2521: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2522: if (set) *set = PETSC_TRUE;
2523: PetscTokenCreate(svalue,',',&token);
2524: PetscTokenFind(token,&value);
2525: while (value && n < *nmax) {
2526: PetscOptionsStringToBool(value,dvalue);
2527: PetscTokenFind(token,&value);
2528: dvalue++;
2529: n++;
2530: }
2531: PetscTokenDestroy(&token);
2532: *nmax = n;
2533: return(0);
2534: }
2536: /*@C
2537: PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.
2539: Not Collective
2541: Input Parameters:
2542: + options - options database, use NULL for default global database
2543: . pre - option prefix or NULL
2544: . name - option name
2545: . list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2546: - nmax - maximum number of values to retrieve
2548: Output Parameters:
2549: + ivalue - the enum values to return
2550: . nmax - actual number of values retreived
2551: - set - PETSC_TRUE if found, else PETSC_FALSE
2553: Level: beginner
2555: Notes:
2556: The array must be passed as a comma separated list.
2558: There must be no intervening spaces between the values.
2560: list is usually something like PCASMTypes or some other predefined list of enum names.
2562: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2563: PetscOptionsGetEnum(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2564: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(),
2565: PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(),
2566: PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2567: PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2568: @*/
2569: PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set)
2570: {
2571: const char *svalue;
2572: char *value;
2573: PetscInt n = 0;
2574: PetscEnum evalue;
2575: PetscBool flag;
2576: PetscToken token;
2585: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2586: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2587: if (set) *set = PETSC_TRUE;
2588: PetscTokenCreate(svalue,',',&token);
2589: PetscTokenFind(token,&value);
2590: while (value && n < *nmax) {
2591: PetscEnumFind(list,value,&evalue,&flag);
2592: if (!flag) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
2593: ivalue[n++] = evalue;
2594: PetscTokenFind(token,&value);
2595: }
2596: PetscTokenDestroy(&token);
2597: *nmax = n;
2598: return(0);
2599: }
2601: /*@C
2602: PetscOptionsGetIntArray - Gets an array of integer values for a particular
2603: option in the database.
2605: Not Collective
2607: Input Parameters:
2608: + options - options database, use NULL for default global database
2609: . pre - string to prepend to each name or NULL
2610: . name - the option one is seeking
2611: - nmax - maximum number of values to retrieve
2613: Output Parameter:
2614: + ivalue - the integer values to return
2615: . nmax - actual number of values retreived
2616: - set - PETSC_TRUE if found, else PETSC_FALSE
2618: Level: beginner
2620: Notes:
2621: The array can be passed as
2622: a comma separated list: 0,1,2,3,4,5,6,7
2623: a range (start-end+1): 0-8
2624: a range with given increment (start-end+1:inc): 0-7:2
2625: a combination of values and ranges separated by commas: 0,1-8,8-15:2
2627: There must be no intervening spaces between the values.
2629: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2630: PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2631: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2632: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2633: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2634: PetscOptionsFList(), PetscOptionsEList()
2635: @*/
2636: PetscErrorCode PetscOptionsGetIntArray(PetscOptions options,const char pre[],const char name[],PetscInt ivalue[],PetscInt *nmax,PetscBool *set)
2637: {
2638: const char *svalue;
2639: char *value;
2641: PetscInt n = 0,i,j,start,end,inc,nvalues;
2642: size_t len;
2643: PetscBool flag,foundrange;
2644: PetscToken token;
2651: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2652: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2653: if (set) *set = PETSC_TRUE;
2654: PetscTokenCreate(svalue,',',&token);
2655: PetscTokenFind(token,&value);
2656: while (value && n < *nmax) {
2657: /* look for form d-D where d and D are integers */
2658: foundrange = PETSC_FALSE;
2659: PetscStrlen(value,&len);
2660: if (value[0] == '-') i=2;
2661: else i=1;
2662: for (;i<(int)len; i++) {
2663: if (value[i] == '-') {
2664: if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
2665: value[i] = 0;
2667: PetscOptionsStringToInt(value,&start);
2668: inc = 1;
2669: j = i+1;
2670: for (;j<(int)len; j++) {
2671: if (value[j] == ':') {
2672: value[j] = 0;
2674: PetscOptionsStringToInt(value+j+1,&inc);
2675: 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);
2676: break;
2677: }
2678: }
2679: PetscOptionsStringToInt(value+i+1,&end);
2680: 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);
2681: nvalues = (end-start)/inc + (end-start)%inc;
2682: 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);
2683: for (;start<end; start+=inc) {
2684: *ivalue = start; ivalue++;n++;
2685: }
2686: foundrange = PETSC_TRUE;
2687: break;
2688: }
2689: }
2690: if (!foundrange) {
2691: PetscOptionsStringToInt(value,ivalue);
2692: ivalue++;
2693: n++;
2694: }
2695: PetscTokenFind(token,&value);
2696: }
2697: PetscTokenDestroy(&token);
2698: *nmax = n;
2699: return(0);
2700: }
2702: /*@C
2703: PetscOptionsGetRealArray - Gets an array of double precision values for a
2704: particular option in the database. The values must be separated with
2705: commas with no intervening spaces.
2707: Not Collective
2709: Input Parameters:
2710: + options - options database, use NULL for default global database
2711: . pre - string to prepend to each name or NULL
2712: . name - the option one is seeking
2713: - nmax - maximum number of values to retrieve
2715: Output Parameters:
2716: + dvalue - the double values to return
2717: . nmax - actual number of values retreived
2718: - set - PETSC_TRUE if found, else PETSC_FALSE
2720: Level: beginner
2722: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2723: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2724: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2725: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2726: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2727: PetscOptionsFList(), PetscOptionsEList()
2728: @*/
2729: PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set)
2730: {
2731: const char *svalue;
2732: char *value;
2734: PetscInt n = 0;
2735: PetscBool flag;
2736: PetscToken token;
2743: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2744: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2745: if (set) *set = PETSC_TRUE;
2746: PetscTokenCreate(svalue,',',&token);
2747: PetscTokenFind(token,&value);
2748: while (value && n < *nmax) {
2749: PetscOptionsStringToReal(value,dvalue++);
2750: PetscTokenFind(token,&value);
2751: n++;
2752: }
2753: PetscTokenDestroy(&token);
2754: *nmax = n;
2755: return(0);
2756: }
2758: /*@C
2759: PetscOptionsGetScalarArray - Gets an array of scalars for a
2760: particular option in the database. The values must be separated with
2761: commas with no intervening spaces.
2763: Not Collective
2765: Input Parameters:
2766: + options - options database, use NULL for default global database
2767: . pre - string to prepend to each name or NULL
2768: . name - the option one is seeking
2769: - nmax - maximum number of values to retrieve
2771: Output Parameters:
2772: + dvalue - the scalar values to return
2773: . nmax - actual number of values retreived
2774: - set - PETSC_TRUE if found, else PETSC_FALSE
2776: Level: beginner
2778: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
2779: PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
2780: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2781: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2782: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2783: PetscOptionsFList(), PetscOptionsEList()
2784: @*/
2785: PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set)
2786: {
2787: const char *svalue;
2788: char *value;
2790: PetscInt n = 0;
2791: PetscBool flag;
2792: PetscToken token;
2799: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2800: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2801: if (set) *set = PETSC_TRUE;
2802: PetscTokenCreate(svalue,',',&token);
2803: PetscTokenFind(token,&value);
2804: while (value && n < *nmax) {
2805: PetscOptionsStringToScalar(value,dvalue++);
2806: PetscTokenFind(token,&value);
2807: n++;
2808: }
2809: PetscTokenDestroy(&token);
2810: *nmax = n;
2811: return(0);
2812: }
2814: /*@C
2815: PetscOptionsGetStringArray - Gets an array of string values for a particular
2816: option in the database. The values must be separated with commas with
2817: no intervening spaces.
2819: Not Collective
2821: Input Parameters:
2822: + options - options database, use NULL for default global database
2823: . pre - string to prepend to name or NULL
2824: . name - the option one is seeking
2825: - nmax - maximum number of strings
2827: Output Parameter:
2828: + strings - location to copy strings
2829: - set - PETSC_TRUE if found, else PETSC_FALSE
2831: Level: beginner
2833: Notes:
2834: The user should pass in an array of pointers to char, to hold all the
2835: strings returned by this function.
2837: The user is responsible for deallocating the strings that are
2838: returned. The Fortran interface for this routine is not supported.
2840: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2841: PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2842: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2843: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2844: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2845: PetscOptionsFList(), PetscOptionsEList()
2846: @*/
2847: PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set)
2848: {
2849: const char *svalue;
2850: char *value;
2852: PetscInt n = 0;
2853: PetscBool flag;
2854: PetscToken token;
2861: PetscOptionsFindPair(options,pre,name,&svalue,&flag);
2862: if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
2863: if (set) *set = PETSC_TRUE;
2864: PetscTokenCreate(svalue,',',&token);
2865: PetscTokenFind(token,&value);
2866: while (value && n < *nmax) {
2867: PetscStrallocpy(value,&strings[n]);
2868: PetscTokenFind(token,&value);
2869: n++;
2870: }
2871: PetscTokenDestroy(&token);
2872: *nmax = n;
2873: return(0);
2874: }
2876: /*@C
2877: PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one
2879: Prints a deprecation warning, unless an option is supplied to suppress.
2881: Logically Collective
2883: Input Parameters:
2884: + pre - string to prepend to name or NULL
2885: . oldname - the old, deprecated option
2886: . newname - the new option, or NULL if option is purely removed
2887: . version - a string describing the version of first deprecation, e.g. "3.9"
2888: - info - additional information string, or NULL.
2890: Options Database Keys:
2891: . -options_suppress_deprecated_warnings - do not print deprecation warnings
2893: Notes:
2894: Must be called between PetscOptionsBegin() (or PetscObjectOptionsBegin()) and PetscOptionsEnd().
2895: Only the proces of rank zero that owns the PetscOptionsItems are argument (managed by PetscOptionsBegin() or
2896: PetscObjectOptionsBegin() prints the information
2897: If newname is provided, the old option is replaced. Otherwise, it remains
2898: in the options database.
2899: If an option is not replaced, the info argument should be used to advise the user
2900: on how to proceed.
2901: There is a limit on the length of the warning printed, so very long strings
2902: provided as info may be truncated.
2904: Level: developer
2906: .seealso: PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsScalar(), PetscOptionsBool(), PetscOptionsString(), PetscOptionsSetValue()
2908: @*/
2909: PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[])
2910: {
2911: PetscErrorCode ierr;
2912: PetscBool found,quiet;
2913: const char *value;
2914: const char * const quietopt="-options_suppress_deprecated_warnings";
2915: char msg[4096];
2921: PetscOptionsFindPair(PetscOptionsObject->options,PetscOptionsObject->prefix,oldname,&value,&found);
2922: if (found) {
2923: if (newname) {
2924: if (PetscOptionsObject->prefix) {
2925: PetscOptionsPrefixPush(PetscOptionsObject->options,PetscOptionsObject->prefix);
2926: }
2927: PetscOptionsSetValue(PetscOptionsObject->options,newname,value);
2928: if (PetscOptionsObject->prefix) {
2929: PetscOptionsPrefixPop(PetscOptionsObject->options);
2930: }
2931: PetscOptionsClearValue(PetscOptionsObject->options,oldname);
2932: }
2933: quiet = PETSC_FALSE;
2934: PetscOptionsGetBool(PetscOptionsObject->options,NULL,quietopt,&quiet,NULL);
2935: if (!quiet) {
2936: PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option ");
2937: PetscStrcat(msg,oldname);
2938: PetscStrcat(msg," is deprecated as of version ");
2939: PetscStrcat(msg,version);
2940: PetscStrcat(msg," and will be removed in a future release.");
2941: if (newname) {
2942: PetscStrcat(msg," Please use the option ");
2943: PetscStrcat(msg,newname);
2944: PetscStrcat(msg," instead.");
2945: }
2946: if (info) {
2947: PetscStrcat(msg," ");
2948: PetscStrcat(msg,info);
2949: }
2950: PetscStrcat(msg," (Silence this warning with ");
2951: PetscStrcat(msg,quietopt);
2952: PetscStrcat(msg,")\n");
2953: PetscPrintf(PetscOptionsObject->comm,msg);
2954: }
2955: }
2956: return(0);
2957: }