Actual source code: options.c

  1: #define PETSC_DLL
  2: /*
  3:    These routines simplify the use of command line, file options, etc., and are used to manipulate the options database.
  4:    This provides the low-level interface, the high level interface is in aoptions.c

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

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

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

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

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

 42: } PetscOptionsTable;


 45: static PetscOptionsTable      *options = 0;

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

 60: /*
 61:    PetscOptionsAtoi - Converts a string to an integer value. Handles special cases such as "default" and "decide"
 62: */
 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: /*
106:    Converts a string to PetscReal value. Handles special cases like "default" and "decide"
107: */
108: PetscErrorCode  PetscOptionsAtod(const char name[],PetscReal *a)
109: {
111:   size_t         len;
112:   PetscTruth     decide,tdefault;

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

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

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

142: /*
143:    PetscOptionsAtol - Converts string to PetscTruth, handles cases like "yes", "no", "true", "false", "0", "1"
144: */
145: PetscErrorCode  PetscOptionsAtol(const char value[], PetscTruth *a)
146: {
147:   PetscTruth     istrue, isfalse;
148:   size_t         len;

152:   PetscStrlen(value, &len);
153:   if (!len) SETERRQ(PETSC_ERR_ARG_WRONG, "Character string of length zero has no logical value");
154:   PetscStrcasecmp(value,"TRUE",&istrue);
155:   if (istrue) {*a = PETSC_TRUE; return(0);}
156:   PetscStrcasecmp(value,"YES",&istrue);
157:   if (istrue) {*a = PETSC_TRUE; return(0);}
158:   PetscStrcasecmp(value,"1",&istrue);
159:   if (istrue) {*a = PETSC_TRUE; return(0);}
160:   PetscStrcasecmp(value,"on",&istrue);
161:   if (istrue) {*a = PETSC_TRUE; return(0);}
162:   PetscStrcasecmp(value,"FALSE",&isfalse);
163:   if (isfalse) {*a = PETSC_FALSE; return(0);}
164:   PetscStrcasecmp(value,"NO",&isfalse);
165:   if (isfalse) {*a = PETSC_FALSE; return(0);}
166:   PetscStrcasecmp(value,"0",&isfalse);
167:   if (isfalse) {*a = PETSC_FALSE; return(0);}
168:   PetscStrcasecmp(value,"off",&isfalse);
169:   if (isfalse) {*a = PETSC_FALSE; return(0);}
170:   SETERRQ1(PETSC_ERR_ARG_WRONG, "Unknown logical value: %s", value);
171:   return(0);
172: }

176: /*@C
177:     PetscGetProgramName - Gets the name of the running program. 

179:     Not Collective

181:     Input Parameter:
182: .   len - length of the string name

184:     Output Parameter:
185: .   name - the name of the running program

187:    Level: advanced

189:     Notes:
190:     The name of the program is copied into the user-provided character
191:     array of length len.  On some machines the program name includes 
192:     its entire path, so one should generally set len >= PETSC_MAX_PATH_LEN.
193: @*/
194: PetscErrorCode  PetscGetProgramName(char name[],size_t len)
195: {

199:   if (!options) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call PetscInitialize() first");
200:   if (!options->namegiven) SETERRQ(PETSC_ERR_PLIB,"Unable to determine program name");
201:   PetscStrncpy(name,options->programname,len);
202:   return(0);
203: }

207: PetscErrorCode  PetscSetProgramName(const char name[])
208: {

212:   options->namegiven = PETSC_TRUE;
213:   PetscStrncpy(options->programname,name,PETSC_MAX_PATH_LEN);
214:   return(0);
215: }

219: /*@
220:     PetscOptionsValidKey - PETSc Options database keys must begin with a - followed by a letter.

222:    Input Parameter:
223: .    in_str - string to check if valid

225:    Output Parameter:
226: .    key - PETSC_TRUE if a valid key

228: @*/
229: PetscErrorCode  PetscOptionsValidKey(const char in_str[],PetscTruth *key)
230: {
232:   *key = PETSC_FALSE;
233:   if (!in_str) return(0);
234:   if (in_str[0] != '-') return(0);
235:   if ((in_str[1] < 'A') || (in_str[1] > 'z')) return(0);
236:   *key = PETSC_TRUE;
237:   return(0);
238: }

242: /*@C
243:      PetscOptionsInsertString - Inserts options into the database from a string

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

248:   Input Parameter:
249: .   in_str - string that contains options separated by blanks


252:   Level: intermediate

254:   Contributed by Boyana Norris

256: .seealso: PetscOptionsSetValue(), PetscOptionsPrint(), PetscOptionsHasName(), PetscOptionsGetInt(),
257:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsTruth(),
258:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
259:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
260:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
261:           PetscOptionsList(), PetscOptionsEList(), PetscOptionsInsertFile()

263: @*/
264: PetscErrorCode  PetscOptionsInsertString(const char in_str[])
265: {
266:   char           *first,*second;
268:   PetscToken     token;
269:   PetscTruth     key;

272:   PetscTokenCreate(in_str,' ',&token);
273:   PetscTokenFind(token,&first);
274:   while (first) {
275:     PetscOptionsValidKey(first,&key);
276:     if (key) {
277:       PetscTokenFind(token,&second);
278:       PetscOptionsValidKey(second,&key);
279:       if (!key) {
280:         PetscOptionsSetValue(first,second);
281:         PetscTokenFind(token,&first);
282:       } else {
283:         PetscOptionsSetValue(first,PETSC_NULL);
284:         first = second;
285:       }
286:     } else {
287:       PetscTokenFind(token,&first);
288:     }
289:   }
290:   PetscTokenDestroy(token);
291:   return(0);
292: }

294: /*
295:     Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free()
296: */
297: static char *Petscgetline(FILE * f)
298: {
299:   size_t size = 0;
300:   size_t len  = 0;
301:   size_t last = 0;
302:   char * buf  = PETSC_NULL;

304:   if (feof(f)) return 0;
305:   do {
306:     size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */
307:     buf = (char*)realloc((void *)buf,size); /* realloc(NULL,n) is the same as malloc(n) */
308:     /* Actually do the read. Note that fgets puts a terminal '\0' on the
309:     end of the string, so we make sure we overwrite this */
310:     if (!fgets(buf+len,size,f)) buf[len]=0;
311:     PetscStrlen(buf,&len);
312:     last = len - 1;
313:   } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r');
314:   if (len) return buf;
315:   free(buf);
316:   return 0;
317: }


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

325:      Collective on MPI_Comm

327:   Input Parameter:
328: +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
329: .   file - name of file
330: -   require - if PETSC_TRUE will generate an error if the file does not exist


333:   Level: intermediate

335: .seealso: PetscOptionsSetValue(), PetscOptionsPrint(), PetscOptionsHasName(), PetscOptionsGetInt(),
336:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsTruth(),
337:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
338:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
339:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
340:           PetscOptionsList(), PetscOptionsEList()

342: @*/
343: PetscErrorCode  PetscOptionsInsertFile(MPI_Comm comm,const char file[],PetscTruth require)
344: {
345:   char           *string,fname[PETSC_MAX_PATH_LEN],*first,*second,*third,*vstring = 0,*astring = 0;
347:   size_t         i,len;
348:   FILE           *fd;
349:   PetscToken     token;
350:   int            err;
351:   char           cmt[3]={'#','!','%'},*cmatch;
352:   PetscMPIInt    rank,cnt=0,acnt=0;

355:   MPI_Comm_rank(comm,&rank);
356:   if (!rank) {
357:     /* Warning: assume a maximum size for all options in a string */
358:     PetscMalloc(128000*sizeof(char),&vstring);
359:     vstring[0] = 0;
360:     PetscMalloc(64000*sizeof(char),&astring);
361:     astring[0] = 0;
362:     cnt     = 0;
363:     acnt    = 0;

365:     PetscFixFilename(file,fname);
366:     fd   = fopen(fname,"r");
367:     if (fd) {
368:       /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */
369:       PetscInfo1(0,"Opened options file %s\n",file);
370:       while ((string = Petscgetline(fd))) {
371:         /* eliminate comments from each line */
372:         for (i=0; i<3; i++){
373:           PetscStrchr(string,cmt[i],&cmatch);
374:           if (cmatch) *cmatch = 0;
375:         }
376:         PetscStrlen(string,&len);
377:         /* replace tabs, ^M, \n with " " */
378:         for (i=0; i<len; i++) {
379:           if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') {
380:             string[i] = ' ';
381:           }
382:         }
383:         PetscTokenCreate(string,' ',&token);
384:         free(string);
385:         PetscTokenFind(token,&first);
386:         if (!first) {
387:           goto destroy;
388:         } else if (!first[0]) { /* if first token is empty spaces, redo first token */
389:           PetscTokenFind(token,&first);
390:         }
391:         PetscTokenFind(token,&second);
392:         if (!first) {
393:           goto destroy;
394:         } else if (first[0] == '-') {
395:           /* warning: should be making sure we do not overfill vstring */
396:           PetscStrcat(vstring,first);
397:           PetscStrcat(vstring," ");
398:           if (second) {
399:             /* protect second with quotes in case it contains strings */
400:             PetscStrcat(vstring,"\"");
401:             PetscStrcat(vstring,second);
402:             PetscStrcat(vstring,"\"");
403:           }
404:           PetscStrcat(vstring," ");
405:         } else {
406:           PetscTruth match;

408:           PetscStrcasecmp(first,"alias",&match);
409:           if (match) {
410:             PetscTokenFind(token,&third);
411:             if (!third) SETERRQ1(PETSC_ERR_ARG_WRONG,"Error in options file:alias missing (%s)",second);
412:             PetscStrcat(astring,second);
413:             PetscStrcat(astring," ");
414:             PetscStrcat(astring,third);
415:             PetscStrcat(astring," ");
416:           } else {
417:             SETERRQ1(PETSC_ERR_ARG_WRONG,"Unknown statement in options file: (%s)",string);
418:           }
419:         }
420:         destroy:
421:         PetscTokenDestroy(token);
422:       }
423:       err = fclose(fd);
424:       if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
425:       PetscStrlen(astring,&len);
426:       acnt = PetscMPIIntCast(len);
427:       PetscStrlen(vstring,&len);
428:       cnt  = PetscMPIIntCast(len);
429:     } else if (require) {
430:       SETERRQ1(PETSC_ERR_USER,"Unable to open Options File %s",fname);
431:     }
432:   }

434:   MPI_Bcast(&acnt,1,MPI_INT,0,comm);
435:   if (acnt) {
436:     PetscToken token;
437:     char       *first,*second;

439:     if (rank) {
440:       PetscMalloc((acnt+1)*sizeof(char),&astring);
441:     }
442:     MPI_Bcast(astring,acnt,MPI_CHAR,0,comm);
443:     astring[acnt] = 0;
444:     PetscTokenCreate(astring,' ',&token);
445:     PetscTokenFind(token,&first);
446:     while (first) {
447:       PetscTokenFind(token,&second);
448:       PetscOptionsSetAlias(first,second);
449:       PetscTokenFind(token,&first);
450:     }
451:     PetscTokenDestroy(token);
452:   }

454:   MPI_Bcast(&cnt,1,MPI_INT,0,comm);
455:   if (cnt) {
456:     if (rank) {
457:       PetscMalloc((cnt+1)*sizeof(char),&vstring);
458:     }
459:     MPI_Bcast(vstring,cnt,MPI_CHAR,0,comm);
460:     vstring[cnt] = 0;
461:     PetscOptionsInsertString(vstring);
462:   }
463:   PetscFree(astring);
464:   PetscFree(vstring);
465:   return(0);
466: }

470: /*@C
471:    PetscOptionsInsert - Inserts into the options database from the command line,
472:                    the environmental variable and a file.

474:    Input Parameters:
475: +  argc - count of number of command line arguments
476: .  args - the command line arguments
477: -  file - optional filename, defaults to ~username/.petscrc

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

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

487:    Level: advanced

489:    Concepts: options database^adding

491: .seealso: PetscOptionsDestroy_Private(), PetscOptionsPrint(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
492:           PetscInitialize()
493: @*/
494: PetscErrorCode  PetscOptionsInsert(int *argc,char ***args,const char file[])
495: {
497:   PetscMPIInt    rank;
498:   char           pfile[PETSC_MAX_PATH_LEN];
499:   PetscTruth     flag = PETSC_FALSE;

502:   if (options == PETSC_NULL) {
503:     fprintf(stderr, "Options have not been enabled.\nYou might have forgotten to call PetscInitialize().\n");
504:     MPI_Abort(MPI_COMM_WORLD, PETSC_ERR_SUP);
505:   }
506:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

508:   options->argc     = (argc) ? *argc : 0;
509:   options->args     = (args) ? *args : PETSC_NULL;

511:   if (file) {
512:     PetscOptionsInsertFile(PETSC_COMM_WORLD,file,PETSC_TRUE);
513:   }
514:   PetscOptionsGetTruth(PETSC_NULL,"-skip_petscrc",&flag,PETSC_NULL);
515:   if (!flag) {
516:     PetscGetHomeDirectory(pfile,PETSC_MAX_PATH_LEN-16);
517:     /* warning: assumes all processes have a home directory or none, but nothing in between */
518:     if (pfile[0]) {
519:       PetscStrcat(pfile,"/.petscrc");
520:       PetscOptionsInsertFile(PETSC_COMM_WORLD,pfile,PETSC_FALSE);
521:     }
522:     PetscOptionsInsertFile(PETSC_COMM_WORLD,".petscrc",PETSC_FALSE);
523:     PetscOptionsInsertFile(PETSC_COMM_WORLD,"petscrc",PETSC_FALSE);
524:   }

526:   /* insert environmental options */
527:   {
528:     char   *eoptions = 0;
529:     size_t len = 0;
530:     if (!rank) {
531:       eoptions = (char*)getenv("PETSC_OPTIONS");
532:       PetscStrlen(eoptions,&len);
533:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
534:     } else {
535:       MPI_Bcast(&len,1,MPIU_SIZE_T,0,PETSC_COMM_WORLD);
536:       if (len) {
537:         PetscMalloc((len+1)*sizeof(char*),&eoptions);
538:       }
539:     }
540:     if (len) {
541:       MPI_Bcast(eoptions,len,MPI_CHAR,0,PETSC_COMM_WORLD);
542:       if (rank) eoptions[len] = 0;
543:       PetscOptionsInsertString(eoptions);
544:       if (rank) {PetscFree(eoptions);}
545:     }
546:   }

548:   /* insert command line options */
549:   if (argc && args && *argc) {
550:     int        left    = *argc - 1;
551:     char       **eargs = *args + 1;
552:     PetscTruth isoptions_file,isp4,tisp4,isp4yourname,isp4rmrank;

554:     while (left) {
555:       PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);
556:       PetscStrcasecmp(eargs[0],"-p4pg",&isp4);
557:       PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);
558:       PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);
559:       PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);
560:       isp4 = (PetscTruth) (isp4 || tisp4);
561:       PetscStrcasecmp(eargs[0],"-np",&tisp4);
562:       isp4 = (PetscTruth) (isp4 || tisp4);
563:       PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);

565:       if (eargs[0][0] != '-') {
566:         eargs++; left--;
567:       } else if (isoptions_file) {
568:         if (left <= 1) SETERRQ(PETSC_ERR_USER,"Missing filename for -options_file filename option");
569:         if (eargs[1][0] == '-') SETERRQ(PETSC_ERR_USER,"Missing filename for -options_file filename option");
570:         PetscOptionsInsertFile(PETSC_COMM_WORLD,eargs[1],PETSC_TRUE);
571:         eargs += 2; left -= 2;

573:       /*
574:          These are "bad" options that MPICH, etc put on the command line
575:          we strip them out here.
576:       */
577:       } else if (tisp4 || isp4rmrank) {
578:         eargs += 1; left -= 1;
579:       } else if (isp4 || isp4yourname) {
580:         eargs += 2; left -= 2;
581:       } else if ((left < 2) || ((eargs[1][0] == '-') &&
582:                ((eargs[1][1] > '9') || (eargs[1][1] < '0')))) {
583:         PetscOptionsSetValue(eargs[0],PETSC_NULL);
584:         eargs++; left--;
585:       } else {
586:         PetscOptionsSetValue(eargs[0],eargs[1]);
587:         eargs += 2; left -= 2;
588:       }
589:     }
590:   }
591:   return(0);
592: }

596: /*@C
597:    PetscOptionsPrint - Prints the options that have been loaded. This is
598:    useful for debugging purposes.

600:    Collective on PETSC_COMM_WORLD

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

605:    Options Database Key:
606: .  -optionstable - Activates PetscOptionsPrint() within PetscFinalize()

608:    Level: advanced

610:    Concepts: options database^printing

612: .seealso: PetscOptionsAllUsed()
613: @*/
614: PetscErrorCode  PetscOptionsPrint(FILE *fd)
615: {
617:   PetscInt       i;

620:   if (!fd) fd = PETSC_STDOUT;
621:   if (!options) {PetscOptionsInsert(0,0,0);}
622:   if (options->N) {
623:     PetscFPrintf(PETSC_COMM_WORLD,fd,"#PETSc Option Table entries:\n");
624:   } else {
625:     PetscFPrintf(PETSC_COMM_WORLD,fd,"#No PETSc Option Table entries\n");
626:   }
627:   for (i=0; i<options->N; i++) {
628:     if (options->values[i]) {
629:       PetscFPrintf(PETSC_COMM_WORLD,fd,"-%s %s\n",options->names[i],options->values[i]);
630:     } else {
631:       PetscFPrintf(PETSC_COMM_WORLD,fd,"-%s\n",options->names[i]);
632:     }
633:   }
634:   if (options->N) {
635:     PetscFPrintf(PETSC_COMM_WORLD,fd,"#End of PETSc Option Table entries\n");
636:   }
637:   return(0);
638: }

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

645:    Not Collective

647:    Output Parameter:
648: .  copts - pointer where string pointer is stored

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

652:    Level: advanced

654:    Concepts: options database^listing

656: .seealso: PetscOptionsAllUsed(), PetscOptionsPrint()
657: @*/
658: PetscErrorCode  PetscOptionsGetAll(char *copts[])
659: {
661:   PetscInt       i;
662:   size_t         len = 1,lent;
663:   char           *coptions;

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

668:   /* count the length of the required string */
669:   for (i=0; i<options->N; i++) {
670:     PetscStrlen(options->names[i],&lent);
671:     len += 2 + lent;
672:     if (options->values[i]) {
673:       PetscStrlen(options->values[i],&lent);
674:       len += 1 + lent;
675:     }
676:   }
677:   PetscMalloc(len*sizeof(char),&coptions);
678:   coptions[0] = 0;
679:   for (i=0; i<options->N; i++) {
680:     PetscStrcat(coptions,"-");
681:     PetscStrcat(coptions,options->names[i]);
682:     PetscStrcat(coptions," ");
683:     if (options->values[i]) {
684:       PetscStrcat(coptions,options->values[i]);
685:       PetscStrcat(coptions," ");
686:     }
687:   }
688:   *copts = coptions;
689:   return(0);
690: }

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

697:    Level: developer

699: .seealso: PetscOptionsInsert()
700: @*/
701: PetscErrorCode  PetscOptionsClear(void)
702: {
703:   PetscInt i;

706:   if (!options) return(0);
707:   for (i=0; i<options->N; i++) {
708:     if (options->names[i])  free(options->names[i]);
709:     if (options->values[i]) free(options->values[i]);
710:   }
711:   for (i=0; i<options->Naliases; i++) {
712:     free(options->aliases1[i]);
713:     free(options->aliases2[i]);
714:   }
715:   options->N        = 0;
716:   options->Naliases = 0;
717:   return(0);
718: }

722: /*@C
723:     PetscOptionsDestroy - Destroys the option database. 

725:     Note:
726:     Since PetscOptionsDestroy() is called by PetscFinalize(), the user 
727:     typically does not need to call this routine.

729:    Level: developer

731: .seealso: PetscOptionsInsert()
732: @*/
733: PetscErrorCode  PetscOptionsDestroy(void)
734: {

738:   if (!options) return(0);
739:   PetscOptionsClear();
740:   free(options);
741:   options = 0;
742:   return(0);
743: }

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

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

754:    Input Parameters:
755: +  name - name of option, this SHOULD have the - prepended
756: -  value - the option value (not used for all options)

758:    Level: intermediate

760:    Note:
761:    Only some options have values associated with them, such as
762:    -ksp_rtol tol.  Other options stand alone, such as -ksp_monitor.

764:   Concepts: options database^adding option

766: .seealso: PetscOptionsInsert()
767: @*/
768: PetscErrorCode  PetscOptionsSetValue(const char iname[],const char value[])
769: {
770:   size_t         len;
772:   PetscInt       N,n,i;
773:   char           **names;
774:   const char     *name = (char*)iname;
775:   PetscTruth     gt,match;

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

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

784:   name++;
785:   /* first check against aliases */
786:   N = options->Naliases;
787:   for (i=0; i<N; i++) {
788:     PetscStrcasecmp(options->aliases1[i],name,&match);
789:     if (match) {
790:       name = options->aliases2[i];
791:       break;
792:     }
793:   }

795:   N     = options->N;
796:   n     = N;
797:   names = options->names;
798: 
799:   for (i=0; i<N; i++) {
800:     PetscStrcasecmp(names[i],name,&match);
801:     PetscStrgrt(names[i],name,&gt);
802:     if (match) {
803:       if (options->values[i]) free(options->values[i]);
804:       PetscStrlen(value,&len);
805:       if (len) {
806:         options->values[i] = (char*)malloc((len+1)*sizeof(char));
807:         PetscStrcpy(options->values[i],value);
808:       } else { options->values[i] = 0;}
809:       PetscOptionsMonitor(name,value);
810:       return(0);
811:     } else if (gt) {
812:       n = i;
813:       break;
814:     }
815:   }
816:   if (N >= MAXOPTIONS) {
817:     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);
818:   }
819:   /* shift remaining values down 1 */
820:   for (i=N; i>n; i--) {
821:     options->names[i]  = options->names[i-1];
822:     options->values[i] = options->values[i-1];
823:     options->used[i]   = options->used[i-1];
824:   }
825:   /* insert new name and value */
826:   PetscStrlen(name,&len);
827:   options->names[n] = (char*)malloc((len+1)*sizeof(char));
828:   PetscStrcpy(options->names[n],name);
829:   PetscStrlen(value,&len);
830:   if (len) {
831:     options->values[n] = (char*)malloc((len+1)*sizeof(char));
832:     PetscStrcpy(options->values[n],value);
833:   } else {options->values[n] = 0;}
834:   options->used[n] = PETSC_FALSE;
835:   options->N++;
836:   PetscOptionsMonitor(name,value);
837:   return(0);
838: }

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

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

849:    Input Parameter:
850: .  name - name of option, this SHOULD have the - prepended

852:    Level: intermediate

854:    Concepts: options database^removing option
855: .seealso: PetscOptionsInsert()
856: @*/
857: PetscErrorCode  PetscOptionsClearValue(const char iname[])
858: {
860:   PetscInt       N,n,i;
861:   char           **names,*name=(char*)iname;
862:   PetscTruth     gt,match;

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

868:   name++;

870:   N     = options->N; n = 0;
871:   names = options->names;
872: 
873:   for (i=0; i<N; i++) {
874:     PetscStrcasecmp(names[i],name,&match);
875:     PetscStrgrt(names[i],name,&gt);
876:     if (match) {
877:       if (options->names[i])  free(options->names[i]);
878:       if (options->values[i]) free(options->values[i]);
879:       PetscOptionsMonitor(name,"");
880:       break;
881:     } else if (gt) {
882:       return(0); /* it was not listed */
883:     }
884:     n++;
885:   }
886:   if (n == N) return(0); /* it was not listed */

888:   /* shift remaining values down 1 */
889:   for (i=n; i<N-1; i++) {
890:     options->names[i]  = options->names[i+1];
891:     options->values[i] = options->values[i+1];
892:     options->used[i]   = options->used[i+1];
893:   }
894:   options->N--;
895:   return(0);
896: }

900: /*@C
901:    PetscOptionsSetAlias - Makes a key and alias for another key

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

906:    Input Parameters:
907: +  inewname - the alias
908: -  ioldname - the name that alias will refer to 

910:    Level: advanced

912: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
913:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsTruth(),
914:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
915:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
916:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
917:           PetscOptionsList(), PetscOptionsEList()
918: @*/
919: PetscErrorCode  PetscOptionsSetAlias(const char inewname[],const char ioldname[])
920: {
922:   PetscInt       n = options->Naliases;
923:   size_t         len;
924:   char           *newname = (char *)inewname,*oldname = (char*)ioldname;

927:   if (newname[0] != '-') SETERRQ1(PETSC_ERR_ARG_WRONG,"aliased must have -: Instead %s",newname);
928:   if (oldname[0] != '-') SETERRQ1(PETSC_ERR_ARG_WRONG,"aliasee must have -: Instead %s",oldname);
929:   if (n >= MAXALIASES) {
930:     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);
931:   }

933:   newname++; oldname++;
934:   PetscStrlen(newname,&len);
935:   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
936:   PetscStrcpy(options->aliases1[n],newname);
937:   PetscStrlen(oldname,&len);
938:   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
939:   PetscStrcpy(options->aliases2[n],oldname);
940:   options->Naliases++;
941:   return(0);
942: }

946: static PetscErrorCode PetscOptionsFindPair_Private(const char pre[],const char name[],char *value[],PetscTruth *flg)
947: {
949:   PetscInt       i,N;
950:   size_t         len;
951:   char           **names,tmp[256];
952:   PetscTruth     match;

955:   if (!options) {PetscOptionsInsert(0,0,0);}
956:   N = options->N;
957:   names = options->names;

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

961:   /* append prefix to name */
962:   if (pre) {
963:     if (pre[0] == '-') SETERRQ(PETSC_ERR_ARG_WRONG,"Prefix should not begin with a -");
964:     PetscStrncpy(tmp,pre,256);
965:     PetscStrlen(tmp,&len);
966:     PetscStrncat(tmp,name+1,256-len-1);
967:   } else {
968:     PetscStrncpy(tmp,name+1,256);
969:   }

971:   /* slow search */
972:   *flg = PETSC_FALSE;
973:   for (i=0; i<N; i++) {
974:     PetscStrcasecmp(names[i],tmp,&match);
975:     if (match) {
976:        *value           = options->values[i];
977:        options->used[i] = PETSC_TRUE;
978:        *flg             = PETSC_TRUE;
979:        break;
980:      }
981:   }
982:   if (!*flg) {
983:     PetscInt j,cnt = 0,locs[16],loce[16];
984:     size_t   n;
985:     PetscStrlen(tmp,&n);
986:     /* determine the location and number of all _%d_ in the key */
987:     for (i=0; i< (PetscInt)n; i++) {
988:       if (tmp[i] == '_') {
989:         for (j=i+1; j< (PetscInt)n; j++) {
990:           if (tmp[j] >= '0' && tmp[j] <= '9') continue;
991:           if (tmp[j] == '_' && j > i+1) { /* found a number */
992:             locs[cnt]   = i+1;
993:             loce[cnt++] = j+1;
994:           }
995:           break;
996:         }
997:       }
998:     }
999:     if (cnt) {
1000:       char tmp2[256];
1001:       for (i=0; i<cnt; i++) {
1002:         PetscStrcpy(tmp2,"-");
1003:         PetscStrncat(tmp2,tmp,locs[i]);
1004:         PetscStrcat(tmp2,tmp+loce[i]);
1005:         PetscOptionsFindPair_Private(PETSC_NULL,tmp2,value,flg);
1006:         if (*flg) break;
1007:       }
1008:     }
1009:   }
1010:   return(0);
1011: }

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

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

1021:    Input Parameters:
1022: +  name - the option one is seeking 
1023: -  mess - error message (may be PETSC_NULL)

1025:    Level: advanced

1027:    Concepts: options database^rejecting option

1029: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1030:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1031:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1032:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1033:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1034:           PetscOptionsList(), PetscOptionsEList()
1035: @*/
1036: PetscErrorCode  PetscOptionsReject(const char name[],const char mess[])
1037: {
1039:   PetscTruth     flag = PETSC_FALSE;

1042:   PetscOptionsHasName(PETSC_NULL,name,&flag);
1043:   if (flag) {
1044:     if (mess) {
1045:       SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s with %s",name,mess);
1046:     } else {
1047:       SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s",name);
1048:     }
1049:   }
1050:   return(0);
1051: }

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

1059:    Not Collective

1061:    Input Parameters:
1062: +  name - the option one is seeking 
1063: -  pre - string to prepend to the name or PETSC_NULL

1065:    Output Parameters:
1066: .  flg - PETSC_TRUE if found else PETSC_FALSE.

1068:    Level: beginner

1070:    Concepts: options database^has option name

1072:    Notes: Name cannot be simply -h

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

1076: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1077:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1078:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1079:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1080:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1081:           PetscOptionsList(), PetscOptionsEList()
1082: @*/
1083: PetscErrorCode  PetscOptionsHasName(const char pre[],const char name[],PetscTruth *flg)
1084: {
1085:   char           *value;
1087:   PetscTruth     flag;

1090:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1091:   if (flg) *flg = flag;
1092:   return(0);
1093: }

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

1100:    Not Collective

1102:    Input Parameters:
1103: +  pre - the string to prepend to the name or PETSC_NULL
1104: -  name - the option one is seeking

1106:    Output Parameter:
1107: +  ivalue - the integer value to return
1108: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1110:    Level: beginner

1112:    Concepts: options database^has int

1114: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1115:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth()
1116:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsTruth(),
1117:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1118:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1119:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1120:           PetscOptionsList(), PetscOptionsEList()
1121: @*/
1122: PetscErrorCode  PetscOptionsGetInt(const char pre[],const char name[],PetscInt *ivalue,PetscTruth *flg)
1123: {
1124:   char           *value;
1126:   PetscTruth     flag;

1131:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1132:   if (flag) {
1133:     if (!value) {if (flg) *flg = PETSC_FALSE;}
1134:     else {
1135:       if (flg) *flg = PETSC_TRUE;
1136:       PetscOptionsAtoi(value,ivalue);
1137:     }
1138:   } else {
1139:     if (flg) *flg = PETSC_FALSE;
1140:   }
1141:   return(0);
1142: }

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

1149:    Not Collective

1151:    Input Parameters:
1152: +  pre - the string to prepend to the name or PETSC_NULL
1153: .  opt - option name
1154: .  list - the possible choices
1155: .  ntext - number of choices

1157:    Output Parameter:
1158: +  value - the index of the value to return
1159: -  set - PETSC_TRUE if found, else PETSC_FALSE
1160:    
1161:    Level: intermediate

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

1165:    Concepts: options database^list

1167: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),  
1168:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1169:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1170:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1171:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1172:           PetscOptionsList(), PetscOptionsEList()
1173: @*/
1174: PetscErrorCode  PetscOptionsGetEList(const char pre[],const char opt[],const char *const*list,PetscInt ntext,PetscInt *value,PetscTruth *set)
1175: {
1177:   size_t         alen,len = 0;
1178:   char           *svalue;
1179:   PetscTruth     aset,flg = PETSC_FALSE;
1180:   PetscInt       i;

1183:   for ( i=0; i<ntext; i++) {
1184:     PetscStrlen(list[i],&alen);
1185:     if (alen > len) len = alen;
1186:   }
1187:   len += 5; /* a little extra space for user mistypes */
1188:   PetscMalloc(len*sizeof(char),&svalue);
1189:   PetscOptionsGetString(pre,opt,svalue,len,&aset);
1190:   if (aset) {
1191:     if (set) *set = PETSC_TRUE;
1192:     for (i=0; i<ntext; i++) {
1193:       PetscStrcasecmp(svalue,list[i],&flg);
1194:       if (flg) {
1195:         *value = i;
1196:         break;
1197:       }
1198:     }
1199:     if (!flg) SETERRQ3(PETSC_ERR_USER,"Unknown option %s for -%s%s",svalue,pre?pre:"",opt+1);
1200:   } else if (set) {
1201:     *set = PETSC_FALSE;
1202:   }
1203:   PetscFree(svalue);
1204:   return(0);
1205: }

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

1212:    Not Collective

1214:    Input Parameters:
1215: +  pre - option prefix or PETSC_NULL
1216: .  opt - option name
1217: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
1218: -  defaultv - the default (current) value

1220:    Output Parameter:
1221: +  value - the  value to return
1222: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1224:    Level: beginner

1226:    Concepts: options database

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

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

1232: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
1233:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth()
1234:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsTruth(),
1235:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1236:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1237:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1238:           PetscOptionsList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
1239: @*/
1240: PetscErrorCode  PetscOptionsGetEnum(const char pre[],const char opt[],const char *const*list,PetscEnum *value,PetscTruth *set)
1241: {
1243:   PetscInt       ntext = 0,tval;
1244:   PetscTruth     fset;

1247:   while (list[ntext++]) {
1248:     if (ntext > 50) SETERRQ(PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
1249:   }
1250:   if (ntext < 3) SETERRQ(PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1251:   ntext -= 3;
1252:   PetscOptionsGetEList(pre,opt,list,ntext,&tval,&fset);
1253:   /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */
1254:   if (fset) *value = (PetscEnum)tval;
1255:   if (set) *set = fset;
1256:   return(0);
1257: }

1261: /*@C
1262:    PetscOptionsGetTruth - Gets the Logical (true or false) value for a particular 
1263:             option in the database.

1265:    Not Collective

1267:    Input Parameters:
1268: +  pre - the string to prepend to the name or PETSC_NULL
1269: -  name - the option one is seeking

1271:    Output Parameter:
1272: +  ivalue - the logical value to return
1273: -  flg - PETSC_TRUE  if found, else PETSC_FALSE

1275:    Level: beginner

1277:    Notes:
1278:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1279:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

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

1284:    Concepts: options database^has logical

1286: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
1287:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsTruth(),
1288:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1289:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1290:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1291:           PetscOptionsList(), PetscOptionsEList()
1292: @*/
1293: PetscErrorCode  PetscOptionsGetTruth(const char pre[],const char name[],PetscTruth *ivalue,PetscTruth *flg)
1294: {
1295:   char           *value;
1296:   PetscTruth     flag;

1302:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1303:   if (flag) {
1304:     if (flg) *flg = PETSC_TRUE;
1305:     if (!value) {
1306:       *ivalue = PETSC_TRUE;
1307:     } else {
1308:       PetscOptionsAtol(value, ivalue);
1309:     }
1310:   } else {
1311:     if (flg) *flg = PETSC_FALSE;
1312:   }
1313:   return(0);
1314: }

1318: /*@C
1319:    PetscOptionsGetTruthArray - Gets an array of Logical (true or false) values for a particular 
1320:    option in the database.  The values must be separated with commas with 
1321:    no intervening spaces. 

1323:    Not Collective

1325:    Input Parameters:
1326: +  pre - string to prepend to each name or PETSC_NULL
1327: .  name - the option one is seeking
1328: -  nmax - maximum number of values to retrieve

1330:    Output Parameter:
1331: +  dvalue - the integer values to return
1332: .  nmax - actual number of values retreived
1333: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1335:    Level: beginner

1337:    Concepts: options database^array of ints

1339:    Notes:
1340:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1341:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

1343: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1344:            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1345:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1346:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1347:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1348:           PetscOptionsList(), PetscOptionsEList()
1349: @*/
1350: PetscErrorCode  PetscOptionsGetTruthArray(const char pre[],const char name[],PetscTruth dvalue[],PetscInt *nmax,PetscTruth *flg)
1351: {
1352:   char           *value;
1354:   PetscInt       n = 0;
1355:   PetscTruth     flag;
1356:   PetscToken     token;

1361:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1362:   if (!flag)  {if (flg) *flg = PETSC_FALSE; *nmax = 0; return(0);}
1363:   if (!value) {if (flg) *flg = PETSC_TRUE; *nmax = 0; return(0);}

1365:   if (flg) *flg = PETSC_TRUE;

1367:   PetscTokenCreate(value,',',&token);
1368:   PetscTokenFind(token,&value);
1369:   while (n < *nmax) {
1370:     if (!value) break;
1371:     PetscOptionsAtol(value,dvalue);
1372:     PetscTokenFind(token,&value);
1373:     dvalue++;
1374:     n++;
1375:   }
1376:   PetscTokenDestroy(token);
1377:   *nmax = n;
1378:   return(0);
1379: }

1383: /*@C
1384:    PetscOptionsGetReal - Gets the double precision value for a particular 
1385:    option in the database.

1387:    Not Collective

1389:    Input Parameters:
1390: +  pre - string to prepend to each name or PETSC_NULL
1391: -  name - the option one is seeking

1393:    Output Parameter:
1394: +  dvalue - the double value to return
1395: -  flg - PETSC_TRUE if found, PETSC_FALSE if not found

1397:    Level: beginner

1399:    Concepts: options database^has double

1401: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1402:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsTruth(),
1403:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1404:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1405:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1406:           PetscOptionsList(), PetscOptionsEList()
1407: @*/
1408: PetscErrorCode  PetscOptionsGetReal(const char pre[],const char name[],PetscReal *dvalue,PetscTruth *flg)
1409: {
1410:   char           *value;
1412:   PetscTruth     flag;

1417:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1418:   if (flag) {
1419:     if (!value) {if (flg) *flg = PETSC_FALSE;}
1420:     else        {if (flg) *flg = PETSC_TRUE; PetscOptionsAtod(value,dvalue);}
1421:   } else {
1422:     if (flg) *flg = PETSC_FALSE;
1423:   }
1424:   return(0);
1425: }

1429: /*@C
1430:    PetscOptionsGetScalar - Gets the scalar value for a particular 
1431:    option in the database.

1433:    Not Collective

1435:    Input Parameters:
1436: +  pre - string to prepend to each name or PETSC_NULL
1437: -  name - the option one is seeking

1439:    Output Parameter:
1440: +  dvalue - the double value to return
1441: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1443:    Level: beginner

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

1449:    Concepts: options database^has scalar

1451: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1452:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1453:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1454:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1455:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1456:           PetscOptionsList(), PetscOptionsEList()
1457: @*/
1458: PetscErrorCode  PetscOptionsGetScalar(const char pre[],const char name[],PetscScalar *dvalue,PetscTruth *flg)
1459: {
1460:   char           *value;
1461:   PetscTruth     flag;

1467:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1468:   if (flag) {
1469:     if (!value) {
1470:       if (flg) *flg = PETSC_FALSE;
1471:     } else {
1472: #if !defined(PETSC_USE_COMPLEX)
1473:       PetscOptionsAtod(value,dvalue);
1474: #else
1475:       PetscReal  re=0.0,im=0.0;
1476:       PetscToken token;
1477:       char       *tvalue = 0;

1479:       PetscTokenCreate(value,',',&token);
1480:       PetscTokenFind(token,&tvalue);
1481:       if (!tvalue) { SETERRQ(PETSC_ERR_ARG_WRONG,"unknown string specified\n"); }
1482:       PetscOptionsAtod(tvalue,&re);
1483:       PetscTokenFind(token,&tvalue);
1484:       if (!tvalue) { /* Unknown separator used. using only real value */
1485:         *dvalue = re;
1486:       } else {
1487:         PetscOptionsAtod(tvalue,&im);
1488:         *dvalue = re + PETSC_i*im;
1489:       }
1490:       PetscTokenDestroy(token);
1491: #endif
1492:       if (flg) *flg    = PETSC_TRUE;
1493:     }
1494:   } else { /* flag */
1495:     if (flg) *flg = PETSC_FALSE;
1496:   }
1497:   return(0);
1498: }

1502: /*@C
1503:    PetscOptionsGetRealArray - Gets an array of double precision values for a 
1504:    particular option in the database.  The values must be separated with 
1505:    commas with no intervening spaces.

1507:    Not Collective

1509:    Input Parameters:
1510: +  pre - string to prepend to each name or PETSC_NULL
1511: .  name - the option one is seeking
1512: -  nmax - maximum number of values to retrieve

1514:    Output Parameters:
1515: +  dvalue - the double value to return
1516: .  nmax - actual number of values retreived
1517: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1519:    Level: beginner

1521:    Concepts: options database^array of doubles

1523: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1524:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsTruth(),
1525:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1526:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1527:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1528:           PetscOptionsList(), PetscOptionsEList()
1529: @*/
1530: PetscErrorCode  PetscOptionsGetRealArray(const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscTruth *flg)
1531: {
1532:   char           *value;
1534:   PetscInt       n = 0;
1535:   PetscTruth     flag;
1536:   PetscToken     token;

1541:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1542:   if (!flag)  {if (flg) *flg = PETSC_FALSE; *nmax = 0; return(0);}
1543:   if (!value) {if (flg) *flg = PETSC_TRUE; *nmax = 0; return(0);}

1545:   if (flg) *flg = PETSC_TRUE;

1547:   PetscTokenCreate(value,',',&token);
1548:   PetscTokenFind(token,&value);
1549:   while (n < *nmax) {
1550:     if (!value) break;
1551:     PetscOptionsAtod(value,dvalue++);
1552:     PetscTokenFind(token,&value);
1553:     n++;
1554:   }
1555:   PetscTokenDestroy(token);
1556:   *nmax = n;
1557:   return(0);
1558: }

1562: /*@C
1563:    PetscOptionsGetIntArray - Gets an array of integer values for a particular 
1564:    option in the database.  The values must be separated with commas with 
1565:    no intervening spaces. 

1567:    Not Collective

1569:    Input Parameters:
1570: +  pre - string to prepend to each name or PETSC_NULL
1571: .  name - the option one is seeking
1572: -  nmax - maximum number of values to retrieve, can include d-D to indicate d,d+1,..,D-1

1574:    Output Parameter:
1575: +  dvalue - the integer values to return
1576: .  nmax - actual number of values retreived
1577: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1579:    Level: beginner

1581:    Concepts: options database^array of ints

1583: .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 
1584:            PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1585:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1586:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1587:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1588:           PetscOptionsList(), PetscOptionsEList()
1589: @*/
1590: PetscErrorCode  PetscOptionsGetIntArray(const char pre[],const char name[],PetscInt dvalue[],PetscInt *nmax,PetscTruth *flg)
1591: {
1592:   char           *value;
1594:   PetscInt       n = 0,i,start,end;
1595:   size_t         len;
1596:   PetscTruth     flag,foundrange;
1597:   PetscToken     token;

1602:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1603:   if (!flag)  {if (flg) *flg = PETSC_FALSE; *nmax = 0; return(0);}
1604:   if (!value) {if (flg) *flg = PETSC_TRUE; *nmax = 0; return(0);}

1606:   if (flg) *flg = PETSC_TRUE;

1608:   PetscTokenCreate(value,',',&token);
1609:   PetscTokenFind(token,&value);
1610:   while (n < *nmax) {
1611:     if (!value) break;
1612: 
1613:     /* look for form  d-D where d and D are integers */
1614:     foundrange = PETSC_FALSE;
1615:     PetscStrlen(value,&len);
1616:     if (value[0] == '-') i=2;
1617:     else i=1;
1618:     for (;i<(int)len; i++) {
1619:       if (value[i] == '-') {
1620:         if (i == (int)len-1) SETERRQ2(PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value);
1621:         value[i] = 0;
1622:         PetscOptionsAtoi(value,&start);
1623:         PetscOptionsAtoi(value+i+1,&end);
1624:         if (end <= start) SETERRQ3(PETSC_ERR_USER,"Error in %D-th array entry, %s-%s cannot have decreasing list",n,value,value+i+1);
1625:         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);
1626:         for (;start<end; start++) {
1627:           *dvalue = start; dvalue++;n++;
1628:         }
1629:         foundrange = PETSC_TRUE;
1630:         break;
1631:       }
1632:     }
1633:     if (!foundrange) {
1634:       PetscOptionsAtoi(value,dvalue);
1635:       dvalue++;
1636:       n++;
1637:     }
1638:     PetscTokenFind(token,&value);
1639:   }
1640:   PetscTokenDestroy(token);
1641:   *nmax = n;
1642:   return(0);
1643: }

1647: /*@C
1648:    PetscOptionsGetString - Gets the string value for a particular option in
1649:    the database.

1651:    Not Collective

1653:    Input Parameters:
1654: +  pre - string to prepend to name or PETSC_NULL
1655: .  name - the option one is seeking
1656: -  len - maximum string length

1658:    Output Parameters:
1659: +  string - location to copy string
1660: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1662:    Level: beginner

1664:    Fortran Note:
1665:    The Fortran interface is slightly different from the C/C++
1666:    interface (len is not used).  Sample usage in Fortran follows
1667: .vb
1668:       character *20 string
1669:       integer   flg, ierr
1670:       call PetscOptionsGetString(PETSC_NULL_CHARACTER,'-s',string,flg,ierr)
1671: .ve

1673:    Concepts: options database^string

1675: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),  
1676:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1677:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1678:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1679:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1680:           PetscOptionsList(), PetscOptionsEList()
1681: @*/
1682: PetscErrorCode  PetscOptionsGetString(const char pre[],const char name[],char string[],size_t len,PetscTruth *flg)
1683: {
1684:   char           *value;
1686:   PetscTruth     flag;

1691:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1692:   if (!flag) {
1693:     if (flg) *flg = PETSC_FALSE;
1694:   } else {
1695:     if (flg) *flg = PETSC_TRUE;
1696:     if (value) {
1697:       PetscStrncpy(string,value,len);
1698:     } else {
1699:       PetscMemzero(string,len);
1700:     }
1701:   }
1702:   return(0);
1703: }

1707: /*@C
1708:    PetscOptionsGetStringArray - Gets an array of string values for a particular
1709:    option in the database. The values must be separated with commas with 
1710:    no intervening spaces. 

1712:    Not Collective

1714:    Input Parameters:
1715: +  pre - string to prepend to name or PETSC_NULL
1716: .  name - the option one is seeking
1717: -  nmax - maximum number of strings

1719:    Output Parameter:
1720: +  strings - location to copy strings
1721: -  flg - PETSC_TRUE if found, else PETSC_FALSE

1723:    Level: beginner

1725:    Notes: 
1726:    The user should pass in an array of pointers to char, to hold all the
1727:    strings returned by this function.

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

1732:    Contributed by Matthew Knepley.

1734:    Concepts: options database^array of strings

1736: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),  
1737:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsTruth(),
1738:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1739:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1740:           PetscOptionsTruthGroupBegin(), PetscOptionsTruthGroup(), PetscOptionsTruthGroupEnd(),
1741:           PetscOptionsList(), PetscOptionsEList()
1742: @*/
1743: PetscErrorCode  PetscOptionsGetStringArray(const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscTruth *flg)
1744: {
1745:   char           *value;
1747:   PetscInt       n;
1748:   PetscTruth     flag;
1749:   PetscToken     token;
1750: 
1754:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1755:   if (!flag)  {*nmax = 0; if (flg) *flg = PETSC_FALSE; return(0);}
1756:   if (!value) {*nmax = 0; if (flg) *flg = PETSC_FALSE;return(0);}
1757:   if (!*nmax) {if (flg) *flg = PETSC_FALSE;return(0);}
1758:   if (flg) *flg = PETSC_TRUE;

1760:   PetscTokenCreate(value,',',&token);
1761:   PetscTokenFind(token,&value);
1762:   n = 0;
1763:   while (n < *nmax) {
1764:     if (!value) break;
1765:     PetscStrallocpy(value,&strings[n]);
1766:     PetscTokenFind(token,&value);
1767:     n++;
1768:   }
1769:   PetscTokenDestroy(token);
1770:   *nmax = n;
1771:   return(0);
1772: }

1776: /*@C
1777:    PetscOptionsAllUsed - Returns a count of the number of options in the 
1778:    database that have never been selected.

1780:    Not Collective

1782:    Output Parameter:
1783: .   N - count of options not used

1785:    Level: advanced

1787: .seealso: PetscOptionsPrint()
1788: @*/
1789: PetscErrorCode  PetscOptionsAllUsed(int *N)
1790: {
1791:   PetscInt i,n = 0;

1794:   for (i=0; i<options->N; i++) {
1795:     if (!options->used[i]) { n++; }
1796:   }
1797:   *N = n;
1798:   return(0);
1799: }

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

1806:   Not collective

1808:    Options Database Key:
1809: .  -options_left - Activates OptionsAllUsed() within PetscFinalize()

1811:   Level: advanced

1813: .seealso: PetscOptionsAllUsed()
1814: @*/
1815: PetscErrorCode  PetscOptionsLeft(void)
1816: {
1818:   PetscInt       i;

1821:   for (i=0; i<options->N; i++) {
1822:     if (!options->used[i]) {
1823:       if (options->values[i]) {
1824:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",options->names[i],options->values[i]);
1825:       } else {
1826:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s no value \n",options->names[i]);
1827:       }
1828:     }
1829:   }
1830:   return(0);
1831: }


1836: /*
1837:     PetscOptionsCreate - Creates the empty options database.

1839: */
1840: PetscErrorCode  PetscOptionsCreate(void)
1841: {

1845:   options = (PetscOptionsTable*)malloc(sizeof(PetscOptionsTable));
1846:   PetscMemzero(options->used,MAXOPTIONS*sizeof(PetscTruth));
1847:   options->namegiven                 = PETSC_FALSE;
1848:   options->N                         = 0;
1849:   options->Naliases                  = 0;
1850:   options->numbermonitors         = 0;

1852:   PetscOptionsObject.prefix = PETSC_NULL;
1853:   PetscOptionsObject.title  = PETSC_NULL;
1854: 
1855:   return(0);
1856: }

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

1863:    Collective on PETSC_COMM_WORLD

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

1872:    Notes:
1873:    To see all options, run your program with the -help option or consult
1874:    the users manual. 

1876:    Level: intermediate

1878: .keywords: set, options, database
1879: @*/
1880: PetscErrorCode  PetscOptionsSetFromOptions(void)
1881: {
1882:   PetscTruth          flgc,flgm;
1883:   PetscErrorCode      ierr;
1884:   char                monfilename[PETSC_MAX_PATH_LEN];
1885:   PetscViewer         monviewer;

1888:   PetscOptionsBegin(PETSC_COMM_WORLD,"","Options database options","PetscOptions");
1889:     PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);
1890:     PetscOptionsName("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",&flgc);
1891:   PetscOptionsEnd();
1892:   if (flgm) {
1893:     PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);
1894:     PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerDestroy);
1895:   }
1896:   if (flgc) { PetscOptionsMonitorCancel(); }
1897:   return(0);
1898: }


1903: /*@C
1904:    PetscOptionsMonitorDefault - Print all options set value events.

1906:    Collective on PETSC_COMM_WORLD

1908:    Input Parameters:
1909: +  name  - option name string
1910: .  value - option value string
1911: -  dummy - unused monitor context 

1913:    Level: intermediate

1915: .keywords: PetscOptions, default, monitor

1917: .seealso: PetscOptionsMonitorSet()
1918: @*/
1919: PetscErrorCode  PetscOptionsMonitorDefault(const char name[], const char value[], void *dummy)
1920: {
1922:   PetscViewer    viewer = (PetscViewer) dummy;

1925:   if (!viewer) {
1926:     PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);
1927:   }
1928:   PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
1929:   return(0);
1930: }

1934: /*@C
1935:    PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that
1936:    modified the PETSc options database.
1937:       
1938:    Not collective

1940:    Input Parameters:
1941: +  monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring
1942: .  mctx    - [optional] context for private data for the
1943:              monitor routine (use PETSC_NULL if no context is desired)
1944: -  monitordestroy - [optional] routine that frees monitor context
1945:           (may be PETSC_NULL)

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

1950: +  name - option name string
1951: .  value - option value string
1952: -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()

1954:    Options Database Keys:
1955: +    -options_monitor    - sets PetscOptionsMonitorDefault()
1956: -    -options_monitor_cancel - cancels all monitors that have
1957:                           been hardwired into a code by 
1958:                           calls to PetscOptionsMonitorSet(), but
1959:                           does not cancel those set via
1960:                           the options database.

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

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

1971:    Level: beginner

1973: .keywords: PetscOptions, set, monitor

1975: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
1976: @*/
1977: PetscErrorCode  PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1978: {
1980:   if (options->numbermonitors >= MAXOPTIONSMONITORS) {
1981:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
1982:   }
1983:   options->monitor[options->numbermonitors]           = monitor;
1984:   options->monitordestroy[options->numbermonitors]    = monitordestroy;
1985:   options->monitorcontext[options->numbermonitors++]  = (void*)mctx;
1986:   return(0);
1987: }

1991: /*@
1992:    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.

1994:    Not collective 

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

2001:    Level: intermediate

2003: .keywords: PetscOptions, set, monitor

2005: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
2006: @*/
2007: PetscErrorCode  PetscOptionsMonitorCancel(void)
2008: {
2010:   PetscInt       i;

2013:   for (i=0; i<options->numbermonitors; i++) {
2014:     if (options->monitordestroy[i]) {
2015:       (*options->monitordestroy[i])(options->monitorcontext[i]);
2016:     }
2017:   }
2018:   options->numbermonitors = 0;
2019:   return(0);
2020: }