Actual source code: options.c

petsc-master 2015-03-27
Report Typos and Errors
  2: /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */
  3: #define PETSC_DESIRE_FEATURE_TEST_MACROS

  5: /*
  6:    These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
  7:    This provides the low-level interface, the high level interface is in aoptions.c

  9:    Some routines use regular malloc and free because it cannot know  what malloc is requested with the
 10:    options database until it has already processed the input.
 11: */

 13: #include <petsc-private/petscimpl.h>        /*I  "petscsys.h"   I*/
 14: #include <petscviewer.h>
 15: #include <ctype.h>
 16: #if defined(PETSC_HAVE_MALLOC_H)
 17: #include <malloc.h>
 18: #endif
 19: #if defined(PETSC_HAVE_YAML)
 20: #include <yaml.h>
 21: #endif

 23: /*
 24:     This table holds all the options set by the user. For simplicity, we use a static size database
 25: */
 26: #define MAXOPTIONS 512
 27: #define MAXALIASES 25
 28: #define MAXOPTIONSMONITORS 5
 29: #define MAXPREFIXES 25

 31: typedef struct {
 32:   int            N,argc,Naliases;
 33:   char           **args,*names[MAXOPTIONS],*values[MAXOPTIONS];
 34:   char           *aliases1[MAXALIASES],*aliases2[MAXALIASES];
 35:   PetscBool      used[MAXOPTIONS];
 36:   PetscBool      namegiven;
 37:   char           programname[PETSC_MAX_PATH_LEN]; /* HP includes entire path in name */

 39:   /* --------User (or default) routines (most return -1 on error) --------*/
 40:   PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[], const char[], void*); /* returns control to user after */
 41:   PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void**);         /* */
 42:   void           *monitorcontext[MAXOPTIONSMONITORS];                  /* to pass arbitrary user data into monitor */
 43:   PetscInt       numbermonitors;                                       /* to, for instance, detect options being set */

 45:   /* Prefixes */
 46:   PetscInt prefixind,prefixstack[MAXPREFIXES];
 47:   char     prefix[2048];
 48: } PetscOptionsTable;


 51: static PetscOptionsTable      *options = 0;

 53: /*
 54:     Options events monitor
 55: */
 56: #define PetscOptionsMonitor(name,value)                              \
 57:   { PetscErrorCode _ierr; PetscInt _i,_im = options->numbermonitors; \
 58:     for (_i=0; _i<_im; _i++) { \
 59:       _(*options->monitor[_i])(name, value, options->monitorcontext[_i]);CHKERRQ(_ierr); \
 60:     } \
 61:   }

 65: /*
 66:    PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide"
 67: */
 68: PetscErrorCode  PetscOptionsStringToInt(const char name[],PetscInt *a)
 69: {
 71:   size_t         i,len;
 72:   PetscBool      decide,tdefault,mouse;

 75:   PetscStrlen(name,&len);
 76:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");

 78:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
 79:   if (!tdefault) {
 80:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
 81:   }
 82:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
 83:   if (!decide) {
 84:     PetscStrcasecmp(name,"DECIDE",&decide);
 85:   }
 86:   PetscStrcasecmp(name,"mouse",&mouse);

 88:   if (tdefault)    *a = PETSC_DEFAULT;
 89:   else if (decide) *a = PETSC_DECIDE;
 90:   else if (mouse)  *a = -1;
 91:   else {
 92:     if (name[0] != '+' && name[0] != '-' && name[0] < '0' && name[0] > '9') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);

 94:     for (i=1; i<len; i++) {
 95:       if (name[i] < '0' || name[i] > '9') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);
 96:     }

 98: #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL)
 99:     *a = atoll(name);
100: #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64)
101:     *a = _atoi64(name);
102: #else
103:     *a = (PetscInt)atoi(name);
104: #endif
105:   }
106:   return(0);
107: }

111: /*
112:    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
113: */
114: PetscErrorCode  PetscOptionsStringToReal(const char name[],PetscReal *a)
115: {
117:   size_t         len;
118:   PetscBool      decide,tdefault;

121:   PetscStrlen(name,&len);
122:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");

124:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
125:   if (!tdefault) {
126:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
127:   }
128:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
129:   if (!decide) {
130:     PetscStrcasecmp(name,"DECIDE",&decide);
131:   }

133:   if (tdefault)    *a = PETSC_DEFAULT;
134:   else if (decide) *a = PETSC_DECIDE;
135:   else {
136:     if (name[0] != '+' && name[0] != '-' && name[0] != '.' && name[0] < '0' && name[0] > '9') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
137:     *a = atof(name);
138:   }
139:   return(0);
140: }

144: /*
145:    Converts a string to PetscScalar value. Handles
146:       [-][2].0
147:       [-][2].0i
148:       [-][2].0+/-2.0i

150: */
151: PetscErrorCode  PetscOptionsStringToScalar(const char name[],PetscScalar *a)
152: {
154:   size_t         len;

157:   PetscStrlen(name,&len);
158:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value");

160:   if (name[0] == '+') name++;
161:   if (name[0] == 'i') {
162: #if defined(PETSC_USE_COMPLEX)
163:     *a = PETSC_i;
164: #else
165:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s is imaginary but complex not supported ",name);
166: #endif
167:   } else {
168:     PetscToken token;
169:     char       *tvalue;
170:     PetscBool  neg = PETSC_FALSE, negim = PETSC_FALSE;
171:     PetscReal  re = 0.0,im = 0.0;

173:     if (name[0] != '-' && name[0] != '.' && name[0] < '0' && name[0] > '9') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
174:     if (name[0] == '-') {
175:       neg = PETSC_TRUE;
176:       name++;
177:     }
178:     if (name[0] == 'i') {
179: #if defined(PETSC_USE_COMPLEX)
180:       *a = -PETSC_i;
181: #else
182:      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s is imaginary but complex not supported ",name);
183: #endif
184:       return(0);
185:     }

187:     PetscTokenCreate(name,'+',&token);
188:     PetscTokenFind(token,&tvalue);
189:     if (!tvalue) {
190:       PetscTokenDestroy(&token);
191:       PetscTokenCreate(name,'-',&token);
192:       PetscTokenFind(token,&tvalue);
193:     }
194:     if (tvalue) {
195:       PetscOptionsStringToReal(tvalue,&re);
196:       if (neg) re = -re;
197:       PetscTokenFind(token,&tvalue);
198:       if (!tvalue) {
199:         *a = re;
200:         PetscTokenDestroy(&token);
201:         return(0);
202:       }
203:       PetscStrlen(tvalue,&len);
204:       if (tvalue[len-1] != 'i') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
205:       tvalue[len-1] = 0;
206:       PetscOptionsStringToReal(tvalue,&im);
207:       if (negim) im = -im;
208:     } else {
209:       PetscStrstr(name,"i",&tvalue);
210:       if (tvalue) {
211:         tvalue[0] = 0;
212:         PetscOptionsStringToReal(name,&im);
213:       } else {
214:         PetscOptionsStringToReal(name,&re);
215:       }
216:     }
217:     PetscTokenDestroy(&token);
218: #if defined(PETSC_USE_COMPLEX)
219:     *a = re + im*PETSC_i;
220: #else
221:     if (im != 0.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s is complex but complex not supported ",name);
222:     *a = re;
223: #endif
224:   }
225:   return(0);
226: }

230: /*
231:    PetscOptionsStringToBool - Converts string to PetscBool , handles cases like "yes", "no", "true", "false", "0", "1"
232: */
233: PetscErrorCode  PetscOptionsStringToBool(const char value[], PetscBool  *a)
234: {
235:   PetscBool      istrue, isfalse;
236:   size_t         len;

240:   PetscStrlen(value, &len);
241:   if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Character string of length zero has no logical value");
242:   PetscStrcasecmp(value,"TRUE",&istrue);
243:   if (istrue) {*a = PETSC_TRUE; return(0);}
244:   PetscStrcasecmp(value,"YES",&istrue);
245:   if (istrue) {*a = PETSC_TRUE; return(0);}
246:   PetscStrcasecmp(value,"1",&istrue);
247:   if (istrue) {*a = PETSC_TRUE; return(0);}
248:   PetscStrcasecmp(value,"on",&istrue);
249:   if (istrue) {*a = PETSC_TRUE; return(0);}
250:   PetscStrcasecmp(value,"FALSE",&isfalse);
251:   if (isfalse) {*a = PETSC_FALSE; return(0);}
252:   PetscStrcasecmp(value,"NO",&isfalse);
253:   if (isfalse) {*a = PETSC_FALSE; return(0);}
254:   PetscStrcasecmp(value,"0",&isfalse);
255:   if (isfalse) {*a = PETSC_FALSE; return(0);}
256:   PetscStrcasecmp(value,"off",&isfalse);
257:   if (isfalse) {*a = PETSC_FALSE; return(0);}
258:   SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
259:   return(0);
260: }

264: /*@C
265:     PetscGetProgramName - Gets the name of the running program.

267:     Not Collective

269:     Input Parameter:
270: .   len - length of the string name

272:     Output Parameter:
273: .   name - the name of the running program

275:    Level: advanced

277:     Notes:
278:     The name of the program is copied into the user-provided character
279:     array of length len.  On some machines the program name includes
280:     its entire path, so one should generally set len >= PETSC_MAX_PATH_LEN.
281: @*/
282: PetscErrorCode  PetscGetProgramName(char name[],size_t len)
283: {

287:   if (!options) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call PetscInitialize() first");
288:   if (!options->namegiven) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to determine program name");
289:   PetscStrncpy(name,options->programname,len);
290:   return(0);
291: }

295: PetscErrorCode  PetscSetProgramName(const char name[])
296: {

300:   options->namegiven = PETSC_TRUE;

302:   PetscStrncpy(options->programname,name,PETSC_MAX_PATH_LEN);
303:   return(0);
304: }

308: /*@
309:     PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter.

311:    Input Parameter:
312: .    in_str - string to check if valid

314:    Output Parameter:
315: .    key - PETSC_TRUE if a valid key

317:   Level: intermediate

319: @*/
320: PetscErrorCode  PetscOptionsValidKey(const char in_str[],PetscBool  *key)
321: {
322:   PetscBool      inf,INF;

326:   *key = PETSC_FALSE;
327:   if (!in_str) return(0);
328:   if (in_str[0] != '-') return(0);
329:   if (in_str[1] == '-') in_str++;
330:   if (!isalpha((int)(in_str[1]))) return(0);
331:   PetscStrncmp(in_str+1,"inf",3,&inf);
332:   PetscStrncmp(in_str+1,"INF",3,&INF);
333:   if ((inf || INF) && !(in_str[4] == '_' || isalnum((int)(in_str[4])))) return(0);
334:   *key = PETSC_TRUE;
335:   return(0);
336: }

340: /*@C
341:      PetscOptionsInsertString - Inserts options into the database from a string

343:      Not collective: but only processes that call this routine will set the options
344:                      included in the string

346:   Input Parameter:
347: .   in_str - string that contains options separated by blanks


350:   Level: intermediate

352:   Contributed by Boyana Norris

354: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
355:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
356:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
357:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
358:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
359:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile()

361: @*/
362: PetscErrorCode  PetscOptionsInsertString(const char in_str[])
363: {
364:   char           *first,*second;
366:   PetscToken     token;
367:   PetscBool      key,ispush,ispop;

370:   PetscTokenCreate(in_str,' ',&token);
371:   PetscTokenFind(token,&first);
372:   while (first) {
373:     PetscStrcasecmp(first,"-prefix_push",&ispush);
374:     PetscStrcasecmp(first,"-prefix_pop",&ispop);
375:     PetscOptionsValidKey(first,&key);
376:     if (ispush) {
377:       PetscTokenFind(token,&second);
378:       PetscOptionsPrefixPush(second);
379:       PetscTokenFind(token,&first);
380:     } else if (ispop) {
381:       PetscOptionsPrefixPop();
382:       PetscTokenFind(token,&first);
383:     } else if (key) {
384:       PetscTokenFind(token,&second);
385:       PetscOptionsValidKey(second,&key);
386:       if (!key) {
387:         PetscOptionsSetValue(first,second);
388:         PetscTokenFind(token,&first);
389:       } else {
390:         PetscOptionsSetValue(first,NULL);
391:         first = second;
392:       }
393:     } else {
394:       PetscTokenFind(token,&first);
395:     }
396:   }
397:   PetscTokenDestroy(&token);
398:   return(0);
399: }

401: /*
402:     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
403: */
404: static char *Petscgetline(FILE * f)
405: {
406:   size_t size  = 0;
407:   size_t len   = 0;
408:   size_t last  = 0;
409:   char   *buf  = NULL;

411:   if (feof(f)) return 0;
412:   do {
413:     size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
414:     buf   = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
415:     /* Actually do the read. Note that fgets puts a terminal '\0' on the
416:     end of the string, so we make sure we overwrite this */
417:     if (!fgets(buf+len,size,f)) buf[len]=0;
418:     PetscStrlen(buf,&len);
419:     last = len - 1;
420:   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
421:   if (len) return buf;
422:   free(buf);
423:   return 0;
424: }


429: /*@C
430:      PetscOptionsInsertFile - Inserts options into the database from a file.

432:      Collective on MPI_Comm

434:   Input Parameter:
435: +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
436: .   file - name of file
437: -   require - if PETSC_TRUE will generate an error if the file does not exist


440:   Notes: Use  # for lines that are comments and which should be ignored.

442:   Level: developer

444: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
445:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
446:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
447:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
448:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
449:           PetscOptionsFList(), PetscOptionsEList()

451: @*/
452: PetscErrorCode  PetscOptionsInsertFile(MPI_Comm comm,const char file[],PetscBool require)
453: {
454:   char           *string,fname[PETSC_MAX_PATH_LEN],*first,*second,*third,*vstring = 0,*astring = 0,*packed = 0;
456:   size_t         i,len,bytes;
457:   FILE           *fd;
458:   PetscToken     token;
459:   int            err;
460:   char           cmt[1]={'#'},*cmatch;
461:   PetscMPIInt    rank,cnt=0,acnt=0,counts[2];

464:   MPI_Comm_rank(comm,&rank);
465:   if (!rank) {
466:     cnt        = 0;
467:     acnt       = 0;

469:     PetscFixFilename(file,fname);
470:     fd   = fopen(fname,"r");
471:     if (fd) {
472:       PetscSegBuffer vseg,aseg;
473:       PetscSegBufferCreate(1,4000,&vseg);
474:       PetscSegBufferCreate(1,2000,&aseg);

476:       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
477:       PetscInfo1(0,"Opened options file %s\n",file);

479:       while ((string = Petscgetline(fd))) {
480:         /* eliminate comments from each line */
481:         for (i=0; i<1; i++) {
482:           PetscStrchr(string,cmt[i],&cmatch);
483:           if (cmatch) *cmatch = 0;
484:         }
485:         PetscStrlen(string,&len);
486:         /* replace tabs, ^M, \n with " " */
487:         for (i=0; i<len; i++) {
488:           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
489:             string[i] = ' ';
490:           }
491:         }
492:         PetscTokenCreate(string,' ',&token);
493:         free(string);
494:         PetscTokenFind(token,&first);
495:         if (!first) {
496:           goto destroy;
497:         } else if (!first[0]) { /* if first token is empty spaces, redo first token */
498:           PetscTokenFind(token,&first);
499:         }
500:         PetscTokenFind(token,&second);
501:         if (!first) {
502:           goto destroy;
503:         } else if (first[0] == '-') {
504:           PetscStrlen(first,&len);
505:           PetscSegBufferGet(vseg,len+1,&vstring);
506:           PetscMemcpy(vstring,first,len);
507:           vstring[len] = ' ';
508:           if (second) {
509:             PetscStrlen(second,&len);
510:             PetscSegBufferGet(vseg,len+3,&vstring);
511:             vstring[0] = '"';
512:             PetscMemcpy(vstring+1,second,len);
513:             vstring[len+1] = '"';
514:             vstring[len+2] = ' ';
515:           }
516:         } else {
517:           PetscBool match;

519:           PetscStrcasecmp(first,"alias",&match);
520:           if (match) {
521:             PetscTokenFind(token,&third);
522:             if (!third) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file:alias missing (%s)",second);
523:             PetscStrlen(second,&len);
524:             PetscSegBufferGet(aseg,len+1,&astring);
525:             PetscMemcpy(astring,second,len);
526:             astring[len] = ' ';

528:             PetscStrlen(third,&len);
529:             PetscSegBufferGet(aseg,len+1,&astring);
530:             PetscMemcpy(astring,third,len);
531:             astring[len] = ' ';
532:           } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown statement in options file: (%s)",string);
533:         }
534: destroy:
535:         PetscTokenDestroy(&token);
536:       }
537:       err = fclose(fd);
538:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
539:       PetscSegBufferGetSize(aseg,&bytes); /* size without null termination */
540:       PetscMPIIntCast(bytes,&acnt);
541:       PetscSegBufferGet(aseg,1,&astring);
542:       astring[0] = 0;
543:       PetscSegBufferGetSize(vseg,&bytes); /* size without null termination */
544:       PetscMPIIntCast(bytes,&cnt);
545:       PetscSegBufferGet(vseg,1,&vstring);
546:       vstring[0] = 0;
547:       PetscMalloc1(2+acnt+cnt,&packed);
548:       PetscSegBufferExtractTo(aseg,packed);
549:       PetscSegBufferExtractTo(vseg,packed+acnt+1);
550:       PetscSegBufferDestroy(&aseg);
551:       PetscSegBufferDestroy(&vseg);
552:     } else if (require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open Options File %s",fname);
553:   }

555:   counts[0] = acnt;
556:   counts[1] = cnt;
557:   MPI_Bcast(counts,2,MPI_INT,0,comm);
558:   acnt = counts[0];
559:   cnt = counts[1];
560:   if (rank) {
561:     PetscMalloc1(2+acnt+cnt,&packed);
562:   }
563:   if (acnt || cnt) {
564:     MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm);
565:     astring = packed;
566:     vstring = packed + acnt + 1;
567:   }

569:   if (acnt) {
570:     PetscToken token;
571:     char       *first,*second;

573:     PetscTokenCreate(astring,' ',&token);
574:     PetscTokenFind(token,&first);
575:     while (first) {
576:       PetscTokenFind(token,&second);
577:       PetscOptionsSetAlias(first,second);
578:       PetscTokenFind(token,&first);
579:     }
580:     PetscTokenDestroy(&token);
581:   }

583:   if (cnt) {
584:     PetscOptionsInsertString(vstring);
585:   }
586:   PetscFree(packed);
587:   return(0);
588: }

592: static PetscErrorCode PetscOptionsInsertArgs_Private(int argc,char *args[])
593: {
595:   int            left    = argc - 1;
596:   char           **eargs = args + 1;

599:   while (left) {
600:     PetscBool isoptions_file,isprefixpush,isprefixpop,isp4,tisp4,isp4yourname,isp4rmrank,key;
601:     PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);
602:     PetscStrcasecmp(eargs[0],"-prefix_push",&isprefixpush);
603:     PetscStrcasecmp(eargs[0],"-prefix_pop",&isprefixpop);
604:     PetscStrcasecmp(eargs[0],"-p4pg",&isp4);
605:     PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);
606:     PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);
607:     PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);
608:     isp4 = (PetscBool) (isp4 || tisp4);
609:     PetscStrcasecmp(eargs[0],"-np",&tisp4);
610:     isp4 = (PetscBool) (isp4 || tisp4);
611:     PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);
612:     PetscOptionsValidKey(eargs[0],&key);

614:     if (!key) {
615:       eargs++; left--;
616:     } else if (isoptions_file) {
617:       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
618:       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option");
619:       PetscOptionsInsertFile(PETSC_COMM_WORLD,eargs[1],PETSC_TRUE);
620:       eargs += 2; left -= 2;
621:     } else if (isprefixpush) {
622:       if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option");
623:       if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')");
624:       PetscOptionsPrefixPush(eargs[1]);
625:       eargs += 2; left -= 2;
626:     } else if (isprefixpop) {
627:       PetscOptionsPrefixPop();
628:       eargs++; left--;

630:       /*
631:        These are "bad" options that MPICH, etc put on the command line
632:        we strip them out here.
633:        */
634:     } else if (tisp4 || isp4rmrank) {
635:       eargs += 1; left -= 1;
636:     } else if (isp4 || isp4yourname) {
637:       eargs += 2; left -= 2;
638:     } else {
639:       PetscBool nextiskey = PETSC_FALSE;
640:       if (left >= 2) {PetscOptionsValidKey(eargs[1],&nextiskey);}
641:       if (left < 2 || nextiskey) {
642:         PetscOptionsSetValue(eargs[0],NULL);
643:         eargs++; left--;
644:       } else {
645:         PetscOptionsSetValue(eargs[0],eargs[1]);
646:         eargs += 2; left -= 2;
647:       }
648:     }
649:   }
650:   return(0);
651: }


656: /*@C
657:    PetscOptionsInsert - Inserts into the options database from the command line,
658:                    the environmental variable and a file.

660:    Input Parameters:
661: +  argc - count of number of command line arguments
662: .  args - the command line arguments
663: -  file - optional filename, defaults to ~username/.petscrc

665:    Note:
666:    Since PetscOptionsInsert() is automatically called by PetscInitialize(),
667:    the user does not typically need to call this routine. PetscOptionsInsert()
668:    can be called several times, adding additional entries into the database.

670:    Options Database Keys:
671: +   -options_monitor <optional filename> - print options names and values as they are set
672: .   -options_file <filename> - read options from a file

674:    Level: advanced

676:    Concepts: options database^adding

678: .seealso: PetscOptionsDestroy_Private(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
679:           PetscInitialize()
680: @*/
681: PetscErrorCode  PetscOptionsInsert(int *argc,char ***args,const char file[])
682: {
684:   PetscMPIInt    rank;
685:   char           pfile[PETSC_MAX_PATH_LEN];
686:   PetscBool      flag = PETSC_FALSE;

689:   if (!options) {
690:     fprintf(stderr, "Options have not been enabled.\nYou might have forgotten to call PetscInitialize().\n");
691:     MPI_Abort(MPI_COMM_WORLD, PETSC_ERR_SUP);
692:   }
693:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

695:   options->argc = (argc) ? *argc : 0;
696:   options->args = (args) ? *args : NULL;

698:   if (file && file[0]) {
699:     char fullpath[PETSC_MAX_PATH_LEN];

701:     PetscStrreplace(PETSC_COMM_WORLD,file,fullpath,PETSC_MAX_PATH_LEN);
702:     PetscOptionsInsertFile(PETSC_COMM_WORLD,fullpath,PETSC_TRUE);
703:   }
704:   /*
705:      We want to be able to give -skip_petscrc on the command line, but need to parse it first.  Since the command line
706:      should take precedence, we insert it twice.  It would be sufficient to just scan for -skip_petscrc.
707:   */
708:   if (argc && args && *argc) {PetscOptionsInsertArgs_Private(*argc,*args);}
709:   PetscOptionsGetBool(NULL,"-skip_petscrc",&flag,NULL);
710:   if (!flag) {
711:     PetscGetHomeDirectory(pfile,PETSC_MAX_PATH_LEN-16);
712:     /* PetscOptionsInsertFile() does a fopen() on rank0 only - so only rank0 HomeDir value is relavent */
713:     if (pfile[0]) { PetscStrcat(pfile,"/.petscrc"); }
714:     PetscOptionsInsertFile(PETSC_COMM_WORLD,pfile,PETSC_FALSE);
715:     PetscOptionsInsertFile(PETSC_COMM_WORLD,".petscrc",PETSC_FALSE);
716:     PetscOptionsInsertFile(PETSC_COMM_WORLD,"petscrc",PETSC_FALSE);
717:   }

719:   /* insert environmental options */
720:   {
721:     char   *eoptions = 0;
722:     size_t len       = 0;
723:     if (!rank) {
724:       eoptions = (char*)getenv("PETSC_OPTIONS");
725:       PetscStrlen(eoptions,&len);
726:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
727:     } else {
728:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
729:       if (len) {
730:         PetscMalloc1(len+1,&eoptions);
731:       }
732:     }
733:     if (len) {
734:       MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
735:       if (rank) eoptions[len] = 0;
736:       PetscOptionsInsertString(eoptions);
737:       if (rank) {PetscFree(eoptions);}
738:     }
739:   }

741: #if defined(PETSC_HAVE_YAML)
742:   char      yaml_file[PETSC_MAX_PATH_LEN];
743:   PetscBool yaml_flg = PETSC_FALSE;
744:   PetscOptionsGetString(NULL,"-options_file_yaml",yaml_file,PETSC_MAX_PATH_LEN,&yaml_flg);
745:   if (yaml_flg) PetscOptionsInsertFileYAML(PETSC_COMM_WORLD,yaml_file,PETSC_TRUE);
746: #endif

748:   /* insert command line options again because they take precedence over arguments in petscrc/environment */
749:   if (argc && args && *argc) {PetscOptionsInsertArgs_Private(*argc,*args);}
750:   return(0);
751: }

755: /*@C
756:    PetscOptionsView - Prints the options that have been loaded. This is
757:    useful for debugging purposes.

759:    Logically Collective on PetscViewer

761:    Input Parameter:
762: .  viewer - must be an PETSCVIEWERASCII viewer

764:    Options Database Key:
765: .  -options_table - Activates PetscOptionsView() within PetscFinalize()

767:    Level: advanced

769:    Concepts: options database^printing

771: .seealso: PetscOptionsAllUsed()
772: @*/
773: PetscErrorCode  PetscOptionsView(PetscViewer viewer)
774: {
776:   PetscInt       i;
777:   PetscBool      isascii;

780:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
781:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
782:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");

784:   if (!options) {PetscOptionsInsert(0,0,0);}
785:   if (options->N) {
786:     PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");
787:   } else {
788:     PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");
789:   }
790:   for (i=0; i<options->N; i++) {
791:     if (options->values[i]) {
792:       PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);
793:     } else {
794:       PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);
795:     }
796:   }
797:   if (options->N) {
798:     PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");
799:   }
800:   return(0);
801: }

805: /*
806:    Called by error handlers to print options used in run
807: */
808: PetscErrorCode  PetscOptionsViewError(void)
809: {
810:   PetscInt       i;

813:   if (options->N) {
814:     (*PetscErrorPrintf)("PETSc Option Table entries:\n");
815:   } else {
816:     (*PetscErrorPrintf)("No PETSc Option Table entries\n");
817:   }
818:   for (i=0; i<options->N; i++) {
819:     if (options->values[i]) {
820:       (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]);
821:     } else {
822:       (*PetscErrorPrintf)("-%s\n",options->names[i]);
823:     }
824:   }
825:   return(0);
826: }

830: /*@C
831:    PetscOptionsGetAll - Lists all the options the program was run with in a single string.

833:    Not Collective

835:    Output Parameter:
836: .  copts - pointer where string pointer is stored

838:    Notes: the array and each entry in the array should be freed with PetscFree()

840:    Level: advanced

842:    Concepts: options database^listing

844: .seealso: PetscOptionsAllUsed(), PetscOptionsView()
845: @*/
846: PetscErrorCode  PetscOptionsGetAll(char *copts[])
847: {
849:   PetscInt       i;
850:   size_t         len       = 1,lent = 0;
851:   char           *coptions = NULL;

854:   if (!options) {PetscOptionsInsert(0,0,0);}

856:   /* count the length of the required string */
857:   for (i=0; i<options->N; i++) {
858:     PetscStrlen(options->names[i],&lent);
859:     len += 2 + lent;
860:     if (options->values[i]) {
861:       PetscStrlen(options->values[i],&lent);
862:       len += 1 + lent;
863:     }
864:   }
865:   PetscMalloc1(len,&coptions);
866:   coptions[0] = 0;
867:   for (i=0; i<options->N; i++) {
868:     PetscStrcat(coptions,"-");
869:     PetscStrcat(coptions,options->names[i]);
870:     PetscStrcat(coptions," ");
871:     if (options->values[i]) {
872:       PetscStrcat(coptions,options->values[i]);
873:       PetscStrcat(coptions," ");
874:     }
875:   }
876:   *copts = coptions;
877:   return(0);
878: }

882: /*@
883:    PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow.

885:    Not Collective, but prefix will only be applied on calling ranks

887:    Input Parameter:
888: .  prefix - The string to append to the existing prefix

890:    Options Database Keys:
891:  +   -prefix_push <some_prefix_> - push the given prefix
892:  -   -prefix_pop - pop the last prefix

894:    Notes:
895:    It is common to use this in conjunction with -options_file as in

897:  $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop

899:    where the files no longer require all options to be prefixed with -system2_.

901: Level: advanced

903: .seealso: PetscOptionsPrefixPop()
904: @*/
905: PetscErrorCode  PetscOptionsPrefixPush(const char prefix[])
906: {
908:   size_t         n;
909:   PetscInt       start;
910:   char           buf[2048];
911:   PetscBool      key;

915:   /* Want to check validity of the key using PetscOptionsValidKey(), which requires that the first character is a '-' */
916:   buf[0] = '-';
917:   PetscStrncpy(buf+1,prefix,sizeof(buf) - 1);
918:   buf[sizeof(buf) - 1] = 0;
919:   PetscOptionsValidKey(buf,&key);
920:   if (!key) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Given prefix \"%s\" not valid (the first character must be a letter, do not include leading '-')",prefix);

922:   if (!options) {PetscOptionsInsert(0,0,0);}
923:   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);
924:   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
925:   PetscStrlen(prefix,&n);
926:   if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
927:   PetscMemcpy(options->prefix+start,prefix,n+1);
928:   options->prefixstack[options->prefixind++] = start+n;
929:   return(0);
930: }

934: /*@
935:    PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details

937:    Not  Collective, but prefix will only be popped on calling ranks

939:    Level: advanced

941: .seealso: PetscOptionsPrefixPush()
942: @*/
943: PetscErrorCode  PetscOptionsPrefixPop(void)
944: {
945:   PetscInt offset;

948:   if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
949:   options->prefixind--;
950:   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
951:   options->prefix[offset] = 0;
952:   return(0);
953: }

957: /*@C
958:     PetscOptionsClear - Removes all options form the database leaving it empty.

960:    Level: developer

962: .seealso: PetscOptionsInsert()
963: @*/
964: PetscErrorCode  PetscOptionsClear(void)
965: {
966:   PetscInt i;

969:   if (!options) return(0);
970:   for (i=0; i<options->N; i++) {
971:     if (options->names[i])  free(options->names[i]);
972:     if (options->values[i]) free(options->values[i]);
973:   }
974:   for (i=0; i<options->Naliases; i++) {
975:     free(options->aliases1[i]);
976:     free(options->aliases2[i]);
977:   }
978:   options->prefix[0] = 0;
979:   options->prefixind = 0;
980:   options->N         = 0;
981:   options->Naliases  = 0;
982:   return(0);
983: }

987: /*@C
988:     PetscOptionsDestroy - Destroys the option database.

990:     Note:
991:     Since PetscOptionsDestroy() is called by PetscFinalize(), the user
992:     typically does not need to call this routine.

994:    Level: developer

996: .seealso: PetscOptionsInsert()
997: @*/
998: PetscErrorCode  PetscOptionsDestroy(void)
999: {

1003:   if (!options) return(0);
1004:   PetscOptionsClear();
1005:   free(options);
1006:   options = 0;
1007:   return(0);
1008: }

1012: /*@C
1013:    PetscOptionsSetValue - Sets an option name-value pair in the options
1014:    database, overriding whatever is already present.

1016:    Not collective, but setting values on certain processors could cause problems
1017:    for parallel objects looking for options.

1019:    Input Parameters:
1020: +  name - name of option, this SHOULD have the - prepended
1021: -  value - the option value (not used for all options)

1023:    Level: intermediate

1025:    Note:
1026:    Only some options have values associated with them, such as
1027:    -ksp_rtol tol.  Other options stand alone, such as -ksp_monitor.

1029:   Developers Note: Uses malloc() directly because PETSc may not yet have been fully initialized

1031:   Concepts: options database^adding option

1033: .seealso: PetscOptionsInsert()
1034: @*/
1035: PetscErrorCode  PetscOptionsSetValue(const char iname[],const char value[])
1036: {
1037:   size_t         len;
1039:   PetscInt       N,n,i;
1040:   char           **names;
1041:   char           fullname[2048];
1042:   const char     *name = iname;
1043:   PetscBool      gt,match;

1046:   if (!options) {PetscOptionsInsert(0,0,0);}

1048:   /* this is so that -h and -hel\p are equivalent (p4 does not like -help)*/
1049:   PetscStrcasecmp(name,"-h",&match);
1050:   if (match) name = "-help";

1052:   name++; /* skip starting hyphen */
1053:   if (options->prefixind > 0) {
1054:     PetscStrncpy(fullname,options->prefix,sizeof(fullname));
1055:     PetscStrncat(fullname,name,sizeof(fullname));
1056:     name = fullname;
1057:   }

1059:   /* check against aliases */
1060:   N = options->Naliases;
1061:   for (i=0; i<N; i++) {
1062:     PetscStrcasecmp(options->aliases1[i],name,&match);
1063:     if (match) {
1064:       name = options->aliases2[i];
1065:       break;
1066:     }
1067:   }

1069:   N     = options->N;
1070:   n     = N;
1071:   names = options->names;

1073:   for (i=0; i<N; i++) {
1074:     PetscStrcasecmp(names[i],name,&match);
1075:     PetscStrgrt(names[i],name,&gt);
1076:     if (match) {
1077:       if (options->values[i]) free(options->values[i]);
1078:       PetscStrlen(value,&len);
1079:       if (len) {
1080:         options->values[i] = (char*)malloc((len+1)*sizeof(char));
1081:         PetscStrcpy(options->values[i],value);
1082:       } else options->values[i] = 0;
1083:       PetscOptionsMonitor(name,value);
1084:       return(0);
1085:     } else if (gt) {
1086:       n = i;
1087:       break;
1088:     }
1089:   }
1090:   if (N >= MAXOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"No more room in option table, limit %d recompile \n src/sys/objects/options.c with larger value for MAXOPTIONS\n",MAXOPTIONS);

1092:   /* shift remaining values down 1 */
1093:   for (i=N; i>n; i--) {
1094:     options->names[i]  = options->names[i-1];
1095:     options->values[i] = options->values[i-1];
1096:     options->used[i]   = options->used[i-1];
1097:   }
1098:   /* insert new name and value */
1099:   PetscStrlen(name,&len);
1100:   options->names[n] = (char*)malloc((len+1)*sizeof(char));
1101:   PetscStrcpy(options->names[n],name);
1102:   PetscStrlen(value,&len);
1103:   if (len) {
1104:     options->values[n] = (char*)malloc((len+1)*sizeof(char));
1105:     PetscStrcpy(options->values[n],value);
1106:   } else options->values[n] = 0;
1107:   options->used[n] = PETSC_FALSE;
1108:   options->N++;
1109:   PetscOptionsMonitor(name,value);
1110:   return(0);
1111: }

1115: /*@C
1116:    PetscOptionsClearValue - Clears an option name-value pair in the options
1117:    database, overriding whatever is already present.

1119:    Not Collective, but setting values on certain processors could cause problems
1120:    for parallel objects looking for options.

1122:    Input Parameter:
1123: .  name - name of option, this SHOULD have the - prepended

1125:    Level: intermediate

1127:    Concepts: options database^removing option
1128: .seealso: PetscOptionsInsert()
1129: @*/
1130: PetscErrorCode  PetscOptionsClearValue(const char iname[])
1131: {
1133:   PetscInt       N,n,i;
1134:   char           **names,*name=(char*)iname;
1135:   PetscBool      gt,match;

1138:   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);
1139:   if (!options) {PetscOptionsInsert(0,0,0);}

1141:   name++;

1143:   N     = options->N; n = 0;
1144:   names = options->names;

1146:   for (i=0; i<N; i++) {
1147:     PetscStrcasecmp(names[i],name,&match);
1148:     PetscStrgrt(names[i],name,&gt);
1149:     if (match) {
1150:       if (options->names[i])  free(options->names[i]);
1151:       if (options->values[i]) free(options->values[i]);
1152:       PetscOptionsMonitor(name,"");
1153:       break;
1154:     } else if (gt) return(0); /* it was not listed */

1156:     n++;
1157:   }
1158:   if (n == N) return(0); /* it was not listed */

1160:   /* shift remaining values down 1 */
1161:   for (i=n; i<N-1; i++) {
1162:     options->names[i]  = options->names[i+1];
1163:     options->values[i] = options->values[i+1];
1164:     options->used[i]   = options->used[i+1];
1165:   }
1166:   options->N--;
1167:   return(0);
1168: }

1172: /*@C
1173:    PetscOptionsSetAlias - Makes a key and alias for another key

1175:    Not Collective, but setting values on certain processors could cause problems
1176:    for parallel objects looking for options.

1178:    Input Parameters:
1179: +  inewname - the alias
1180: -  ioldname - the name that alias will refer to

1182:    Level: advanced

1184: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1185:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
1186:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1187:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1188:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1189:           PetscOptionsFList(), PetscOptionsEList()
1190: @*/
1191: PetscErrorCode  PetscOptionsSetAlias(const char inewname[],const char ioldname[])
1192: {
1194:   PetscInt       n = options->Naliases;
1195:   size_t         len;
1196:   char           *newname = (char*)inewname,*oldname = (char*)ioldname;

1199:   if (newname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliased must have -: Instead %s",newname);
1200:   if (oldname[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"aliasee must have -: Instead %s",oldname);
1201:   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);

1203:   newname++; oldname++;
1204:   PetscStrlen(newname,&len);
1205:   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
1206:   PetscStrcpy(options->aliases1[n],newname);
1207:   PetscStrlen(oldname,&len);
1208:   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
1209:   PetscStrcpy(options->aliases2[n],oldname);
1210:   options->Naliases++;
1211:   return(0);
1212: }

1216: PetscErrorCode PetscOptionsFindPair_Private(const char pre[],const char name[],char *value[],PetscBool  *flg)
1217: {
1219:   PetscInt       i,N;
1220:   size_t         len;
1221:   char           **names,tmp[256];
1222:   PetscBool      match;

1225:   if (!options) {PetscOptionsInsert(0,0,0);}
1226:   N     = options->N;
1227:   names = options->names;

1229:   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);

1231:   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1232:   if (pre) {
1233:     char       *ptr   = tmp;
1234:     const char *namep = name;
1235:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
1236:     if (name[1] == '-') {
1237:       *ptr++ = '-';
1238:       namep++;
1239:     }
1240:     PetscStrncpy(ptr,pre,tmp+sizeof(tmp)-ptr);
1241:     tmp[sizeof(tmp)-1] = 0;
1242:     PetscStrlen(tmp,&len);
1243:     PetscStrncat(tmp,namep+1,sizeof(tmp)-len-1);
1244:   } else {
1245:     PetscStrncpy(tmp,name+1,sizeof(tmp));
1246:     tmp[sizeof(tmp)-1] = 0;
1247:   }
1248: #if defined(PETSC_USE_DEBUG)
1249:   {
1250:     PetscBool valid;
1251:     char      key[sizeof(tmp)+1] = "-";

1253:     PetscMemcpy(key+1,tmp,sizeof(tmp));
1254:     PetscOptionsValidKey(key,&valid);
1255:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1256:   }
1257: #endif

1259:   /* slow search */
1260:   *flg = PETSC_FALSE;
1261:   for (i=0; i<N; i++) {
1262:     PetscStrcasecmp(names[i],tmp,&match);
1263:     if (match) {
1264:       *value           = options->values[i];
1265:       options->used[i] = PETSC_TRUE;
1266:       *flg             = PETSC_TRUE;
1267:       break;
1268:     }
1269:   }
1270:   if (!*flg) {
1271:     PetscInt j,cnt = 0,locs[16],loce[16];
1272:     size_t   n;
1273:     PetscStrlen(tmp,&n);
1274:     /* determine the location and number of all _%d_ in the key */
1275:     for (i=0; i< (PetscInt)n; i++) {
1276:       if (tmp[i] == '_') {
1277:         for (j=i+1; j< (PetscInt)n; j++) {
1278:           if (tmp[j] >= '0' && tmp[j] <= '9') continue;
1279:           if (tmp[j] == '_' && j > i+1) { /* found a number */
1280:             locs[cnt]   = i+1;
1281:             loce[cnt++] = j+1;
1282:           }
1283:           break;
1284:         }
1285:       }
1286:     }
1287:     if (cnt) {
1288:       char tmp2[256];
1289:       for (i=0; i<cnt; i++) {
1290:         PetscStrcpy(tmp2,"-");
1291:         PetscStrncat(tmp2,tmp,locs[i]);
1292:         PetscStrcat(tmp2,tmp+loce[i]);
1293:         PetscOptionsFindPair_Private(NULL,tmp2,value,flg);
1294:         if (*flg) break;
1295:       }
1296:     }
1297:   }
1298:   return(0);
1299: }

1303: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(const char pre[], const char name[], char *value[], PetscBool *flg)
1304: {
1306:   PetscInt       i,N;
1307:   size_t         len;
1308:   char           **names,tmp[256];
1309:   PetscBool      match;

1312:   if (!options) {PetscOptionsInsert(0,0,0);}
1313:   N     = options->N;
1314:   names = options->names;

1316:   if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with -: Instead %s",name);

1318:   /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */
1319:   if (pre) {
1320:     char       *ptr   = tmp;
1321:     const char *namep = name;
1322:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
1323:     if (name[1] == '-') {
1324:       *ptr++ = '-';
1325:       namep++;
1326:     }
1327:     PetscStrncpy(ptr,pre,tmp+sizeof(tmp)-ptr);
1328:     tmp[sizeof(tmp)-1] = 0;
1329:     PetscStrlen(tmp,&len);
1330:     PetscStrncat(tmp,namep+1,sizeof(tmp)-len-1);
1331:   } else {
1332:     PetscStrncpy(tmp,name+1,sizeof(tmp));
1333:     tmp[sizeof(tmp)-1] = 0;
1334:   }
1335: #if defined(PETSC_USE_DEBUG)
1336:   {
1337:     PetscBool valid;
1338:     char      key[sizeof(tmp)+1] = "-";

1340:     PetscMemcpy(key+1,tmp,sizeof(tmp));
1341:     PetscOptionsValidKey(key,&valid);
1342:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1343:   }
1344: #endif

1346:   /* slow search */
1347:   *flg = PETSC_FALSE;
1348:   PetscStrlen(tmp,&len);
1349:   for (i = 0; i < N; ++i) {
1350:     PetscStrncmp(names[i], tmp, len, &match);
1351:     if (match) {
1352:       if (value) *value = options->values[i];
1353:       options->used[i]  = PETSC_TRUE;
1354:       if (flg)   *flg   = PETSC_TRUE;
1355:       break;
1356:     }
1357:   }
1358:   return(0);
1359: }

1363: /*@C
1364:    PetscOptionsReject - Generates an error if a certain option is given.

1366:    Not Collective, but setting values on certain processors could cause problems
1367:    for parallel objects looking for options.

1369:    Input Parameters:
1370: +  name - the option one is seeking
1371: -  mess - error message (may be NULL)

1373:    Level: advanced

1375:    Concepts: options database^rejecting option

1377: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1378:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1379:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1380:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1381:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1382:           PetscOptionsFList(), PetscOptionsEList()
1383: @*/
1384: PetscErrorCode  PetscOptionsReject(const char name[],const char mess[])
1385: {
1387:   PetscBool      flag = PETSC_FALSE;

1390:   PetscOptionsHasName(NULL,name,&flag);
1391:   if (flag) {
1392:     if (mess) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s with %s",name,mess);
1393:     else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s",name);
1394:   }
1395:   return(0);
1396: }

1400: /*@C
1401:    PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or boolean, even
1402:                       its value is set to false.

1404:    Not Collective

1406:    Input Parameters:
1407: +  name - the option one is seeking
1408: -  pre - string to prepend to the name or NULL

1410:    Output Parameters:
1411: .  set - PETSC_TRUE if found else PETSC_FALSE.

1413:    Level: beginner

1415:    Concepts: options database^has option name

1417:    Notes: Name cannot be simply -h

1419:           In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values.

1421: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1422:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1423:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1424:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1425:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1426:           PetscOptionsFList(), PetscOptionsEList()
1427: @*/
1428: PetscErrorCode  PetscOptionsHasName(const char pre[],const char name[],PetscBool  *set)
1429: {
1430:   char           *value;
1432:   PetscBool      flag;

1435:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1436:   if (set) *set = flag;
1437:   return(0);
1438: }

1442: /*@C
1443:    PetscOptionsGetInt - Gets the integer value for a particular option in the database.

1445:    Not Collective

1447:    Input Parameters:
1448: +  pre - the string to prepend to the name or NULL
1449: -  name - the option one is seeking

1451:    Output Parameter:
1452: +  ivalue - the integer value to return
1453: -  set - PETSC_TRUE if found, else PETSC_FALSE

1455:    Level: beginner

1457:    Concepts: options database^has int

1459: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1460:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1461:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1462:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1463:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1464:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1465:           PetscOptionsFList(), PetscOptionsEList()
1466: @*/
1467: PetscErrorCode  PetscOptionsGetInt(const char pre[],const char name[],PetscInt *ivalue,PetscBool  *set)
1468: {
1469:   char           *value;
1471:   PetscBool      flag;

1476:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1477:   if (flag) {
1478:     if (!value) {
1479:       if (set) *set = PETSC_FALSE;
1480:     } else {
1481:       if (set) *set = PETSC_TRUE;
1482:       PetscOptionsStringToInt(value,ivalue);
1483:     }
1484:   } else {
1485:     if (set) *set = PETSC_FALSE;
1486:   }
1487:   return(0);
1488: }

1492: /*@C
1493:      PetscOptionsGetEList - Puts a list of option values that a single one may be selected from

1495:    Not Collective

1497:    Input Parameters:
1498: +  pre - the string to prepend to the name or NULL
1499: .  opt - option name
1500: .  list - the possible choices (one of these must be selected, anything else is invalid)
1501: .  ntext - number of choices

1503:    Output Parameter:
1504: +  value - the index of the value to return (defaults to zero if the option name is given but choice is listed)
1505: -  set - PETSC_TRUE if found, else PETSC_FALSE

1507:    Level: intermediate

1509:    See PetscOptionsFList() for when the choices are given in a PetscFunctionList()

1511:    Concepts: options database^list

1513: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1514:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1515:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1516:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1517:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1518:           PetscOptionsFList(), PetscOptionsEList()
1519: @*/
1520: PetscErrorCode  PetscOptionsGetEList(const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool  *set)
1521: {
1523:   size_t         alen,len = 0;
1524:   char           *svalue;
1525:   PetscBool      aset,flg = PETSC_FALSE;
1526:   PetscInt       i;

1529:   for (i=0; i<ntext; i++) {
1530:     PetscStrlen(list[i],&alen);
1531:     if (alen > len) len = alen;
1532:   }
1533:   len += 5; /* a little extra space for user mistypes */
1534:   PetscMalloc1(len,&svalue);
1535:   PetscOptionsGetString(pre,opt,svalue,len,&aset);
1536:   if (aset) {
1537:     PetscEListFind(ntext,list,svalue,value,&flg);
1538:     if (!flg) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre ? pre : "",opt+1);
1539:     if (set) *set = PETSC_TRUE;
1540:   } else if (set) *set = PETSC_FALSE;
1541:   PetscFree(svalue);
1542:   return(0);
1543: }

1547: /*@C
1548:    PetscOptionsGetEnum - Gets the enum value for a particular option in the database.

1550:    Not Collective

1552:    Input Parameters:
1553: +  pre - option prefix or NULL
1554: .  opt - option name
1555: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
1556: -  defaultv - the default (current) value

1558:    Output Parameter:
1559: +  value - the  value to return
1560: -  set - PETSC_TRUE if found, else PETSC_FALSE

1562:    Level: beginner

1564:    Concepts: options database

1566:    Notes: Must be between a PetscOptionsBegin() and a PetscOptionsEnd()

1568:           list is usually something like PCASMTypes or some other predefined list of enum names

1570: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1571:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
1572:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
1573:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1574:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1575:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1576:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
1577: @*/
1578: PetscErrorCode  PetscOptionsGetEnum(const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool  *set)
1579: {
1581:   PetscInt       ntext = 0,tval;
1582:   PetscBool      fset;

1585:   while (list[ntext++]) {
1586:     if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
1587:   }
1588:   if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1589:   ntext -= 3;
1590:   PetscOptionsGetEList(pre,opt,list,ntext,&tval,&fset);
1591:   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
1592:   if (fset) *value = (PetscEnum)tval;
1593:   if (set) *set = fset;
1594:   return(0);
1595: }

1599: /*@C
1600:    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
1601:             option in the database.

1603:    Not Collective

1605:    Input Parameters:
1606: +  pre - the string to prepend to the name or NULL
1607: -  name - the option one is seeking

1609:    Output Parameter:
1610: +  ivalue - the logical value to return
1611: -  set - PETSC_TRUE  if found, else PETSC_FALSE

1613:    Level: beginner

1615:    Notes:
1616:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1617:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

1619:        If the user does not supply the option (as either true or false) ivalue is NOT changed. Thus
1620:      you NEED TO ALWAYS initialize the ivalue.

1622:    Concepts: options database^has logical

1624: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1625:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(),
1626:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1627:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1628:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1629:           PetscOptionsFList(), PetscOptionsEList()
1630: @*/
1631: PetscErrorCode  PetscOptionsGetBool(const char pre[],const char name[],PetscBool  *ivalue,PetscBool  *set)
1632: {
1633:   char           *value;
1634:   PetscBool      flag;

1640:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1641:   if (flag) {
1642:     if (set) *set = PETSC_TRUE;
1643:     if (!value) *ivalue = PETSC_TRUE;
1644:     else {
1645:       PetscOptionsStringToBool(value, ivalue);
1646:     }
1647:   } else {
1648:     if (set) *set = PETSC_FALSE;
1649:   }
1650:   return(0);
1651: }

1655: /*@C
1656:    PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular
1657:    option in the database.  The values must be separated with commas with
1658:    no intervening spaces.

1660:    Not Collective

1662:    Input Parameters:
1663: +  pre - string to prepend to each name or NULL
1664: .  name - the option one is seeking
1665: -  nmax - maximum number of values to retrieve

1667:    Output Parameter:
1668: +  dvalue - the integer values to return
1669: .  nmax - actual number of values retreived
1670: -  set - PETSC_TRUE if found, else PETSC_FALSE

1672:    Level: beginner

1674:    Concepts: options database^array of ints

1676:    Notes:
1677:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1678:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

1680: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1681:            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1682:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1683:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1684:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1685:           PetscOptionsFList(), PetscOptionsEList()
1686: @*/
1687: PetscErrorCode  PetscOptionsGetBoolArray(const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool  *set)
1688: {
1689:   char           *value;
1691:   PetscInt       n = 0;
1692:   PetscBool      flag;
1693:   PetscToken     token;

1698:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1699:   if (!flag)  {if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
1700:   if (!value) {if (set) *set = PETSC_TRUE;  *nmax = 0; return(0);}

1702:   if (set) *set = PETSC_TRUE;

1704:   PetscTokenCreate(value,',',&token);
1705:   PetscTokenFind(token,&value);
1706:   while (n < *nmax) {
1707:     if (!value) break;
1708:     PetscOptionsStringToBool(value,dvalue);
1709:     PetscTokenFind(token,&value);
1710:     dvalue++;
1711:     n++;
1712:   }
1713:   PetscTokenDestroy(&token);
1714:   *nmax = n;
1715:   return(0);
1716: }

1720: /*@C
1721:    PetscOptionsGetReal - Gets the double precision value for a particular
1722:    option in the database.

1724:    Not Collective

1726:    Input Parameters:
1727: +  pre - string to prepend to each name or NULL
1728: -  name - the option one is seeking

1730:    Output Parameter:
1731: +  dvalue - the double value to return
1732: -  set - PETSC_TRUE if found, PETSC_FALSE if not found

1734:    Note: if the option is given but no value is provided then set is given the value PETSC_FALSE

1736:    Level: beginner

1738:    Concepts: options database^has double

1740: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1741:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(),
1742:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1743:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1744:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1745:           PetscOptionsFList(), PetscOptionsEList()
1746: @*/
1747: PetscErrorCode  PetscOptionsGetReal(const char pre[],const char name[],PetscReal *dvalue,PetscBool  *set)
1748: {
1749:   char           *value;
1751:   PetscBool      flag;

1756:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1757:   if (flag) {
1758:     if (!value) {
1759:       if (set) *set = PETSC_FALSE;
1760:     } else {
1761:       if (set) *set = PETSC_TRUE;
1762:       PetscOptionsStringToReal(value,dvalue);
1763:     }
1764:   } else {
1765:     if (set) *set = PETSC_FALSE;
1766:   }
1767:   return(0);
1768: }

1772: /*@C
1773:    PetscOptionsGetScalar - Gets the scalar value for a particular
1774:    option in the database.

1776:    Not Collective

1778:    Input Parameters:
1779: +  pre - string to prepend to each name or NULL
1780: -  name - the option one is seeking

1782:    Output Parameter:
1783: +  dvalue - the double value to return
1784: -  set - PETSC_TRUE if found, else PETSC_FALSE

1786:    Level: beginner

1788:    Usage:
1789:    A complex number 2+3i must be specified with NO spaces

1791:    Note: if the option is given but no value is provided then set is given the value PETSC_FALSE

1793:    Concepts: options database^has scalar

1795: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1796:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1797:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1798:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1799:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1800:           PetscOptionsFList(), PetscOptionsEList()
1801: @*/
1802: PetscErrorCode  PetscOptionsGetScalar(const char pre[],const char name[],PetscScalar *dvalue,PetscBool  *set)
1803: {
1804:   char           *value;
1805:   PetscBool      flag;

1811:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1812:   if (flag) {
1813:     if (!value) {
1814:       if (set) *set = PETSC_FALSE;
1815:     } else {
1816: #if !defined(PETSC_USE_COMPLEX)
1817:       PetscOptionsStringToReal(value,dvalue);
1818: #else
1819:       PetscOptionsStringToScalar(value,dvalue);
1820: #endif
1821:       if (set) *set = PETSC_TRUE;
1822:     }
1823:   } else { /* flag */
1824:     if (set) *set = PETSC_FALSE;
1825:   }
1826:   return(0);
1827: }

1831: /*@C
1832:    PetscOptionsGetRealArray - Gets an array of double precision values for a
1833:    particular option in the database.  The values must be separated with
1834:    commas with no intervening spaces.

1836:    Not Collective

1838:    Input Parameters:
1839: +  pre - string to prepend to each name or NULL
1840: .  name - the option one is seeking
1841: -  nmax - maximum number of values to retrieve

1843:    Output Parameters:
1844: +  dvalue - the double values to return
1845: .  nmax - actual number of values retreived
1846: -  set - PETSC_TRUE if found, else PETSC_FALSE

1848:    Level: beginner

1850:    Concepts: options database^array of doubles

1852: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1853:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
1854:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1855:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1856:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1857:           PetscOptionsFList(), PetscOptionsEList()
1858: @*/
1859: PetscErrorCode  PetscOptionsGetRealArray(const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool  *set)
1860: {
1861:   char           *value;
1863:   PetscInt       n = 0;
1864:   PetscBool      flag;
1865:   PetscToken     token;

1870:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1871:   if (!flag) {
1872:     if (set) *set = PETSC_FALSE;
1873:     *nmax = 0;
1874:     return(0);
1875:   }
1876:   if (!value) {
1877:     if (set) *set = PETSC_TRUE;
1878:     *nmax = 0;
1879:     return(0);
1880:   }

1882:   if (set) *set = PETSC_TRUE;

1884:   PetscTokenCreate(value,',',&token);
1885:   PetscTokenFind(token,&value);
1886:   while (n < *nmax) {
1887:     if (!value) break;
1888:     PetscOptionsStringToReal(value,dvalue++);
1889:     PetscTokenFind(token,&value);
1890:     n++;
1891:   }
1892:   PetscTokenDestroy(&token);
1893:   *nmax = n;
1894:   return(0);
1895: }

1899: /*@C
1900:    PetscOptionsGetScalarArray - Gets an array of scalars for a
1901:    particular option in the database.  The values must be separated with
1902:    commas with no intervening spaces.

1904:    Not Collective

1906:    Input Parameters:
1907: +  pre - string to prepend to each name or NULL
1908: .  name - the option one is seeking
1909: -  nmax - maximum number of values to retrieve

1911:    Output Parameters:
1912: +  dvalue - the scalar values to return
1913: .  nmax - actual number of values retreived
1914: -  set - PETSC_TRUE if found, else PETSC_FALSE

1916:    Level: beginner

1918:    Concepts: options database^array of doubles

1920: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1921:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
1922:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1923:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1924:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1925:           PetscOptionsFList(), PetscOptionsEList()
1926: @*/
1927: PetscErrorCode  PetscOptionsGetScalarArray(const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool  *set)
1928: {
1929:   char           *value;
1931:   PetscInt       n = 0;
1932:   PetscBool      flag;
1933:   PetscToken     token;

1938:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1939:   if (!flag) {
1940:     if (set) *set = PETSC_FALSE;
1941:     *nmax = 0;
1942:     return(0);
1943:   }
1944:   if (!value) {
1945:     if (set) *set = PETSC_TRUE;
1946:     *nmax = 0;
1947:     return(0);
1948:   }

1950:   if (set) *set = PETSC_TRUE;

1952:   PetscTokenCreate(value,',',&token);
1953:   PetscTokenFind(token,&value);
1954:   while (n < *nmax) {
1955:     if (!value) break;
1956:     PetscOptionsStringToScalar(value,dvalue++);
1957:     PetscTokenFind(token,&value);
1958:     n++;
1959:   }
1960:   PetscTokenDestroy(&token);
1961:   *nmax = n;
1962:   return(0);
1963: }

1967: /*@C
1968:    PetscOptionsGetIntArray - Gets an array of integer values for a particular
1969:    option in the database.

1971:    Not Collective

1973:    Input Parameters:
1974: +  pre - string to prepend to each name or NULL
1975: .  name - the option one is seeking
1976: -  nmax - maximum number of values to retrieve

1978:    Output Parameter:
1979: +  dvalue - the integer values to return
1980: .  nmax - actual number of values retreived
1981: -  set - PETSC_TRUE if found, else PETSC_FALSE

1983:    Level: beginner

1985:    Notes:
1986:    The array can be passed as
1987:    a comma seperated list:                                 0,1,2,3,4,5,6,7
1988:    a range (start-end+1):                                  0-8
1989:    a range with given increment (start-end+1:inc):         0-7:2
1990:    a combination of values and ranges seperated by commas: 0,1-8,8-15:2

1992:    There must be no intervening spaces between the values.

1994:    Concepts: options database^array of ints

1996: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(),
1997:            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1998:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1999:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2000:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2001:           PetscOptionsFList(), PetscOptionsEList()
2002: @*/
2003: PetscErrorCode  PetscOptionsGetIntArray(const char pre[],const char name[],PetscInt dvalue[],PetscInt *nmax,PetscBool  *set)
2004: {
2005:   char           *value;
2007:   PetscInt       n = 0,i,j,start,end,inc,nvalues;
2008:   size_t         len;
2009:   PetscBool      flag,foundrange;
2010:   PetscToken     token;

2015:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
2016:   if (!flag) {
2017:     if (set) *set = PETSC_FALSE;
2018:     *nmax = 0;
2019:     return(0);
2020:   }
2021:   if (!value) {
2022:     if (set) *set = PETSC_TRUE;
2023:     *nmax = 0;
2024:     return(0);
2025:   }

2027:   if (set) *set = PETSC_TRUE;

2029:   PetscTokenCreate(value,',',&token);
2030:   PetscTokenFind(token,&value);
2031:   while (n < *nmax) {
2032:     if (!value) break;

2034:     /* look for form  d-D where d and D are integers */
2035:     foundrange = PETSC_FALSE;
2036:     PetscStrlen(value,&len);
2037:     if (value[0] == '-') i=2;
2038:     else i=1;
2039:     for (;i<(int)len; i++) {
2040:       if (value[i] == '-') {
2041:         if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
2042:         value[i] = 0;

2044:         PetscOptionsStringToInt(value,&start);
2045:         inc  = 1;
2046:         j    = i+1;
2047:         for (;j<(int)len; j++) {
2048:           if (value[j] == ':') {
2049:             value[j] = 0;

2051:             PetscOptionsStringToInt(value+j+1,&inc);
2052:             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);
2053:             break;
2054:           }
2055:         }
2056:         PetscOptionsStringToInt(value+i+1,&end);
2057:         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);
2058:         nvalues = (end-start)/inc + (end-start)%inc;
2059:         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);
2060:         for (;start<end; start+=inc) {
2061:           *dvalue = start; dvalue++;n++;
2062:         }
2063:         foundrange = PETSC_TRUE;
2064:         break;
2065:       }
2066:     }
2067:     if (!foundrange) {
2068:       PetscOptionsStringToInt(value,dvalue);
2069:       dvalue++;
2070:       n++;
2071:     }
2072:     PetscTokenFind(token,&value);
2073:   }
2074:   PetscTokenDestroy(&token);
2075:   *nmax = n;
2076:   return(0);
2077: }

2081: /*@C
2082:    PetscOptionsGetString - Gets the string value for a particular option in
2083:    the database.

2085:    Not Collective

2087:    Input Parameters:
2088: +  pre - string to prepend to name or NULL
2089: .  name - the option one is seeking
2090: -  len - maximum length of the string including null termination

2092:    Output Parameters:
2093: +  string - location to copy string
2094: -  set - PETSC_TRUE if found, else PETSC_FALSE

2096:    Level: beginner

2098:    Fortran Note:
2099:    The Fortran interface is slightly different from the C/C++
2100:    interface (len is not used).  Sample usage in Fortran follows
2101: .vb
2102:       character *20 string
2103:       integer   flg, ierr
2104:       call PetscOptionsGetString(NULL_CHARACTER,'-s',string,flg,ierr)
2105: .ve

2107:    Notes: 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

2109:    Concepts: options database^string

2111:     Note:
2112:       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).

2114: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2115:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2116:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2117:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2118:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2119:           PetscOptionsFList(), PetscOptionsEList()
2120: @*/
2121: PetscErrorCode  PetscOptionsGetString(const char pre[],const char name[],char string[],size_t len,PetscBool  *set)
2122: {
2123:   char           *value;
2125:   PetscBool      flag;

2130:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
2131:   if (!flag) {
2132:     if (set) *set = PETSC_FALSE;
2133:   } else {
2134:     if (set) *set = PETSC_TRUE;
2135:     if (value) {
2136:       PetscStrncpy(string,value,len);
2137:       string[len-1] = 0;        /* Ensure that the string is NULL terminated */
2138:     } else {
2139:       PetscMemzero(string,len);
2140:     }
2141:   }
2142:   return(0);
2143: }

2147: char *PetscOptionsGetStringMatlab(const char pre[],const char name[])
2148: {
2149:   char           *value;
2151:   PetscBool      flag;

2154:   PetscOptionsFindPair_Private(pre,name,&value,&flag);if (ierr) return(0);
2155:   if (flag) PetscFunctionReturn(value);
2156:   else return(0);
2157: }


2162: /*@C
2163:    PetscOptionsGetStringArray - Gets an array of string values for a particular
2164:    option in the database. The values must be separated with commas with
2165:    no intervening spaces.

2167:    Not Collective

2169:    Input Parameters:
2170: +  pre - string to prepend to name or NULL
2171: .  name - the option one is seeking
2172: -  nmax - maximum number of strings

2174:    Output Parameter:
2175: +  strings - location to copy strings
2176: -  set - PETSC_TRUE if found, else PETSC_FALSE

2178:    Level: beginner

2180:    Notes:
2181:    The user should pass in an array of pointers to char, to hold all the
2182:    strings returned by this function.

2184:    The user is responsible for deallocating the strings that are
2185:    returned. The Fortran interface for this routine is not supported.

2187:    Contributed by Matthew Knepley.

2189:    Concepts: options database^array of strings

2191: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2192:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2193:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2194:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2195:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2196:           PetscOptionsFList(), PetscOptionsEList()
2197: @*/
2198: PetscErrorCode  PetscOptionsGetStringArray(const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool  *set)
2199: {
2200:   char           *value;
2202:   PetscInt       n;
2203:   PetscBool      flag;
2204:   PetscToken     token;

2209:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
2210:   if (!flag) {
2211:     *nmax = 0;
2212:     if (set) *set = PETSC_FALSE;
2213:     return(0);
2214:   }
2215:   if (!value) {
2216:     *nmax = 0;
2217:     if (set) *set = PETSC_FALSE;
2218:     return(0);
2219:   }
2220:   if (!*nmax) {
2221:     if (set) *set = PETSC_FALSE;
2222:     return(0);
2223:   }
2224:   if (set) *set = PETSC_TRUE;

2226:   PetscTokenCreate(value,',',&token);
2227:   PetscTokenFind(token,&value);
2228:   n    = 0;
2229:   while (n < *nmax) {
2230:     if (!value) break;
2231:     PetscStrallocpy(value,&strings[n]);
2232:     PetscTokenFind(token,&value);
2233:     n++;
2234:   }
2235:   PetscTokenDestroy(&token);
2236:   *nmax = n;
2237:   return(0);
2238: }

2242: /*@C
2243:    PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database

2245:    Not Collective

2247:    Input Parameter:
2248: .    option - string name of option

2250:    Output Parameter:
2251: .   used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database

2253:    Level: advanced

2255: .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
2256: @*/
2257: PetscErrorCode  PetscOptionsUsed(const char *option,PetscBool *used)
2258: {
2259:   PetscInt       i;

2263:   *used = PETSC_FALSE;
2264:   for (i=0; i<options->N; i++) {
2265:     PetscStrcmp(options->names[i],option,used);
2266:     if (*used) {
2267:       *used = options->used[i];
2268:       break;
2269:     }
2270:   }
2271:   return(0);
2272: }

2276: /*@C
2277:    PetscOptionsAllUsed - Returns a count of the number of options in the
2278:    database that have never been selected.

2280:    Not Collective

2282:    Output Parameter:
2283: .   N - count of options not used

2285:    Level: advanced

2287: .seealso: PetscOptionsView()
2288: @*/
2289: PetscErrorCode  PetscOptionsAllUsed(PetscInt *N)
2290: {
2291:   PetscInt i,n = 0;

2294:   for (i=0; i<options->N; i++) {
2295:     if (!options->used[i]) n++;
2296:   }
2297:   *N = n;
2298:   return(0);
2299: }

2303: /*@
2304:     PetscOptionsLeft - Prints to screen any options that were set and never used.

2306:   Not collective

2308:    Options Database Key:
2309: .  -options_left - Activates OptionsAllUsed() within PetscFinalize()

2311:   Level: advanced

2313: .seealso: PetscOptionsAllUsed()
2314: @*/
2315: PetscErrorCode  PetscOptionsLeft(void)
2316: {
2318:   PetscInt       i;

2321:   for (i=0; i<options->N; i++) {
2322:     if (!options->used[i]) {
2323:       if (options->values[i]) {
2324:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",options->names[i],options->values[i]);
2325:       } else {
2326:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",options->names[i]);
2327:       }
2328:     }
2329:   }
2330:   return(0);
2331: }


2336: /*
2337:     PetscOptionsCreate - Creates the empty options database.

2339: */
2340: PetscErrorCode  PetscOptionsCreate(void)
2341: {

2345:   options = (PetscOptionsTable*)malloc(sizeof(PetscOptionsTable));
2346:   PetscMemzero(options,sizeof(PetscOptionsTable));

2348:   options->namegiven      = PETSC_FALSE;
2349:   options->N              = 0;
2350:   options->Naliases       = 0;
2351:   options->numbermonitors = 0;

2353:   return(0);
2354: }

2358: /*@
2359:    PetscOptionsSetFromOptions - Sets options related to the handling of options in PETSc

2361:    Collective on PETSC_COMM_WORLD

2363:    Options Database Keys:
2364: +  -options_monitor <optional filename> - prints the names and values of all runtime options as they are set. The monitor functionality is not
2365:                 available for options set through a file, environment variable, or on
2366:                 the command line. Only options set after PetscInitialize() completes will
2367:                 be monitored.
2368: .  -options_monitor_cancel - cancel all options database monitors

2370:    Notes:
2371:    To see all options, run your program with the -help option or consult Users-Manual: Introduction

2373:    Level: intermediate

2375: .keywords: set, options, database
2376: @*/
2377: PetscErrorCode  PetscOptionsSetFromOptions(void)
2378: {
2379:   PetscBool      flgc = PETSC_FALSE,flgm;
2381:   char           monfilename[PETSC_MAX_PATH_LEN];
2382:   PetscViewer    monviewer;

2385:   PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for handling options","PetscOptions");
2386:   PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);
2387:   PetscOptionsBool("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",flgc,&flgc,NULL);
2388:   PetscOptionsEnd();
2389:   if (flgm) {
2390:     PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);
2391:     PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
2392:   }
2393:   if (flgc) { PetscOptionsMonitorCancel(); }
2394:   return(0);
2395: }


2400: /*@C
2401:    PetscOptionsMonitorDefault - Print all options set value events.

2403:    Logically Collective on PETSC_COMM_WORLD

2405:    Input Parameters:
2406: +  name  - option name string
2407: .  value - option value string
2408: -  dummy - unused monitor context

2410:    Level: intermediate

2412: .keywords: PetscOptions, default, monitor

2414: .seealso: PetscOptionsMonitorSet()
2415: @*/
2416: PetscErrorCode  PetscOptionsMonitorDefault(const char name[], const char value[], void *dummy)
2417: {
2419:   PetscViewer    viewer = (PetscViewer) dummy;

2422:   if (!viewer) {
2423:     PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);
2424:   }
2425:   PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
2426:   return(0);
2427: }

2431: /*@C
2432:    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
2433:    modified the PETSc options database.

2435:    Not collective

2437:    Input Parameters:
2438: +  monitor - pointer to function (if this is NULL, it turns off monitoring
2439: .  mctx    - [optional] context for private data for the
2440:              monitor routine (use NULL if no context is desired)
2441: -  monitordestroy - [optional] routine that frees monitor context
2442:           (may be NULL)

2444:    Calling Sequence of monitor:
2445: $     monitor (const char name[], const char value[], void *mctx)

2447: +  name - option name string
2448: .  value - option value string
2449: -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()

2451:    Options Database Keys:
2452: +    -options_monitor    - sets PetscOptionsMonitorDefault()
2453: -    -options_monitor_cancel - cancels all monitors that have
2454:                           been hardwired into a code by
2455:                           calls to PetscOptionsMonitorSet(), but
2456:                           does not cancel those set via
2457:                           the options database.

2459:    Notes:
2460:    The default is to do nothing.  To print the name and value of options
2461:    being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine,
2462:    with a null monitoring context.

2464:    Several different monitoring routines may be set by calling
2465:    PetscOptionsMonitorSet() multiple times; all will be called in the
2466:    order in which they were set.

2468:    Level: beginner

2470: .keywords: PetscOptions, set, monitor

2472: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
2473: @*/
2474: PetscErrorCode  PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
2475: {
2477:   if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
2478:   options->monitor[options->numbermonitors]          = monitor;
2479:   options->monitordestroy[options->numbermonitors]   = monitordestroy;
2480:   options->monitorcontext[options->numbermonitors++] = (void*)mctx;
2481:   return(0);
2482: }

2486: /*@
2487:    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.

2489:    Not collective

2491:    Options Database Key:
2492: .  -options_monitor_cancel - Cancels all monitors that have
2493:     been hardwired into a code by calls to PetscOptionsMonitorSet(),
2494:     but does not cancel those set via the options database.

2496:    Level: intermediate

2498: .keywords: PetscOptions, set, monitor

2500: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
2501: @*/
2502: PetscErrorCode  PetscOptionsMonitorCancel(void)
2503: {
2505:   PetscInt       i;

2508:   for (i=0; i<options->numbermonitors; i++) {
2509:     if (options->monitordestroy[i]) {
2510:       (*options->monitordestroy[i])(&options->monitorcontext[i]);
2511:     }
2512:   }
2513:   options->numbermonitors = 0;
2514:   return(0);
2515: }

2517: #define CHKERRQI(incall,ierr) if (ierr) {incall = PETSC_FALSE; }

2521: /*@C
2522:   PetscObjectViewFromOptions - Processes command line options to determine if/how a PetscObject is to be viewed. 

2524:   Collective on PetscObject

2526:   Input Parameters:
2527: + obj   - the object
2528: . prefix - prefix to use for viewing, or NULL to use the prefix of obj
2529: - optionname - option to activate viewing

2531:   Level: intermediate

2533: @*/
2534: PetscErrorCode PetscObjectViewFromOptions(PetscObject obj,const char prefix[],const char optionname[])
2535: {
2536:   PetscErrorCode    ierr;
2537:   PetscViewer       viewer;
2538:   PetscBool         flg;
2539:   static PetscBool  incall = PETSC_FALSE;
2540:   PetscViewerFormat format;

2543:   if (incall) return(0);
2544:   incall = PETSC_TRUE;
2545:   if (!prefix) prefix = ((PetscObject)obj)->prefix;
2546:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj),prefix,optionname,&viewer,&format,&flg);CHKERRQI(incall,ierr);
2547:   if (flg) {
2548:     PetscViewerPushFormat(viewer,format);CHKERRQI(incall,ierr);
2549:     PetscObjectView(obj,viewer);CHKERRQI(incall,ierr);
2550:     PetscViewerPopFormat(viewer);CHKERRQI(incall,ierr);
2551:     PetscViewerDestroy(&viewer);CHKERRQI(incall,ierr);
2552:   }
2553:   incall = PETSC_FALSE;
2554:   return(0);
2555: }