Actual source code: options.c

  1: /*$Id: options.c,v 1.252 2001/08/07 21:28:54 bsmith Exp $*/
  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) && !defined(__cplusplus)
 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: #ifndef MAXPATHLEN
 24: #define MAXPATHLEN 1024
 25: #endif

 27: /* 
 28:     For simplicity, we use a static size database
 29: */
 30: #define MAXOPTIONS 256
 31: #define MAXALIASES 25

 33: typedef struct {
 34:   int        N,argc,Naliases;
 35:   char       **args,*names[MAXOPTIONS],*values[MAXOPTIONS];
 36:   char       *aliases1[MAXALIASES],*aliases2[MAXALIASES];
 37:   int        used[MAXOPTIONS];
 38:   PetscTruth namegiven;
 39:   char       programname[MAXPATHLEN]; /* HP includes entire path in name */
 40: } PetscOptionsTable;

 42: static PetscOptionsTable *options = 0;

 44: int PetscOptionsAtoi(const char name[],int *a)
 45: {
 46:   int        i,ierr,len;
 47:   PetscTruth decide,tdefault,mouse;

 50:   PetscStrlen(name,&len);
 51:   if (!len) SETERRQ(1,"character string of length zero has no numerical value");

 53:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
 54:   if (!tdefault) {
 55:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
 56:   }
 57:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
 58:   if (!decide) {
 59:     PetscStrcasecmp(name,"DECIDE",&decide);
 60:   }
 61:   PetscStrcasecmp(name,"mouse",&mouse);

 63:   if (tdefault) {
 64:     *a = PETSC_DEFAULT;
 65:   } else if (decide) {
 66:     *a = PETSC_DECIDE;
 67:   } else if (mouse) {
 68:     *a = -1;
 69:   } else {
 70:     if (name[0] != '+' && name[0] != '-' && name[0] < '0' && name[0] > '9') {
 71:       SETERRQ1(1,"Input string %s has no integer value (do not include . in it)",name);
 72:     }
 73:     for (i=1; i<len; i++) {
 74:       if (name[i] < '0' || name[i] > '9') {
 75:         SETERRQ1(1,"Input string %s has no integer value (do not include . in it)",name);
 76:       }
 77:     }
 78:     *a  = atoi(name);
 79:   }
 80:   return(0);
 81: }

 83: int PetscOptionsAtod(const char name[],PetscReal *a)
 84: {
 85:   int        ierr,len;
 86:   PetscTruth decide,tdefault;

 89:   PetscStrlen(name,&len);
 90:   if (!len) SETERRQ(1,"character string of length zero has no numerical value");

 92:   PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);
 93:   if (!tdefault) {
 94:     PetscStrcasecmp(name,"DEFAULT",&tdefault);
 95:   }
 96:   PetscStrcasecmp(name,"PETSC_DECIDE",&decide);
 97:   if (!decide) {
 98:     PetscStrcasecmp(name,"DECIDE",&decide);
 99:   }

101:   if (tdefault) {
102:     *a = PETSC_DEFAULT;
103:   } else if (decide) {
104:     *a = PETSC_DECIDE;
105:   } else {
106:     if (name[0] != '+' && name[0] != '-' && name[0] != '.' && name[0] < '0' && name[0] > '9') {
107:       SETERRQ1(1,"Input string %s has no numeric value ",name);
108:     }
109:     *a  = atof(name);
110:   }
111:   return(0);
112: }

114: /*@C
115:     PetscGetProgramName - Gets the name of the running program. 

117:     Not Collective

119:     Input Parameter:
120: .   len - length of the string name

122:     Output Parameter:
123: .   name - the name of the running program

125:    Level: advanced

127:     Notes:
128:     The name of the program is copied into the user-provided character
129:     array of length len.  On some machines the program name includes 
130:     its entire path, so one should generally set len >= MAXPATHLEN.
131: @*/
132: int PetscGetProgramName(char name[],int len)
133: {

137:   if (!options) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call PetscInitialize() first");
138:   if (!options->namegiven) SETERRQ(PETSC_ERR_PLIB,"Unable to determine program name");
139:   PetscStrncpy(name,options->programname,len);
140:   return(0);
141: }

143: int PetscSetProgramName(const char name[])
144: {

148:   options->namegiven = PETSC_TRUE;
149:   ierr  = PetscStrncpy(options->programname,name,MAXPATHLEN);
150:   return(0);
151: }

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

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

159:   Input Parameter:
160: .   file - name of file


163:   Level: intermediate

165: .seealso: PetscOptionsSetValue(), PetscOptionsPrint(), PetscOptionsHasName(), PetscOptionsGetInt(),
166:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsLogical(),
167:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
168:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
169:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
170:           PetscOptionsList(), PetscOptionsEList()

172: @*/
173: int PetscOptionsInsertFile(const char file[])
174: {
175:   char       string[128],fname[256],*first,*second,*third,*final;
176:   int        len,ierr,i;
177:   FILE       *fd;
178:   PetscToken *token;

181:   PetscFixFilename(file,fname);
182:   fd   = fopen(fname,"r");
183:   if (fd) {
184:     while (fgets(string,128,fd)) {
185:       /* Comments are indicated by #, ! or % in the first column */
186:       if (string[0] == '#') continue;
187:       if (string[0] == '!') continue;
188:       if (string[0] == '%') continue;

190:       PetscStrlen(string,&len);

192:       /* replace tabs, ^M with " " */
193:       for (i=0; i<len; i++) {
194:         if (string[i] == 't' || string[i] == 'r') {
195:           string[i] = ' ';
196:         }
197:       }
198:       PetscTokenCreate(string,' ',&token);
199:       PetscTokenFind(token,&first);
200:       PetscTokenFind(token,&second);
201:       if (first && first[0] == '-') {
202:         if (second) {final = second;} else {final = first;}
203:         PetscStrlen(final,&len);
204:         while (len > 0 && (final[len-1] == ' ' || final[len-1] == 'n')) {
205:           len--; final[len] = 0;
206:         }
207:         PetscOptionsSetValue(first,second);
208:       } else if (first) {
209:         PetscTruth match;

211:         PetscStrcmp(first,"alias",&match);
212:         if (match) {
213:           PetscTokenFind(token,&third);
214:           if (!third) SETERRQ1(PETSC_ERR_ARG_WRONG,"Error in options file:alias missing (%s)",second);
215:           PetscStrlen(third,&len);
216:           if (third[len-1] == 'n') third[len-1] = 0;
217:           PetscOptionsSetAlias(second,third);
218:         }
219:       }
220:       PetscTokenDestroy(token);
221:     }
222:     fclose(fd);
223:   }
224:   return(0);
225: }

227: /*@C
228:    PetscOptionsInsert - Inserts into the options database from the command line,
229:                    the environmental variable and a file.

231:    Input Parameters:
232: +  argc - count of number of command line arguments
233: .  args - the command line arguments
234: -  file - optional filename, defaults to ~username/.petscrc

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

241:    Level: advanced

243:    Concepts: options database^adding

245: .seealso: PetscOptionsDestroy_Private(), PetscOptionsPrint()
246: @*/
247: int PetscOptionsInsert(int *argc,char ***args,const char file[])
248: {
249:   int        ierr,rank;
250:   char       pfile[256];
251:   PetscToken *token;

254:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

256:   options->argc     = (argc) ? *argc : 0;
257:   options->args     = (args) ? *args : 0;

259:   if (file) {
260:     PetscOptionsInsertFile(file);
261:   } else {
262:     PetscGetHomeDirectory(pfile,240);
263:     PetscStrcat(pfile,"/.petscrc");
264:     PetscOptionsInsertFile(pfile);
265:   }

267:   /* insert environmental options */
268:   {
269:     char *eoptions = 0,*second,*first;
270:     int  len;
271:     if (!rank) {
272:       eoptions = (char*)getenv("PETSC_OPTIONS");
273:       ierr     = PetscStrlen(eoptions,&len);
274:       ierr     = MPI_Bcast(&len,1,MPI_INT,0,PETSC_COMM_WORLD);
275:     } else {
276:       MPI_Bcast(&len,1,MPI_INT,0,PETSC_COMM_WORLD);
277:       if (len) {
278:         PetscMalloc((len+1)*sizeof(char*),&eoptions);
279:       }
280:     }
281:     if (len) {
282:       ierr          = MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
283:       eoptions[len] = 0;
284:       ierr          =  PetscTokenCreate(eoptions,' ',&token);
285:       ierr          =  PetscTokenFind(token,&first);
286:       while (first) {
287:         if (first[0] != '-') {PetscTokenFind(token,&first); continue;}
288:         PetscTokenFind(token,&second);
289:         if ((!second) || ((second[0] == '-') && (second[1] > '9'))) {
290:           PetscOptionsSetValue(first,(char *)0);
291:           first = second;
292:         } else {
293:           PetscOptionsSetValue(first,second);
294:           PetscTokenFind(token,&first);
295:         }
296:       }
297:        PetscTokenDestroy(token);
298:       if (rank) {PetscFree(eoptions);}
299:     }
300:   }

302:   /* insert command line options */
303:   if (argc && args && *argc) {
304:     int        left    = *argc - 1;
305:     char       **eargs = *args + 1;
306:     PetscTruth isoptions_file,isp4,tisp4;

308:     while (left) {
309:       PetscStrcmp(eargs[0],"-options_file",&isoptions_file);
310:       PetscStrcmp(eargs[0],"-p4pg",&isp4);
311:       PetscStrcmp(eargs[0],"-p4wd",&tisp4);
312:       isp4 = (PetscTruth) (isp4 || tisp4);
313:       PetscStrcmp(eargs[0],"-np",&tisp4);
314:       isp4 = (PetscTruth) (isp4 || tisp4);
315:       PetscStrcmp(eargs[0],"-p4amslave",&tisp4);

317:       if (eargs[0][0] != '-') {
318:         eargs++; left--;
319:       } else if (isoptions_file) {
320:         PetscOptionsInsertFile(eargs[1]);
321:         eargs += 2; left -= 2;

323:       /*
324:          These are "bad" options that MPICH, etc put on the command line
325:          we strip them out here.
326:       */
327:       } else if (tisp4) {
328:         eargs += 1; left -= 1;
329:       } else if (isp4) {
330:         eargs += 2; left -= 2;
331:       } else if ((left < 2) || ((eargs[1][0] == '-') &&
332:                ((eargs[1][1] > '9') || (eargs[1][1] < '0')))) {
333:         PetscOptionsSetValue(eargs[0],PETSC_NULL);
334:         eargs++; left--;
335:       } else {
336:         PetscOptionsSetValue(eargs[0],eargs[1]);
337:         eargs += 2; left -= 2;
338:       }
339:     }
340:   }
341:   return(0);
342: }

344: /*@C
345:    PetscOptionsPrint - Prints the options that have been loaded. This is
346:    useful for debugging purposes.

348:    Collective on PETSC_COMM_WORLD

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

353:    Options Database Key:
354: .  -optionstable - Activates PetscOptionsPrint() within PetscFinalize()

356:    Level: advanced

358:    Concepts: options database^printing

360: .seealso: PetscOptionsAllUsed()
361: @*/
362: int PetscOptionsPrint(FILE *fd)
363: {
364:   int i,ierr;

367:   if (!fd) fd = stdout;
368:   if (!options) {PetscOptionsInsert(0,0,0);}
369:   for (i=0; i<options->N; i++) {
370:     if (options->values[i]) {
371:       PetscFPrintf(PETSC_COMM_WORLD,fd,"OptionTable: -%s %sn",options->names[i],options->values[i]);
372:     } else {
373:       PetscFPrintf(PETSC_COMM_WORLD,fd,"OptionTable: -%sn",options->names[i]);
374:     }
375:   }
376:   return(0);
377: }

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

382:    Not Collective

384:    Output Parameter:
385: .  copts - pointer where string pointer is stored

387:    Level: advanced

389:    Concepts: options database^listing

391: .seealso: PetscOptionsAllUsed(), PetscOptionsPrintf()
392: @*/
393: int PetscOptionsGetAll(char *copts[])
394: {
395:   int  i,ierr,len = 1,lent;
396:   char *coptions;

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

401:   /* count the length of the required string */
402:   for (i=0; i<options->N; i++) {
403:     PetscStrlen(options->names[i],&lent);
404:     len += 1 + lent;
405:     if (options->values[i]) {
406:       PetscStrlen(options->values[i],&lent);
407:       len += 1 + lent;
408:     }
409:   }
410:   PetscMalloc(len*sizeof(char),&coptions);
411:   coptions[0] = 0;
412:   for (i=0; i<options->N; i++) {
413:     PetscStrcat(coptions,"-");
414:     PetscStrcat(coptions,options->names[i]);
415:     PetscStrcat(coptions," ");
416:     if (options->values[i]) {
417:       PetscStrcat(coptions,options->values[i]);
418:       PetscStrcat(coptions," ");
419:     }
420:   }
421:   *copts = coptions;
422:   return(0);
423: }

425: /*@C
426:     PetscOptionsDestroy - Destroys the option database. 

428:     Note:
429:     Since PetscOptionsDestroy() is called by PetscFinalize(), the user 
430:     typically does not need to call this routine.

432:    Level: developer

434: .seealso: PetscOptionsInsert()
435: @*/
436: int PetscOptionsDestroy(void)
437: {
438:   int i;

441:   if (!options) return(0);
442:   for (i=0; i<options->N; i++) {
443:     if (options->names[i]) free(options->names[i]);
444:     if (options->values[i]) free(options->values[i]);
445:   }
446:   for (i=0; i<options->Naliases; i++) {
447:     free(options->aliases1[i]);
448:     free(options->aliases2[i]);
449:   }
450:   free(options);
451:   options = 0;
452:   return(0);
453: }

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

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

462:    Input Parameters:
463: +  name - name of option, this SHOULD have the - prepended
464: -  value - the option value (not used for all options)

466:    Level: intermediate

468:    Note:
469:    Only some options have values associated with them, such as
470:    -ksp_rtol tol.  Other options stand alone, such as -ksp_monitor.

472:   Concepts: options database^adding option

474: .seealso: PetscOptionsInsert()
475: @*/
476: int PetscOptionsSetValue(const char iname[],const char value[])
477: {
478:   int        len,N,n,i,ierr;
479:   char       **names,*name = (char*)iname;
480:   PetscTruth gt,match;

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

485:   /* this is so that -h and -help are equivalent (p4 does not like -help)*/
486:   PetscStrcmp(name,"-h",&match);
487:   if (match) name = "-help";

489:   name++;
490:   /* first check against aliases */
491:   N = options->Naliases;
492:   for (i=0; i<N; i++) {
493:     PetscStrcmp(options->aliases1[i],name,&match);
494:     if (match) {
495:       name = options->aliases2[i];
496:       break;
497:     }
498:   }

500:   N     = options->N;
501:   n     = N;
502:   names = options->names;
503: 
504:   for (i=0; i<N; i++) {
505:     PetscStrcmp(names[i],name,&match);
506:     ierr  = PetscStrgrt(names[i],name,&gt);
507:     if (match) {
508:       if (options->values[i]) free(options->values[i]);
509:       PetscStrlen(value,&len);
510:       if (len) {
511:         options->values[i] = (char*)malloc((len+1)*sizeof(char));
512:         PetscStrcpy(options->values[i],value);
513:       } else { options->values[i] = 0;}
514:       return(0);
515:     } else if (gt) {
516:       n = i;
517:       break;
518:     }
519:   }
520:   if (N >= MAXOPTIONS) {
521:     SETERRQ1(1,"No more room in option table, limit %d recompile n src/sys/src/objects/options.c with larger value for MAXOPTIONSn",MAXOPTIONS);
522:   }
523:   /* shift remaining values down 1 */
524:   for (i=N; i>n; i--) {
525:     names[i]           = names[i-1];
526:     options->values[i] = options->values[i-1];
527:     options->used[i]   = options->used[i-1];
528:   }
529:   /* insert new name and value */
530:   PetscStrlen(name,&len);
531:   names[n] = (char*)malloc((len+1)*sizeof(char));
532:   PetscStrcpy(names[n],name);
533:   if (value) {
534:     PetscStrlen(value,&len);
535:     options->values[n] = (char*)malloc((len+1)*sizeof(char));
536:     PetscStrcpy(options->values[n],value);
537:   } else {options->values[n] = 0;}
538:   options->used[n] = 0;
539:   options->N++;
540:   return(0);
541: }

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

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

550:    Input Parameter:
551: .  name - name of option, this SHOULD have the - prepended

553:    Level: intermediate

555:    Concepts: options database^removing option
556: .seealso: PetscOptionsInsert()
557: @*/
558: int PetscOptionsClearValue(const char iname[])
559: {
560:   int        N,n,i,ierr;
561:   char       **names,*name=(char*)iname;
562:   PetscTruth gt,match;

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

567:   name++;

569:   N     = options->N; n = 0;
570:   names = options->names;
571: 
572:   for (i=0; i<N; i++) {
573:     PetscStrcmp(names[i],name,&match);
574:     ierr  = PetscStrgrt(names[i],name,&gt);
575:     if (match) {
576:       if (options->values[i]) free(options->values[i]);
577:       break;
578:     } else if (gt) {
579:       return(0); /* it was not listed */
580:     }
581:     n++;
582:   }
583:   /* shift remaining values down 1 */
584:   for (i=n; i<N-1; i++) {
585:     names[i]           = names[i+1];
586:     options->values[i] = options->values[i+1];
587:     options->used[i]   = options->used[i+1];
588:   }
589:   options->N--;
590:   return(0);
591: }

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

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

599:    Input Parameters:
600: +  name - the option one is seeking 
601: -  mess - error message (may be PETSC_NULL)

603:    Level: advanced

605:    Concepts: options database^rejecting option

607: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
608:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsLogical(),
609:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
610:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
611:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
612:           PetscOptionsList(), PetscOptionsEList()
613: @*/
614: int PetscOptionsSetAlias(const char inewname[],const char ioldname[])
615: {
616:   int  ierr,len,n = options->Naliases;
617:   char *newname = (char *)inewname,*oldname = (char*)ioldname;

620:   if (newname[0] != '-') SETERRQ1(PETSC_ERR_ARG_WRONG,"aliased must have -: Instead %s",newname);
621:   if (oldname[0] != '-') SETERRQ1(PETSC_ERR_ARG_WRONG,"aliasee must have -: Instead %s",oldname);
622:   if (n >= MAXALIASES) {
623:     SETERRQ1(PETSC_ERR_MEM,"You have defined to many PETSc options aliases, limit %d recompile n  src/sys/src/objects/options.c with larger value for MAXALIASES",MAXALIASES);
624:   }

626:   newname++; oldname++;
627:   PetscStrlen(newname,&len);
628:   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
629:   PetscStrcpy(options->aliases1[n],newname);
630:   PetscStrlen(oldname,&len);
631:   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
632:   PetscStrcpy(options->aliases2[n],oldname);
633:   options->Naliases++;
634:   return(0);
635: }

637: static int PetscOptionsFindPair_Private(const char pre[],const char name[],char *value[],PetscTruth *flg)
638: {
639:   int        i,N,ierr,len;
640:   char       **names,tmp[256];
641:   PetscTruth match;

644:   if (!options) {PetscOptionsInsert(0,0,0);}
645:   N = options->N;
646:   names = options->names;

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

650:   /* append prefix to name */
651:   if (pre) {
652:     PetscStrncpy(tmp,pre,256);
653:     PetscStrlen(tmp,&len);
654:     PetscStrncat(tmp,name+1,256-len-1);
655:   } else {
656:     PetscStrncpy(tmp,name+1,256);
657:   }

659:   /* slow search */
660:   *flg = PETSC_FALSE;
661:   for (i=0; i<N; i++) {
662:     PetscStrcmp(names[i],tmp,&match);
663:     if (match) {
664:        *value = options->values[i];
665:        options->used[i]++;
666:        *flg = PETSC_TRUE;
667:        break;
668:      }
669:   }
670:   return(0);
671: }

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

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

679:    Input Parameters:
680: +  name - the option one is seeking 
681: -  mess - error message (may be PETSC_NULL)

683:    Level: advanced

685:    Concepts: options database^rejecting option

687: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
688:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsLogical(),
689:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
690:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
691:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
692:           PetscOptionsList(), PetscOptionsEList()
693: @*/
694: int PetscOptionsReject(const char name[],const char mess[])
695: {
696:   int        ierr;
697:   PetscTruth flag;

700:   PetscOptionsHasName(PETSC_NULL,name,&flag);
701:   if (flag) {
702:     if (mess) {
703:       SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s with %s",name,mess);
704:     } else {
705:       SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s",name);
706:     }
707:   }
708:   return(0);
709: }

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

714:    Not Collective

716:    Input Parameters:
717: +  name - the option one is seeking 
718: -  pre - string to prepend to the name or PETSC_NULL

720:    Output Parameters:
721: .  flg - PETSC_TRUE if found else PETSC_FALSE.

723:    Level: beginner

725:    Concepts: options database^has option name

727: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
728:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsLogical(),
729:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
730:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
731:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
732:           PetscOptionsList(), PetscOptionsEList()
733: @*/
734: int PetscOptionsHasName(const char pre[],const char name[],PetscTruth *flg)
735: {
736:   char       *value;
737:   int        ierr;
738:   PetscTruth isfalse,flag;

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

743:   /* remove if turned off */
744:   if (flag) {
745:     PetscStrcmp(value,"FALSE",&isfalse);
746:     if (isfalse) flag = PETSC_FALSE;
747:     PetscStrcmp(value,"NO",&isfalse);
748:     if (isfalse) flag = PETSC_FALSE;
749:     PetscStrcmp(value,"0",&isfalse);
750:     if (isfalse) flag = PETSC_FALSE;
751:     PetscStrcmp(value,"false",&isfalse);
752:     if (isfalse) flag = PETSC_FALSE;
753:     PetscStrcmp(value,"no",&isfalse);
754:   }
755:   if (flg) *flg = flag;

757:   return(0);
758: }

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

763:    Not Collective

765:    Input Parameters:
766: +  pre - the string to prepend to the name or PETSC_NULL
767: -  name - the option one is seeking

769:    Output Parameter:
770: +  ivalue - the integer value to return
771: -  flg - PETSC_TRUE if found, else PETSC_FALSE

773:    Level: beginner

775:    Concepts: options database^has int

777: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
778:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsLogical()
779:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsLogical(),
780:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
781:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
782:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
783:           PetscOptionsList(), PetscOptionsEList()
784: @*/
785: int PetscOptionsGetInt(const char pre[],const char name[],int *ivalue,PetscTruth *flg)
786: {
787:   char       *value;
788:   int        ierr;
789:   PetscTruth flag;

793:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
794:   if (flag) {
795:     if (!value) {if (flg) *flg = PETSC_FALSE; *ivalue = 0;}
796:     else {
797:       if (flg) *flg = PETSC_TRUE;
798:       PetscOptionsAtoi(value,ivalue);
799:     }
800:   } else {
801:     if (flg) *flg = PETSC_FALSE;
802:   }
803:   return(0);
804: }

806: /*@C
807:    PetscOptionsGetLogical - Gets the Logical (true or false) value for a particular 
808:             option in the database.

810:    Not Collective

812:    Input Parameters:
813: +  pre - the string to prepend to the name or PETSC_NULL
814: -  name - the option one is seeking

816:    Output Parameter:
817: +  ivalue - the logical value to return
818: -  flg - PETSC_TRUE  if found, else PETSC_FALSE

820:    Level: beginner

822:    Notes:
823:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
824:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

826:    Concepts: options database^has logical

828: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
829:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsLogical(),
830:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
831:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
832:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
833:           PetscOptionsList(), PetscOptionsEList()
834: @*/
835: int PetscOptionsGetLogical(const char pre[],const char name[],PetscTruth *ivalue,PetscTruth *flg)
836: {
837:   char       *value;
838:   PetscTruth flag,istrue,isfalse;
839:   int        ierr;

843:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
844:   if (flag) {
845:     if (flg) *flg = PETSC_TRUE;
846:     if (!value) {
847:       *ivalue = PETSC_TRUE;
848:     } else {
849:       *ivalue = PETSC_TRUE;
850:       PetscStrcmp(value,"TRUE",&istrue);
851:       if (istrue) return(0);
852:       PetscStrcmp(value,"YES",&istrue);
853:       if (istrue) return(0);
854:       PetscStrcmp(value,"YES",&istrue);
855:       if (istrue) return(0);
856:       PetscStrcmp(value,"1",&istrue);
857:       if (istrue) return(0);
858:       PetscStrcmp(value,"true",&istrue);
859:       if (istrue) return(0);
860:       PetscStrcmp(value,"yes",&istrue);
861:       if (istrue) return(0);
862:       PetscStrcmp(value,"on",&istrue);
863:       if (istrue) return(0);

865:       *ivalue = PETSC_FALSE;
866:       PetscStrcmp(value,"FALSE",&isfalse);
867:       if (isfalse) return(0);
868:       PetscStrcmp(value,"NO",&isfalse);
869:       if (isfalse) return(0);
870:       PetscStrcmp(value,"0",&isfalse);
871:       if (isfalse) return(0);
872:       PetscStrcmp(value,"false",&isfalse);
873:       if (isfalse) return(0);
874:       PetscStrcmp(value,"no",&isfalse);
875:       if (isfalse) return(0);
876:       PetscStrcmp(value,"off",&isfalse);
877:       if (isfalse) return(0);

879:       SETERRQ1(1,"Unknown logical value: %s",value);
880:     }
881:   } else {
882:     if (flg) *flg = PETSC_FALSE;
883:   }
884:   return(0);
885: }

887: /*@C
888:    PetscOptionsGetReal - Gets the double precision value for a particular 
889:    option in the database.

891:    Not Collective

893:    Input Parameters:
894: +  pre - string to prepend to each name or PETSC_NULL
895: -  name - the option one is seeking

897:    Output Parameter:
898: +  dvalue - the double value to return
899: -  flg - PETSC_TRUE if found, PETSC_FALSE if not found

901:    Level: beginner

903:    Concepts: options database^has double

905: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
906:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsLogical(),
907:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
908:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
909:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
910:           PetscOptionsList(), PetscOptionsEList()
911: @*/
912: int PetscOptionsGetReal(const char pre[],const char name[],PetscReal *dvalue,PetscTruth *flg)
913: {
914:   char       *value;
915:   int        ierr;
916:   PetscTruth flag;

920:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
921:   if (flag) {
922:     if (!value) {if (flg) *flg = PETSC_FALSE; *dvalue = 0.0;}
923:     else        {if (flg) *flg = PETSC_TRUE; PetscOptionsAtod(value,dvalue);}
924:   } else {
925:     if (flg) *flg = PETSC_FALSE;
926:   }
927:   return(0);
928: }

930: /*@C
931:    PetscOptionsGetScalar - Gets the scalar value for a particular 
932:    option in the database.

934:    Not Collective

936:    Input Parameters:
937: +  pre - string to prepend to each name or PETSC_NULL
938: -  name - the option one is seeking

940:    Output Parameter:
941: +  dvalue - the double value to return
942: -  flg - PETSC_TRUE if found, else PETSC_FALSE

944:    Level: beginner

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

950:    Concepts: options database^has scalar

952: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
953:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsLogical(),
954:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
955:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
956:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
957:           PetscOptionsList(), PetscOptionsEList()
958: @*/
959: int PetscOptionsGetScalar(const char pre[],const char name[],PetscScalar *dvalue,PetscTruth *flg)
960: {
961:   char       *value;
962:   PetscTruth flag;
963:   int        ierr;

967:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
968:   if (flag) {
969:     if (!value) {
970:       if (flg) *flg = PETSC_FALSE; *dvalue = 0.0;
971:     } else {
972: #if !defined(PETSC_USE_COMPLEX)
973:       PetscOptionsAtod(value,dvalue);
974: #else
975:       PetscReal  re=0.0,im=0.0;
976:       PetscToken *token;
977:       char       *tvalue = 0;

979:       PetscTokenCreate(value,',',&token);
980:       PetscTokenFind(token,&tvalue);
981:       if (!tvalue) { SETERRQ(1,"unknown string specifiedn"); }
982:       ierr    = PetscOptionsAtod(tvalue,&re);
983:       ierr    = PetscTokenFind(token,&tvalue);
984:       if (!tvalue) { /* Unknown separator used. using only real value */
985:         *dvalue = re;
986:       } else {
987:         ierr    = PetscOptionsAtod(tvalue,&im);
988:         *dvalue = re + PETSC_i*im;
989:       }
990:       ierr    = PetscTokenDestroy(token);
991: #endif
992:       if (flg) *flg    = PETSC_TRUE;
993:     }
994:   } else { /* flag */
995:     if (flg) *flg = PETSC_FALSE;
996:   }
997:   return(0);
998: }

1000: /*@C
1001:    PetscOptionsGetRealArray - Gets an array of double precision values for a 
1002:    particular option in the database.  The values must be separated with 
1003:    commas with no intervening spaces.

1005:    Not Collective

1007:    Input Parameters:
1008: +  pre - string to prepend to each name or PETSC_NULL
1009: .  name - the option one is seeking
1010: -  nmax - maximum number of values to retrieve

1012:    Output Parameters:
1013: +  dvalue - the double value to return
1014: .  nmax - actual number of values retreived
1015: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1017:    Level: beginner

1019:    Concepts: options database^array of doubles

1021: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1022:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsLogical(),
1023:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1024:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1025:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
1026:           PetscOptionsList(), PetscOptionsEList()
1027: @*/
1028: int PetscOptionsGetRealArray(const char pre[],const char name[],PetscReal dvalue[],int *nmax,PetscTruth *flg)
1029: {
1030:   char       *value;
1031:   int        n = 0,ierr;
1032:   PetscTruth flag;
1033:   PetscToken *token;

1037:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1038:   if (!flag)  {if (flg) *flg = PETSC_FALSE; *nmax = 0; return(0);}
1039:   if (!value) {if (flg) *flg = PETSC_TRUE; *nmax = 0; return(0);}

1041:   if (flg) *flg = PETSC_TRUE;

1043:   PetscTokenCreate(value,',',&token);
1044:   PetscTokenFind(token,&value);
1045:   while (n < *nmax) {
1046:     if (!value) break;
1047:     PetscOptionsAtod(value,dvalue++);
1048:     PetscTokenFind(token,&value);
1049:     n++;
1050:   }
1051:   PetscTokenDestroy(token);
1052:   *nmax = n;
1053:   return(0);
1054: }

1056: /*@C
1057:    PetscOptionsGetIntArray - Gets an array of integer values for a particular 
1058:    option in the database.  The values must be separated with commas with 
1059:    no intervening spaces. 

1061:    Not Collective

1063:    Input Parameters:
1064: +  pre - string to prepend to each name or PETSC_NULL
1065: .  name - the option one is seeking
1066: -  nmax - maximum number of values to retrieve

1068:    Output Parameter:
1069: +  dvalue - the integer values to return
1070: .  nmax - actual number of values retreived
1071: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1073:    Level: beginner

1075:    Concepts: options database^array of ints

1077: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1078:            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsLogical(),
1079:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1080:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1081:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
1082:           PetscOptionsList(), PetscOptionsEList()
1083: @*/
1084: int PetscOptionsGetIntArray(const char pre[],const char name[],int dvalue[],int *nmax,PetscTruth *flg)
1085: {
1086:   char       *value;
1087:   int        n = 0,ierr;
1088:   PetscTruth flag;
1089:   PetscToken *token;

1093:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1094:   if (!flag)  {if (flg) *flg = PETSC_FALSE; *nmax = 0; return(0);}
1095:   if (!value) {if (flg) *flg = PETSC_TRUE; *nmax = 0; return(0);}

1097:   if (flg) *flg = PETSC_TRUE;

1099:   PetscTokenCreate(value,',',&token);
1100:   PetscTokenFind(token,&value);
1101:   while (n < *nmax) {
1102:     if (!value) break;
1103:     ierr      = PetscOptionsAtoi(value,dvalue);
1104:     dvalue++;
1105:     ierr      = PetscTokenFind(token,&value);
1106:     n++;
1107:   }
1108:   ierr      = PetscTokenDestroy(token);
1109:   *nmax = n;
1110:   return(0);
1111: }

1113: /*@C
1114:    PetscOptionsGetString - Gets the string value for a particular option in
1115:    the database.

1117:    Not Collective

1119:    Input Parameters:
1120: +  pre - string to prepend to name or PETSC_NULL
1121: .  name - the option one is seeking
1122: -  len - maximum string length

1124:    Output Parameters:
1125: +  string - location to copy string
1126: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1128:    Level: beginner

1130:    Fortran Note:
1131:    The Fortran interface is slightly different from the C/C++
1132:    interface (len is not used).  Sample usage in Fortran follows
1133: .vb
1134:       character *20 string
1135:       integer   flg, ierr
1136:       call PetscOptionsGetString(PETSC_NULL_CHARACTER,'-s',string,flg,ierr)
1137: .ve

1139:    Concepts: options database^string

1141: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),  
1142:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsLogical(),
1143:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1144:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1145:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
1146:           PetscOptionsList(), PetscOptionsEList()
1147: @*/
1148: int PetscOptionsGetString(const char pre[],const char name[],char string[],int len,PetscTruth *flg)
1149: {
1150:   char       *value;
1151:   int        ierr;
1152:   PetscTruth flag;

1156:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1157:   if (!flag) {
1158:     if (flg) *flg = PETSC_FALSE;
1159:   } else {
1160:     if (flg) *flg = PETSC_TRUE;
1161:     if (value) {
1162:       PetscStrncpy(string,value,len);
1163:     } else {
1164:       PetscMemzero(string,len);
1165:     }
1166:   }
1167:   return(0);
1168: }

1170: /*@C
1171:    PetscOptionsGetStringArray - Gets an array of string values for a particular
1172:    option in the database. The values must be separated with commas with 
1173:    no intervening spaces. 

1175:    Not Collective

1177:    Input Parameters:
1178: +  pre - string to prepend to name or PETSC_NULL
1179: .  name - the option one is seeking
1180: -  nmax - maximum number of strings

1182:    Output Parameter:
1183: +  strings - location to copy strings
1184: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1186:    Level: beginner

1188:    Notes: 
1189:    The user should pass in an array of pointers to char, to hold all the
1190:    strings returned by this function.

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

1195:    Contributed by Matthew Knepley.

1197:    Concepts: options database^array of strings

1199: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),  
1200:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsLogical(),
1201:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1202:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1203:           PetscOptionsLogicalGroupBegin(), PetscOptionsLogicalGroup(), PetscOptionsLogicalGroupEnd(),
1204:           PetscOptionsList(), PetscOptionsEList()
1205: @*/
1206: int PetscOptionsGetStringArray(const char pre[],const char name[],char **strings,int *nmax,PetscTruth *flg)
1207: {
1208:   char       *value;
1209:   int        len,n,ierr;
1210:   PetscTruth flag;
1211:   PetscToken *token;
1212: 
1215:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1216:   if (!flag)  {*nmax = 0; if (flg) *flg = PETSC_FALSE; return(0);}
1217:   if (!value) {*nmax = 0; if (flg) *flg = PETSC_FALSE;return(0);}
1218:   if (!*nmax) {if (flg) *flg = PETSC_FALSE;return(0);}
1219:   if (flg) *flg = PETSC_TRUE;

1221:   PetscTokenCreate(value,',',&token);
1222:   PetscTokenFind(token,&value);
1223:   n = 0;
1224:   while (n < *nmax) {
1225:     if (!value) break;
1226:     PetscStrlen(value,&len);
1227:     PetscMalloc((len+1)*sizeof(char),&strings[n]);
1228:     PetscStrcpy(strings[n],value);
1229:     PetscTokenFind(token,&value);
1230:     n++;
1231:   }
1232:   PetscTokenDestroy(token);
1233:   *nmax = n;
1234:   return(0);
1235: }

1237: /*@C
1238:    PetscOptionsAllUsed - Returns a count of the number of options in the 
1239:    database that have never been selected.

1241:    Not Collective

1243:    Output Parameter:
1244: .   N - count of options not used

1246:    Level: advanced

1248: .seealso: PetscOptionsPrint()
1249: @*/
1250: int PetscOptionsAllUsed(int *N)
1251: {
1252:   int  i,n = 0;

1255:   for (i=0; i<options->N; i++) {
1256:     if (!options->used[i]) { n++; }
1257:   }
1258:   *N = n;
1259:   return(0);
1260: }

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

1265:   Not collective

1267:    Options Database Key:
1268: .  -options_left - Activates OptionsAllUsed() within PetscFinalize()

1270:   Level: advanced

1272: .seealso: PetscOptionsAllUsed()
1273: @*/
1274: int PetscOptionsLeft(void)
1275: {
1276:   int        i,ierr;

1279:   for (i=0; i<options->N; i++) {
1280:     if (!options->used[i]) {
1281:       if (options->values[i]) {
1282:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %sn",options->names[i],options->values[i]);
1283:       } else {
1284:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s no value n",options->names[i]);
1285:       }
1286:     }
1287:   }
1288:   return(0);
1289: }

1291: /*
1292:     PetscOptionsCreate - Creates the empty options database.

1294: */
1295: int PetscOptionsCreate(void)
1296: {

1300:   options = (PetscOptionsTable*)malloc(sizeof(PetscOptionsTable));
1301:   ierr    = PetscMemzero(options->used,MAXOPTIONS*sizeof(int));
1302:   options->namegiven = PETSC_FALSE;
1303:   options->N         = 0;
1304:   options->Naliases  = 0;
1305:   return(0);
1306: }