changeDictionary.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  changeDictionary
29 
30 Group
31  grpPreProcessingUtilities
32 
33 Description
34  Utility to change dictionary entries, e.g. can be used to change the patch
35  type in the field and polyMesh/boundary files.
36 
37  Reads dictionaries (fields) and entries to change from a dictionary.
38  E.g. to make the \em movingWall a \em fixedValue for \em p but all other
39  \em Walls a zeroGradient boundary condition, the
40  \c system/changeDictionaryDict would contain the following:
41  \verbatim
42  p // field to change
43  {
44  boundaryField
45  {
46  ".*Wall" // entry to change
47  {
48  type zeroGradient;
49  }
50  movingWall // entry to change
51  {
52  type fixedValue;
53  value uniform 123.45;
54  }
55  }
56  }
57  \endverbatim
58  Replacement entries starting with '~' will remove the entry.
59 
60 Usage
61  \b changeDictionary [OPTION]
62 
63  Options:
64  - \par -subDict
65  Specify the subDict name of the replacements dictionary.
66 
67  - \par -literalRE
68  Do not interpret regular expressions or patchGroups; treat them as any
69  other keyword.
70 
71  - \par -enableFunctionEntries
72  Enable function entries (default: disabled)
73 
74  - \par -disablePatchGroups
75  Disable the default checking for keys being patchGroups
76 
77 \*---------------------------------------------------------------------------*/
78 
79 #include "argList.H"
80 #include "IOobjectList.H"
81 #include "IOPtrList.H"
82 #include "volFields.H"
83 #include "timeSelector.H"
84 
85 using namespace Foam;
86 
87 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
88 
89 namespace Foam
90 {
92 }
93 
94 
95 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
96 
97 // Extract groupPatch info from boundary file info
98 HashTable<wordList> extractPatchGroups(const dictionary& boundaryDict)
99 {
100  HashTable<wordList> groupToPatch;
101 
102  for (const entry& dEntry : boundaryDict)
103  {
104  if (!dEntry.isDict())
105  {
106  continue;
107  }
108 
109  const word& patchName = dEntry.keyword();
110  const dictionary& patchDict = dEntry.dict();
111 
112  wordList groupNames;
113  patchDict.readIfPresent("inGroups", groupNames);
114 
115  for (const word& groupName : groupNames)
116  {
117  auto groupIter = groupToPatch.find(groupName);
118  if (groupIter.good())
119  {
120  (*groupIter).append(patchName);
121  }
122  else
123  {
124  groupToPatch.insert(groupName, wordList(one{}, patchName));
125  }
126  }
127  }
128 
129  return groupToPatch;
130 }
131 
132 
133 bool merge
134 (
135  const bool addNonExisting,
136  dictionary&,
137  const dictionary&,
138  const bool,
139  const HashTable<wordList>&
140 );
141 
142 
143 // Add thisEntry to dictionary thisDict.
144 bool addEntry
145 (
146  dictionary& thisDict,
147  entry& thisEntry,
148  const entry& mergeEntry,
149  const bool literalRE,
150  const HashTable<wordList>& shortcuts
151 )
152 {
153  bool changed = false;
154 
155  // Recursively merge sub-dictionaries
156  // TODO: merge without copying
157  if (thisEntry.isDict() && mergeEntry.isDict())
158  {
159  if
160  (
161  merge
162  (
163  true,
164  const_cast<dictionary&>(thisEntry.dict()),
165  mergeEntry.dict(),
166  literalRE,
167  shortcuts
168  )
169  )
170  {
171  changed = true;
172  }
173  }
174  else
175  {
176  // Should use in-place modification instead of adding
177  thisDict.add(mergeEntry.clone(thisDict).ptr(), true);
178  changed = true;
179  }
180 
181  return changed;
182 }
183 
184 
185 // List of indices into thisKeys
186 labelList findMatches
187 (
188  const HashTable<wordList>& shortcuts,
189  const wordList& shortcutNames,
190  const wordList& thisKeys,
191  const wordRe& key
192 )
193 {
194  labelList matches;
195 
196  if (key.isPattern())
197  {
198  // Wildcard match
199  matches = wordRes::matching(key, thisKeys);
200  }
201  else if (shortcuts.size())
202  {
203  // See if patchGroups expand to valid thisKeys
204  labelList indices = wordRes::matching(key, shortcutNames);
205 
206  for (const label idx : indices)
207  {
208  const word& name = shortcutNames[idx];
209  const wordList& keys = shortcuts[name];
210  for (const word& k : keys)
211  {
212  const label index = thisKeys.find(k);
213  if (index != -1)
214  {
215  matches.append(index);
216  }
217  }
218  }
219  }
220  return matches;
221 }
222 
223 
224 // Dictionary merging/editing.
225 // literalRE:
226 // - true: behave like dictionary::merge, i.e. add regexps just like
227 // any other key.
228 // - false : interpret wildcard as a rule for items to be matched.
229 bool merge
230 (
231  const bool addNonExisting,
232  dictionary& thisDict,
233  const dictionary& mergeDict,
234  const bool literalRE,
235  const HashTable<wordList>& shortcuts
236 )
237 {
238  const wordList shortcutNames(shortcuts.toc());
239 
240  bool changed = false;
241 
242  // Save current (non-wildcard) keys before adding items.
243  wordHashSet thisKeysSet;
244  {
245  for (const word& k : thisDict.keys(false))
246  {
247  thisKeysSet.insert(k);
248  }
249  }
250 
251  // Pass 1. All literal matches
252 
253  for (const entry& mergeEntry : mergeDict)
254  {
255  const keyType& key = mergeEntry.keyword();
256 
257  if (key[0] == '~')
258  {
259  const word eraseKey = key.substr(1);
260  if (thisDict.remove(eraseKey))
261  {
262  // Mark thisDict entry as having been match for wildcard
263  // handling later on.
264  thisKeysSet.erase(eraseKey);
265  }
266  changed = true;
267  }
268  else if (literalRE || !(key.isPattern() || shortcuts.found(key)))
269  {
270  entry* eptr = thisDict.findEntry(key, keyType::LITERAL);
271 
272  if (eptr)
273  {
274  // Mark thisDict entry as having been match for wildcard
275  // handling later on.
276  thisKeysSet.erase(eptr->keyword());
277 
278  if
279  (
280  addEntry
281  (
282  thisDict,
283  *eptr,
284  mergeEntry,
285  literalRE,
286  shortcuts
287  )
288  )
289  {
290  changed = true;
291  }
292  }
293  else
294  {
295  if (addNonExisting)
296  {
297  // Not found - just add
298  thisDict.add(mergeEntry.clone(thisDict).ptr());
299  changed = true;
300  }
301  else
302  {
303  IOWarningInFunction(mergeDict)
304  << "Ignoring non-existing entry " << key
305  << endl;
306  }
307  }
308  }
309  }
310 
311 
312  // Pass 2. Wildcard or shortcut matches (if any) on any non-match keys.
313 
314  if (!literalRE && thisKeysSet.size())
315  {
316  // Pick up remaining dictionary entries
317  wordList thisKeys(thisKeysSet.toc());
318 
319  for (const entry& mergeEntry : mergeDict)
320  {
321  const keyType& key = mergeEntry.keyword();
322 
323  if (key[0] == '~')
324  {
325  const word eraseKey = key.substr(1);
326 
327  // List of indices into thisKeys
328  labelList matches
329  (
330  findMatches
331  (
332  shortcuts,
333  shortcutNames,
334  thisKeys,
335  eraseKey
336  )
337  );
338 
339  // Remove all matches
340  for (const label matchi : matches)
341  {
342  const word& k = thisKeys[matchi];
343  thisKeysSet.erase(k);
344  }
345  changed = true;
346  }
347  else
348  {
349  // List of indices into thisKeys
350  labelList matches
351  (
352  findMatches
353  (
354  shortcuts,
355  shortcutNames,
356  thisKeys,
357  key
358  )
359  );
360 
361  // Add all matches
362  for (const label matchi : matches)
363  {
364  const word& k = thisKeys[matchi];
365 
366  entry* eptr = thisDict.findEntry(k, keyType::LITERAL);
367 
368  if
369  (
370  addEntry
371  (
372  thisDict,
373  *eptr,
374  mergeEntry,
375  literalRE,
376  HashTable<wordList>(0) // no shortcuts
377  // at deeper levels
378  )
379  )
380  {
381  changed = true;
382  }
383  }
384  }
385  }
386  }
387 
388  return changed;
389 }
390 
391 
392 
393 int main(int argc, char *argv[])
394 {
396  (
397  "Utility to change dictionary entries"
398  " (such as the patch type for fields and polyMesh/boundary files)."
399  );
400 
401  argList::addOption("dict", "file", "Alternative changeDictionaryDict");
402 
404  (
405  "subDict",
406  "name",
407  "Specify the subDict name of the replacements dictionary"
408  );
410  (
411  "instance",
412  "name",
413  "Override instance setting (default is the time name)"
414  );
415 
416  // Add explicit time option
418 
420  (
421  "literalRE",
422  "Treat regular expressions literally (i.e., as a keyword)"
423  );
425  (
426  "enableFunctionEntries",
427  "Enable expansion of dictionary directives - #include, #codeStream etc"
428  );
430  (
431  "disablePatchGroups",
432  "Disable matching keys to patch groups"
433  );
434 
435  #include "addRegionOption.H"
436 
437  #include "setRootCase.H"
438  #include "createTime.H"
439 
440  // Optionally override controlDict time with -time options
442  if (times.size() < 1)
443  {
445  << "No times selected." << exit(FatalError);
446  }
447  forAll(times, timei)
448  {
449  word instance;
450  if (args.readIfPresent("instance", instance))
451  {
452  if (times.size() > 1)
453  {
455  << "Multiple times selected with 'instance' option"
456  << exit(FatalError);
457  }
458  }
459  else
460  {
461  runTime.setTime(times[timei], timei);
462  instance = runTime.timeName();
463  }
464 
465  #include "createNamedMesh.H"
466 
467  const bool literalRE = args.found("literalRE");
468  if (literalRE)
469  {
470  Info<< "Not interpreting any regular expressions (RE)"
471  << " in the changeDictionaryDict." << endl
472  << "Instead they are handled as any other entry, i.e. added if"
473  << " not present." << endl;
474  }
475 
476  const bool enableEntries = args.found("enableFunctionEntries");
477  if (enableEntries)
478  {
479  Info<< "Allowing dictionary preprocessing (#include, #codeStream)."
480  << endl;
481  }
482 
483  const int oldFlag = entry::disableFunctionEntries;
484  if (!enableEntries)
485  {
486  // By default disable dictionary expansion for fields
488  }
489 
490 
491  const bool disablePatchGroups = args.found("disablePatchGroups");
492  if (disablePatchGroups)
493  {
494  Info<< "Not interpreting any keys in the changeDictionary"
495  << " as patchGroups"
496  << endl;
497  }
498 
499 
500  // Make sure we do not use the master-only reading since we read
501  // fields (different per processor) as dictionaries.
503 
504 
505  // Get the replacement rules from a dictionary
506 
507  const word dictName("changeDictionaryDict");
508  #include "setSystemMeshDictionaryIO.H"
510 
511  const dictionary* replaceDictsPtr = &dict;
512 
513  if (args.found("subDict"))
514  {
515  replaceDictsPtr = &dict.subDict(args["subDict"]);
516  }
517 
518  const dictionary& replaceDicts = *replaceDictsPtr;
519 
520  Info<< "Read dictionary " << dict.name()
521  << " with replacements for dictionaries "
522  << replaceDicts.toc() << endl;
523 
524 
525 
526  // Always read boundary to get patch groups
527  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
528 
529  Info<< "Reading polyMesh/boundary file to extract patch names"
530  << endl;
531 
532  // Read PtrList of dictionary as dictionary.
533  const word oldTypeName = IOPtrList<entry>::typeName;
535  IOPtrList<entry> dictList
536  (
537  IOobject
538  (
539  "boundary",
541  (
543  "boundary",
545  ),
547  mesh,
551  )
552  );
553  const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
554 
555  // Fake type back to what was in field
556  const_cast<word&>(dictList.type()) = dictList.headerClassName();
557 
558  // Temporary convert to dictionary
559  dictionary fieldDict;
560  for (const entry& e : dictList)
561  {
562  if (e.isDict())
563  {
564  fieldDict.add(e.keyword(), e.dict());
565  }
566  }
567 
568  if (dictList.size())
569  {
570  Info<< "Loaded dictionary " << dictList.name()
571  << " with entries " << fieldDict.toc() << endl;
572  }
573 
574  // Extract any patchGroups information (= shortcut for set of
575  // patches)
576  HashTable<wordList> patchGroups;
577  if (!disablePatchGroups)
578  {
579  patchGroups = extractPatchGroups(fieldDict);
580  if (patchGroups.size())
581  {
582  Info<< "Extracted patch groups:" << endl;
583  wordList groups(patchGroups.sortedToc());
584  forAll(groups, i)
585  {
586  Info<< " group " << groups[i] << " with patches "
587  << patchGroups[groups[i]] << endl;
588  }
589  }
590  }
591 
592 
593  // Every replacement is a dictionary name and a keyword in this
594 
595  for (const entry& replaceEntry : replaceDicts)
596  {
597  if (!replaceEntry.isDict())
598  {
599  // Could also warn
600  continue;
601  }
602 
603  const word& fieldName = replaceEntry.keyword();
604  const dictionary& replaceDict = replaceEntry.dict();
605 
606  Info<< "Replacing entries in dictionary " << fieldName << endl;
607 
608  // Handle 'boundary' specially:
609  // - is PtrList of dictionaries
610  // - is in polyMesh/
611  if (fieldName == "boundary")
612  {
613  Info<< "Special handling of " << fieldName
614  << " as polyMesh/boundary file." << endl;
615 
616  // Merge the replacements in. Do not add non-existing entries.
617  Info<< "Merging entries from " << replaceDict.toc() << endl;
618  merge(false, fieldDict, replaceDict, literalRE, patchGroups);
619 
620  Info<< "fieldDict:" << fieldDict << endl;
621 
622  // Convert back into dictList
623  wordList doneKeys(dictList.size());
624 
625  label nEntries = fieldDict.size();
626  nEntries = 0;
627 
628  forAll(dictList, i)
629  {
630  doneKeys[i] = dictList[i].keyword();
631 
632  const entry* ePtr = fieldDict.findEntry
633  (
634  doneKeys[i],
636  );
637  // Check that it hasn't been removed from fieldDict
638  if (ePtr)
639  {
640  dictList.set(nEntries++, ePtr->clone());
641  fieldDict.remove(doneKeys[i]);
642  }
643  }
644 
645  // Add remaining entries
646  for (const entry& e : fieldDict)
647  {
648  dictList.set(nEntries++, e.clone());
649  }
650  dictList.setSize(nEntries);
651 
652  Info<< "Writing modified " << fieldName << endl;
653  dictList.writeObject
654  (
656  true
657  );
658  }
659  else
660  {
661  // Read dictionary
662  // Note: disable class type checking so we can load field
663  Info<< "Loading dictionary " << fieldName << endl;
664  const word oldTypeName = localIOdictionary::typeName;
665  const_cast<word&>(localIOdictionary::typeName) = word::null;
666 
667  IOobject fieldHeader
668  (
669  fieldName,
670  instance,
671  mesh,
675  );
676 
677  if (fieldHeader.typeHeaderOk<localIOdictionary>(false))
678  {
679  //IOdictionary fieldDict(fieldHeader);
680  //- dictionaries to-be-changed are either boundary
681  // or field dictionary. Both are processor-local.
682  localIOdictionary fieldDict(fieldHeader);
683 
684  const_cast<word&>(localIOdictionary::typeName) =
685  oldTypeName;
686 
687  // Fake type back to what was in field
688  const_cast<word&>(fieldDict.type()) =
689  fieldDict.headerClassName();
690 
691  Info<< "Loaded dictionary " << fieldName
692  << " with entries " << fieldDict.toc() << endl;
693 
694  // Merge the replacements in (allow adding)
695  Info<< "Merging entries from " << replaceDict.toc() << endl;
696  merge(true, fieldDict, replaceDict, literalRE, patchGroups);
697 
698  Info<< "Writing modified fieldDict " << fieldName << endl;
699  fieldDict.regIOobject::write();
700  }
701  else
702  {
704  << "Requested field to change " << fieldName
705  << " does not exist in " << fieldHeader.path() << endl;
706  }
707  }
708 
710  }
711  }
712 
713  Info<< "\nEnd\n" << endl;
714 
715  return 0;
716 }
717 
718 
719 // ************************************************************************* //
A class for handling keywords in dictionaries.
Definition: keyType.H:66
virtual autoPtr< entry > clone(const dictionary &parentDict) const =0
Construct on freestore as copy with reference to the.
dictionary dict
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:462
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:521
bool found(const Key &key) const
Same as contains()
Definition: HashTable.H:1370
const word dictName("faMeshDefinition")
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:411
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Required Classes.
virtual const dictionary & dict() const =0
Return dictionary, if entry is a dictionary, otherwise Fatal.
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:374
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:625
A simple container for options an IOstream can normally have.
label k
Boltzmann constant.
Ignore writing from objectRegistry::writeObject()
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:232
const fileName & name() const noexcept
The dictionary name.
Definition: dictionaryI.H:41
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:441
wordList toc() const
Return the table of contents.
Definition: dictionary.C:587
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
bool remove(const word &keyword)
Remove an entry specified by keyword.
localIOdictionary is derived from IOdictionary but excludes parallel master reading.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:152
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:358
Required Classes.
static int disableFunctionEntries
Enable or disable use of function entries and variable expansions.
Definition: entry.H:139
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
const keyType & keyword() const noexcept
Return keyword.
Definition: entry.H:231
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
word findInstance(const fileName &directory, const word &name=word::null, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, const word &stopInstance=word::null, const bool constant_fallback=true) const
Return time instance (location) of directory containing the file name (eg, used in reading mesh data)...
Definition: Time.C:725
A class for handling words, derived from Foam::string.
Definition: word.H:63
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
Definition: HashTableI.H:86
static labelList matching(const wordRe &select, const UList< StringType > &input, const bool invert=false)
Determine the list indices for all matches.
Reading is optional [identical to LAZY_READ].
static const word null
An empty word.
Definition: word.H:84
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:385
static instantList selectIfPresent(Time &runTime, const argList &args)
If any time option provided return the set of times - as per select0() - otherwise return just the cu...
Definition: timeSelector.C:291
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:902
String literal.
Definition: keyType.H:82
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings...
Definition: wordRe.H:78
label find(const T &val) const
Find index of the first occurrence of the value.
Definition: UList.C:173
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition: Time.C:714
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
defineTemplateTypeNameAndDebug(faScalarMatrix, 0)
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:351
List< keyType > keys(bool patterns=false) const
Return the list of available keys or patterns.
Definition: dictionary.C:607
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:496
List< word > wordList
List of word.
Definition: fileName.H:59
A PtrList of objects of type <T> with automated input and output.
Definition: IOPtrList.H:49
#define WarningInFunction
Report a warning using Foam::Warning.
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:163
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:841
const entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
Definition: dictionaryI.H:84
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual bool isDict() const noexcept
True if this entry is a dictionary.
Definition: entry.H:284
IOobject dictIO
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:316
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:148
IOstreamOption::streamFormat writeFormat() const noexcept
Get write stream format.
Definition: TimeI.H:123
Foam::argList args(argc, argv)
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
Regular expression.
Definition: keyType.H:83
Do not request registration (bool: false)
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
Definition: timeSelector.C:101
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:56