Actual source code: options.c

  1: #define PETSC_DLL
  2: /*
  3:    These routines simplify the use of command line, file options, etc.,
  4:    and are used to manipulate the options database.

  6:   This file uses regular malloc and free because it cannot know 
  7:   what malloc is being used until it has already processed the input.
  8: */

 10:  #include petsc.h
 11:  #include petscsys.h
 12: #if defined(PETSC_HAVE_STDLIB_H)
 13: #include <stdlib.h>
 14: #endif
 15: #if defined(PETSC_HAVE_MALLOC_H)
 16: #include <malloc.h>
 17: #endif
 18: #if defined(PETSC_HAVE_SYS_PARAM_H)
 19: #include "sys/param.h"
 20: #endif
 21: #include "petscfix.h"

 23: /* 
 24:     For simplicity, we use a static size database
 25: */
 26: #define MAXOPTIONS 512
 27: #define MAXALIASES 25
 28: #define MAXOPTIONSMONITORS 5

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

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

 44: } PetscOptionsTable;


 47: static PetscOptionsTable *options = 0;


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

 63: PetscErrorCode  PetscOptionsAtoi(const char name[],PetscInt *a)
 64: {
 66:   size_t         i,len;
 67:   PetscTruth     decide,tdefault,mouse;

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

 73:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
 74:   if (!tdefault) {
 75:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
 76:   }
 77:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
 78:   if (!decide) {
 79:     PetscStrcasecmp(name,"DECIDE",&decide);
 80:   }
 81:   PetscStrcasecmp(name,"mouse",&mouse);

 83:   if (tdefault) {
 84:     *a = PETSC_DEFAULT;
 85:   } else if (decide) {
 86:     *a = PETSC_DECIDE;
 87:   } else if (mouse) {
 88:     *a = -1;
 89:   } else {
 90:     if (name[0] != '+' && name[0] != '-' && name[0] < '0' && name[0] > '9') {
 91:       SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);
 92:     }
 93:     for (i=1; i<len; i++) {
 94:       if (name[i] < '0' || name[i] > '9') {
 95:         SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name);
 96:       }
 97:     }
 98:     *a  = atoi(name);
 99:   }
100:   return(0);
101: }

105: PetscErrorCode  PetscOptionsAtod(const char name[],PetscReal *a)
106: {
108:   size_t         len;
109:   PetscTruth     decide,tdefault;

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

115:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
116:   if (!tdefault) {
117:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
118:   }
119:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
120:   if (!decide) {
121:     PetscStrcasecmp(name,"DECIDE",&decide);
122:   }

124:   if (tdefault) {
125:     *a = PETSC_DEFAULT;
126:   } else if (decide) {
127:     *a = PETSC_DECIDE;
128:   } else {
129:     if (name[0] != '+' && name[0] != '-' && name[0] != '.' && name[0] < '0' && name[0] > '9') {
130:       SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name);
131:     }
132:     *a  = atof(name);
133:   }
134:   return(0);
135: }

139: /*@C
140:     PetscGetProgramName - Gets the name of the running program. 

142:     Not Collective

144:     Input Parameter:
145: .   len - length of the string name

147:     Output Parameter:
148: .   name - the name of the running program

150:    Level: advanced

152:     Notes:
153:     The name of the program is copied into the user-provided character
154:     array of length len.  On some machines the program name includes 
155:     its entire path, so one should generally set len >= PETSC_MAX_PATH_LEN.
156: @*/
157: PetscErrorCode  PetscGetProgramName(char name[],size_t len)
158: {

162:   if (!options) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call PetscInitialize() first");
163:   if (!options->namegiven) SETERRQ(PETSC_ERR_PLIB,"Unable to determine program name");
164:   PetscStrncpy(name,options->programname,len);
165:   return(0);
166: }

170: PetscErrorCode  PetscSetProgramName(const char name[])
171: {

175:   options->namegiven = PETSC_TRUE;
176:   PetscStrncpy(options->programname,name,PETSC_MAX_PATH_LEN);
177:   return(0);
178: }

182: PetscErrorCode  PetscOptionsValidKey(const char in_str[],PetscTruth *key)
183: {
185:   *key = PETSC_FALSE;
186:   if (!in_str) return(0);
187:   if (in_str[0] != '-') return(0);
188:   if ((in_str[1] < 'A') || (in_str[1] > 'z')) return(0);
189:   *key = PETSC_TRUE;
190:   return(0);
191: }

195: /*@C
196:      PetscOptionsInsertString - Inserts options into the database from a string

198:      Not collective: but only processes that call this routine will set the options
199:                      included in the file

201:   Input Parameter:
202: .   in_str - string that contains options separated by blanks


205:   Level: intermediate

207:   Contributed by Boyana Norris

209: .seealso: PetscOptionsSetValue(), PetscOptionsPrint(), PetscOptionsHasName(), PetscOptionsGetInt(),
210:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsTruth(),
211:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
212:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
213:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
214:           PetscOptionsList(), PetscOptionsEList(), PetscOptionsInsertFile()

216: @*/
217: PetscErrorCode  PetscOptionsInsertString(const char in_str[])
218: {
219:   char           *first,*second;
221:   PetscToken     token;
222:   PetscTruth     key;

225:   PetscTokenCreate(in_str,' ',&token);
226:   PetscTokenFind(token,&first);
227:   while (first) {
228:     PetscOptionsValidKey(first,&key);
229:     if (key) {
230:       PetscTokenFind(token,&second);
231:       PetscOptionsValidKey(second,&key);
232:       if (!key) {
233:         PetscOptionsSetValue(first,second);
234:         PetscTokenFind(token,&first);
235:       } else {
236:         PetscOptionsSetValue(first,PETSC_NULL);
237:         first = second;
238:       }
239:     } else {
240:       PetscTokenFind(token,&first);
241:     }
242:   }
243:   PetscTokenDestroy(token);
244:   return(0);
245: }

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

252:      Not collective: but only processes that call this routine will set the options
253:                      included in the file

255:   Input Parameter:
256: .   file - name of file


259:   Level: intermediate

261: .seealso: PetscOptionsSetValue(), PetscOptionsPrint(), PetscOptionsHasName(), PetscOptionsGetInt(),
262:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsTruth(),
263:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
264:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
265:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
266:           PetscOptionsList(), PetscOptionsEList()

268: @*/
269: PetscErrorCode  PetscOptionsInsertFile(const char file[])
270: {
271:   char           string[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN],*first,*second,*third,*final;
273:   size_t         i,len,startIndex;
274:   FILE           *fd;
275:   PetscToken     token;
276:   int            err;

279:   PetscFixFilename(file,fname);
280:   fd   = fopen(fname,"r");
281:   if (fd) {
282:     while (fgets(string,128,fd)) {
283:       /* Comments are indicated by #, ! or % in the first column */
284:       if (string[0] == '#') continue;
285:       if (string[0] == '!') continue;
286:       if (string[0] == '%') continue;

288:       PetscStrlen(string,&len);

290:       /* replace tabs, ^M with " " */
291:       for (i=0; i<len; i++) {
292:         if (string[i] == '\t' || string[i] == '\r') {
293:           string[i] = ' ';
294:         }
295:       }
296:       for(startIndex = 0; startIndex < len-1; startIndex++) {
297:         if (string[startIndex] != ' ') break;
298:       }
299:       PetscTokenCreate(&string[startIndex],' ',&token);
300:       PetscTokenFind(token,&first);
301:       PetscTokenFind(token,&second);
302:       if (first && first[0] == '-') {
303:         if (second) {final = second;} else {final = first;}
304:         PetscStrlen(final,&len);
305:         while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) {
306:           len--; final[len] = 0;
307:         }
308:         PetscOptionsSetValue(first,second);
309:       } else if (first) {
310:         PetscTruth match;

312:         PetscStrcasecmp(first,"alias",&match);
313:         if (match) {
314:           PetscTokenFind(token,&third);
315:           if (!third) SETERRQ1(PETSC_ERR_ARG_WRONG,"Error in options file:alias missing (%s)",second);
316:           PetscStrlen(third,&len);
317:           if (third[len-1] == '\n') third[len-1] = 0;
318:           PetscOptionsSetAlias(second,third);
319:         }
320:       }
321:       PetscTokenDestroy(token);
322:     }
323:     err = fclose(fd);
324:     if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
325:   } else {
326:     SETERRQ1(PETSC_ERR_USER,"Unable to open Options File %s",fname);
327:   }
328:   return(0);
329: }

333: /*@C
334:    PetscOptionsInsert - Inserts into the options database from the command line,
335:                    the environmental variable and a file.

337:    Input Parameters:
338: +  argc - count of number of command line arguments
339: .  args - the command line arguments
340: -  file - optional filename, defaults to ~username/.petscrc

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

347:    Options Database Keys:
348: +   -options_monitor <optional filename> - print options names and values as they are set

350:    Level: advanced

352:    Concepts: options database^adding

354: .seealso: PetscOptionsDestroy_Private(), PetscOptionsPrint(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
355:           PetscInitialize()
356: @*/
357: PetscErrorCode  PetscOptionsInsert(int *argc,char ***args,const char file[])
358: {
360:   PetscMPIInt    rank;
361:   char           pfile[PETSC_MAX_PATH_LEN];
362:   PetscTruth     flag;

365:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

367:   options->argc     = (argc) ? *argc : 0;
368:   options->args     = (args) ? *args : PETSC_NULL;

370:   if (file) {
371:     PetscOptionsInsertFile(file);
372:   }
373:   PetscOptionsHasName(PETSC_NULL,"-skip_petscrc",&flag);
374:   if (!flag) {
375:     PetscGetHomeDirectory(pfile,PETSC_MAX_PATH_LEN-16);
376:     if (pfile[0]) {
377:       PetscStrcat(pfile,"/.petscrc");
378:       PetscTestFile(pfile,'r',&flag);
379:       if (flag) {
380:         PetscOptionsInsertFile(pfile);
381:         PetscInfo(0,"Loading ~/.petscrc\n");
382:       }
383:     }
384:     PetscTestFile(".petscrc",'r',&flag);
385:     if (flag) {
386:       PetscOptionsInsertFile(".petscrc");
387:       PetscInfo(0,"Loading local directory file .petscrc\n");
388:     }
389:   }

391:   /* insert environmental options */
392:   {
393:     char   *eoptions = 0;
394:     size_t len = 0;
395:     if (!rank) {
396:       eoptions = (char*)getenv("PETSC_OPTIONS");
397:       PetscStrlen(eoptions,&len);
398:       MPI_Bcast(&len,1,MPI_INT,0,PETSC_COMM_WORLD);
399:     } else {
400:       MPI_Bcast(&len,1,MPI_INT,0,PETSC_COMM_WORLD);
401:       if (len) {
402:         PetscMalloc((len+1)*sizeof(char*),&eoptions);
403:       }
404:     }
405:     if (len) {
406:       MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
407:       if (rank) eoptions[len] = 0;
408:       PetscOptionsInsertString(eoptions);
409:       if (rank) {PetscFree(eoptions);}
410:     }
411:   }

413:   /* insert command line options */
414:   if (argc && args && *argc) {
415:     int        left    = *argc - 1;
416:     char       **eargs = *args + 1;
417:     PetscTruth isoptions_file,isp4,tisp4,isp4yourname,isp4rmrank;

419:     while (left) {
420:       PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);
421:       PetscStrcasecmp(eargs[0],"-p4pg",&isp4);
422:       PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);
423:       PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);
424:       PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);
425:       isp4 = (PetscTruth) (isp4 || tisp4);
426:       PetscStrcasecmp(eargs[0],"-np",&tisp4);
427:       isp4 = (PetscTruth) (isp4 || tisp4);
428:       PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);

430:       if (eargs[0][0] != '-') {
431:         eargs++; left--;
432:       } else if (isoptions_file) {
433:         if (left <= 1) SETERRQ(PETSC_ERR_USER,"Missing filename for -options_file filename option");
434:         if (eargs[1][0] == '-') SETERRQ(PETSC_ERR_USER,"Missing filename for -options_file filename option");
435:         PetscOptionsInsertFile(eargs[1]);
436:         eargs += 2; left -= 2;

438:       /*
439:          These are "bad" options that MPICH, etc put on the command line
440:          we strip them out here.
441:       */
442:       } else if (tisp4 || isp4rmrank) {
443:         eargs += 1; left -= 1;
444:       } else if (isp4 || isp4yourname) {
445:         eargs += 2; left -= 2;
446:       } else if ((left < 2) || ((eargs[1][0] == '-') &&
447:                ((eargs[1][1] > '9') || (eargs[1][1] < '0')))) {
448:         PetscOptionsSetValue(eargs[0],PETSC_NULL);
449:         eargs++; left--;
450:       } else {
451:         PetscOptionsSetValue(eargs[0],eargs[1]);
452:         eargs += 2; left -= 2;
453:       }
454:     }
455:   }
456:   return(0);
457: }

461: /*@C
462:    PetscOptionsPrint - Prints the options that have been loaded. This is
463:    useful for debugging purposes.

465:    Collective on PETSC_COMM_WORLD

467:    Input Parameter:
468: .  FILE fd - location to print options (usually stdout or stderr)

470:    Options Database Key:
471: .  -optionstable - Activates PetscOptionsPrint() within PetscFinalize()

473:    Level: advanced

475:    Concepts: options database^printing

477: .seealso: PetscOptionsAllUsed()
478: @*/
479: PetscErrorCode  PetscOptionsPrint(FILE *fd)
480: {
482:   PetscInt       i;

485:   if (!fd) fd = PETSC_STDOUT;
486:   if (!options) {PetscOptionsInsert(0,0,0);}
487:   for (i=0; i<options->N; i++) {
488:     if (options->values[i]) {
489:       PetscFPrintf(PETSC_COMM_WORLD,fd,"OptionTable: -%s %s\n",options->names[i],options->values[i]);
490:     } else {
491:       PetscFPrintf(PETSC_COMM_WORLD,fd,"OptionTable: -%s\n",options->names[i]);
492:     }
493:   }
494:   return(0);
495: }

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

502:    Not Collective

504:    Output Parameter:
505: .  copts - pointer where string pointer is stored

507:    Level: advanced

509:    Concepts: options database^listing

511: .seealso: PetscOptionsAllUsed(), PetscOptionsPrint()
512: @*/
513: PetscErrorCode  PetscOptionsGetAll(char *copts[])
514: {
516:   PetscInt       i;
517:   size_t         len = 1,lent;
518:   char           *coptions;

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

523:   /* count the length of the required string */
524:   for (i=0; i<options->N; i++) {
525:     PetscStrlen(options->names[i],&lent);
526:     len += 2 + lent;
527:     if (options->values[i]) {
528:       PetscStrlen(options->values[i],&lent);
529:       len += 1 + lent;
530:     }
531:   }
532:   PetscMalloc(len*sizeof(char),&coptions);
533:   coptions[0] = 0;
534:   for (i=0; i<options->N; i++) {
535:     PetscStrcat(coptions,"-");
536:     PetscStrcat(coptions,options->names[i]);
537:     PetscStrcat(coptions," ");
538:     if (options->values[i]) {
539:       PetscStrcat(coptions,options->values[i]);
540:       PetscStrcat(coptions," ");
541:     }
542:   }
543:   *copts = coptions;
544:   return(0);
545: }

549: /*@C
550:     PetscOptionsDestroy - Destroys the option database. 

552:     Note:
553:     Since PetscOptionsDestroy() is called by PetscFinalize(), the user 
554:     typically does not need to call this routine.

556:    Level: developer

558: .seealso: PetscOptionsInsert()
559: @*/
560: PetscErrorCode  PetscOptionsDestroy(void)
561: {
562:   PetscInt i;

565:   if (!options) return(0);
566:   for (i=0; i<options->N; i++) {
567:     if (options->names[i]) free(options->names[i]);
568:     if (options->values[i]) free(options->values[i]);
569:   }
570:   for (i=0; i<options->Naliases; i++) {
571:     free(options->aliases1[i]);
572:     free(options->aliases2[i]);
573:   }
574:   free(options);
575:   options = 0;
576:   return(0);
577: }

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

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

588:    Input Parameters:
589: +  name - name of option, this SHOULD have the - prepended
590: -  value - the option value (not used for all options)

592:    Level: intermediate

594:    Note:
595:    Only some options have values associated with them, such as
596:    -ksp_rtol tol.  Other options stand alone, such as -ksp_monitor.

598:   Concepts: options database^adding option

600: .seealso: PetscOptionsInsert()
601: @*/
602: PetscErrorCode  PetscOptionsSetValue(const char iname[],const char value[])
603: {
604:   size_t         len;
606:   PetscInt       N,n,i;
607:   char           **names;
608:   const char     *name = (char*)iname;
609:   PetscTruth     gt,match;

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

614:   /* this is so that -h and -help are equivalent (p4 does not like -help)*/
615:   PetscStrcasecmp(name,"-h",&match);
616:   if (match) name = "-help";

618:   name++;
619:   /* first check against aliases */
620:   N = options->Naliases;
621:   for (i=0; i<N; i++) {
622:     PetscStrcasecmp(options->aliases1[i],name,&match);
623:     if (match) {
624:       name = options->aliases2[i];
625:       break;
626:     }
627:   }

629:   N     = options->N;
630:   n     = N;
631:   names = options->names;
632: 
633:   for (i=0; i<N; i++) {
634:     PetscStrcasecmp(names[i],name,&match);
635:     PetscStrgrt(names[i],name,&gt);
636:     if (match) {
637:       if (options->values[i]) free(options->values[i]);
638:       PetscStrlen(value,&len);
639:       if (len) {
640:         options->values[i] = (char*)malloc((len+1)*sizeof(char));
641:         PetscStrcpy(options->values[i],value);
642:       } else { options->values[i] = 0;}
643:       PetscOptionsMonitor(name,value);
644:       return(0);
645:     } else if (gt) {
646:       n = i;
647:       break;
648:     }
649:   }
650:   if (N >= MAXOPTIONS) {
651:     SETERRQ1(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);
652:   }
653:   /* shift remaining values down 1 */
654:   for (i=N; i>n; i--) {
655:     names[i]           = names[i-1];
656:     options->values[i] = options->values[i-1];
657:     options->used[i]   = options->used[i-1];
658:   }
659:   /* insert new name and value */
660:   PetscStrlen(name,&len);
661:   names[n] = (char*)malloc((len+1)*sizeof(char));
662:   PetscStrcpy(names[n],name);
663:   if (value) {
664:     PetscStrlen(value,&len);
665:     options->values[n] = (char*)malloc((len+1)*sizeof(char));
666:     PetscStrcpy(options->values[n],value);
667:   } else {options->values[n] = 0;}
668:   options->used[n] = PETSC_FALSE;
669:   options->N++;
670:   PetscOptionsMonitor(name,value);
671:   return(0);
672: }

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

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

683:    Input Parameter:
684: .  name - name of option, this SHOULD have the - prepended

686:    Level: intermediate

688:    Concepts: options database^removing option
689: .seealso: PetscOptionsInsert()
690: @*/
691: PetscErrorCode  PetscOptionsClearValue(const char iname[])
692: {
694:   PetscInt       N,n,i;
695:   char           **names,*name=(char*)iname;
696:   PetscTruth     gt,match;

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

702:   name++;

704:   N     = options->N; n = 0;
705:   names = options->names;
706: 
707:   for (i=0; i<N; i++) {
708:     PetscStrcasecmp(names[i],name,&match);
709:     PetscStrgrt(names[i],name,&gt);
710:     if (match) {
711:       if (options->values[i]) free(options->values[i]);
712:       PetscOptionsMonitor(name,"");
713:       break;
714:     } else if (gt) {
715:       return(0); /* it was not listed */
716:     }
717:     n++;
718:   }
719:   if (n == N) return(0); /* it was not listed */

721:   /* shift remaining values down 1 */
722:   for (i=n; i<N-1; i++) {
723:     names[i]           = names[i+1];
724:     options->values[i] = options->values[i+1];
725:     options->used[i]   = options->used[i+1];
726:   }
727:   options->N--;
728:   return(0);
729: }

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

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

739:    Input Parameters:
740: +  name - the option one is seeking 
741: -  mess - error message (may be PETSC_NULL)

743:    Level: advanced

745:    Concepts: options database^rejecting option

747: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
748:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsTruth(),
749:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
750:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
751:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
752:           PetscOptionsList(), PetscOptionsEList()
753: @*/
754: PetscErrorCode  PetscOptionsSetAlias(const char inewname[],const char ioldname[])
755: {
757:   PetscInt       n = options->Naliases;
758:   size_t         len;
759:   char           *newname = (char *)inewname,*oldname = (char*)ioldname;

762:   if (newname[0] != '-') SETERRQ1(PETSC_ERR_ARG_WRONG,"aliased must have -: Instead %s",newname);
763:   if (oldname[0] != '-') SETERRQ1(PETSC_ERR_ARG_WRONG,"aliasee must have -: Instead %s",oldname);
764:   if (n >= MAXALIASES) {
765:     SETERRQ1(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);
766:   }

768:   newname++; oldname++;
769:   PetscStrlen(newname,&len);
770:   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
771:   PetscStrcpy(options->aliases1[n],newname);
772:   PetscStrlen(oldname,&len);
773:   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
774:   PetscStrcpy(options->aliases2[n],oldname);
775:   options->Naliases++;
776:   return(0);
777: }

781: static PetscErrorCode PetscOptionsFindPair_Private(const char pre[],const char name[],char *value[],PetscTruth *flg)
782: {
784:   PetscInt       i,N;
785:   size_t         len;
786:   char           **names,tmp[256];
787:   PetscTruth     match;

790:   if (!options) {PetscOptionsInsert(0,0,0);}
791:   N = options->N;
792:   names = options->names;

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

796:   /* append prefix to name */
797:   if (pre) {
798:     if (pre[0] == '-') SETERRQ(PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
799:     PetscStrncpy(tmp,pre,256);
800:     PetscStrlen(tmp,&len);
801:     PetscStrncat(tmp,name+1,256-len-1);
802:   } else {
803:     PetscStrncpy(tmp,name+1,256);
804:   }

806:   /* slow search */
807:   *flg = PETSC_FALSE;
808:   for (i=0; i<N; i++) {
809:     PetscStrcasecmp(names[i],tmp,&match);
810:     if (match) {
811:        *value           = options->values[i];
812:        options->used[i] = PETSC_TRUE;
813:        *flg             = PETSC_TRUE;
814:        break;
815:      }
816:   }
817:   if (!*flg) {
818:     PetscInt j,cnt = 0,locs[16],loce[16];
819:     size_t   n;
820:     PetscStrlen(tmp,&n);
821:     /* determine the location and number of all _%d_ in the key */
822:     for (i=0; i< (PetscInt)n; i++) {
823:       if (tmp[i] == '_') {
824:         for (j=i+1; j< (PetscInt)n; j++) {
825:           if (tmp[j] >= '0' && tmp[j] <= '9') continue;
826:           if (tmp[j] == '_' && j > i+1) { /* found a number */
827:             locs[cnt]   = i+1;
828:             loce[cnt++] = j+1;
829:           }
830:           break;
831:         }
832:       }
833:     }
834:     if (cnt) {
835:       char tmp2[256];
836:       for (i=0; i<cnt; i++) {
837:         PetscStrcpy(tmp2,"-");
838:         PetscStrncat(tmp2,tmp,locs[i]);
839:         PetscStrcat(tmp2,tmp+loce[i]);
840:         PetscOptionsFindPair_Private(PETSC_NULL,tmp2,value,flg);
841:         if (*flg) break;
842:       }
843:     }
844:   }
845:   return(0);
846: }

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

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

856:    Input Parameters:
857: +  name - the option one is seeking 
858: -  mess - error message (may be PETSC_NULL)

860:    Level: advanced

862:    Concepts: options database^rejecting option

864: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
865:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
866:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
867:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
868:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
869:           PetscOptionsList(), PetscOptionsEList()
870: @*/
871: PetscErrorCode  PetscOptionsReject(const char name[],const char mess[])
872: {
874:   PetscTruth     flag;

877:   PetscOptionsHasName(PETSC_NULL,name,&flag);
878:   if (flag) {
879:     if (mess) {
880:       SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s with %s",name,mess);
881:     } else {
882:       SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s",name);
883:     }
884:   }
885:   return(0);
886: }

890: /*@C
891:    PetscOptionsHasName - Determines whether a certain option is given in the database.

893:    Not Collective

895:    Input Parameters:
896: +  name - the option one is seeking 
897: -  pre - string to prepend to the name or PETSC_NULL

899:    Output Parameters:
900: .  flg - PETSC_TRUE if found else PETSC_FALSE.

902:    Level: beginner

904:    Concepts: options database^has option name

906:    Notes: Name cannot be simply -h

908: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
909:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
910:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
911:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
912:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
913:           PetscOptionsList(), PetscOptionsEList()
914: @*/
915: PetscErrorCode  PetscOptionsHasName(const char pre[],const char name[],PetscTruth *flg)
916: {
917:   char           *value;
919:   PetscTruth     isfalse,flag;

922:   PetscOptionsFindPair_Private(pre,name,&value,&flag);

924:   /* remove if turned off */
925:   if (flag) {
926:     PetscStrcasecmp(value,"FALSE",&isfalse);
927:     if (isfalse) flag = PETSC_FALSE;
928:     PetscStrcasecmp(value,"NO",&isfalse);
929:     if (isfalse) flag = PETSC_FALSE;
930:     PetscStrcasecmp(value,"0",&isfalse);
931:     if (isfalse) flag = PETSC_FALSE;
932:   }
933:   if (flg) *flg = flag;
934:   return(0);
935: }

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

942:    Not Collective

944:    Input Parameters:
945: +  pre - the string to prepend to the name or PETSC_NULL
946: -  name - the option one is seeking

948:    Output Parameter:
949: +  ivalue - the integer value to return
950: -  flg - PETSC_TRUE if found, else PETSC_FALSE

952:    Level: beginner

954:    Concepts: options database^has int

956: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
957:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth()
958:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsTruth(),
959:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
960:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
961:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
962:           PetscOptionsList(), PetscOptionsEList()
963: @*/
964: PetscErrorCode  PetscOptionsGetInt(const char pre[],const char name[],PetscInt *ivalue,PetscTruth *flg)
965: {
966:   char           *value;
968:   PetscTruth     flag;

973:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
974:   if (flag) {
975:     if (!value) {if (flg) *flg = PETSC_FALSE;}
976:     else {
977:       if (flg) *flg = PETSC_TRUE;
978:       PetscOptionsAtoi(value,ivalue);
979:     }
980:   } else {
981:     if (flg) *flg = PETSC_FALSE;
982:   }
983:   return(0);
984: }

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

991:    Not Collective

993:    Input Parameters:
994: +  pre - the string to prepend to the name or PETSC_NULL
995: .  opt - option name
996: .  list - the possible choices
997: .  ntext - number of choices

999:    Output Parameter:
1000: +  value - the index of the value to return
1001: -  set - PETSC_TRUE if found, else PETSC_FALSE
1002:    
1003:    Level: intermediate

1005:    See PetscOptionsList() for when the choices are given in a PetscFList()

1007:    Concepts: options database^list

1009: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),  
1010:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1011:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1012:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1013:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1014:           PetscOptionsList(), PetscOptionsEList()
1015: @*/
1016: PetscErrorCode  PetscOptionsGetEList(const char pre[],const char opt[],const char **list,PetscInt ntext,PetscInt *value,PetscTruth *set)
1017: {
1019:   size_t         alen,len = 0;
1020:   char           *svalue;
1021:   PetscTruth     aset,flg = PETSC_FALSE;
1022:   PetscInt       i;

1025:   for ( i=0; i<ntext; i++) {
1026:     PetscStrlen(list[i],&alen);
1027:     if (alen > len) len = alen;
1028:   }
1029:   len += 5; /* a little extra space for user mistypes */
1030:   PetscMalloc(len*sizeof(char),&svalue);
1031:   PetscOptionsGetString(pre,opt,svalue,len,&aset);
1032:   if (aset) {
1033:     if (set) *set = PETSC_TRUE;
1034:     for (i=0; i<ntext; i++) {
1035:       PetscStrcasecmp(svalue,list[i],&flg);
1036:       if (flg) {
1037:         *value = i;
1038:         break;
1039:       }
1040:     }
1041:     if (!flg) SETERRQ3(PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre?pre:"",opt+1);
1042:   } else if (set) {
1043:     *set = PETSC_FALSE;
1044:   }
1045:   PetscFree(svalue);
1046:   return(0);
1047: }

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

1054:    Not Collective

1056:    Input Parameters:
1057: +  pre - option prefix or PETSC_NULL
1058: .  opt - option name
1059: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
1060: -  defaultv - the default (current) value

1062:    Output Parameter:
1063: +  value - the  value to return
1064: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1066:    Level: beginner

1068:    Concepts: options database

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

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

1074: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1075:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth()
1076:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsTruth(),
1077:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1078:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1079:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1080:           PetscOptionsList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
1081: @*/
1082: PetscErrorCode  PetscOptionsGetEnum(const char pre[],const char opt[],const char **list,PetscEnum *value,PetscTruth *set)
1083: {
1085:   PetscInt       ntext = 0;

1088:   while (list[ntext++]) {
1089:     if (ntext > 50) SETERRQ(PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
1090:   }
1091:   if (ntext < 3) SETERRQ(PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1092:   ntext -= 3;
1093:   PetscOptionsGetEList(pre,opt,list,ntext,(PetscInt*)value,set);
1094:   return(0);
1095: }

1099: /*@C
1100:    PetscOptionsGetTruth - Gets the Logical (true or false) value for a particular 
1101:             option in the database.

1103:    Not Collective

1105:    Input Parameters:
1106: +  pre - the string to prepend to the name or PETSC_NULL
1107: -  name - the option one is seeking

1109:    Output Parameter:
1110: +  ivalue - the logical value to return
1111: -  flg - PETSC_TRUE  if found, else PETSC_FALSE

1113:    Level: beginner

1115:    Notes:
1116:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1117:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

1119:    Concepts: options database^has logical

1121: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1122:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsTruth(),
1123:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1124:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1125:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1126:           PetscOptionsList(), PetscOptionsEList()
1127: @*/
1128: PetscErrorCode  PetscOptionsGetTruth(const char pre[],const char name[],PetscTruth *ivalue,PetscTruth *flg)
1129: {
1130:   char           *value;
1131:   PetscTruth     flag,istrue,isfalse;

1137:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1138:   if (flag) {
1139:     if (flg) *flg = PETSC_TRUE;
1140:     if (!value) {
1141:       *ivalue = PETSC_TRUE;
1142:     } else {
1143:       *ivalue = PETSC_TRUE;
1144:       PetscStrcasecmp(value,"TRUE",&istrue);
1145:       if (istrue) return(0);
1146:       PetscStrcasecmp(value,"YES",&istrue);
1147:       if (istrue) return(0);
1148:       PetscStrcasecmp(value,"1",&istrue);
1149:       if (istrue) return(0);
1150:       PetscStrcasecmp(value,"on",&istrue);
1151:       if (istrue) return(0);

1153:       *ivalue = PETSC_FALSE;
1154:       PetscStrcasecmp(value,"FALSE",&isfalse);
1155:       if (isfalse) return(0);
1156:       PetscStrcasecmp(value,"NO",&isfalse);
1157:       if (isfalse) return(0);
1158:       PetscStrcasecmp(value,"0",&isfalse);
1159:       if (isfalse) return(0);
1160:       PetscStrcasecmp(value,"off",&isfalse);
1161:       if (isfalse) return(0);

1163:       SETERRQ1(PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value);
1164:     }
1165:   } else {
1166:     if (flg) *flg = PETSC_FALSE;
1167:   }
1168:   return(0);
1169: }

1173: /*@C
1174:    PetscOptionsGetReal - Gets the double precision value for a particular 
1175:    option in the database.

1177:    Not Collective

1179:    Input Parameters:
1180: +  pre - string to prepend to each name or PETSC_NULL
1181: -  name - the option one is seeking

1183:    Output Parameter:
1184: +  dvalue - the double value to return
1185: -  flg - PETSC_TRUE if found, PETSC_FALSE if not found

1187:    Level: beginner

1189:    Concepts: options database^has double

1191: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1192:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsTruth(),
1193:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1194:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1195:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1196:           PetscOptionsList(), PetscOptionsEList()
1197: @*/
1198: PetscErrorCode  PetscOptionsGetReal(const char pre[],const char name[],PetscReal *dvalue,PetscTruth *flg)
1199: {
1200:   char           *value;
1202:   PetscTruth     flag;

1207:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1208:   if (flag) {
1209:     if (!value) {if (flg) *flg = PETSC_FALSE;}
1210:     else        {if (flg) *flg = PETSC_TRUE; PetscOptionsAtod(value,dvalue);}
1211:   } else {
1212:     if (flg) *flg = PETSC_FALSE;
1213:   }
1214:   return(0);
1215: }

1219: /*@C
1220:    PetscOptionsGetScalar - Gets the scalar value for a particular 
1221:    option in the database.

1223:    Not Collective

1225:    Input Parameters:
1226: +  pre - string to prepend to each name or PETSC_NULL
1227: -  name - the option one is seeking

1229:    Output Parameter:
1230: +  dvalue - the double value to return
1231: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1233:    Level: beginner

1235:    Usage:
1236:    A complex number 2+3i can be specified as 2,3 at the command line.
1237:    or a number 2.0e-10 - 3.3e-20 i  can be specified as 2.0e-10,3.3e-20

1239:    Concepts: options database^has scalar

1241: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1242:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1243:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1244:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1245:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1246:           PetscOptionsList(), PetscOptionsEList()
1247: @*/
1248: PetscErrorCode  PetscOptionsGetScalar(const char pre[],const char name[],PetscScalar *dvalue,PetscTruth *flg)
1249: {
1250:   char           *value;
1251:   PetscTruth     flag;

1257:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1258:   if (flag) {
1259:     if (!value) {
1260:       if (flg) *flg = PETSC_FALSE;
1261:     } else {
1262: #if !defined(PETSC_USE_COMPLEX)
1263:       PetscOptionsAtod(value,dvalue);
1264: #else
1265:       PetscReal  re=0.0,im=0.0;
1266:       PetscToken token;
1267:       char       *tvalue = 0;

1269:       PetscTokenCreate(value,',',&token);
1270:       PetscTokenFind(token,&tvalue);
1271:       if (!tvalue) { SETERRQ(PETSC_ERR_ARG_WRONG,"unknown string specified\n"); }
1272:       PetscOptionsAtod(tvalue,&re);
1273:       PetscTokenFind(token,&tvalue);
1274:       if (!tvalue) { /* Unknown separator used. using only real value */
1275:         *dvalue = re;
1276:       } else {
1277:         PetscOptionsAtod(tvalue,&im);
1278:         *dvalue = re + PETSC_i*im;
1279:       }
1280:       PetscTokenDestroy(token);
1281: #endif
1282:       if (flg) *flg    = PETSC_TRUE;
1283:     }
1284:   } else { /* flag */
1285:     if (flg) *flg = PETSC_FALSE;
1286:   }
1287:   return(0);
1288: }

1292: /*@C
1293:    PetscOptionsGetRealArray - Gets an array of double precision values for a 
1294:    particular option in the database.  The values must be separated with 
1295:    commas with no intervening spaces.

1297:    Not Collective

1299:    Input Parameters:
1300: +  pre - string to prepend to each name or PETSC_NULL
1301: .  name - the option one is seeking
1302: -  nmax - maximum number of values to retrieve

1304:    Output Parameters:
1305: +  dvalue - the double value to return
1306: .  nmax - actual number of values retreived
1307: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1309:    Level: beginner

1311:    Concepts: options database^array of doubles

1313: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1314:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsTruth(),
1315:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1316:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1317:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1318:           PetscOptionsList(), PetscOptionsEList()
1319: @*/
1320: PetscErrorCode  PetscOptionsGetRealArray(const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscTruth *flg)
1321: {
1322:   char           *value;
1324:   PetscInt       n = 0;
1325:   PetscTruth     flag;
1326:   PetscToken     token;

1331:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1332:   if (!flag)  {if (flg) *flg = PETSC_FALSE; *nmax = 0; return(0);}
1333:   if (!value) {if (flg) *flg = PETSC_TRUE; *nmax = 0; return(0);}

1335:   if (flg) *flg = PETSC_TRUE;

1337:   PetscTokenCreate(value,',',&token);
1338:   PetscTokenFind(token,&value);
1339:   while (n < *nmax) {
1340:     if (!value) break;
1341:     PetscOptionsAtod(value,dvalue++);
1342:     PetscTokenFind(token,&value);
1343:     n++;
1344:   }
1345:   PetscTokenDestroy(token);
1346:   *nmax = n;
1347:   return(0);
1348: }

1352: /*@C
1353:    PetscOptionsGetIntArray - Gets an array of integer values for a particular 
1354:    option in the database.  The values must be separated with commas with 
1355:    no intervening spaces. 

1357:    Not Collective

1359:    Input Parameters:
1360: +  pre - string to prepend to each name or PETSC_NULL
1361: .  name - the option one is seeking
1362: -  nmax - maximum number of values to retrieve

1364:    Output Parameter:
1365: +  dvalue - the integer values to return
1366: .  nmax - actual number of values retreived
1367: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1369:    Level: beginner

1371:    Concepts: options database^array of ints

1373: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1374:            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1375:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1376:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1377:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1378:           PetscOptionsList(), PetscOptionsEList()
1379: @*/
1380: PetscErrorCode  PetscOptionsGetIntArray(const char pre[],const char name[],PetscInt dvalue[],PetscInt *nmax,PetscTruth *flg)
1381: {
1382:   char           *value;
1384:   PetscInt       n = 0,i,start,end;
1385:   size_t         len;
1386:   PetscTruth     flag,foundrange;
1387:   PetscToken     token;

1392:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1393:   if (!flag)  {if (flg) *flg = PETSC_FALSE; *nmax = 0; return(0);}
1394:   if (!value) {if (flg) *flg = PETSC_TRUE; *nmax = 0; return(0);}

1396:   if (flg) *flg = PETSC_TRUE;

1398:   PetscTokenCreate(value,',',&token);
1399:   PetscTokenFind(token,&value);
1400:   while (n < *nmax) {
1401:     if (!value) break;
1402: 
1403:     /* look for form  d-D where d and D are integers */
1404:     foundrange = PETSC_FALSE;
1405:     PetscStrlen(value,&len);
1406:     if (value[0] == '-') i=2;
1407:     else i=1;
1408:     for (;i<(int)len; i++) {
1409:       if (value[i] == '-') {
1410:         if (i == (int)len-1) SETERRQ2(PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
1411:         value[i] = 0;
1412:         PetscOptionsAtoi(value,&start);
1413:         PetscOptionsAtoi(value+i+1,&end);
1414:         if (end <= start) SETERRQ3(PETSC_ERR_USER,"Error in %D-th array entry, %s-%s cannot have decreasing list",n,value,value+i+1);
1415:         if (n + end - start - 1 >= *nmax) SETERRQ4(PETSC_ERR_USER,"Error in %D-th array entry, not enough space in left in array (%D) to contain entire range from %D to %D",n,*nmax-n,start,end);
1416:         for (;start<end; start++) {
1417:           *dvalue = start; dvalue++;n++;
1418:         }
1419:         foundrange = PETSC_TRUE;
1420:         break;
1421:       }
1422:     }
1423:     if (!foundrange) {
1424:       PetscOptionsAtoi(value,dvalue);
1425:       dvalue++;
1426:       n++;
1427:     }
1428:     PetscTokenFind(token,&value);
1429:   }
1430:   PetscTokenDestroy(token);
1431:   *nmax = n;
1432:   return(0);
1433: }

1437: /*@C
1438:    PetscOptionsGetString - Gets the string value for a particular option in
1439:    the database.

1441:    Not Collective

1443:    Input Parameters:
1444: +  pre - string to prepend to name or PETSC_NULL
1445: .  name - the option one is seeking
1446: -  len - maximum string length

1448:    Output Parameters:
1449: +  string - location to copy string
1450: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1452:    Level: beginner

1454:    Fortran Note:
1455:    The Fortran interface is slightly different from the C/C++
1456:    interface (len is not used).  Sample usage in Fortran follows
1457: .vb
1458:       character *20 string
1459:       integer   flg, ierr
1460:       call PetscOptionsGetString(PETSC_NULL_CHARACTER,'-s',string,flg,ierr)
1461: .ve

1463:    Concepts: options database^string

1465: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),  
1466:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1467:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1468:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1469:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1470:           PetscOptionsList(), PetscOptionsEList()
1471: @*/
1472: PetscErrorCode  PetscOptionsGetString(const char pre[],const char name[],char string[],size_t len,PetscTruth *flg)
1473: {
1474:   char           *value;
1476:   PetscTruth     flag;

1481:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1482:   if (!flag) {
1483:     if (flg) *flg = PETSC_FALSE;
1484:   } else {
1485:     if (flg) *flg = PETSC_TRUE;
1486:     if (value) {
1487:       PetscStrncpy(string,value,len);
1488:     } else {
1489:       PetscMemzero(string,len);
1490:     }
1491:   }
1492:   return(0);
1493: }

1497: /*@C
1498:    PetscOptionsGetStringArray - Gets an array of string values for a particular
1499:    option in the database. The values must be separated with commas with 
1500:    no intervening spaces. 

1502:    Not Collective

1504:    Input Parameters:
1505: +  pre - string to prepend to name or PETSC_NULL
1506: .  name - the option one is seeking
1507: -  nmax - maximum number of strings

1509:    Output Parameter:
1510: +  strings - location to copy strings
1511: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1513:    Level: beginner

1515:    Notes: 
1516:    The user should pass in an array of pointers to char, to hold all the
1517:    strings returned by this function.

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

1522:    Contributed by Matthew Knepley.

1524:    Concepts: options database^array of strings

1526: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),  
1527:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1528:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1529:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1530:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1531:           PetscOptionsList(), PetscOptionsEList()
1532: @*/
1533: PetscErrorCode  PetscOptionsGetStringArray(const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscTruth *flg)
1534: {
1535:   char           *value;
1537:   PetscInt       n;
1538:   PetscTruth     flag;
1539:   PetscToken     token;
1540: 
1544:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1545:   if (!flag)  {*nmax = 0; if (flg) *flg = PETSC_FALSE; return(0);}
1546:   if (!value) {*nmax = 0; if (flg) *flg = PETSC_FALSE;return(0);}
1547:   if (!*nmax) {if (flg) *flg = PETSC_FALSE;return(0);}
1548:   if (flg) *flg = PETSC_TRUE;

1550:   PetscTokenCreate(value,',',&token);
1551:   PetscTokenFind(token,&value);
1552:   n = 0;
1553:   while (n < *nmax) {
1554:     if (!value) break;
1555:     PetscStrallocpy(value,&strings[n]);
1556:     PetscTokenFind(token,&value);
1557:     n++;
1558:   }
1559:   PetscTokenDestroy(token);
1560:   *nmax = n;
1561:   return(0);
1562: }

1566: /*@C
1567:    PetscOptionsAllUsed - Returns a count of the number of options in the 
1568:    database that have never been selected.

1570:    Not Collective

1572:    Output Parameter:
1573: .   N - count of options not used

1575:    Level: advanced

1577: .seealso: PetscOptionsPrint()
1578: @*/
1579: PetscErrorCode  PetscOptionsAllUsed(int *N)
1580: {
1581:   PetscInt i,n = 0;

1584:   for (i=0; i<options->N; i++) {
1585:     if (!options->used[i]) { n++; }
1586:   }
1587:   *N = n;
1588:   return(0);
1589: }

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

1596:   Not collective

1598:    Options Database Key:
1599: .  -options_left - Activates OptionsAllUsed() within PetscFinalize()

1601:   Level: advanced

1603: .seealso: PetscOptionsAllUsed()
1604: @*/
1605: PetscErrorCode  PetscOptionsLeft(void)
1606: {
1608:   PetscInt       i;

1611:   for (i=0; i<options->N; i++) {
1612:     if (!options->used[i]) {
1613:       if (options->values[i]) {
1614:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",options->names[i],options->values[i]);
1615:       } else {
1616:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s no value \n",options->names[i]);
1617:       }
1618:     }
1619:   }
1620:   return(0);
1621: }


1624: /*
1625:     PetscOptionsCreate - Creates the empty options database.

1627: */
1630: PetscErrorCode  PetscOptionsCreate(void)
1631: {

1635:   options = (PetscOptionsTable*)malloc(sizeof(PetscOptionsTable));
1636:   PetscMemzero(options->used,MAXOPTIONS*sizeof(PetscTruth));
1637:   options->namegiven                 = PETSC_FALSE;
1638:   options->N                         = 0;
1639:   options->Naliases                  = 0;
1640:   options->numbermonitors         = 0;

1642:   PetscOptionsObject.prefix = PETSC_NULL;
1643:   PetscOptionsObject.title  = PETSC_NULL;
1644: 
1645:   return(0);
1646: }

1650: /*@
1651:    PetscOptionsSetFromOptions - Sets various SNES and KSP parameters from user options.

1653:    Collective on PETSC_COMM_WORLD

1655:    Options Database Keys:
1656: +  -options_monitor <optional filename> - prints the names and values of all 
1657:                                  runtime options as they are set. The monitor functionality is not 
1658:                 available for options set through a file, environment variable, or on 
1659:                 the command line. Only options set after PetscInitialize completes will 
1660:                 be monitored.
1661: .  -options_monitor_cancel - cancel all options database monitors    

1663:    Notes:
1664:    To see all options, run your program with the -help option or consult
1665:    the users manual. 

1667:    Level: intermediate

1669: .keywords: set, options, database
1670: @*/
1671: PetscErrorCode  PetscOptionsSetFromOptions(void)
1672: {
1673:   PetscTruth          flg;
1674:   PetscErrorCode      ierr;
1675:   char                monfilename[PETSC_MAX_PATH_LEN];
1676:   PetscViewer         monviewer;


1680:   PetscOptionsBegin(PETSC_COMM_WORLD,"","Options database options","PetscOptions");
1681:   PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
1682:   if (flg && (!options->numbermonitors)) {
1683:     PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);
1684:     PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerDestroy);
1685:   }
1686: 
1687:   PetscOptionsName("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",&flg);
1688:   if (flg) { PetscOptionsMonitorCancel(); }
1689: 
1690:   PetscOptionsEnd();

1692:   return(0);
1693: }


1698: /*@C
1699:    PetscOptionsMonitorDefault - Print all options set value events.

1701:    Collective on PETSC_COMM_WORLD

1703:    Input Parameters:
1704: +  name  - option name string
1705: .  value - option value string
1706: -  dummy - unused monitor context 

1708:    Level: intermediate

1710: .keywords: PetscOptions, default, monitor

1712: .seealso: PetscOptionsMonitorSet()
1713: @*/
1714: PetscErrorCode  PetscOptionsMonitorDefault(const char name[], const char value[], void *dummy)
1715: {
1717:   PetscViewer    viewer = (PetscViewer) dummy;

1720:   if (!viewer) {
1721:     PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);
1722:   }
1723:   PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
1724:   return(0);
1725: }

1729: /*@C
1730:    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
1731:    modified the PETSc options database.
1732:       
1733:    Not collective

1735:    Input Parameters:
1736: +  monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring
1737: .  mctx    - [optional] context for private data for the
1738:              monitor routine (use PETSC_NULL if no context is desired)
1739: -  monitordestroy - [optional] routine that frees monitor context
1740:           (may be PETSC_NULL)

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

1745: +  name - option name string
1746: .  value - option value string
1747: -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()

1749:    Options Database Keys:
1750: +    -options_monitor    - sets PetscOptionsMonitorDefault()
1751: -    -options_monitor_cancel - cancels all monitors that have
1752:                           been hardwired into a code by 
1753:                           calls to PetscOptionsMonitorSet(), but
1754:                           does not cancel those set via
1755:                           the options database.

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

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

1766:    Level: beginner

1768: .keywords: PetscOptions, set, monitor

1770: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
1771: @*/
1772: PetscErrorCode  PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1773: {
1775:   if (options->numbermonitors >= MAXOPTIONSMONITORS) {
1776:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
1777:   }
1778:   options->monitor[options->numbermonitors]           = monitor;
1779:   options->monitordestroy[options->numbermonitors]    = monitordestroy;
1780:   options->monitorcontext[options->numbermonitors++]  = (void*)mctx;
1781:   return(0);
1782: }

1786: /*@
1787:    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.

1789:    Not collective 

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

1796:    Level: intermediate

1798: .keywords: PetscOptions, set, monitor

1800: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
1801: @*/
1802: PetscErrorCode  PetscOptionsMonitorCancel(void)
1803: {
1805:   PetscInt       i;

1808:   for (i=0; i<options->numbermonitors; i++) {
1809:     if (options->monitordestroy[i]) {
1810:       (*options->monitordestroy[i])(options->monitorcontext[i]);
1811:     }
1812:   }
1813:   options->numbermonitors = 0;
1814:   return(0);
1815: }