Actual source code: options.c

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

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

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

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

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

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

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

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


 51: static PetscOptionsTable      *options = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

266: /*@C
267:     PetscGetProgramName - Gets the name of the running program.

269:     Not Collective

271:     Input Parameter:
272: .   len - length of the string name

274:     Output Parameter:
275: .   name - the name of the running program

277:    Level: advanced

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

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

297: PetscErrorCode  PetscSetProgramName(const char name[])
298: {

302:   options->namegiven = PETSC_TRUE;

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

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

313:    Input Parameter:
314: .    in_str - string to check if valid

316:    Output Parameter:
317: .    key - PETSC_TRUE if a valid key

319:   Level: intermediate

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

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

342: /*@C
343:      PetscOptionsInsertString - Inserts options into the database from a string

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

348:   Input Parameter:
349: .   in_str - string that contains options separated by blanks


352:   Level: intermediate

354:   Contributed by Boyana Norris

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

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

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

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

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


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

434:      Collective on MPI_Comm

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


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

444:    Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options
445:    such as -log_summary or -malloc_debug are processed properly. This routine only sets options into the options database that will be processed by later
446:    calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize().

448:   Level: developer

450: .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
451:           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
452:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
453:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
454:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
455:           PetscOptionsFList(), PetscOptionsEList()

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

470:   MPI_Comm_rank(comm,&rank);
471:   if (!rank) {
472:     cnt        = 0;
473:     acnt       = 0;

475:     PetscFixFilename(file,fname);
476:     fd   = fopen(fname,"r");
477:     if (fd) {
478:       PetscSegBuffer vseg,aseg;
479:       PetscSegBufferCreate(1,4000,&vseg);
480:       PetscSegBufferCreate(1,2000,&aseg);

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

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

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

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

561:   counts[0] = acnt;
562:   counts[1] = cnt;
563:   MPI_Bcast(counts,2,MPI_INT,0,comm);
564:   acnt = counts[0];
565:   cnt = counts[1];
566:   if (rank) {
567:     PetscMalloc1(2+acnt+cnt,&packed);
568:   }
569:   if (acnt || cnt) {
570:     MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm);
571:     astring = packed;
572:     vstring = packed + acnt + 1;
573:   }

575:   if (acnt) {
576:     PetscToken token;
577:     char       *first,*second;

579:     PetscTokenCreate(astring,' ',&token);
580:     PetscTokenFind(token,&first);
581:     while (first) {
582:       PetscTokenFind(token,&second);
583:       PetscOptionsSetAlias(first,second);
584:       PetscTokenFind(token,&first);
585:     }
586:     PetscTokenDestroy(&token);
587:   }

589:   if (cnt) {
590:     PetscOptionsInsertString(vstring);
591:   }
592:   PetscFree(packed);
593:   return(0);
594: }

598: static PetscErrorCode PetscOptionsInsertArgs_Private(int argc,char *args[])
599: {
601:   int            left    = argc - 1;
602:   char           **eargs = args + 1;

605:   while (left) {
606:     PetscBool isoptions_file,isprefixpush,isprefixpop,isp4,tisp4,isp4yourname,isp4rmrank,key;
607:     PetscStrcasecmp(eargs[0],"-options_file",&isoptions_file);
608:     PetscStrcasecmp(eargs[0],"-prefix_push",&isprefixpush);
609:     PetscStrcasecmp(eargs[0],"-prefix_pop",&isprefixpop);
610:     PetscStrcasecmp(eargs[0],"-p4pg",&isp4);
611:     PetscStrcasecmp(eargs[0],"-p4yourname",&isp4yourname);
612:     PetscStrcasecmp(eargs[0],"-p4rmrank",&isp4rmrank);
613:     PetscStrcasecmp(eargs[0],"-p4wd",&tisp4);
614:     isp4 = (PetscBool) (isp4 || tisp4);
615:     PetscStrcasecmp(eargs[0],"-np",&tisp4);
616:     isp4 = (PetscBool) (isp4 || tisp4);
617:     PetscStrcasecmp(eargs[0],"-p4amslave",&tisp4);
618:     PetscOptionsValidKey(eargs[0],&key);

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

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


662: /*@C
663:    PetscOptionsInsert - Inserts into the options database from the command line,
664:                    the environmental variable and a file.

666:    Input Parameters:
667: +  argc - count of number of command line arguments
668: .  args - the command line arguments
669: -  file - optional filename, defaults to ~username/.petscrc

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

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

680:    Level: advanced

682:    Concepts: options database^adding

684: .seealso: PetscOptionsDestroy_Private(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(),
685:           PetscInitialize()
686: @*/
687: PetscErrorCode  PetscOptionsInsert(int *argc,char ***args,const char file[])
688: {
690:   PetscMPIInt    rank;
691:   char           pfile[PETSC_MAX_PATH_LEN];
692:   PetscBool      flag = PETSC_FALSE;

695:   if (!options) {
696:     fprintf(stderr, "Options have not been enabled.\nYou might have forgotten to call PetscInitialize().\n");
697:     MPI_Abort(MPI_COMM_WORLD, PETSC_ERR_SUP);
698:   }
699:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

701:   options->argc = (argc) ? *argc : 0;
702:   options->args = (args) ? *args : NULL;

704:   if (file && file[0]) {
705:     char fullpath[PETSC_MAX_PATH_LEN];

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

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

747: #if defined(PETSC_HAVE_YAML)
748:   char      yaml_file[PETSC_MAX_PATH_LEN];
749:   PetscBool yaml_flg = PETSC_FALSE;
750:   PetscOptionsGetString(NULL,"-options_file_yaml",yaml_file,PETSC_MAX_PATH_LEN,&yaml_flg);
751:   if (yaml_flg) PetscOptionsInsertFileYAML(PETSC_COMM_WORLD,yaml_file,PETSC_TRUE);
752: #endif

754:   /* insert command line options again because they take precedence over arguments in petscrc/environment */
755:   if (argc && args && *argc) {PetscOptionsInsertArgs_Private(*argc,*args);}
756:   return(0);
757: }

761: /*@C
762:    PetscOptionsView - Prints the options that have been loaded. This is
763:    useful for debugging purposes.

765:    Logically Collective on PetscViewer

767:    Input Parameter:
768: .  viewer - must be an PETSCVIEWERASCII viewer

770:    Options Database Key:
771: .  -options_table - Activates PetscOptionsView() within PetscFinalize()

773:    Level: advanced

775:    Concepts: options database^printing

777: .seealso: PetscOptionsAllUsed()
778: @*/
779: PetscErrorCode  PetscOptionsView(PetscViewer viewer)
780: {
782:   PetscInt       i;
783:   PetscBool      isascii;

786:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
787:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
788:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer");

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

811: /*
812:    Called by error handlers to print options used in run
813: */
814: PetscErrorCode  PetscOptionsViewError(void)
815: {
816:   PetscInt       i;

819:   if (options->N) {
820:     (*PetscErrorPrintf)("PETSc Option Table entries:\n");
821:   } else {
822:     (*PetscErrorPrintf)("No PETSc Option Table entries\n");
823:   }
824:   for (i=0; i<options->N; i++) {
825:     if (options->values[i]) {
826:       (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]);
827:     } else {
828:       (*PetscErrorPrintf)("-%s\n",options->names[i]);
829:     }
830:   }
831:   return(0);
832: }

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

839:    Not Collective

841:    Output Parameter:
842: .  copts - pointer where string pointer is stored

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

846:    Level: advanced

848:    Concepts: options database^listing

850: .seealso: PetscOptionsAllUsed(), PetscOptionsView()
851: @*/
852: PetscErrorCode  PetscOptionsGetAll(char *copts[])
853: {
855:   PetscInt       i;
856:   size_t         len       = 1,lent = 0;
857:   char           *coptions = NULL;

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

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

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

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

893:    Input Parameter:
894: .  prefix - The string to append to the existing prefix

896:    Options Database Keys:
897:  +   -prefix_push <some_prefix_> - push the given prefix
898:  -   -prefix_pop - pop the last prefix

900:    Notes:
901:    It is common to use this in conjunction with -options_file as in

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

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

907: Level: advanced

909: .seealso: PetscOptionsPrefixPop()
910: @*/
911: PetscErrorCode  PetscOptionsPrefixPush(const char prefix[])
912: {
914:   size_t         n;
915:   PetscInt       start;
916:   char           buf[2048];
917:   PetscBool      key;

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

928:   if (!options) {PetscOptionsInsert(0,0,0);}
929:   if (options->prefixind >= MAXPREFIXES) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum depth of prefix stack %d exceeded, recompile \n src/sys/objects/options.c with larger value for MAXPREFIXES",MAXPREFIXES);
930:   start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
931:   PetscStrlen(prefix,&n);
932:   if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix));
933:   PetscMemcpy(options->prefix+start,prefix,n+1);
934:   options->prefixstack[options->prefixind++] = start+n;
935:   return(0);
936: }

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

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

945:    Level: advanced

947: .seealso: PetscOptionsPrefixPush()
948: @*/
949: PetscErrorCode  PetscOptionsPrefixPop(void)
950: {
951:   PetscInt offset;

954:   if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed");
955:   options->prefixind--;
956:   offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0;
957:   options->prefix[offset] = 0;
958:   return(0);
959: }

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

966:    Level: developer

968: .seealso: PetscOptionsInsert()
969: @*/
970: PetscErrorCode  PetscOptionsClear(void)
971: {
972:   PetscInt i;

975:   if (!options) return(0);
976:   for (i=0; i<options->N; i++) {
977:     if (options->names[i])  free(options->names[i]);
978:     if (options->values[i]) free(options->values[i]);
979:   }
980:   for (i=0; i<options->Naliases; i++) {
981:     free(options->aliases1[i]);
982:     free(options->aliases2[i]);
983:   }
984:   options->prefix[0] = 0;
985:   options->prefixind = 0;
986:   options->N         = 0;
987:   options->Naliases  = 0;
988:   return(0);
989: }

993: /*@C
994:     PetscOptionsDestroy - Destroys the option database.

996:     Note:
997:     Since PetscOptionsDestroy() is called by PetscFinalize(), the user
998:     typically does not need to call this routine.

1000:    Level: developer

1002: .seealso: PetscOptionsInsert()
1003: @*/
1004: PetscErrorCode  PetscOptionsDestroy(void)
1005: {

1009:   if (!options) return(0);
1010:   PetscOptionsClear();
1011:   free(options);
1012:   options = 0;
1013:   return(0);
1014: }

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

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

1025:    Input Parameters:
1026: +  name - name of option, this SHOULD have the - prepended
1027: -  value - the option value (not used for all options)

1029:    Level: intermediate

1031:    Note:
1032:    Only some options have values associated with them, such as
1033:    -ksp_rtol tol.  Other options stand alone, such as -ksp_monitor.

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

1037:   Concepts: options database^adding option

1039: .seealso: PetscOptionsInsert()
1040: @*/
1041: PetscErrorCode  PetscOptionsSetValue(const char iname[],const char value[])
1042: {
1043:   size_t         len;
1045:   PetscInt       N,n,i;
1046:   char           **names;
1047:   char           fullname[2048];
1048:   const char     *name = iname;
1049:   PetscBool      gt,match;

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

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

1058:   name++; /* skip starting hyphen */
1059:   if (options->prefixind > 0) {
1060:     PetscStrncpy(fullname,options->prefix,sizeof(fullname));
1061:     PetscStrncat(fullname,name,sizeof(fullname));
1062:     name = fullname;
1063:   }

1065:   /* check against aliases */
1066:   N = options->Naliases;
1067:   for (i=0; i<N; i++) {
1068:     PetscStrcasecmp(options->aliases1[i],name,&match);
1069:     if (match) {
1070:       name = options->aliases2[i];
1071:       break;
1072:     }
1073:   }

1075:   N     = options->N;
1076:   n     = N;
1077:   names = options->names;

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

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

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

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

1128:    Input Parameter:
1129: .  name - name of option, this SHOULD have the - prepended

1131:    Level: intermediate

1133:    Concepts: options database^removing option
1134: .seealso: PetscOptionsInsert()
1135: @*/
1136: PetscErrorCode  PetscOptionsClearValue(const char iname[])
1137: {
1139:   PetscInt       N,n,i;
1140:   char           **names,*name=(char*)iname;
1141:   PetscBool      gt,match;

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

1147:   name++;

1149:   N     = options->N; n = 0;
1150:   names = options->names;

1152:   for (i=0; i<N; i++) {
1153:     PetscStrcasecmp(names[i],name,&match);
1154:     PetscStrgrt(names[i],name,&gt);
1155:     if (match) {
1156:       if (options->names[i])  free(options->names[i]);
1157:       if (options->values[i]) free(options->values[i]);
1158:       PetscOptionsMonitor(name,"");
1159:       break;
1160:     } else if (gt) return(0); /* it was not listed */

1162:     n++;
1163:   }
1164:   if (n == N) return(0); /* it was not listed */

1166:   /* shift remaining values down 1 */
1167:   for (i=n; i<N-1; i++) {
1168:     options->names[i]  = options->names[i+1];
1169:     options->values[i] = options->values[i+1];
1170:     options->used[i]   = options->used[i+1];
1171:   }
1172:   options->N--;
1173:   return(0);
1174: }

1178: /*@C
1179:    PetscOptionsSetAlias - Makes a key and alias for another key

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

1184:    Input Parameters:
1185: +  inewname - the alias
1186: -  ioldname - the name that alias will refer to

1188:    Level: advanced

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

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

1209:   newname++; oldname++;
1210:   PetscStrlen(newname,&len);
1211:   options->aliases1[n] = (char*)malloc((len+1)*sizeof(char));
1212:   PetscStrcpy(options->aliases1[n],newname);
1213:   PetscStrlen(oldname,&len);
1214:   options->aliases2[n] = (char*)malloc((len+1)*sizeof(char));
1215:   PetscStrcpy(options->aliases2[n],oldname);
1216:   options->Naliases++;
1217:   return(0);
1218: }

1222: PetscErrorCode PetscOptionsFindPair_Private(const char pre[],const char name[],char *value[],PetscBool  *flg)
1223: {
1225:   PetscInt       i,N;
1226:   size_t         len;
1227:   char           **names,tmp[256];
1228:   PetscBool      match;

1231:   if (!options) {PetscOptionsInsert(0,0,0);}
1232:   N     = options->N;
1233:   names = options->names;

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

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

1259:     PetscMemcpy(key+1,tmp,sizeof(tmp));
1260:     PetscOptionsValidKey(key,&valid);
1261:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1262:   }
1263: #endif

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

1309: PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(const char pre[], const char name[], char *value[], PetscBool *flg)
1310: {
1312:   PetscInt       i,N;
1313:   size_t         len;
1314:   char           **names,tmp[256];
1315:   PetscBool      match;

1318:   if (!options) {PetscOptionsInsert(0,0,0);}
1319:   N     = options->N;
1320:   names = options->names;

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

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

1346:     PetscMemcpy(key+1,tmp,sizeof(tmp));
1347:     PetscOptionsValidKey(key,&valid);
1348:     if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name);
1349:   }
1350: #endif

1352:   /* slow search */
1353:   *flg = PETSC_FALSE;
1354:   PetscStrlen(tmp,&len);
1355:   for (i = 0; i < N; ++i) {
1356:     PetscStrncmp(names[i], tmp, len, &match);
1357:     if (match) {
1358:       if (value) *value = options->values[i];
1359:       options->used[i]  = PETSC_TRUE;
1360:       if (flg)   *flg   = PETSC_TRUE;
1361:       break;
1362:     }
1363:   }
1364:   return(0);
1365: }

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

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

1375:    Input Parameters:
1376: +  name - the option one is seeking
1377: -  mess - error message (may be NULL)

1379:    Level: advanced

1381:    Concepts: options database^rejecting option

1383: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(),
1384:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1385:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1386:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1387:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1388:           PetscOptionsFList(), PetscOptionsEList()
1389: @*/
1390: PetscErrorCode  PetscOptionsReject(const char name[],const char mess[])
1391: {
1393:   PetscBool      flag = PETSC_FALSE;

1396:   PetscOptionsHasName(NULL,name,&flag);
1397:   if (flag) {
1398:     if (mess) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s with %s",name,mess);
1399:     else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: %s",name);
1400:   }
1401:   return(0);
1402: }

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

1410:    Not Collective

1412:    Input Parameters:
1413: +  name - the option one is seeking
1414: -  pre - string to prepend to the name or NULL

1416:    Output Parameters:
1417: .  set - PETSC_TRUE if found else PETSC_FALSE.

1419:    Level: beginner

1421:    Concepts: options database^has option name

1423:    Notes: Name cannot be simply -h

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

1427: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
1428:            PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
1429:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
1430:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
1431:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
1432:           PetscOptionsFList(), PetscOptionsEList()
1433: @*/
1434: PetscErrorCode  PetscOptionsHasName(const char pre[],const char name[],PetscBool  *set)
1435: {
1436:   char           *value;
1438:   PetscBool      flag;

1441:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1442:   if (set) *set = flag;
1443:   return(0);
1444: }

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

1451:    Not Collective

1453:    Input Parameters:
1454: +  pre - the string to prepend to the name or NULL
1455: -  name - the option one is seeking

1457:    Output Parameter:
1458: +  ivalue - the integer value to return
1459: -  set - PETSC_TRUE if found, else PETSC_FALSE

1461:    Level: beginner

1463:    Concepts: options database^has int

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

1482:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1483:   if (flag) {
1484:     if (!value) {
1485:       if (set) *set = PETSC_FALSE;
1486:     } else {
1487:       if (set) *set = PETSC_TRUE;
1488:       PetscOptionsStringToInt(value,ivalue);
1489:     }
1490:   } else {
1491:     if (set) *set = PETSC_FALSE;
1492:   }
1493:   return(0);
1494: }

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

1501:    Not Collective

1503:    Input Parameters:
1504: +  pre - the string to prepend to the name or NULL
1505: .  opt - option name
1506: .  list - the possible choices (one of these must be selected, anything else is invalid)
1507: .  ntext - number of choices

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

1513:    Level: intermediate

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

1517:    Concepts: options database^list

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

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

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

1556:    Not Collective

1558:    Input Parameters:
1559: +  pre - option prefix or NULL
1560: .  opt - option name
1561: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
1562: -  defaultv - the default (current) value

1564:    Output Parameter:
1565: +  value - the  value to return
1566: -  set - PETSC_TRUE if found, else PETSC_FALSE

1568:    Level: beginner

1570:    Concepts: options database

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

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

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

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

1605: /*@C
1606:    PetscOptionsGetBool - Gets the Logical (true or false) value for a particular
1607:             option in the database.

1609:    Not Collective

1611:    Input Parameters:
1612: +  pre - the string to prepend to the name or NULL
1613: -  name - the option one is seeking

1615:    Output Parameter:
1616: +  ivalue - the logical value to return
1617: -  set - PETSC_TRUE  if found, else PETSC_FALSE

1619:    Level: beginner

1621:    Notes:
1622:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1623:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

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

1628:    Concepts: options database^has logical

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

1646:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1647:   if (flag) {
1648:     if (set) *set = PETSC_TRUE;
1649:     if (!value) *ivalue = PETSC_TRUE;
1650:     else {
1651:       PetscOptionsStringToBool(value, ivalue);
1652:     }
1653:   } else {
1654:     if (set) *set = PETSC_FALSE;
1655:   }
1656:   return(0);
1657: }

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

1666:    Not Collective

1668:    Input Parameters:
1669: +  pre - string to prepend to each name or NULL
1670: .  name - the option one is seeking
1671: -  nmax - maximum number of values to retrieve

1673:    Output Parameter:
1674: +  dvalue - the integer values to return
1675: .  nmax - actual number of values retreived
1676: -  set - PETSC_TRUE if found, else PETSC_FALSE

1678:    Level: beginner

1680:    Concepts: options database^array of ints

1682:    Notes:
1683:        TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE
1684:        FALSE, false, NO, no, and 0 all translate to PETSC_FALSE

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

1704:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1705:   if (!flag)  {if (set) *set = PETSC_FALSE; *nmax = 0; return(0);}
1706:   if (!value) {if (set) *set = PETSC_TRUE;  *nmax = 0; return(0);}

1708:   if (set) *set = PETSC_TRUE;

1710:   PetscTokenCreate(value,',',&token);
1711:   PetscTokenFind(token,&value);
1712:   while (n < *nmax) {
1713:     if (!value) break;
1714:     PetscOptionsStringToBool(value,dvalue);
1715:     PetscTokenFind(token,&value);
1716:     dvalue++;
1717:     n++;
1718:   }
1719:   PetscTokenDestroy(&token);
1720:   *nmax = n;
1721:   return(0);
1722: }

1726: /*@C
1727:    PetscOptionsGetReal - Gets the double precision value for a particular
1728:    option in the database.

1730:    Not Collective

1732:    Input Parameters:
1733: +  pre - string to prepend to each name or NULL
1734: -  name - the option one is seeking

1736:    Output Parameter:
1737: +  dvalue - the double value to return
1738: -  set - PETSC_TRUE if found, PETSC_FALSE if not found

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

1742:    Level: beginner

1744:    Concepts: options database^has double

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

1762:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1763:   if (flag) {
1764:     if (!value) {
1765:       if (set) *set = PETSC_FALSE;
1766:     } else {
1767:       if (set) *set = PETSC_TRUE;
1768:       PetscOptionsStringToReal(value,dvalue);
1769:     }
1770:   } else {
1771:     if (set) *set = PETSC_FALSE;
1772:   }
1773:   return(0);
1774: }

1778: /*@C
1779:    PetscOptionsGetScalar - Gets the scalar value for a particular
1780:    option in the database.

1782:    Not Collective

1784:    Input Parameters:
1785: +  pre - string to prepend to each name or NULL
1786: -  name - the option one is seeking

1788:    Output Parameter:
1789: +  dvalue - the double value to return
1790: -  set - PETSC_TRUE if found, else PETSC_FALSE

1792:    Level: beginner

1794:    Usage:
1795:    A complex number 2+3i must be specified with NO spaces

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

1799:    Concepts: options database^has scalar

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

1817:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1818:   if (flag) {
1819:     if (!value) {
1820:       if (set) *set = PETSC_FALSE;
1821:     } else {
1822: #if !defined(PETSC_USE_COMPLEX)
1823:       PetscOptionsStringToReal(value,dvalue);
1824: #else
1825:       PetscOptionsStringToScalar(value,dvalue);
1826: #endif
1827:       if (set) *set = PETSC_TRUE;
1828:     }
1829:   } else { /* flag */
1830:     if (set) *set = PETSC_FALSE;
1831:   }
1832:   return(0);
1833: }

1837: /*@C
1838:    PetscOptionsGetRealArray - Gets an array of double precision values for a
1839:    particular option in the database.  The values must be separated with
1840:    commas with no intervening spaces.

1842:    Not Collective

1844:    Input Parameters:
1845: +  pre - string to prepend to each name or NULL
1846: .  name - the option one is seeking
1847: -  nmax - maximum number of values to retrieve

1849:    Output Parameters:
1850: +  dvalue - the double values to return
1851: .  nmax - actual number of values retreived
1852: -  set - PETSC_TRUE if found, else PETSC_FALSE

1854:    Level: beginner

1856:    Concepts: options database^array of doubles

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

1876:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1877:   if (!flag) {
1878:     if (set) *set = PETSC_FALSE;
1879:     *nmax = 0;
1880:     return(0);
1881:   }
1882:   if (!value) {
1883:     if (set) *set = PETSC_TRUE;
1884:     *nmax = 0;
1885:     return(0);
1886:   }

1888:   if (set) *set = PETSC_TRUE;

1890:   PetscTokenCreate(value,',',&token);
1891:   PetscTokenFind(token,&value);
1892:   while (n < *nmax) {
1893:     if (!value) break;
1894:     PetscOptionsStringToReal(value,dvalue++);
1895:     PetscTokenFind(token,&value);
1896:     n++;
1897:   }
1898:   PetscTokenDestroy(&token);
1899:   *nmax = n;
1900:   return(0);
1901: }

1905: /*@C
1906:    PetscOptionsGetScalarArray - Gets an array of scalars for a
1907:    particular option in the database.  The values must be separated with
1908:    commas with no intervening spaces.

1910:    Not Collective

1912:    Input Parameters:
1913: +  pre - string to prepend to each name or NULL
1914: .  name - the option one is seeking
1915: -  nmax - maximum number of values to retrieve

1917:    Output Parameters:
1918: +  dvalue - the scalar values to return
1919: .  nmax - actual number of values retreived
1920: -  set - PETSC_TRUE if found, else PETSC_FALSE

1922:    Level: beginner

1924:    Concepts: options database^array of doubles

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

1944:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
1945:   if (!flag) {
1946:     if (set) *set = PETSC_FALSE;
1947:     *nmax = 0;
1948:     return(0);
1949:   }
1950:   if (!value) {
1951:     if (set) *set = PETSC_TRUE;
1952:     *nmax = 0;
1953:     return(0);
1954:   }

1956:   if (set) *set = PETSC_TRUE;

1958:   PetscTokenCreate(value,',',&token);
1959:   PetscTokenFind(token,&value);
1960:   while (n < *nmax) {
1961:     if (!value) break;
1962:     PetscOptionsStringToScalar(value,dvalue++);
1963:     PetscTokenFind(token,&value);
1964:     n++;
1965:   }
1966:   PetscTokenDestroy(&token);
1967:   *nmax = n;
1968:   return(0);
1969: }

1973: /*@C
1974:    PetscOptionsGetIntArray - Gets an array of integer values for a particular
1975:    option in the database.

1977:    Not Collective

1979:    Input Parameters:
1980: +  pre - string to prepend to each name or NULL
1981: .  name - the option one is seeking
1982: -  nmax - maximum number of values to retrieve

1984:    Output Parameter:
1985: +  dvalue - the integer values to return
1986: .  nmax - actual number of values retreived
1987: -  set - PETSC_TRUE if found, else PETSC_FALSE

1989:    Level: beginner

1991:    Notes:
1992:    The array can be passed as
1993:    a comma separated list:                                 0,1,2,3,4,5,6,7
1994:    a range (start-end+1):                                  0-8
1995:    a range with given increment (start-end+1:inc):         0-7:2
1996:    a combination of values and ranges separated by commas: 0,1-8,8-15:2

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

2000:    Concepts: options database^array of ints

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

2021:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
2022:   if (!flag) {
2023:     if (set) *set = PETSC_FALSE;
2024:     *nmax = 0;
2025:     return(0);
2026:   }
2027:   if (!value) {
2028:     if (set) *set = PETSC_TRUE;
2029:     *nmax = 0;
2030:     return(0);
2031:   }

2033:   if (set) *set = PETSC_TRUE;

2035:   PetscTokenCreate(value,',',&token);
2036:   PetscTokenFind(token,&value);
2037:   while (n < *nmax) {
2038:     if (!value) break;

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

2050:         PetscOptionsStringToInt(value,&start);
2051:         inc  = 1;
2052:         j    = i+1;
2053:         for (;j<(int)len; j++) {
2054:           if (value[j] == ':') {
2055:             value[j] = 0;

2057:             PetscOptionsStringToInt(value+j+1,&inc);
2058:             if (inc <= 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry,%s cannot have negative increment",n,value+j+1);
2059:             break;
2060:           }
2061:         }
2062:         PetscOptionsStringToInt(value+i+1,&end);
2063:         if (end <= start) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry, %s-%s cannot have decreasing list",n,value,value+i+1);
2064:         nvalues = (end-start)/inc + (end-start)%inc;
2065:         if (n + nvalues  > *nmax) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry, not enough space left in array (%D) to contain entire range from %D to %D",n,*nmax-n,start,end);
2066:         for (;start<end; start+=inc) {
2067:           *dvalue = start; dvalue++;n++;
2068:         }
2069:         foundrange = PETSC_TRUE;
2070:         break;
2071:       }
2072:     }
2073:     if (!foundrange) {
2074:       PetscOptionsStringToInt(value,dvalue);
2075:       dvalue++;
2076:       n++;
2077:     }
2078:     PetscTokenFind(token,&value);
2079:   }
2080:   PetscTokenDestroy(&token);
2081:   *nmax = n;
2082:   return(0);
2083: }

2087: /*@C
2088:    PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database.

2090:    Not Collective

2092:    Input Parameters:
2093: +  pre - option prefix or NULL
2094: .  name - option name
2095: .  list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null
2096: -  nmax - maximum number of values to retrieve

2098:    Output Parameters:
2099: +  dvalue - the  enum values to return
2100: .  nmax - actual number of values retreived
2101: -  set - PETSC_TRUE if found, else PETSC_FALSE

2103:    Level: beginner

2105:    Concepts: options database

2107:    Notes:
2108:    The array must be passed as a comma separated list.

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

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

2114: .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(),
2115:           PetscOptionsGetEnum(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
2116:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(),
2117:           PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(),
2118:           PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2119:           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum()
2120: @*/
2121: PetscErrorCode PetscOptionsGetEnumArray(const char pre[],const char name[],const char *const *list,PetscEnum dvalue[],PetscInt *nmax,PetscBool *set)
2122: {
2123:   char           *svalue;
2124:   PetscInt       n = 0;
2125:   PetscEnum      evalue;
2126:   PetscBool      flag;
2127:   PetscToken     token;


2136:   PetscOptionsFindPair_Private(pre,name,&svalue,&flag);
2137:   if (!flag) {
2138:     if (set) *set = PETSC_FALSE;
2139:     *nmax = 0;
2140:     return(0);
2141:   }
2142:   if (!svalue) {
2143:     if (set) *set = PETSC_TRUE;
2144:     *nmax = 0;
2145:     return(0);
2146:   }
2147:   if (set) *set = PETSC_TRUE;

2149:   PetscTokenCreate(svalue,',',&token);
2150:   PetscTokenFind(token,&svalue);
2151:   while (svalue && n < *nmax) {
2152:     PetscEnumFind(list,svalue,&evalue,&flag);
2153:     if (!flag) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1);
2154:     dvalue[n++] = evalue;
2155:     PetscTokenFind(token,&svalue);
2156:   }
2157:   *nmax = n;
2158:   PetscTokenDestroy(&token);
2159:   return(0);
2160: }

2164: /*@C
2165:    PetscOptionsGetString - Gets the string value for a particular option in
2166:    the database.

2168:    Not Collective

2170:    Input Parameters:
2171: +  pre - string to prepend to name or NULL
2172: .  name - the option one is seeking
2173: -  len - maximum length of the string including null termination

2175:    Output Parameters:
2176: +  string - location to copy string
2177: -  set - PETSC_TRUE if found, else PETSC_FALSE

2179:    Level: beginner

2181:    Fortran Note:
2182:    The Fortran interface is slightly different from the C/C++
2183:    interface (len is not used).  Sample usage in Fortran follows
2184: .vb
2185:       character *20 string
2186:       integer   flg, ierr
2187:       call PetscOptionsGetString(NULL_CHARACTER,'-s',string,flg,ierr)
2188: .ve

2190:    Notes: if the option is given but no string is provided then an empty string is returned and set is given the value of PETSC_TRUE

2192:    Concepts: options database^string

2194:     Note:
2195:       Even if the user provided no string (for example -optionname -someotheroption) the flag is set to PETSC_TRUE (and the string is fulled with nulls).

2197: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2198:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2199:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2200:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2201:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2202:           PetscOptionsFList(), PetscOptionsEList()
2203: @*/
2204: PetscErrorCode  PetscOptionsGetString(const char pre[],const char name[],char string[],size_t len,PetscBool  *set)
2205: {
2206:   char           *value;
2208:   PetscBool      flag;

2213:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
2214:   if (!flag) {
2215:     if (set) *set = PETSC_FALSE;
2216:   } else {
2217:     if (set) *set = PETSC_TRUE;
2218:     if (value) {
2219:       PetscStrncpy(string,value,len);
2220:       string[len-1] = 0;        /* Ensure that the string is NULL terminated */
2221:     } else {
2222:       PetscMemzero(string,len);
2223:     }
2224:   }
2225:   return(0);
2226: }

2230: char *PetscOptionsGetStringMatlab(const char pre[],const char name[])
2231: {
2232:   char           *value;
2234:   PetscBool      flag;

2237:   PetscOptionsFindPair_Private(pre,name,&value,&flag);if (ierr) return(0);
2238:   if (flag) PetscFunctionReturn(value);
2239:   else return(0);
2240: }


2245: /*@C
2246:    PetscOptionsGetStringArray - Gets an array of string values for a particular
2247:    option in the database. The values must be separated with commas with
2248:    no intervening spaces.

2250:    Not Collective

2252:    Input Parameters:
2253: +  pre - string to prepend to name or NULL
2254: .  name - the option one is seeking
2255: -  nmax - maximum number of strings

2257:    Output Parameter:
2258: +  strings - location to copy strings
2259: -  set - PETSC_TRUE if found, else PETSC_FALSE

2261:    Level: beginner

2263:    Notes:
2264:    The user should pass in an array of pointers to char, to hold all the
2265:    strings returned by this function.

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

2270:    Contributed by Matthew Knepley.

2272:    Concepts: options database^array of strings

2274: .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),
2275:            PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(),
2276:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
2277:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
2278:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
2279:           PetscOptionsFList(), PetscOptionsEList()
2280: @*/
2281: PetscErrorCode  PetscOptionsGetStringArray(const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool  *set)
2282: {
2283:   char           *value;
2285:   PetscInt       n;
2286:   PetscBool      flag;
2287:   PetscToken     token;

2292:   PetscOptionsFindPair_Private(pre,name,&value,&flag);
2293:   if (!flag) {
2294:     *nmax = 0;
2295:     if (set) *set = PETSC_FALSE;
2296:     return(0);
2297:   }
2298:   if (!value) {
2299:     *nmax = 0;
2300:     if (set) *set = PETSC_FALSE;
2301:     return(0);
2302:   }
2303:   if (!*nmax) {
2304:     if (set) *set = PETSC_FALSE;
2305:     return(0);
2306:   }
2307:   if (set) *set = PETSC_TRUE;

2309:   PetscTokenCreate(value,',',&token);
2310:   PetscTokenFind(token,&value);
2311:   n    = 0;
2312:   while (n < *nmax) {
2313:     if (!value) break;
2314:     PetscStrallocpy(value,&strings[n]);
2315:     PetscTokenFind(token,&value);
2316:     n++;
2317:   }
2318:   PetscTokenDestroy(&token);
2319:   *nmax = n;
2320:   return(0);
2321: }

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

2328:    Not Collective

2330:    Input Parameter:
2331: .    option - string name of option

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

2336:    Level: advanced

2338: .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed()
2339: @*/
2340: PetscErrorCode  PetscOptionsUsed(const char *option,PetscBool *used)
2341: {
2342:   PetscInt       i;

2346:   *used = PETSC_FALSE;
2347:   for (i=0; i<options->N; i++) {
2348:     PetscStrcmp(options->names[i],option,used);
2349:     if (*used) {
2350:       *used = options->used[i];
2351:       break;
2352:     }
2353:   }
2354:   return(0);
2355: }

2359: /*@C
2360:    PetscOptionsAllUsed - Returns a count of the number of options in the
2361:    database that have never been selected.

2363:    Not Collective

2365:    Output Parameter:
2366: .   N - count of options not used

2368:    Level: advanced

2370: .seealso: PetscOptionsView()
2371: @*/
2372: PetscErrorCode  PetscOptionsAllUsed(PetscInt *N)
2373: {
2374:   PetscInt i,n = 0;

2377:   for (i=0; i<options->N; i++) {
2378:     if (!options->used[i]) n++;
2379:   }
2380:   *N = n;
2381:   return(0);
2382: }

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

2389:   Not collective

2391:    Options Database Key:
2392: .  -options_left - Activates OptionsAllUsed() within PetscFinalize()

2394:   Level: advanced

2396: .seealso: PetscOptionsAllUsed()
2397: @*/
2398: PetscErrorCode  PetscOptionsLeft(void)
2399: {
2401:   PetscInt       i;

2404:   for (i=0; i<options->N; i++) {
2405:     if (!options->used[i]) {
2406:       if (options->values[i]) {
2407:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",options->names[i],options->values[i]);
2408:       } else {
2409:         PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",options->names[i]);
2410:       }
2411:     }
2412:   }
2413:   return(0);
2414: }


2419: /*
2420:     PetscOptionsCreate - Creates the empty options database.

2422: */
2423: PetscErrorCode  PetscOptionsCreate(void)
2424: {

2428:   options = (PetscOptionsTable*)malloc(sizeof(PetscOptionsTable));
2429:   PetscMemzero(options,sizeof(PetscOptionsTable));

2431:   options->namegiven      = PETSC_FALSE;
2432:   options->N              = 0;
2433:   options->Naliases       = 0;
2434:   options->numbermonitors = 0;

2436:   return(0);
2437: }

2441: /*@
2442:    PetscOptionsSetFromOptions - Sets options related to the handling of options in PETSc

2444:    Collective on PETSC_COMM_WORLD

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

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

2456:    Level: intermediate

2458: .keywords: set, options, database
2459: @*/
2460: PetscErrorCode  PetscOptionsSetFromOptions(void)
2461: {
2462:   PetscBool      flgc = PETSC_FALSE,flgm;
2464:   char           monfilename[PETSC_MAX_PATH_LEN];
2465:   PetscViewer    monviewer;

2468:   PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for handling options","PetscOptions");
2469:   PetscOptionsString("-options_monitor","Monitor options database","PetscOptionsMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flgm);
2470:   PetscOptionsBool("-options_monitor_cancel","Cancel all options database monitors","PetscOptionsMonitorCancel",flgc,&flgc,NULL);
2471:   PetscOptionsEnd();
2472:   if (flgm) {
2473:     PetscViewerASCIIOpen(PETSC_COMM_WORLD,monfilename,&monviewer);
2474:     PetscOptionsMonitorSet(PetscOptionsMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
2475:   }
2476:   if (flgc) { PetscOptionsMonitorCancel(); }
2477:   return(0);
2478: }


2483: /*@C
2484:    PetscOptionsMonitorDefault - Print all options set value events.

2486:    Logically Collective on PETSC_COMM_WORLD

2488:    Input Parameters:
2489: +  name  - option name string
2490: .  value - option value string
2491: -  dummy - unused monitor context

2493:    Level: intermediate

2495: .keywords: PetscOptions, default, monitor

2497: .seealso: PetscOptionsMonitorSet()
2498: @*/
2499: PetscErrorCode  PetscOptionsMonitorDefault(const char name[], const char value[], void *dummy)
2500: {
2502:   PetscViewer    viewer = (PetscViewer) dummy;

2505:   if (!viewer) {
2506:     PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer);
2507:   }
2508:   PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);
2509:   return(0);
2510: }

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

2518:    Not collective

2520:    Input Parameters:
2521: +  monitor - pointer to function (if this is NULL, it turns off monitoring
2522: .  mctx    - [optional] context for private data for the
2523:              monitor routine (use NULL if no context is desired)
2524: -  monitordestroy - [optional] routine that frees monitor context
2525:           (may be NULL)

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

2530: +  name - option name string
2531: .  value - option value string
2532: -  mctx  - optional monitoring context, as set by PetscOptionsMonitorSet()

2534:    Options Database Keys:
2535: +    -options_monitor    - sets PetscOptionsMonitorDefault()
2536: -    -options_monitor_cancel - cancels all monitors that have
2537:                           been hardwired into a code by
2538:                           calls to PetscOptionsMonitorSet(), but
2539:                           does not cancel those set via
2540:                           the options database.

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

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

2551:    Level: beginner

2553: .keywords: PetscOptions, set, monitor

2555: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorCancel()
2556: @*/
2557: PetscErrorCode  PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
2558: {
2560:   if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set");
2561:   options->monitor[options->numbermonitors]          = monitor;
2562:   options->monitordestroy[options->numbermonitors]   = monitordestroy;
2563:   options->monitorcontext[options->numbermonitors++] = (void*)mctx;
2564:   return(0);
2565: }

2569: /*@
2570:    PetscOptionsMonitorCancel - Clears all monitors for a PetscOptions object.

2572:    Not collective

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

2579:    Level: intermediate

2581: .keywords: PetscOptions, set, monitor

2583: .seealso: PetscOptionsMonitorDefault(), PetscOptionsMonitorSet()
2584: @*/
2585: PetscErrorCode  PetscOptionsMonitorCancel(void)
2586: {
2588:   PetscInt       i;

2591:   for (i=0; i<options->numbermonitors; i++) {
2592:     if (options->monitordestroy[i]) {
2593:       (*options->monitordestroy[i])(&options->monitorcontext[i]);
2594:     }
2595:   }
2596:   options->numbermonitors = 0;
2597:   return(0);
2598: }

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

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

2607:   Collective on PetscObject

2609:   Input Parameters:
2610: + obj   - the object
2611: . bobj  - optional other object that provides prefix (if NULL then the prefix in obj is used)
2612: - optionname - option to activate viewing

2614:   Level: intermediate

2616: @*/
2617: PetscErrorCode PetscObjectViewFromOptions(PetscObject obj,PetscObject bobj,const char optionname[])
2618: {
2619:   PetscErrorCode    ierr;
2620:   PetscViewer       viewer;
2621:   PetscBool         flg;
2622:   static PetscBool  incall = PETSC_FALSE;
2623:   PetscViewerFormat format;
2624:   char              *prefix;

2627:   if (incall) return(0);
2628:   incall = PETSC_TRUE;
2629:   prefix = bobj ? bobj->prefix : obj->prefix;
2630:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj),prefix,optionname,&viewer,&format,&flg);CHKERRQI(incall,ierr);
2631:   if (flg) {
2632:     PetscViewerPushFormat(viewer,format);CHKERRQI(incall,ierr);
2633:     PetscObjectView(obj,viewer);CHKERRQI(incall,ierr);
2634:     PetscViewerPopFormat(viewer);CHKERRQI(incall,ierr);
2635:     PetscViewerDestroy(&viewer);CHKERRQI(incall,ierr);
2636:   }
2637:   incall = PETSC_FALSE;
2638:   return(0);
2639: }