ENH: remove restricted precision for calc/eval (#2635)

- in earlier versions: used 'fixed' notation
  to force floating point numbers to be printed with at least
  some decimal digits. However, in the meantime we are more
  flexible with handling float/int input so remove this constraint.

- use ITstream::toString, which makes the string expansion of ${var}
  and the expression expansion of $[var] consistent.
This commit is contained in:
Mark Olesen
2023-02-21 13:14:25 +01:00
parent 74d65ed018
commit d006339c9a
5 changed files with 85 additions and 50 deletions

View File

@ -0,0 +1,39 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2306 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Test evaluation with small values
dp #eval{ sqrt(3./2.) *1e-3};
a #eval{ 2/sqrt(2.)*$dp };
A_square #eval{ $a*$a };
A_inlet #eval{ $A_square-2*degToRad(180)*$dp*$dp*0.25 };
Q $A_inlet;
Qerror #eval{$A_inlet};
e #eval{0.2526944494428081};
Uin #eval{ $Q/($A_square*$e) };
// Bypass
alt_dp #eval{ sqrt(3./2.) *1e-3};
alt_a #eval{ 2/sqrt(2.)*$[alt_dp] };
alt_A_square #eval{ $[alt_a]*$[alt_a] };
alt_A_inlet #eval{ $[alt_A_square]-2*degToRad(180)*$[alt_dp]*$[alt_dp]*0.25 };
alt_Q $alt_A_inlet;
alt_Qerror #eval{ $[alt_A_inlet] };
alt_e #eval{0.2526944494428081};
alt_Uin #eval{ $[alt_Q]/($[alt_A_square]*$[alt_e]) };
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017-2022 OpenCFD Ltd.
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -287,11 +287,11 @@ void Foam::ITstream::print(Ostream& os) const
}
else
{
os << toks.first().lineNumber();
os << toks.front().lineNumber();
if (toks.first().lineNumber() < toks.last().lineNumber())
if (toks.front().lineNumber() < toks.back().lineNumber())
{
os << '-' << toks.last().lineNumber();
os << '-' << toks.back().lineNumber();
}
}
os << ", ";
@ -302,17 +302,22 @@ void Foam::ITstream::print(Ostream& os) const
std::string Foam::ITstream::toString() const
{
// NOTE: may wish to have special handling if there is a single token
// and it is already a string or word
const tokenList& toks = *this;
const label nToks = toks.size();
if (nToks == 1 && toks.front().isStringType())
{
// Already a string-type (WORD, STRING, ...). Just copy.
return toks.front().stringToken();
}
OStringStream buf;
unsigned i = 0;
for (const token& tok : *this)
buf.precision(16); // Some reasonably high precision
bool addSpace = false; // Separate from previous token with a space
for (const token& tok : toks)
{
if (i++)
{
buf << ' ';
}
if (addSpace) buf << token::SPACE;
addSpace = true;
buf << tok;
}
@ -345,7 +350,7 @@ void Foam::ITstream::seek(label pos)
if (nToks)
{
lineNumber_ = toks.first().lineNumber();
lineNumber_ = toks.front().lineNumber();
}
setOpened();
@ -358,7 +363,7 @@ void Foam::ITstream::seek(label pos)
if (nToks)
{
lineNumber_ = toks.last().lineNumber();
lineNumber_ = toks.back().lineNumber();
}
setEof();
@ -461,7 +466,7 @@ Foam::Istream& Foam::ITstream::read(token& tok)
if (nToks)
{
tok.lineNumber(toks.last().lineNumber());
tok.lineNumber(toks.back().lineNumber());
}
else
{

View File

@ -87,13 +87,14 @@ Foam::string Foam::functionEntries::calcEntry::evaluate
dictionary codeDict(parentDict, codeSubDict);
// Use function to write stream
OStringStream os(is.format());
OStringStream buf(is.format());
buf.precision(16); // Some reasonably high precision
streamingFunctionType function = getFunction(parentDict, codeDict);
(*function)(os, parentDict);
(*function)(buf, parentDict);
// Return evaluated content as string
return os.str();
return buf.str();
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2018 Bernhard Gschaider
Copyright (C) 2019-2021 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -238,18 +238,9 @@ void Foam::exprTools::expressionEntry::inplaceExpand
if (castTo.empty())
{
// Serialized with spaces
// Serialized with spaces - fails for non-primitiveEntry
ITstream& its = eptr->stream();
if (its.size() == 1 && its[0].isStringType())
{
// Already a string-type (WORD, STRING, ...). Just copy.
varValue = its[0].stringToken();
}
else
{
varValue = its.toString();
}
varValue = its.toString();
}
else
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -231,33 +231,32 @@ static inline std::string entryToString
if (eptr)
{
OStringStream buf;
// Force floating point numbers to be printed with at least
// some decimal digits.
buf << fixed;
buf.precision(IOstream::defaultPrecision());
// Note, for OpenFOAM-v2212 and earlier: used 'fixed' notation
// to force floating point numbers to be printed with at least
// some decimal digits. However, in the meantime we are more
// flexible with handling float/int input so remove this constraint.
if (allowSubDict && eptr->isDict())
if (eptr->isDict())
{
eptr->dict().write(buf, false);
str = buf.str();
}
else
{
// Fail for non-primitiveEntry
const auto& pe = dynamicCast<const primitiveEntry>(*eptr);
if (pe.size() == 1 && pe[0].isStringType())
if (allowSubDict)
{
// Already a string-type (WORD, STRING, ...). Just copy.
str = pe[0].stringToken();
OStringStream buf;
buf.precision(16); // Some reasonably high precision
eptr->dict().write(buf, false);
str = buf.str();
}
else
{
pe.write(buf, true);
str = buf.str();
// Ignore silently...
}
}
else
{
// Serialized with spaces (primitiveEntry)
ITstream& its = eptr->stream();
return its.toString();
}
}
return str;