dimensionSetIO.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-2015 OpenFOAM Foundation
9 Copyright (C) 2019-2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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\*---------------------------------------------------------------------------*/
28
29#include "dictionary.H"
30#include "dimensionSet.H"
31#include "dimensionedScalar.H"
32#include "IOstreams.H"
33#include <limits>
34
35// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
36
38(
39 const word& entryName,
40 const dictionary& dict,
41 const bool mandatory
42)
43:
44 exponents_(Zero)
45{
46 this->readEntry(entryName, dict, mandatory);
47}
48
49
51(
52 const dictionary& dict,
53 const word& entryName,
54 const bool mandatory
55)
56:
57 exponents_(Zero)
58{
59 this->readEntry(entryName, dict, mandatory);
60}
61
62
64{
65 is >> *this;
66}
67
68
69Foam::dimensionSet::tokeniser::tokeniser(Istream& is)
70:
71 is_(is),
72 tokens_(100),
73 start_(0),
74 size_(0)
75{}
76
77
78// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
79
80void Foam::dimensionSet::tokeniser::push(const token& t)
81{
82 const label end = (start_+size_)%tokens_.size();
83 tokens_[end] = t;
84 if (size_ == tokens_.size())
85 {
86 start_ = tokens_.fcIndex(start_);
87 }
88 else
89 {
90 ++size_;
91 }
92}
93
94
95Foam::token Foam::dimensionSet::tokeniser::pop()
96{
97 token t = tokens_[start_];
98 start_ = tokens_.fcIndex(start_);
99 --size_;
100 return t;
101}
102
103
104void Foam::dimensionSet::tokeniser::unpop(const token& t)
105{
106 ++size_;
107 start_ = tokens_.rcIndex(start_);
108 tokens_[start_] = t;
109}
110
111
112bool Foam::dimensionSet::tokeniser::hasToken() const
113{
114 return size_ || is_.good();
115}
116
117
119{
120 return
121 (
122 !isspace(c)
123 && c != '"' // string quote
124 && c != '\'' // string quote
125 && c != '/' // div
126 && c != ';' // end statement
127 && c != '{' // beg subdict
128 && c != '}' // end subdict
129 && c != '(' // beg expr
130 && c != ')' // end expr
131 && c != '[' // beg dim
132 && c != ']' // end dim
133 && c != '^' // power
134 && c != '*' // mult
135 );
136}
137
138
139Foam::label Foam::dimensionSet::tokeniser::priority(const token& t)
140{
141 if (t.isPunctuation())
142 {
143 if
144 (
145 t.pToken() == token::MULTIPLY
146 || t.pToken() == token::DIVIDE
147 )
148 {
149 return 2;
150 }
151 else if (t.pToken() == '^')
152 {
153 return 3;
154 }
155 }
156
157 // Default priority
158 return 0;
159}
160
161
162void Foam::dimensionSet::tokeniser::splitWord(const word& w)
163{
164 size_t start = 0;
165 for (size_t i=0; i<w.size(); ++i)
166 {
167 if (!valid(w[i]))
168 {
169 if (i > start)
170 {
171 const word subWord = w.substr(start, i-start);
172 if (isdigit(subWord[0]) || subWord[0] == token::SUBTRACT)
173 {
174 push(token(readScalar(subWord)));
175 }
176 else
177 {
178 push(token(subWord));
179 }
180 }
181 if (w[i] != token::SPACE)
182 {
183 if (isdigit(w[i]))
184 {
185 // Single digit: as scalar value
186 const scalar val = (w[i] - '0');
187 push(token(val));
188 }
189 else
190 {
191 push(token(token::punctuationToken(w[i])));
192 }
193 }
194 start = i+1;
195 }
196 }
197 if (start < w.size())
198 {
199 const word subWord = w.substr(start);
200 if (isdigit(subWord[0]) || subWord[0] == token::SUBTRACT)
201 {
202 push(token(readScalar(subWord)));
203 }
204 else
205 {
206 push(token(subWord));
207 }
208 }
209}
210
211
212Foam::token Foam::dimensionSet::tokeniser::nextToken()
213{
214 if (size_ == 0)
215 {
216 token t(is_);
217 if (t.isWord())
218 {
219 splitWord(t.wordToken());
220 return pop();
221 }
222 else
223 {
224 return t;
225 }
226 }
227 else
228 {
229 return pop();
230 }
231}
232
233
234void Foam::dimensionSet::tokeniser::putBack(const token& t)
235{
236 if (size_ == 0)
237 {
238 push(t);
239 }
240 else
241 {
242 unpop(t);
243 }
244}
245
246
247// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
248
249void Foam::dimensionSet::round(const scalar tol)
250{
251 scalar integralPart;
252 for (scalar& val : exponents_)
253 {
254 const scalar fractionalPart = std::modf(val, &integralPart);
255
256 if (mag(fractionalPart-1.0) <= tol)
257 {
258 val = 1.0+integralPart;
259 }
260 else if (mag(fractionalPart+1.0) <= tol)
261 {
262 val = -1.0+integralPart;
263 }
264 else if (mag(fractionalPart) <= tol)
265 {
266 val = integralPart;
267 }
268 }
269}
270
271
272Foam::dimensionedScalar Foam::dimensionSet::parse
273(
274 const label lastPrior,
275 tokeniser& tis,
276 const HashTable<dimensionedScalar>& readSet
277) const
278{
279 dimensionedScalar ds("", dimless, 1);
280
281 // Get initial token
282 token nextToken(tis.nextToken());
283
284 // Store type of last token read. Used to detect two consecutive
285 // symbols and assume multiplication
286 bool haveReadSymbol = false;
287
288
289 while (true)
290 {
291 if (nextToken.isWord())
292 {
293 const word& unitName = nextToken.wordToken();
294 const dimensionedScalar& unitDim = readSet[unitName];
295 ds.dimensions() *= unitDim.dimensions();
296 ds.value() *= unitDim.value();
297 haveReadSymbol = true;
298 }
299 else if (nextToken.isNumber())
300 {
301 // no dimensions, just value
302 ds.value() *= nextToken.number();
303 haveReadSymbol = true;
304 }
305 else if (nextToken.isPunctuation())
306 {
307 label nextPrior = tokeniser::priority(nextToken);
308
309 if (nextToken.pToken() == token::BEGIN_SQR)
310 {
311 // No idea when this will happen
312 tis.putBack(nextToken);
313 return ds;
314 }
315 else if (nextToken.pToken() == token::END_SQR)
316 {
317 tis.putBack(nextToken);
318 return ds;
319 }
320 else if (nextToken.pToken() == token::BEGIN_LIST)
321 {
322 dimensionedScalar sub(parse(nextPrior, tis, readSet));
323
324 token t = tis.nextToken();
325 if (!t.isPunctuation() || t.pToken() != token::END_LIST)
326 {
327 FatalIOErrorInFunction(tis.stream())
328 << "Illegal token " << t << exit(FatalIOError);
329 }
330
331 ds.dimensions() *= sub.dimensions();
332 ds.value() *= sub.value();
333
334 haveReadSymbol = true;
335 }
336 else if (nextToken.pToken() == token::END_LIST)
337 {
338 tis.putBack(nextToken);
339 return ds;
340 }
341 else if (nextToken.pToken() == token::MULTIPLY)
342 {
343 if (nextPrior > lastPrior)
344 {
345 dimensionedScalar sub(parse(nextPrior, tis, readSet));
346
347 ds.dimensions() *= sub.dimensions();
348 ds.value() *= sub.value();
349 }
350 else
351 {
352 // Restore token
353 tis.putBack(nextToken);
354 return ds;
355 }
356 haveReadSymbol = false;
357 }
358 else if (nextToken.pToken() == token::DIVIDE)
359 {
360 if (nextPrior > lastPrior)
361 {
362 dimensionedScalar sub(parse(nextPrior, tis, readSet));
363
364 ds.dimensions() /= sub.dimensions();
365 ds.value() /= sub.value();
366 }
367 else
368 {
369 tis.putBack(nextToken);
370 return ds;
371 }
372 haveReadSymbol = false;
373 }
374 else if (nextToken.pToken() == '^')
375 {
376 if (nextPrior > lastPrior)
377 {
378 dimensionedScalar expon(parse(nextPrior, tis, readSet));
379
380 ds.dimensions().reset(pow(ds.dimensions(), expon.value()));
381 // Round to nearest integer if close to it
382 ds.dimensions().round(10*smallExponent);
383 ds.value() = Foam::pow(ds.value(), expon.value());
384 }
385 else
386 {
387 tis.putBack(nextToken);
388 return ds;
389 }
390 haveReadSymbol = false;
391 }
392 else
393 {
394 FatalIOErrorInFunction(tis.stream())
395 << "Illegal token " << nextToken << exit(FatalIOError);
396 }
397 }
398 else
399 {
400 FatalIOErrorInFunction(tis.stream())
401 << "Illegal token " << nextToken << exit(FatalIOError);
402 }
403
404
405 if (!tis.hasToken())
406 {
407 break;
408 }
409
410 nextToken = tis.nextToken();
411 if (nextToken.error())
412 {
413 break;
414 }
415
416 if (haveReadSymbol && (nextToken.isWord() || nextToken.isNumber()))
417 {
418 // Two consecutive symbols. Assume multiplication
419 tis.putBack(nextToken);
420 nextToken = token(token::MULTIPLY);
421 }
422 }
423
424 return ds;
425}
426
427
429(
430 const word& entryName,
431 const dictionary& dict,
432 const bool mandatory
433)
434{
435 const entry* eptr = dict.findEntry(entryName, keyType::LITERAL);
436
437 if (eptr)
438 {
439 const entry& e = *eptr;
440 ITstream& is = e.stream();
441
442 is >> *this;
443
444 e.checkITstream(is);
445
446 return true;
447 }
448 else if (mandatory)
449 {
451 << "Entry '" << entryName << "' not found in dictionary "
452 << dict.relativeName() << nl
453 << exit(FatalIOError);
454 }
455
456 return false;
457}
458
459
461(
462 Istream& is,
463 scalar& multiplier,
464 const HashTable<dimensionedScalar>& readSet
465)
466{
467 multiplier = 1.0;
468
469 // Read beginning of dimensionSet
470 token startToken(is);
471
472 if (startToken != token::BEGIN_SQR)
473 {
475 << "Expected a '" << token::BEGIN_SQR << "' in dimensionSet\n"
476 << "in stream " << is.info() << nl
477 << exit(FatalIOError);
478 }
479
480 // Read next token
481 token nextToken(is);
482
483 if (!nextToken.isNumber())
484 {
485 is.putBack(nextToken);
486
487 tokeniser tis(is);
488
489 dimensionedScalar ds(parse(0, tis, readSet));
490
491 multiplier = ds.value();
492 exponents_ = ds.dimensions().values();
493 }
494 else
495 {
496 // Read first five dimensions
497 exponents_[dimensionSet::MASS] = nextToken.number();
498 for (int d=1; d < dimensionSet::CURRENT; ++d)
499 {
500 is >> exponents_[d];
501 }
502
503 // Read next token
504 token nextToken(is);
505
506 // If next token is another number
507 // read last two dimensions
508 // and then read another token for the end of the dimensionSet
509 if (nextToken.isNumber())
510 {
511 exponents_[dimensionSet::CURRENT] = nextToken.number();
512 is >> nextToken;
513 exponents_[dimensionSet::LUMINOUS_INTENSITY] = nextToken.number();
514 is >> nextToken;
515 }
516 else
517 {
518 exponents_[dimensionSet::CURRENT] = 0;
519 exponents_[dimensionSet::LUMINOUS_INTENSITY] = 0;
520 }
521
522 // Check end of dimensionSet
523 if (nextToken != token::END_SQR)
524 {
526 << "Expected a '" << token::END_SQR << "' in dimensionSet\n"
527 << "in stream " << is.info() << nl
528 << exit(FatalIOError);
529 }
530 }
531
533 return is;
534}
535
536
538(
539 Istream& is,
540 scalar& multiplier
541)
542{
543 return read(is, multiplier, unitSet());
544}
545
546
548(
549 Istream& is,
550 scalar& multiplier,
551 const dictionary& readSet
552)
553{
554 multiplier = 1.0;
555
556 // Read beginning of dimensionSet
557 token startToken(is);
558
559 if (startToken != token::BEGIN_SQR)
560 {
562 << "Expected a '" << token::BEGIN_SQR << "' in dimensionSet\n"
563 << "in stream " << is.info() << nl
564 << exit(FatalIOError);
565 }
566
567 // Read next token
568 token nextToken(is);
569
570 if (nextToken.isWord())
571 {
572 bool continueParsing = true;
573 do
574 {
575 word symbolPow = nextToken.wordToken();
576 if (symbolPow.back() == token::END_SQR)
577 {
578 symbolPow.resize(symbolPow.size()-1);
579 continueParsing = false;
580 }
581
582
583 // Parse unit
584 dimensionSet symbolSet; // dimless
585
586 const auto index = symbolPow.find('^');
587 if (index != std::string::npos)
588 {
589 const word symbol = symbolPow.substr(0, index);
590 const scalar exponent = readScalar(symbolPow.substr(index+1));
591
593 s.read(readSet.lookup(symbol, keyType::LITERAL), readSet);
594
595 symbolSet.reset(pow(s.dimensions(), exponent));
596
597 // Round to nearest integer if close to it
598 symbolSet.round(10*smallExponent);
599 multiplier *= Foam::pow(s.value(), exponent);
600 }
601 else
602 {
604 s.read(readSet.lookup(symbolPow, keyType::LITERAL), readSet);
605
606 symbolSet.reset(s.dimensions());
607 multiplier *= s.value();
608 }
609
610 // Add dimensions without checking
611 for (int i=0; i < dimensionSet::nDimensions; ++i)
612 {
613 exponents_[i] += symbolSet[i];
614 }
615
616 if (continueParsing)
617 {
618 nextToken = token(is);
619
620 if (!nextToken.isWord() || nextToken == token::END_SQR)
621 {
622 continueParsing = false;
623 }
624 }
625 }
626 while (continueParsing);
627 }
628 else
629 {
630 // Read first five dimensions
631 exponents_[dimensionSet::MASS] = nextToken.number();
632 for (int d=1; d < dimensionSet::CURRENT; ++d)
633 {
634 is >> exponents_[d];
635 }
636
637 // Read next token
638 token nextToken(is);
639
640 // If next token is another number
641 // read last two dimensions
642 // and then read another token for the end of the dimensionSet
643 if (nextToken.isNumber())
644 {
645 exponents_[dimensionSet::CURRENT] = nextToken.number();
646 is >> nextToken;
647 exponents_[dimensionSet::LUMINOUS_INTENSITY] = nextToken.number();
648 is >> nextToken;
649 }
650 else
651 {
652 exponents_[dimensionSet::CURRENT] = 0;
653 exponents_[dimensionSet::LUMINOUS_INTENSITY] = 0;
654 }
655
656 // Check end of dimensionSet
657 if (nextToken != token::END_SQR)
658 {
660 << "Expected a '" << token::END_SQR << "' in dimensionSet\n"
661 << "in stream " << is.info() << nl
662 << exit(FatalIOError);
663 }
664 }
665
667 return is;
668}
669
670
672(
673 Ostream& os,
674 scalar& multiplier,
675 const dimensionSets& writeUnits
676) const
677{
678 multiplier = 1.0;
679
681
682 if (writeUnits.valid() && os.format() == IOstream::ASCII)
683 {
685 for (int d=0; d < dimensionSet::nDimensions; ++d)
686 {
687 exponents[d] = exponents_[d];
688 }
689 writeUnits.coefficients(exponents);
690
691 bool hasPrinted = false;
692
693 // Set precision to lots
694 std::streamsize oldPrecision = os.precision
695 (
696 std::numeric_limits<scalar>::digits10
697 );
698
699 forAll(exponents, i)
700 {
701 if (mag(exponents[i]) > smallExponent)
702 {
703 const dimensionedScalar& ds = writeUnits.units()[i];
704
705 if (hasPrinted)
706 {
707 os << token::SPACE;
708 }
709 hasPrinted = true;
710 os << ds.name();
711 if (mag(exponents[i]-1) > smallExponent)
712 {
713 os << '^' << exponents[i];
714
715 multiplier *= Foam::pow(ds.value(), exponents[i]);
716 }
717 else
718 {
719 multiplier *= ds.value();
720 }
721 }
722 }
723
724 // Reset precision
725 os.precision(oldPrecision);
726 }
727 else
728 {
729 for (int d=0; d < dimensionSet::nDimensions; ++d)
730 {
731 if (d) os << token::SPACE;
732 os << exponents_[d];
733 }
734 }
735
737
739 return os;
740}
741
742
744(
745 Ostream& os,
746 scalar& multiplier
747) const
748{
749 return write(os, multiplier, writeUnitSet());
750}
751
752
753// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
754
756{
757 scalar mult(1.0);
758 ds.read(is, mult);
759
760 if (mag(mult-1.0) > dimensionSet::smallExponent)
761 {
763 << "Cannot use scaled units in dimensionSet"
764 << exit(FatalIOError);
765 }
766
768 return is;
769}
770
771
773{
774 scalar mult(1.0);
775 ds.write(os, mult);
776
778 return os;
779}
780
781
782// ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
A HashTable similar to std::unordered_map.
Definition: HashTable.H:123
streamFormat format() const noexcept
Get the current stream format.
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
InfoProxy< IOstream > info() const
Return info proxy.
Definition: IOstream.H:413
An input stream of tokens.
Definition: ITstream.H:56
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
void putBack(const token &tok)
Put back a token. Only a single put back is permitted.
Definition: Istream.C:70
virtual int precision() const
Get precision of output field.
Definition: OSstream.C:326
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
virtual bool read()
Re-read model coefficients if they have changed.
bool valid() const
True if all internal ids are non-negative.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
fileName relativeName(const bool caseTag=false) const
The dictionary name relative to the case.
Definition: dictionary.C:186
entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find for an entry (non-const access) with the given keyword.
Definition: dictionaryI.H:97
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.C:386
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
Definition: dimensionSet.H:109
static constexpr int nDimensions
There are 7 base dimensions.
Definition: dimensionSet.H:119
Istream & read(Istream &is, scalar &multiplier, const dictionary &)
Read using provided units. Used only in initial parsing.
dimensionSet()
Default construct (dimensionless).
Definition: dimensionSet.C:71
const FixedList< scalar, 7 > & values() const noexcept
Const access to the exponents as a list.
Definition: dimensionSet.C:130
static const scalar smallExponent
Tolerance for 'small' exponents, for near-zero rounding.
Definition: dimensionSet.H:137
void reset(const dimensionSet &ds)
Copy assign the exponents from the dimensionSet.
Definition: dimensionSet.C:149
@ LUMINOUS_INTENSITY
Candela cd.
Definition: dimensionSet.H:130
@ MASS
kilogram kg
Definition: dimensionSet.H:124
@ CURRENT
Ampere A.
Definition: dimensionSet.H:129
bool readEntry(const word &entryName, const dictionary &dict, const bool mandatory=true)
Ostream & write(Ostream &os, scalar &multiplier, const dimensionSets &) const
Write using provided units.
Construction of unit sets.
Definition: dimensionSets.H:83
const PtrList< dimensionedScalar > & units() const noexcept
Return the units.
void coefficients(scalarField &exponents) const
(if valid) obtain set of coefficients of unitNames
bool valid() const noexcept
Is there a valid inverse of the selected unit.
const dimensionSet & dimensions() const
Return const reference to dimensions.
const Type & value() const
Return const reference to value.
const word & name() const
Return const reference to name.
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:70
virtual bool write()
Write the output fields.
@ LITERAL
String literal.
Definition: keyType.H:81
A token holds an item read from Istream.
Definition: token.H:69
bool isNumber() const noexcept
Token is LABEL, FLOAT or DOUBLE.
Definition: tokenI.H:587
punctuationToken
Standard punctuation tokens (a character)
Definition: token.H:121
@ DIVIDE
Divide [isseparator].
Definition: token.H:141
@ BEGIN_SQR
Begin dimensions [isseparator].
Definition: token.H:157
@ BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
@ SUBTRACT
Subtract or start of negative number.
Definition: token.H:153
@ END_LIST
End list [isseparator].
Definition: token.H:156
@ SPACE
Space [isspace].
Definition: token.H:125
@ END_SQR
End dimensions [isseparator].
Definition: token.H:158
@ MULTIPLY
Multiply [isseparator].
Definition: token.H:140
bool good() const noexcept
True if token is not UNDEFINED or ERROR.
Definition: tokenI.H:405
const word & wordToken() const
Return const reference to the word contents.
Definition: tokenI.H:631
bool isWord() const noexcept
Token is word-variant (WORD, DIRECTIVE)
Definition: tokenI.H:609
scalar number() const
Return label, float or double value.
Definition: tokenI.H:593
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
OBJstream os(runTime.globalPath()/outputName)
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
#define FUNCTION_NAME
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
const dimensionSet dimless
Dimensionless.
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
bool isspace(char c) noexcept
Test for whitespace (C-locale)
Definition: char.H:65
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
const HashTable< dimensionedScalar > & unitSet()
Set of all dimensions.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Istream & operator>>(Istream &, directionInfo &)
IOerror FatalIOError
const dimensionSets & writeUnitSet()
Set of units.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
const double expon
Definition: doubleFloat.H:63
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
runTime write()
dictionary dict
volScalarField & e
Definition: createFields.H:11
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333