Merge branch 'update-tokenizer' into 'develop'

ENH: adjust tokenizing

See merge request Development/openfoam!452
This commit is contained in:
Sergio Ferraris
2021-05-19 16:11:50 +00:00
72 changed files with 2568 additions and 973 deletions

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDict;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDict;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDict;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDictCalc1;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDictEval1;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDictEval1;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDictEval1;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,121 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Test expansion with negative signs
value 0.5;
radius 3;
negValue -$value;
select1 10;
sqrt05 #eval{ sqrt(0.5) };
vector ( -10 ${{-$sqrt05}} $value );
corner ( ${{ -$radius*sqrt(0.5) }} 1 0 );
corner2 ${{
vector(-${radius}*sqrt(0.5), ${radius}*sqrt(0.5), 2)
}};
// Just a future idea (2021-05-14) - does not yet work!
#if 0
corner3 #eval #{
variables ( "outer = $radius*sqrt(0.5)" );
vector(-outer, outer, 2)
#};
#endif
// The brace-bracket #eval with multi-lines failed for v2012 and earlier
corner2b #eval
{
vector(-${radius}*sqrt(0.5), $radius*sqrt(0.5), 2)
};
corner2c #eval
${{
vector(-${radius}*sqrt(0.5), $radius*sqrt(0.5), 2)
}};
longSlurp #eval
{
// This is actually a very simple expression
1 + 2
// With a long comment that is stripped out
// during reading anyhow.
};
longVariable
${{
// This is actually a very simple expression in variable syntax
1 + 2
/*
// With a long comment that is stripped out
// during reading anyhow.
*/
}};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Geometric parameters
rxo 2;
ryo 3;
rzo 4;
// Geometric parameters
outerRadius 1;
innerRatio 0.75;
geometry
{
sphere
{
type sphere;
origin (0 0 0);
radius ($rxo $ryo $rzo);
}
innerSphere
{
$sphere
// Different solutions to the same problem
radius_v1
(
${{ $innerRatio*$rxo }}
${{ $innerRatio*$ryo }}
${{ $innerRatio*$rzo }}
);
radius_v2 #eval{ $innerRatio*vector($rxo, $ryo, $rzo) };
radius_v3 ${{ $innerRatio*$[(vector) ../sphere/radius] }};
// Inplace overwrite the same value
radius ${{ $innerRatio*$[(vector) radius] }};
}
}
// ************************************************************************* //

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDict;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Test some parsing

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDictRegex;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#inputMode merge

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDict;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0;
format ascii;
class dictionary;
object testDict;
object dictionary;
note "test with foamDictionary -expand";
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,3 @@
Test-dictionary3.C
EXE = $(FOAM_USER_APPBIN)/Test-dictionary3

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,78 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-dictionary3
Description
Test expressions and re-expansions
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "IOstreams.H"
#include "dictionary.H"
#include "vector.H"
#include "StringStream.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noParallel();
{
IStringStream is
(
"value 10;"
"scalar1 $value;"
"scalar2 -$value;"
// Use #eval expansion entirely
"vector1 ${{vector($value, -$value, $value)}};"
"vector2 ($value -$value $value);"
);
dictionary dict(is);
Info<< "input dictionary:" << dict << nl;
Info<< "value: " << dict.get<scalar>("value") << nl;
Info<< "scalar1: " << dict.get<scalar>("scalar1") << nl;
Info<< "scalar2: " << dict.get<scalar>("scalar2") << nl;
Info<< "vector1: " << dict.get<vector>("vector1") << nl;
Info<< "vector2: " << dict.get<vector>("vector2") << nl;
}
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,3 @@
Test-namedDictionary.C
EXE = $(FOAM_USER_APPBIN)/Test-namedDictionary

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,84 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-namedDictionary
Description
Test handling of keyType/dictionary
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "IOstreams.H"
#include "IOobject.H"
#include "IFstream.H"
#include "namedDictionary.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::addArgument("file1 .. fileN");
argList args(argc, argv, false, true);
if (args.size() <= 1)
{
InfoErr<< "Provide a file or files to test" << nl;
}
else
{
for (label argi=1; argi < args.size(); ++argi)
{
const auto dictFile = args.get<fileName>(argi);
IFstream ifs(dictFile);
dictionary dict(ifs);
IOobject::writeDivider(Info) << nl;
for (const entry& dEntry : dict)
{
if (!dEntry.isStream())
{
continue;
}
Info<< "input: " << dEntry << nl;
List<namedDictionary> list(dEntry.stream());
Info<< "list: " << list << nl;
}
}
}
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,83 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
entry1
(
value1
value2 ; // spurious trailing ';' is removed
this { correct true; }
{ } // Empty everything == ignore
{ anonymous true; }
);
actions1
(
starting
{
name self;
type faceSet;
action new;
source something;
}
{
name self;
type faceSet;
action subset;
source something;
}
);
actions2
(
{
name self;
type faceSet;
action new;
source something;
}
{
name self;
type faceSet;
action subset;
source something;
}
);
actions3
(
{
name self;
type faceSet;
action new;
source something;
}
subset
{
name self;
type faceSet;
action subset;
source something;
}
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,3 @@
Test-splitFunctionArgs.C
EXE = $(FOAM_USER_APPBIN)/Test-splitFunctionArgs

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-splitFunctionArgs
Description
Test splitting of function name args
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "IOstreams.H"
#include "IOobject.H"
#include "IFstream.H"
#include "dictionary.H"
#include "stringOps.H"
#include "Tuple2.H"
using namespace Foam;
// Split out function name and any arguments
// - use as per functionObjectList
void testFunctionNameAndArgsSplit(const std::string& line)
{
word funcName;
wordRes args;
List<Tuple2<word, string>> namedArgs;
const auto lbracket = line.find('(');
if (lbracket == std::string::npos)
{
funcName = word::validate(line);
// No args
}
else
{
funcName = word::validate(line.substr(0, lbracket));
std::string params;
const auto rbracket = line.rfind(')');
if (rbracket != std::string::npos && lbracket < rbracket)
{
params = line.substr(lbracket+1, (rbracket - lbracket - 1));
}
else
{
params = line.substr(lbracket+1);
}
Info<<"parsing: " << params << nl;
stringOps::splitFunctionArgs(params, args, namedArgs);
}
Info<< nl
<< line << nl
<< "function: <" << funcName << '>' << nl
<< " args: " << args << nl
<< " named: " << namedArgs << nl;
}
// Split out any arguments
void testArgsSplit(const std::string& line)
{
wordRes args;
List<Tuple2<word, string>> namedArgs;
stringOps::splitFunctionArgs(line, args, namedArgs);
Info<< nl
<< line << nl
<< " args: " << args << nl
<< " named: " << namedArgs << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::addArgument("file1 .. fileN");
argList args(argc, argv, false, true);
if (args.size() <= 1)
{
InfoErr<< "Provide a file or files to test" << nl;
}
else
{
for (label argi=1; argi < args.size(); ++argi)
{
IOobject::writeDivider(Info);
const auto inputFile = args.get<fileName>(argi);
IFstream is(inputFile);
string line;
while (is.getLine(line))
{
if (line.empty() || line[0] == '#')
{
continue;
}
if (line.starts_with("function:"))
{
auto trim = line.find(':');
++trim;
while (isspace(line[trim]))
{
++trim;
}
line.erase(0, trim);
testFunctionNameAndArgsSplit(line);
}
else
{
testArgsSplit(line);
}
}
}
}
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,47 @@
# -----------------------------------------------------------------------------
# Test names for splitting. Comment character as per -*- sh -*- mode
#
# Prefix with "function: " to test with function name splitting
function: basic
function: func1( a , b );
function: func2(a, value=10);
# discard or flag bad/missing parameters?
function: func3(a , , , value=10);
function: func4();
function: func5( abc );
start=1, end=2
start=1, end=2,
start=100, end= 200, abc
value=100
start=1, end=2
origin=(0 0 0), scale=2, normal=(0 0 1)
# Canonical with named args
function: patchAverage(patch=inlet, p)
# Canonical with unnamed and named args
function: patchAverage(other, patch=inlet, pval)
function: patchAverage(patch=(inlet|outlet), p)
# General
(a, b)
allow=(inlet|outlet), deny=false, regular(value)
# -----------------------------------------------------------------------------

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2020 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,6 +47,7 @@ Description
#include "faceZoneSet.H"
#include "pointZoneSet.H"
#include "IOdictionary.H"
#include "namedDictionary.H"
using namespace Foam;
@ -237,7 +238,7 @@ int main(int argc, char *argv[])
IOdictionary topoSetDict(dictIO);
// Read set construct info from dictionary
PtrList<dictionary> actions(topoSetDict.lookup("actions"));
List<namedDictionary> actionEntries(topoSetDict.lookup("actions"));
forAll(timeDirs, timeI)
{
@ -248,8 +249,13 @@ int main(int argc, char *argv[])
meshReadUpdate(mesh);
// Execute all actions
for (const dictionary& dict : actions)
for (const namedDictionary& actionEntry : actionEntries)
{
const dictionary& dict = actionEntry.dict();
if (dict.empty())
{
continue;
}
const word setName(dict.get<word>("name"));
const word setType(dict.get<word>("type"));

View File

@ -145,6 +145,7 @@ $(strings)/parsing/genericRagelLemonDriver.C
$(strings)/stringOps/stringOps.C
$(strings)/stringOps/stringOpsEvaluate.C
$(strings)/stringOps/stringOpsSort.C
$(strings)/stringOps/stringOpsSplit.C
expr = expressions
$(expr)/exprEntry/expressionEntry.C
@ -275,7 +276,9 @@ $(dictionary)/dictionaryIO.C
$(dictionary)/dictionarySearch.C
$(dictionary)/dictionaryCompat.C
/* Additional helpers */
$(dictionary)/dictionaryContent/dictionaryContent.C
$(dictionary)/namedDictionary/namedDictionary.C
entry = $(dictionary)/entry
$(entry)/entry.C

View File

@ -218,8 +218,8 @@ Foam::Istream& Foam::UIPstream::read(token& t)
case token::COLON :
case token::COMMA :
case token::ASSIGN :
case token::ADD :
case token::SUBTRACT :
case token::PLUS :
case token::MINUS :
case token::MULTIPLY :
case token::DIVIDE :
{
@ -227,12 +227,12 @@ Foam::Istream& Foam::UIPstream::read(token& t)
return *this;
}
// Word/directive
// The word-variants
case token::tokenType::WORD :
case token::tokenType::DIRECTIVE :
{
word val;
if (read(val))
if (readStringFromBuffer(val))
{
if (token::compound::isCompound(val))
{
@ -251,13 +251,14 @@ Foam::Istream& Foam::UIPstream::read(token& t)
return *this;
}
// String types
// The string-variants
case token::tokenType::STRING :
case token::tokenType::EXPRESSION :
case token::tokenType::VARIABLE :
case token::tokenType::VERBATIM :
{
string val;
if (read(val))
if (readStringFromBuffer(val))
{
t = std::move(val);
t.setType(token::tokenType(c));

View File

@ -202,14 +202,19 @@ bool Foam::UOPstream::write(const token& tok)
return true;
}
// The word-variants
case token::tokenType::WORD :
case token::tokenType::DIRECTIVE :
{
writeToBuffer(char(token::tokenType::DIRECTIVE));
writeToBuffer(char(tok.type()));
writeStringToBuffer(tok.wordToken());
return true;
}
// The string-variants
case token::tokenType::STRING :
case token::tokenType::EXPRESSION :
case token::tokenType::VARIABLE :
case token::tokenType::VERBATIM :
{

View File

@ -30,6 +30,7 @@ License
#include "int.H"
#include "token.H"
#include <cctype>
#include <cstring>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -42,14 +43,14 @@ namespace
{
// Convert a single character to a word with length 1
inline static Foam::word charToWord(char c)
inline Foam::word charToWord(char c)
{
return Foam::word(std::string(1, c), false);
}
// Permit slash-scoping of entries
static inline bool validVariableChar(char c)
inline bool validVariableChar(char c)
{
return (Foam::word::valid(c) || c == '/');
}
@ -59,23 +60,51 @@ static inline bool validVariableChar(char c)
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
bool Foam::ISstream::seekCommentEnd_Cstyle()
{
// Search for end of C-style comment - "*/"
// Can use getLine(nullptr, '*') in the logic,
// but written out looks less obscure
char c = 0;
bool star = false;
while (get(c))
{
if (c == '*')
{
star = true;
}
else if (star)
{
star = false;
if (c == '/')
{
// Matched "*/"
return true;
}
}
}
// Exhausted stream without finding "*/" sequence
return false;
}
char Foam::ISstream::nextValid()
{
char c = 0;
while (true)
// Get next non-whitespace character
while (get(c))
{
// Get next non-whitespace character
while (get(c) && isspace(c))
{}
// Return if stream is bad - ie, previous get() failed
if (bad() || isspace(c))
if (isspace(c))
{
return 0;
continue;
}
// Is this the start of a C/C++ comment?
// Check if this starts a C/C++ comment
if (c == '/')
{
if (!get(c))
@ -86,37 +115,15 @@ char Foam::ISstream::nextValid()
if (c == '/')
{
// C++ style single-line comment - skip through past end-of-line
while (get(c) && c != '\n')
{}
// C++ comment: discard through newline
(void) getLine(nullptr, '\n');
}
else if (c == '*')
{
// Within a C-style comment
while (true)
// C-style comment: discard through to "*/" ending
if (!seekCommentEnd_Cstyle())
{
// Search for end of C-style comment - '*/'
if (get(c) && c == '*')
{
if (get(c))
{
if (c == '/')
{
// matched '*/'
break;
}
else if (c == '*')
{
// check again
putback(c);
}
}
}
if (!good())
{
return 0;
}
return 0;
}
}
else
@ -137,28 +144,261 @@ char Foam::ISstream::nextValid()
}
void Foam::ISstream::readWordToken(token& t)
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
word val;
if (read(val).bad())
// Read a verbatim string (excluding block delimiters),
// continuing until a closing "#}" has been found.
//
// The leading "#{" removed from stream prior to calling.
static ISstream& readVerbatim
(
ISstream& is,
std::string& str
)
{
constexpr const unsigned bufLen = 8000;
static char buf[bufLen];
unsigned nChar = 0;
char c;
str.clear();
while (is.get(c))
{
t.setBad();
}
else if (token::compound::isCompound(val))
{
t = token::compound::New(val, *this).ptr();
}
else
{
t = std::move(val); // Move contents to token
if (c == token::HASH)
{
char nextC;
is.get(nextC);
if (nextC == token::END_BLOCK)
{
// Found closing "#}" sequence
str.append(buf, nChar);
return is;
}
else
{
// Re-analyze the character
is.putback(nextC);
}
}
buf[nChar++] = c;
if (nChar == bufLen) // Flush full buffer
{
str.append(buf, nChar);
nChar = 0;
}
}
// Abnormal exit of the loop
str.append(buf, nChar); // Finalize pending content
strncpy(buf, str.c_str(), errLen);
buf[errLen] = '\0';
FatalIOErrorInFunction(is)
<< "Problem while reading verbatim \"" << buf
<< "...\" [after " << str.length() << " chars]\n"
<< exit(FatalIOError);
return is;
}
// Read a variable or expression.
// Handles "$var" and "${var}" forms, permits '/' scoping character.
// Also handles "${{expr}}".
//
// Return the token type or ERROR
//
// The leading "${" or "$c" removed from stream prior to calling.
static token::tokenType readVariable
(
ISstream& is,
std::string& str,
char c // Next character after '$'
)
{
constexpr const unsigned bufLen = 1024;
static char buf[bufLen];
token::tokenType tokType(token::tokenType::VARIABLE);
// The first two characters are known:
buf[0] = token::DOLLAR;
buf[1] = c;
unsigned nChar = 2; // Starts with two characters
unsigned depth = 0; // Depth of {..} nesting
str.clear();
if (c == token::BEGIN_BLOCK)
{
// Processing '${variable}' or '${{expr}}'
++depth;
int lookahead = is.peek();
if (lookahead == token::BEGIN_BLOCK)
{
// Looks like '${{expr...'
tokType = token::tokenType::EXPRESSION;
}
else if (lookahead == token::END_BLOCK)
{
// Looks like '${}'
IOWarningInFunction(is)
<< "Ignoring empty ${}" << endl;
return token::tokenType::ERROR;
}
while (is.get(c))
{
buf[nChar++] = c;
if (c == token::BEGIN_BLOCK)
{
++depth;
}
else if (c == token::END_BLOCK)
{
--depth;
if (!depth)
{
// Found closing '}' character
str.append(buf, nChar);
return tokType;
}
}
else if (c == '/' && tokType == token::tokenType::EXPRESSION)
{
// Strip C/C++ comments from expressions
// Note: could also peek instead of get/putback
if (!is.get(c))
{
break; // Premature end of stream
}
else if (c == '/')
{
--nChar; // Remove initial '/' from buffer
// C++ comment: discard through newline
(void) is.getLine(nullptr, '\n');
}
else if (c == '*')
{
--nChar; // Remove initial '/' from buffer
// C-style comment: seek "*/" ending
if (!is.seekCommentEnd_Cstyle())
{
break; // Premature end of stream
}
}
else
{
// Re-analyze the character
is.putback(c);
}
}
if (nChar == bufLen) // Flush full buffer
{
str.append(buf, nChar);
nChar = 0;
}
}
// Abnormal exit of the loop
str.append(buf, nChar); // Finalize pending content
strncpy(buf, str.c_str(), errLen);
buf[errLen] = '\0';
FatalIOErrorInFunction(is)
<< "stream terminated while reading variable '" << buf
<< "...' [after " << str.length() << " chars]\n"
<< exit(FatalIOError);
return token::tokenType::ERROR;
}
else if (validVariableChar(c))
{
// Processing '$variable'
while (is.get(c))
{
if (!validVariableChar(c))
{
is.putback(c);
break;
}
if (c == token::BEGIN_LIST)
{
++depth;
}
else if (c == token::END_LIST)
{
if (!depth)
{
// Closed ')' without opening '(':
// - don't consider it part of our input
is.putback(c);
break;
}
--depth;
}
buf[nChar++] = c;
if (nChar == bufLen) // Flush full buffer
{
str.append(buf, nChar);
nChar = 0;
}
}
str.append(buf, nChar); // Finalize pending content
if (depth)
{
strncpy(buf, str.c_str(), errLen);
buf[errLen] = '\0';
IOWarningInFunction(is)
<< "Missing " << depth
<< " closing ')' while parsing" << nl << nl
<< buf << endl;
}
return tokType;
}
else
{
// Invalid character. Terminate string (for message)
buf[nChar--] = '\0';
IOWarningInFunction(is)
<< "Ignoring bad variable name: " << buf << nl << endl;
}
return token::tokenType::ERROR;
}
} // End namespace Foam
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::Istream& Foam::ISstream::read(token& t)
{
constexpr const unsigned maxLen = 128; // Max length for labels/scalars
static char buf[maxLen];
constexpr const unsigned bufLen = 128; // Max length for labels/scalars
static char buf[bufLen];
// Return the put back token if it exists
if (Istream::getBack(t))
@ -199,8 +439,8 @@ Foam::Istream& Foam::ISstream::read(token& t)
case token::COLON :
case token::COMMA :
case token::ASSIGN :
case token::ADD :
// NB: token::SUBTRACT handled later as the possible start of a Number
case token::PLUS :
// NB: token::MINUS handled later as the possible start of a Number
case token::MULTIPLY :
case token::DIVIDE :
{
@ -209,7 +449,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
}
// String: enclosed by double quotes.
case token::BEGIN_STRING :
case token::DQUOTE :
{
putback(c);
@ -226,21 +466,21 @@ Foam::Istream& Foam::ISstream::read(token& t)
return *this;
}
// Possible verbatim string or dictionary functionEntry
// Verbatim string '#{ .. #}' or dictionary '#directive'
case token::HASH :
{
char nextC;
if (read(nextC).bad())
{
// Return lone '#' as word
t = charToWord(c);
}
else if (nextC == token::BEGIN_BLOCK)
int lookahead = peek();
if (lookahead == token::BEGIN_BLOCK)
{
// Verbatim string: #{ ... #}
// Token stored without the surrounding delimiters
(void) get(nextC); // Discard '{' lookahead
string val;
if (readVerbatim(val).bad())
if (readVerbatim(*this, val).bad())
{
t.setBad();
}
@ -250,9 +490,14 @@ Foam::Istream& Foam::ISstream::read(token& t)
t.setType(token::tokenType::VERBATIM);
}
}
else
else if (read(nextC).bad())
{
// Word beginning with '#'. Eg, "#include"
// Return lone '#' as word
t = charToWord(c);
}
else if (word::valid(nextC))
{
// Directive (wordToken) beginning with '#'. Eg, "#include"
// Put back both so that '#...' is included in the directive
putback(nextC);
@ -269,34 +514,44 @@ Foam::Istream& Foam::ISstream::read(token& t)
t.setType(token::tokenType::DIRECTIVE);
}
}
else
{
// '#' followed by non-word. Just ignore leading '#'?
putback(nextC);
IOWarningInFunction(*this)
<< "Invalid sequence #" << char(nextC)
<< " ... ignoring the leading '#'" << nl << endl;
}
return *this;
}
// Dictionary variable (as rvalue)
// Dictionary variable or ${{ expression }}
case token::DOLLAR :
{
char nextC;
if (read(nextC).bad())
{
// Return lone '$' as word
// Return lone '$' as word. Could also ignore
t = charToWord(c);
}
else
{
// Put back both so that '$...' is included in the variable
putback(nextC);
putback(c);
// NB: the parser is slightly generous here.
// It will also accept '$ {' as input.
// - to be revisited (2021-05-17)
string val;
if (readVariable(val).bad())
token::tokenType tokType = readVariable(*this, val, nextC);
if (tokType == token::tokenType::ERROR)
{
t.setBad();
}
else
{
t = std::move(val); // Move contents to token
t.setType(token::tokenType::VARIABLE);
t.setType(tokType);
}
}
@ -340,14 +595,14 @@ Foam::Istream& Foam::ISstream::read(token& t)
}
buf[nChar++] = c;
if (nChar == maxLen)
if (nChar == bufLen)
{
// Runaway argument - avoid buffer overflow
buf[maxLen-1] = '\0';
buf[bufLen-1] = '\0';
FatalIOErrorInFunction(*this)
<< "number '" << buf << "...'\n"
<< " is too long (max. " << maxLen << " characters)"
<< "Number '" << buf << "...'\n"
<< " is too long (max. " << bufLen << " characters)"
<< exit(FatalIOError);
t.setBad();
@ -368,7 +623,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
if (nChar == 1 && buf[0] == '-')
{
// A single '-' is punctuation
t = token::punctuationToken(token::SUBTRACT);
t = token::punctuationToken(token::MINUS);
}
else if (labelVal && Foam::read(buf, labelVal))
{
@ -397,7 +652,20 @@ Foam::Istream& Foam::ISstream::read(token& t)
default:
{
putback(c);
readWordToken(t);
word val;
if (read(val).bad())
{
t.setBad();
}
else if (token::compound::isCompound(val))
{
t = token::compound::New(val, *this).ptr();
}
else
{
t = std::move(val); // Move contents to token
}
return *this;
}
@ -414,20 +682,22 @@ Foam::Istream& Foam::ISstream::read(char& c)
Foam::Istream& Foam::ISstream::read(word& str)
{
constexpr const unsigned maxLen = 1024;
static char buf[maxLen];
constexpr const unsigned bufLen = 1024;
static char buf[bufLen];
unsigned nChar = 0;
unsigned depth = 0; // Track depth of (..) nesting
unsigned depth = 0; // Depth of (..) nesting
char c;
while
(
(nChar < maxLen)
&& get(c)
&& word::valid(c)
)
str.clear();
while (get(c))
{
if (!word::valid(c))
{
putback(c);
break;
}
if (c == token::BEGIN_LIST)
{
++depth;
@ -436,42 +706,40 @@ Foam::Istream& Foam::ISstream::read(word& str)
{
if (!depth)
{
break; // Closed ')' without an opening '(' ? ... stop
// Closed ')' without opening '(':
// - don't consider it part of our input
putback(c);
break;
}
--depth;
}
buf[nChar++] = c;
if (nChar == bufLen) // Flush full buffer
{
str.append(buf, nChar);
nChar = 0;
}
}
if (nChar >= maxLen)
{
buf[errLen] = '\0';
FatalIOErrorInFunction(*this)
<< "word '" << buf << "...'\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
return *this;
}
buf[nChar] = '\0'; // Terminate string
str.append(buf, nChar); // Finalize pending content
if (bad())
{
// Could probably skip this check
strncpy(buf, str.c_str(), errLen);
buf[errLen] = '\0';
FatalIOErrorInFunction(*this)
<< "Problem while reading word '" << buf << "...' after "
<< nChar << " characters\n"
<< "Problem while reading word '" << buf
<< "...' [after " << str.length() << " chars]\n"
<< exit(FatalIOError);
return *this;
}
if (nChar == 0)
if (str.empty())
{
FatalIOErrorInFunction(*this)
<< "Invalid first character found : " << c
@ -479,25 +747,25 @@ Foam::Istream& Foam::ISstream::read(word& str)
}
else if (depth)
{
strncpy(buf, str.c_str(), errLen);
buf[errLen] = '\0';
IOWarningInFunction(*this)
<< "Missing " << depth
<< " closing ')' while parsing" << nl << nl
<< buf << nl << endl;
}
// Finalize: content already validated, assign without additional checks.
str.assign(buf, nChar);
putback(c);
return *this;
}
Foam::Istream& Foam::ISstream::read(string& str)
{
constexpr const unsigned maxLen = 1024;
static char buf[maxLen];
constexpr const unsigned bufLen = 1024;
static char buf[bufLen];
unsigned nChar = 0;
char c;
if (!get(c))
@ -510,7 +778,7 @@ Foam::Istream& Foam::ISstream::read(string& str)
}
// Note, we could also handle single-quoted strings here (if desired)
if (c != token::BEGIN_STRING)
if (c != token::DQUOTE)
{
FatalIOErrorInFunction(*this)
<< "Incorrect start of string character found : " << c
@ -519,26 +787,25 @@ Foam::Istream& Foam::ISstream::read(string& str)
return *this;
}
unsigned nChar = 0;
str.clear();
bool escaped = false;
while
(
(nChar < maxLen)
&& get(c)
)
while (get(c))
{
if (c == token::END_STRING)
if (c == '\\')
{
escaped = !escaped; // Toggle state (retains backslashes)
}
else if (c == token::DQUOTE)
{
if (escaped)
{
escaped = false;
--nChar; // Overwrite backslash
--nChar; // Overwrite backslash
}
else
{
// Done reading
str.assign(buf, nChar);
str.append(buf, nChar);
return *this;
}
}
@ -547,253 +814,44 @@ Foam::Istream& Foam::ISstream::read(string& str)
if (escaped)
{
escaped = false;
--nChar; // Overwrite backslash
--nChar; // Overwrite backslash
}
else
{
buf[errLen] = buf[nChar] = '\0';
str.append(buf, nChar); // Finalize pending content
strncpy(buf, str.c_str(), errLen);
buf[errLen] = '\0';
FatalIOErrorInFunction(*this)
<< "found '\\n' while reading string \""
<< buf << "...\""
<< "Unescaped '\\n' while reading string \"" << buf
<< "...\" [after " << str.length() << " chars]\n"
<< exit(FatalIOError);
return *this;
}
}
else if (c == '\\')
{
escaped = !escaped; // toggle state (retains backslashes)
}
else
{
escaped = false;
}
buf[nChar++] = c;
if (nChar == bufLen) // Flush full buffer
{
// Keep lookback character (eg, for backslash escaping)
str.append(buf, nChar-1);
nChar = 1;
buf[0] = c;
}
}
if (nChar >= maxLen)
{
buf[errLen] = '\0';
FatalIOErrorInFunction(*this)
<< "string \"" << buf << "...\"\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
return *this;
}
// Abnormal exit of the loop
// Don't worry about a dangling backslash if string terminated prematurely
buf[errLen] = buf[nChar] = '\0';
FatalIOErrorInFunction(*this)
<< "Problem while reading string \"" << buf << "...\""
<< exit(FatalIOError);
return *this;
}
Foam::Istream& Foam::ISstream::readVariable(std::string& str)
{
constexpr const unsigned maxLen = 1024;
static char buf[maxLen];
unsigned nChar = 0;
unsigned depth = 0; // Track depth of (..) or {..} nesting
char c;
// First character must be '$'
if (!get(c) || c != token::DOLLAR)
{
FatalIOErrorInFunction(*this)
<< "Invalid first character found : " << c << nl
<< exit(FatalIOError);
}
buf[nChar++] = c;
// Next character should also exist.
// This should never fail, since it was checked before calling.
if (!get(c))
{
str.assign(buf, nChar);
IOWarningInFunction(*this)
<< "Truncated variable name : " << str << nl;
return *this;
}
buf[nChar++] = c;
str.clear();
if (c == token::BEGIN_BLOCK)
{
// Processing ${...} style.
++depth;
// Could check that the next char is good and not one of '{}'
// since this would indicate "${}", "${{..." or truncated "${"
while (get(c))
{
buf[nChar++] = c;
if (nChar == maxLen)
{
str.append(buf, nChar);
nChar = 0;
}
if (c == token::BEGIN_BLOCK)
{
++depth;
}
else if (c == token::END_BLOCK)
{
--depth;
if (!depth)
{
// Found closing '}' character
str.append(buf, nChar);
return *this;
}
}
}
// Should never reach here on normal input
str.append(buf, nChar); // Finalize pending buffer input
nChar = str.length();
if (str.length() > errLen)
{
str.erase(errLen);
}
FatalIOErrorInFunction(*this)
<< "stream terminated while reading variable '"
<< str.c_str() << "...' [" << nChar << "]\n"
<< exit(FatalIOError);
return *this;
}
else if (validVariableChar(c))
{
// Processing $var style
while
(
(nChar < maxLen) && get(c)
&& (validVariableChar(c))
)
{
if (c == token::BEGIN_LIST)
{
++depth;
}
else if (c == token::END_LIST)
{
if (!depth)
{
break; // Closed ')' without an opening '(' ? ... stop
}
--depth;
}
buf[nChar++] = c;
}
}
else
{
// Invalid character. Terminate string (for message) without
// including the invalid character in the count.
buf[nChar--] = '\0';
IOWarningInFunction(*this)
<< "Bad variable name: " << buf << nl << endl;
}
if (nChar >= maxLen)
{
buf[errLen] = '\0';
FatalIOErrorInFunction(*this)
<< "variable '" << buf << "...'\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
return *this;
}
buf[nChar] = '\0'; // Terminate string
if (bad())
{
// Could probably skip this check
buf[errLen] = '\0';
FatalIOErrorInFunction(*this)
<< "Problem while reading variable '" << buf << "...' after "
<< nChar << " characters\n"
<< exit(FatalIOError);
return *this;
}
if (depth)
{
IOWarningInFunction(*this)
<< "Missing " << depth
<< " closing ')' while parsing" << nl << nl
<< buf << nl << endl;
}
// Finalize
str.assign(buf, nChar);
putback(c);
return *this;
}
Foam::Istream& Foam::ISstream::readVerbatim(std::string& str)
{
constexpr const unsigned maxLen = 8000;
static char buf[maxLen];
unsigned nChar = 0;
char c;
str.clear();
while (get(c))
{
if (c == token::HASH)
{
char nextC;
get(nextC);
if (nextC == token::END_BLOCK)
{
// Found closing "#}" sequence
str.append(buf, nChar);
return *this;
}
else
{
putback(nextC);
}
}
buf[nChar++] = c;
if (nChar == maxLen)
{
str.append(buf, nChar);
nChar = 0;
}
}
// Truncated terminated prematurely
buf[errLen] = buf[nChar] = '\0';
str.append(buf, nChar); // Finalize pending content
strncpy(buf, str.c_str(), errLen);
buf[errLen] = '\0';
FatalIOErrorInFunction(*this)
<< "Problem while reading string \"" << buf << "...\""

View File

@ -69,18 +69,6 @@ class ISstream
//- Get the next valid character
char nextValid();
//- Read a word token
void readWordToken(token& t);
//- Read a verbatim string (excluding block delimiters).
// The leading "#{" has been removed prior to calling,
// continues until the closing "#}" has been found.
Istream& readVerbatim(std::string& str);
//- Read a variable name starting with '$'.
// Handles "$var" and "${var}" forms, permits '/' scoping character.
Istream& readVariable(std::string& str);
//- No copy assignment
void operator=(const ISstream&) = delete;
@ -137,6 +125,13 @@ public:
virtual ios_base::fmtflags flags() const;
// Special-purpose Functions
//- Discard until end of C-style comment '*/'
// \return False if stream exhausted before finding the comment end
bool seekCommentEnd_Cstyle();
// Read Functions
//- Raw, low-level get character function.

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,27 +47,33 @@ bool Foam::OSstream::write(const token& tok)
case token::tokenType::DIRECTIVE :
{
// The '#' sigil is already part of the wordToken
// Token stored with leading '#' sigil - output directly
write(tok.wordToken());
return true;
}
case token::tokenType::VERBATIM :
case token::tokenType::EXPRESSION :
{
// Surrounding '#{ .. #}' to be recognized as verbatim
write(char(token::HASH));
write(char(token::BEGIN_BLOCK));
// Token stored with surrounding '${{ .. }}' - output directly
writeQuoted(tok.stringToken(), false);
write(char(token::HASH));
write(char(token::END_BLOCK));
return true;
}
case token::tokenType::VARIABLE :
{
// Token stored with leading '$' sigil - output directly
writeQuoted(tok.stringToken(), false);
return true;
}
case token::tokenType::VERBATIM :
{
// Token stored without surrounding '#{ .. #}'. Add on output
write(char(token::HASH));
write(char(token::BEGIN_BLOCK));
writeQuoted(tok.stringToken(), false);
write(char(token::HASH));
write(char(token::END_BLOCK));
return true;
}
@ -127,7 +133,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
// Output with surrounding quotes and backslash escaping
os_ << token::BEGIN_STRING;
os_ << token::DQUOTE;
unsigned backslash = 0;
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
@ -144,7 +150,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
++lineNumber_;
++backslash; // backslash escape for newline
}
else if (c == token::END_STRING)
else if (c == token::DQUOTE)
{
++backslash; // backslash escape for quote
}
@ -161,7 +167,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
// silently drop any trailing backslashes
// they would otherwise appear like an escaped end-quote
os_ << token::END_STRING;
os_ << token::DQUOTE;
setState(os_.rdstate());
return *this;

View File

@ -71,11 +71,13 @@ class token
public:
//- Enumeration defining the types of token.
// Since these values are also used to tag content in Pstream,
// the maximum number of types is limited to 30.
enum tokenType
// Since the enumeration is used to tag content in Pstream, it is of
// type \c char and shall have values that do not overlap with regular
// punctuation characters.
enum tokenType : char
{
UNDEFINED = 0, //!< An undefined token-type
UNDEFINED = '\0', //!< An undefined token-type
ERROR = '\x80', //!< Token error encountered
// Fundamental types
FLAG, //!< stream flag (1-byte bitmask)
@ -86,14 +88,18 @@ public:
DOUBLE, //!< double (double-precision) type
// Pointer types
WORD, //!< A Foam::word
STRING, //!< A string (usually double-quoted)
DIRECTIVE, //!< A dictionary \c \#directive (word variant)
VARIABLE, //!< A dictionary \c \$variable (string variant)
VERBATIM, //!< Verbatim string content
WORD, //!< Foam::word
STRING, //!< Foam::string (usually double-quoted)
COMPOUND, //!< Compound type such as \c List\<label\> etc.
ERROR, //!< A token error encountered
DIRECTIVE, //!< Word-variant: dictionary \c \#directive
//!< stored with sigil
EXPRESSION, //!< String-variant: math expression for evaluation
//!< stored with delimiters
VARIABLE, //!< String-variant: dictionary \c \$variable
//!< stored with sigil
VERBATIM, //!< String-variant: verbatim string content
//!< stored without delimiters
// Aliases
FLOAT_SCALAR = FLOAT,
@ -122,16 +128,16 @@ public:
COLON = ':', //!< Colon [#isseparator]
SEMICOLON = ';', //!< Semicolon [#isseparator]
COMMA = ',', //!< Comma [#isseparator]
HASH = '#', //!< Hash - directive or verbatim string
DOLLAR = '$', //!< Dollar - start variable
HASH = '#', //!< Hash - directive or start verbatim string
DOLLAR = '$', //!< Dollar - start variable or expression
QUESTION = '?', //!< Question mark (eg, ternary)
ATSYM = '@', //!< The 'at' symbol
SQUOTE = '\'', //!< Single quote
DQUOTE = '"', //!< Double quote
ASSIGN = '=', //!< Assignment/equals [#isseparator]
ADD = '+', //!< Addition [#isseparator]
SUBTRACT = '-', //!< Subtract or start of negative number
PLUS = '+', //!< Addition [#isseparator]
MINUS = '-', //!< Subtract or start of negative number
MULTIPLY = '*', //!< Multiply [#isseparator]
DIVIDE = '/', //!< Divide [#isseparator]
@ -144,6 +150,8 @@ public:
// With semantically meaning
ADD = PLUS, //!< Addition [#isseparator]
SUBTRACT = MINUS, //!< Subtract or start of negative number
END_STATEMENT = SEMICOLON, //!< End entry [#isseparator]
BEGIN_LIST = LPAREN, //!< Begin list [#isseparator]
END_LIST = RPAREN, //!< End list [#isseparator]
@ -471,10 +479,10 @@ public:
//- Token is LABEL, FLOAT or DOUBLE
inline bool isNumber() const noexcept;
//- Token is WORD or DIRECTIVE word
//- Token is word-variant (WORD, DIRECTIVE)
inline bool isWord() const noexcept;
//- Token is WORD or DIRECTIVE word and equal to parameter
//- Token is word-variant and equal to parameter
inline bool isWord(const std::string& s) const;
//- Token is DIRECTIVE (word variant)
@ -483,16 +491,20 @@ public:
//- Token is (quoted) STRING (string variant)
inline bool isQuotedString() const noexcept;
//- Token is STRING, VARIABLE or VERBATIM (string variant)
//- Token is string-variant (STRING, EXPRESSION, VARIABLE, VERBATIM)
inline bool isString() const noexcept;
//- Token is EXPRESSION (string variant)
inline bool isExpression() const noexcept;
//- Token is VARIABLE (string variant)
inline bool isVariable() const noexcept;
//- Token is VERBATIM string (string variant)
inline bool isVerbatim() const noexcept;
//- Token is WORD, DIRECTIVE, STRING, VARIABLE or VERBATIM
//- Token is word-variant or string-variant
//- (WORD, DIRECTIVE, STRING, EXPRESSION, VARIABLE, VERBATIM)
inline bool isStringType() const noexcept;
//- Token is COMPOUND
@ -542,7 +554,8 @@ public:
//- Return const reference to the string contents.
// Report FatalIOError and return \b "" if token is not a
// STRING, VARIABLE, VERBATIM or an upcast WORD or DIRECTIVE
// STRING, EXPRESSION, VARIABLE, VERBATIM
// or an upcast WORD or DIRECTIVE
inline const string& stringToken() const;
//- Read access for compound token
@ -599,16 +612,16 @@ public:
//- Copy assign from double
inline void operator=(const doubleScalar val);
//- Copy assign from word
//- Copy assign from word content
inline void operator=(const word& w);
//- Copy assign from string
//- Copy assign from string content
inline void operator=(const string& str);
//- Move assign from word
//- Move assign from word content
inline void operator=(word&& w);
//- Move assign from string
//- Move assign from string content
inline void operator=(string&& str);
//- Assign compound with reference counting to token

View File

@ -66,8 +66,8 @@ inline bool Foam::token::isseparator(int c) noexcept
case token::COLON :
case token::COMMA :
case token::ASSIGN :
case token::ADD :
// Excluded token::SUBTRACT since it could start a number
case token::PLUS :
// Excluded token::MINUS since it could start a number
case token::MULTIPLY :
case token::DIVIDE :
{
@ -121,6 +121,7 @@ inline Foam::token::token(const token& tok)
}
case tokenType::STRING:
case tokenType::EXPRESSION:
case tokenType::VARIABLE:
case tokenType::VERBATIM:
{
@ -265,6 +266,7 @@ inline void Foam::token::reset()
}
case tokenType::STRING:
case tokenType::EXPRESSION:
case tokenType::VARIABLE:
case tokenType::VERBATIM:
{
@ -357,6 +359,7 @@ inline bool Foam::token::setType(token::tokenType tokType) noexcept
break;
case tokenType::STRING:
case tokenType::EXPRESSION:
case tokenType::VARIABLE:
case tokenType::VERBATIM:
{
@ -364,6 +367,7 @@ inline bool Foam::token::setType(token::tokenType tokType) noexcept
{
// could also go from WORD to STRING etc - to be decided
case tokenType::STRING:
case tokenType::EXPRESSION:
case tokenType::VARIABLE:
case tokenType::VERBATIM:
type_ = tokType;
@ -651,12 +655,19 @@ inline bool Foam::token::isString() const noexcept
return
(
type_ == tokenType::STRING
|| type_ == tokenType::EXPRESSION
|| type_ == tokenType::VARIABLE
|| type_ == tokenType::VERBATIM
);
}
inline bool Foam::token::isExpression() const noexcept
{
return (type_ == tokenType::EXPRESSION);
}
inline bool Foam::token::isVariable() const noexcept
{
return (type_ == tokenType::VARIABLE);
@ -680,6 +691,7 @@ inline const Foam::string& Foam::token::stringToken() const
if
(
type_ == tokenType::STRING
|| type_ == tokenType::EXPRESSION
|| type_ == tokenType::VARIABLE
|| type_ == tokenType::VERBATIM
)
@ -754,6 +766,7 @@ inline void Foam::token::operator=(const token& tok)
break;
case tokenType::STRING:
case tokenType::EXPRESSION:
case tokenType::VARIABLE:
case tokenType::VERBATIM:
{
@ -903,6 +916,7 @@ inline bool Foam::token::operator==(const token& tok) const
return *data_.wordPtr == *tok.data_.wordPtr;
case tokenType::STRING:
case tokenType::EXPRESSION:
case tokenType::VARIABLE:
case tokenType::VERBATIM:
return *data_.stringPtr == *tok.data_.stringPtr;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -82,6 +82,10 @@ static OS& printTokenInfo(OS& os, const token& tok)
os << "string " << tok.stringToken();
break;
case token::tokenType::EXPRESSION:
os << "expression " << tok.stringToken();
break;
case token::tokenType::VARIABLE:
os << "variable " << tok.stringToken();
break;
@ -141,6 +145,7 @@ Foam::word Foam::token::name() const
case token::tokenType::WORD: return "word";
case token::tokenType::DIRECTIVE: return "directive";
case token::tokenType::STRING: return "string";
case token::tokenType::EXPRESSION: return "expression";
case token::tokenType::VERBATIM: return "verbatim";
case token::tokenType::VARIABLE: return "variable";
case token::tokenType::COMPOUND: return "compound";
@ -194,8 +199,10 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const token& tok)
os << tok.data_.doubleVal;
break;
// Different behaviour for (serial/parallel) streams: preserve types
// Possibly different behaviour for serial/parallel streams:
// preserve types
case token::tokenType::DIRECTIVE:
case token::tokenType::EXPRESSION:
case token::tokenType::VARIABLE:
case token::tokenType::VERBATIMSTRING:
os.write(tok);

View File

@ -56,60 +56,163 @@ namespace functionEntries
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace
{
// This is akin to a SafeIOWarning, which does not yet exist
inline void safeIOWarning
(
const Foam::IOstream& is,
const std::string& msg
)
{
std::cerr
<< "--> FOAM Warning :\n"
<< " Reading \"" << is.name() << "\" at line "
<< is.lineNumber() << '\n'
<< " " << msg << std::endl;
}
} // End anonymous namespace
namespace Foam
{
// Slurp a string until a closing '}' is found.
// Track balanced bracket/brace pairs, with max stack depth of 60.
static bool slurpUntilBalancedBrace(ISstream& is, std::string& str)
{
constexpr const unsigned bufLen = 1024;
static char buf[bufLen];
is.fatalCheck(FUNCTION_NAME);
unsigned nChar = 0;
unsigned depth = 1; // Initial '{' already seen by caller
char c;
str.clear();
while (is.get(c))
{
buf[nChar++] = c;
if (c == token::BEGIN_BLOCK)
{
++depth;
}
else if (c == token::END_BLOCK)
{
--depth;
if (!depth)
{
// Closing '}' character - do not include in output
--nChar;
str.append(buf, nChar);
return true;
}
}
else if (c == '/')
{
// Strip C/C++ comments from expressions
// Note: could also peek instead of get/putback
if (!is.get(c))
{
break; // Premature end of stream
}
else if (c == '/')
{
--nChar; // Remove initial '/' from buffer
// C++ comment: discard through newline
(void) is.getLine(nullptr, '\n');
}
else if (c == '*')
{
--nChar; // Remove initial '/' from buffer
// C-style comment: discard through to "*/" ending
if (!is.seekCommentEnd_Cstyle())
{
break; // Premature end of stream
}
}
else
{
// Reanalyze the char
is.putback(c);
}
}
if (nChar == bufLen)
{
str.append(buf, nChar); // Flush full buffer
nChar = 0;
}
}
// Abnormal exit of the loop
str.append(buf, nChar); // Finalize pending content
safeIOWarning(is, "Premature end while reading expression - missing '}'?");
is.fatalCheck(FUNCTION_NAME);
return false;
}
} // End namespace Foam
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::tokenList Foam::functionEntries::evalEntry::evaluate
(
const dictionary& parentDict,
Istream& is
const string& inputExpr,
label fieldWidth,
const Istream& is
)
{
#ifdef FULLDEBUG
DetailInfo
<< "Using #eval - line "
<< is.lineNumber() << " in file " << parentDict.name() << nl;
#endif
token tok(is);
label fieldWidth(1); // Field width for the result
if (tok.isLabel())
{
// - #eval INT "expr"
// - #eval INT { expr }
// - #eval INT #{ expr #}
fieldWidth = max(1, tok.labelToken());
is >> tok;
}
string s; // String to evaluate
if (tok.isString())
{
// - #eval "expr"
// - #eval #{ expr #}
s = tok.stringToken();
}
else if (tok.isPunctuation(token::BEGIN_BLOCK))
{
// - #eval { expr }
dynamic_cast<ISstream&>(is).getLine(s, token::END_BLOCK);
}
else
// Field width for the result
if (fieldWidth < 1)
{
FatalIOErrorInFunction(is)
<< "Invalid input for #eval."
" Expecting a string or block to evaluate, but found" << nl
<< tok.info() << endl
<< "Invalid field width: " << fieldWidth << nl << endl
<< exit(FatalIOError);
}
#ifdef FULLDEBUG
DetailInfo
<< "input: " << s << endl;
<< "input: " << inputExpr << endl;
#endif
// Expand with env=true, empty=true, subDict=false
// with comments stripped.
// Special handling of $[...] syntax enabled.
string s;
// Passed '${{ expr }}' by accident, or on purpuse
if
(
inputExpr[0] == token::DOLLAR
&& inputExpr[1] == token::BEGIN_BLOCK
&& inputExpr[2] == token::BEGIN_BLOCK
&& inputExpr[inputExpr.length()-1] == token::END_BLOCK
&& inputExpr[inputExpr.length()-2] == token::END_BLOCK
)
{
s.assign(inputExpr, 3, inputExpr.length()-5);
}
else
{
s.assign(inputExpr);
}
expressions::exprString::inplaceExpand(s, parentDict, true);
stringOps::inplaceTrim(s);
@ -184,6 +287,60 @@ Foam::tokenList Foam::functionEntries::evalEntry::evaluate
}
Foam::tokenList Foam::functionEntries::evalEntry::evaluate
(
const dictionary& parentDict,
Istream& is
)
{
#ifdef FULLDEBUG
DetailInfo
<< "Using #eval - line "
<< is.lineNumber() << " in file " << parentDict.name() << nl;
#endif
token tok(is);
label fieldWidth(1); // Field width for the result
if (tok.isLabel())
{
// - #eval INT "expr"
// - #eval INT { expr }
// - #eval INT #{ expr #}
fieldWidth = max(1, tok.labelToken());
is >> tok;
}
string str; // The string to evaluate
if (tok.isString())
{
// - #eval "expr"
// - #eval #{ expr #}
// - #eval ${{ expr }} - wierd but handled
str = tok.stringToken();
}
else if (tok.isPunctuation(token::BEGIN_BLOCK))
{
// - #eval { expr }
slurpUntilBalancedBrace(dynamic_cast<ISstream&>(is), str);
}
else
{
FatalIOErrorInFunction(is)
<< "Invalid input for #eval."
" Expecting a string or block to evaluate, but found" << nl
<< tok.info() << endl
<< exit(FatalIOError);
}
tokenList toks
(
evalEntry::evaluate(parentDict, str, fieldWidth, is)
);
return toks;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionEntries::evalEntry::execute
@ -201,4 +358,21 @@ bool Foam::functionEntries::evalEntry::execute
}
bool Foam::functionEntries::evalEntry::execute
(
const dictionary& parentDict,
primitiveEntry& entry,
const string& inputExpr,
label fieldWidth,
Istream& is
)
{
tokenList toks(evaluate(parentDict, inputExpr, fieldWidth, is));
entry.append(std::move(toks), true); // Lazy resizing
return true;
}
// ************************************************************************* //

View File

@ -87,18 +87,36 @@ class evalEntry
{
//- Evaluate and return a token list
static tokenList evaluate(const dictionary& parentDict, Istream& is);
static tokenList evaluate
(
const dictionary& parentDict,
const string& inputExpr, //!< String to expand and evaluate
label fieldWidth, //!< Field width for the result
const Istream& is //!< For reporting errors
);
//- Evaluate and return a token list
static tokenList evaluate(const dictionary& parentDict, Istream& is);
public:
//- Execute in a primitiveEntry context
//- Execute in a primitiveEntry context, extracts token or line
static bool execute
(
const dictionary& parentDict,
primitiveEntry& thisEntry,
Istream& is
);
//- Execute in a primitiveEntry context, evaluating the given content
static bool execute
(
const dictionary& parentDict,
primitiveEntry& entry,
const string& inputExpr,
label fieldWidth,
Istream& is
);
};

View File

@ -90,7 +90,8 @@ bool Foam::functionEntry::execute
if (!executedictionaryIstreamMemberFunctionTablePtr_)
{
cerr<< FUNCTION_NAME << nl
std::cerr
<< FUNCTION_NAME << nl
<< "Not yet initialized, function = "
<< functionName.c_str() << std::endl;
@ -128,7 +129,8 @@ bool Foam::functionEntry::execute
if (!executeprimitiveEntryIstreamMemberFunctionTablePtr_)
{
cerr<< FUNCTION_NAME << nl
std::cerr
<< FUNCTION_NAME << nl
<< "Not yet initialized, function = "
<< functionName.c_str() << std::endl;

View File

@ -58,12 +58,7 @@ void Foam::functionEntries::ifeqEntry::readToken(token& t, Istream& is)
// Skip dummy tokens - avoids entry::getKeyword consuming #else, #endif
do
{
if
(
is.read(t).bad()
|| is.eof()
|| !t.good()
)
if (is.read(t).bad() || is.eof() || !t.good())
{
return;
}
@ -72,7 +67,7 @@ void Foam::functionEntries::ifeqEntry::readToken(token& t, Istream& is)
}
Foam::token Foam::functionEntries::ifeqEntry::expand
Foam::token Foam::functionEntries::ifeqEntry::expandToken
(
const dictionary& dict,
const string& keyword,
@ -109,7 +104,7 @@ Foam::token Foam::functionEntries::ifeqEntry::expand
}
Foam::token Foam::functionEntries::ifeqEntry::expand
Foam::token Foam::functionEntries::ifeqEntry::expandToken
(
const dictionary& dict,
const token& t
@ -117,15 +112,15 @@ Foam::token Foam::functionEntries::ifeqEntry::expand
{
if (t.isWord())
{
return expand(dict, t.wordToken(), t);
return expandToken(dict, t.wordToken(), t);
}
else if (t.isVariable())
{
return expand(dict, t.stringToken(), t);
return expandToken(dict, t.stringToken(), t);
}
else if (t.isString())
{
return expand(dict, t.stringToken(), t);
return expandToken(dict, t.stringToken(), t);
}
return t;
@ -230,6 +225,9 @@ bool Foam::functionEntries::ifeqEntry::equalToken
}
return false;
case token::EXPRESSION:
return false;
case token::COMPOUND:
return false;
@ -245,7 +243,7 @@ void Foam::functionEntries::ifeqEntry::skipUntil
(
DynamicList<filePos>& stack,
const dictionary& parentDict,
const word& endWord,
const word& endDirective,
Istream& is
)
{
@ -258,28 +256,26 @@ void Foam::functionEntries::ifeqEntry::skipUntil
{
continue;
}
else if
(
t.wordToken() == "#if"
|| t.wordToken() == "#ifeq"
)
else if (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
{
stack.append(filePos(is.name(), is.lineNumber()));
skipUntil(stack, parentDict, "#endif", is);
stack.remove();
}
else if (t.wordToken() == endWord)
else if (t.wordToken() == endDirective)
{
return;
}
}
FatalIOErrorInFunction(parentDict)
<< "Did not find matching " << endWord << nl
<< "Did not find matching " << endDirective << nl
<< exit(FatalIOError);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
bool Foam::functionEntries::ifeqEntry::evaluate
(
const bool doIf,
@ -292,35 +288,47 @@ bool Foam::functionEntries::ifeqEntry::evaluate
{
token t;
readToken(t, is);
bool pending = false;
if (t.isWord() && t.wordToken() == "#ifeq")
if (t.isDirective())
{
// Recurse to evaluate
execute(stack, parentDict, is);
}
else if (t.isWord() && t.wordToken() == "#if")
{
// Recurse to evaluate
ifEntry::execute(stack, parentDict, is);
}
else if
(
doIf
&& t.isWord()
&& (t.wordToken() == "#else" || t.wordToken() == "#elif")
)
{
// Now skip until #endif
skipUntil(stack, parentDict, "#endif", is);
stack.remove();
break;
}
else if (t.isWord() && t.wordToken() == "#endif")
{
stack.remove();
break;
if (t.wordToken() == "#ifeq")
{
// Recurse to evaluate
execute(stack, parentDict, is);
}
else if (t.wordToken() == "#if")
{
// Recurse to evaluate
ifEntry::execute(stack, parentDict, is);
}
else if
(
doIf
&& (t.wordToken() == "#else" || t.wordToken() == "#elif")
)
{
// Now skip until #endif
skipUntil(stack, parentDict, "#endif", is);
stack.remove();
break;
}
else if (t.wordToken() == "#endif")
{
stack.remove();
break;
}
else
{
pending = true;
}
}
else
{
pending = true;
}
if (pending)
{
is.putBack(t);
bool ok = entry::New(parentDict, is);
@ -354,21 +362,23 @@ bool Foam::functionEntries::ifeqEntry::execute
{
readToken(t, is);
if
(
t.isWord()
&& (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
)
// Only consider directives
if (!t.isDirective())
{
continue;
}
if (t.wordToken() == "#if" || t.wordToken() == "#ifeq")
{
stack.append(filePos(is.name(), is.lineNumber()));
skipUntil(stack, parentDict, "#endif", is);
stack.remove();
}
else if (t.isWord() && t.wordToken() == "#else")
else if (t.wordToken() == "#else")
{
break;
}
else if (t.isWord() && t.wordToken() == "#elif")
else if (t.wordToken() == "#elif")
{
// const label lineNo = is.lineNumber();
@ -386,7 +396,7 @@ bool Foam::functionEntries::ifeqEntry::execute
break;
}
}
else if (t.isWord() && t.wordToken() == "#endif")
else if (t.wordToken() == "#endif")
{
stack.remove();
break;
@ -421,11 +431,11 @@ bool Foam::functionEntries::ifeqEntry::execute
// Read first token and expand any string
token cond1(is);
cond1 = expand(parentDict, cond1);
cond1 = expandToken(parentDict, cond1);
// Read second token and expand any string
token cond2(is);
cond2 = expand(parentDict, cond2);
cond2 = expandToken(parentDict, cond2);
const bool equal = equalToken(cond1, cond2);

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,7 +32,7 @@ Description
E.g.
\verbatim
a #calc "0.123";
a #eval "0.123";
b 1.23e-1;
#ifeq $a $b
@ -90,46 +91,15 @@ class ifeqEntry
:
public functionEntry
{
protected:
// Data Types
typedef Tuple2<fileName, label> filePos;
// Protected Member Functions
//- Read tokens. Skip dummy tokens
static void readToken(token& t, Istream& is);
//- Expand a variable (string/word/var starting with '$')
static token expand
(
const dictionary& dict,
const string& keyword,
const token& t
);
//- Expand a string/word/var token
static token expand
(
const dictionary& dict,
const token& t
);
static bool equalToken
(
const token& t1,
const token& t2
);
//- Consume tokens until reached a specific word
static void skipUntil
(
DynamicList<filePos>& stack,
const dictionary& parentDict,
const word& endWord,
Istream& is
);
static bool evaluate
(
const bool doIf,
@ -158,6 +128,41 @@ protected:
);
private:
// Private Member Functions
//- Read tokens. Skip dummy tokens
static void readToken(token& t, Istream& is);
//- Expand a variable (string/word/var starting with '$')
static token expandToken
(
const dictionary& dict,
const string& keyword,
const token& t
);
//- Expand a string/word/var token
static token expandToken
(
const dictionary& dict,
const token& t
);
//- Test for equality
static bool equalToken(const token& t1, const token& t2);
//- Consume tokens until reached a specific directive
static void skipUntil
(
DynamicList<filePos>& stack,
const dictionary& parentDict,
const word& endDirective, //!< end directive (without '#')
Istream& is
);
public:
//- Runtime type information

View File

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "namedDictionary.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::namedDictionary::namedDictionary()
:
Tuple2<keyType, dictionary>()
{}
Foam::namedDictionary::namedDictionary(Istream& is)
{
is >> *this;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::namedDictionary::clear()
{
first().clear();
second().clear();
}
bool Foam::namedDictionary::empty() const noexcept
{
return (first().empty() && second().empty());
}
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, namedDictionary& obj)
{
obj.clear();
// Three possible inputs:
// - key
// - key { ... }
// - { ... }
// Minor consistency with primitiveEntry, also accept the following:
// - key ;
token tok(is);
is.putBack(tok);
if (!tok.isPunctuation(token::BEGIN_BLOCK))
{
is >> obj.keyword();
is >> tok;
// Discards possible trailing ';'
if (!tok.isPunctuation(token::END_STATEMENT))
{
is.putBack(tok);
}
}
if (tok.isPunctuation(token::BEGIN_BLOCK))
{
obj.dict().read(is);
}
is.check(FUNCTION_NAME);
return is;
}
Foam::Ostream& Foam::operator<<(Ostream& os, const namedDictionary& obj)
{
// Three possible outputs:
// - key
// - key { ... }
// - { ... }
// No distinction between a missing and an empty dictionary
if (obj.keyword().empty() || !obj.dict().empty())
{
// Never allow empty output.
// Otherwise cannot re-read for streaming
obj.dict().writeEntry(obj.keyword(), os);
}
else
{
os << obj.keyword();
}
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,154 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::namedDictionary
Description
A tuple of keyType and dictionary, which can be used when reading
named or unnamed dictionary entries or simply a name.
For example,
\verbatim
fields
(
U
T { relax false; }
);
\endverbatim
In can also be used in situations where an individual dictionary entry
should be read.
\verbatim
actions
(
testing { action new; ... } // An action with a name
{ action subset; } // Unnamed action
);
\endverbatim
Normal dictionary reading would fail for this type of input since the
leading 'testing' keyword would cause the entire content to be considered
a single dictionary.
Note
No distinction currently made between a missing and an empty dictionary.
SourceFiles
namedDictionary.C
\*---------------------------------------------------------------------------*/
#ifndef namedDictionary_H
#define namedDictionary_H
#include "dictionary.H"
#include "Tuple2.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class namedDictionary;
Istream& operator>>(Istream&, namedDictionary&);
Ostream& operator<<(Ostream&, const namedDictionary&);
/*---------------------------------------------------------------------------*\
Class namedDictionary Declaration
\*---------------------------------------------------------------------------*/
class namedDictionary
:
public Tuple2<keyType, dictionary>
{
public:
// Constructors
//- Inherit constructors
using Tuple2<keyType, dictionary>::Tuple2;
//- Default construct
namedDictionary();
//- Construct from Istream
explicit namedDictionary(Istream& is);
//- Destructor
~namedDictionary() = default;
// Member Functions
//- Clear keyword and dictionary
void clear();
//- Empty if both keyword and dictionary are empty
bool empty() const noexcept;
//- Return keyword
const keyType& keyword() const noexcept
{
return first();
}
//- Return non-const access to keyword
keyType& keyword() noexcept
{
return first();
}
//- Read-access to the dictionay
const dictionary& dict() const noexcept
{
return second();
}
//- Write access to the dictionay
dictionary& dict() noexcept
{
return second();
}
// IOstream Operators
friend Istream& operator>>(Istream&, namedDictionary&);
friend Ostream& operator<<(Ostream&, const namedDictionary&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -35,7 +35,7 @@ License
// Find the type/position of the ":-" or ":+" alternative values
// Returns 0, '-', '+' corresponding to not-found or ':-' or ':+'
static inline int findParameterAlternative
static inline char findParameterAlternative
(
const std::string& s,
std::string::size_type& pos,
@ -50,7 +50,7 @@ static inline int findParameterAlternative
if (pos < endPos)
{
// in-range: check for '+' or '-' following the ':'
const int altType = s[pos+1];
const char altType = s[pos+1];
if (altType == '+' || altType == '-')
{
return altType;
@ -78,11 +78,13 @@ bool Foam::primitiveEntry::expandVariable
const dictionary& dict
)
{
int altType = 0; // Type ('-' or '+') for ":-" or ":+" alternatives
char altType = 0; // Type ('-' or '+') for ":-" or ":+" alternatives
word expanded;
string altValue;
if (varName.size() > 1 && varName[0] == token::BEGIN_BLOCK)
// Any ${{ expr }} entries have been trapped and processed elsewhere
if (varName[0] == token::BEGIN_BLOCK && varName.size() > 1)
{
// Replace content between {} with string expansion and
// handle ${parameter:-word} or ${parameter:+word}

View File

@ -28,6 +28,7 @@ License
#include "primitiveEntry.H"
#include "functionEntry.H"
#include "evalEntry.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
@ -63,25 +64,51 @@ bool Foam::primitiveEntry::acceptToken
if (tok.isDirective())
{
// Directive: wordToken starts with '#'
// Directive (wordToken) begins with '#'. Eg, "#include"
// Remove leading '#' sigil before dispatching
const word& key = tok.wordToken();
// Min-size is 2: sigil '#' with any content
accept =
(
disableFunctionEntries
|| key.size() == 1
(disableFunctionEntries || key.size() < 2)
|| !expandFunction(key.substr(1), dict, is)
);
}
else if (tok.isExpression())
{
// Expression (stringToken): ${{ expr }}
// Surrounding delimiters are stripped as required in evalEntry
const string& key = tok.stringToken();
// Min-size is 6: decorators '${{}}' with any content
accept =
(
(disableFunctionEntries || key.size() < 6)
|| !functionEntries::evalEntry::execute
(
dict,
*this,
key,
1, // Field width is 1
is // For error messages
)
);
}
else if (tok.isVariable())
{
// Variable: stringToken starts with '$'
// Variable (stringToken): starts with '$'
// Eg, "$varName" or "${varName}"
// Remove leading '$' sigil before dispatching
const string& key = tok.stringToken();
// Min-size is 2: sigil '$' with any content
accept =
(
disableFunctionEntries
|| key.size() == 1
(disableFunctionEntries || key.size() < 2)
|| !expandVariable(key.substr(1), dict)
);
}
@ -116,7 +143,7 @@ bool Foam::primitiveEntry::read(const dictionary& dict, Istream& is)
// - similarly, the bitmask is tested *after* decreasing depth
uint64_t balanced = 0u;
label depth = 0;
int depth = 0;
token tok;
while
@ -274,19 +301,18 @@ void Foam::primitiveEntry::write(Ostream& os, const bool contentsOnly) const
os.writeKeyword(keyword());
}
bool addSpace = false; // Separate from previous tokens with a space
bool addSpace = false; // Separate from previous token with a space
for (const token& tok : *this)
{
if (addSpace) os << token::SPACE;
addSpace = true;
// Try to output token directly, with special handling in Ostreams.
// Output token with direct handling in Ostream(s),
// or use normal '<<' output operator
if (!os.write(tok))
{
os << tok; // Revert to normal '<<' output operator
os << tok;
}
addSpace = true; // Separate from following tokens
}
if (!contentsOnly)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd.
Copyright (C) 2015-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -243,91 +243,42 @@ bool Foam::functionObjectList::readFunctionObject
// 'patchAverage(patch=inlet, p)' -> funcName = patchAverage;
// args = (patch=inlet, p); field = p
word funcName(funcNameArgs);
int argLevel = 0;
word funcName;
wordRes args;
List<Tuple2<word, string>> namedArgs;
bool hasNamedArg = false;
word argName;
word::size_type start = 0;
word::size_type i = 0;
for
(
word::const_iterator iter = funcNameArgs.begin();
iter != funcNameArgs.end();
++iter
)
{
char c = *iter;
if (c == '(')
const auto argsBeg = funcNameArgs.find('(');
if (argsBeg == std::string::npos)
{
if (argLevel == 0)
{
funcName = funcNameArgs.substr(start, i - start);
start = i+1;
}
++argLevel;
// Function name only, no args
funcName = word::validate(funcNameArgs);
}
else if (c == ',' || c == ')')
else
{
if (argLevel == 1)
{
if (hasNamedArg)
{
namedArgs.append
(
Tuple2<word, string>
(
argName,
funcNameArgs.substr(start, i - start)
)
);
hasNamedArg = false;
}
else
{
args.append
(
wordRe
(
word::validate
(
funcNameArgs.substr(start, i - start)
)
)
);
}
start = i+1;
}
// Leading function name
funcName = word::validate(funcNameArgs.substr(0, argsBeg));
if (c == ')')
{
if (argLevel == 1)
{
break;
}
--argLevel;
}
}
else if (c == '=')
{
argName = word::validate
const auto argsEnd = funcNameArgs.rfind(')');
stringOps::splitFunctionArgs
(
funcNameArgs.substr(start, i - start)
funcNameArgs.substr
(
(argsBeg + 1),
(
(argsEnd != std::string::npos && argsBeg < argsEnd)
? (argsEnd - argsBeg - 1)
: std::string::npos
)
),
args,
namedArgs
);
start = i+1;
hasNamedArg = true;
}
++i;
}
// Search for the functionObject dictionary
fileName path = functionObjectList::findDict(funcName);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -145,16 +145,37 @@ Istream& operator>>(Istream& is, Scalar& val)
return is;
}
// Accept separated '-' (or '+') while expecting a number.
// This can arise during dictionary expansions (Eg, -$value)
char prefix = 0;
if (t.isPunctuation())
{
prefix = t.pToken();
if (prefix == token::PLUS || prefix == token::MINUS)
{
is >> t;
}
}
if (t.isNumber())
{
val = t.number();
val =
(
(prefix == token::MINUS)
? (0 - t.number())
: t.number()
);
}
else
{
FatalIOErrorInFunction(is)
<< "Wrong token type - expected scalar value, found "
<< t.info()
<< exit(FatalIOError);
<< "Wrong token type - expected scalar value, found ";
if (prefix == token::PLUS || prefix == token::MINUS)
{
FatalIOError << '\'' << prefix << "' followed by ";
}
FatalIOError << t.info() << exit(FatalIOError);
is.setBad();
return is;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2016 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -100,13 +100,36 @@ Foam::Istream& Foam::operator>>(Istream& is, int32_t& val)
return is;
}
// Accept separated '-' (or '+') while expecting a number.
// This can arise during dictionary expansions (Eg, -$value)
char prefix = 0;
if (t.isPunctuation())
{
prefix = t.pToken();
if (prefix == token::PLUS || prefix == token::MINUS)
{
is >> t;
}
}
if (t.isLabel())
{
val = int32_t(t.labelToken());
val = int32_t
(
(prefix == token::MINUS)
? (0 - t.labelToken())
: t.labelToken()
);
}
else if (t.isScalar())
{
const scalar sval(t.scalarToken());
const scalar sval
(
(prefix == token::MINUS)
? (0 - t.scalarToken())
: t.scalarToken()
);
const intmax_t parsed = intmax_t(std::round(sval));
val = 0 + int32_t(parsed);
@ -135,9 +158,12 @@ Foam::Istream& Foam::operator>>(Istream& is, int32_t& val)
else
{
FatalIOErrorInFunction(is)
<< "Wrong token type - expected label (int32), found "
<< t.info()
<< exit(FatalIOError);
<< "Wrong token type - expected label (int32), found ";
if (prefix == token::PLUS || prefix == token::MINUS)
{
FatalIOError << '\'' << prefix << "' followed by ";
}
FatalIOError << t.info() << exit(FatalIOError);
is.setBad();
return is;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -100,13 +100,37 @@ Foam::Istream& Foam::operator>>(Istream& is, int64_t& val)
return is;
}
// Accept separated '-' (or '+') while expecting a number.
// This can arise during dictionary expansions (Eg, -$value)
char prefix = 0;
if (t.isPunctuation())
{
prefix = t.pToken();
if (prefix == token::PLUS || prefix == token::MINUS)
{
is >> t;
}
}
if (t.isLabel())
{
val = int64_t(t.labelToken());
val = int64_t
(
(prefix == token::MINUS)
? (0 - t.labelToken())
: t.labelToken()
);
}
else if (t.isScalar())
{
const scalar sval(t.scalarToken());
const scalar sval
(
(prefix == token::MINUS)
? (0 - t.scalarToken())
: t.scalarToken()
);
const intmax_t parsed = intmax_t(std::round(sval));
val = 0 + int64_t(parsed);
@ -135,9 +159,12 @@ Foam::Istream& Foam::operator>>(Istream& is, int64_t& val)
else
{
FatalIOErrorInFunction(is)
<< "Wrong token type - expected label (int64), found "
<< t.info()
<< exit(FatalIOError);
<< "Wrong token type - expected label (int64), found ";
if (prefix == token::PLUS || prefix == token::MINUS)
{
FatalIOError << '\'' << prefix << "' followed by ";
}
FatalIOError << t.info() << exit(FatalIOError);
is.setBad();
return is;
}

View File

@ -693,7 +693,7 @@ static void expandString
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
std::string::size_type Foam::stringOps::count
(

View File

@ -57,6 +57,7 @@ namespace Foam
// Forward Declarations
class OSstream;
template<class T1, class T2> class Tuple2;
/*---------------------------------------------------------------------------*\
Namespace stringOps Declaration
@ -282,6 +283,14 @@ namespace stringOps
// Return true if a replacement was successful.
bool inplaceReplaceVar(std::string& s, const word& varName);
//- Return a copy of the input string with validated characters
template<class StringType, class UnaryPredicate>
StringType validate
(
const std::string& str,
const UnaryPredicate& accept,
const bool invert=false //!< Invert the test logic
);
//- Find (first, last) non-space locations in string or sub-string.
// This may change to std::string_view in the future.
@ -334,6 +343,30 @@ namespace stringOps
//- Inplace transform string with std::toupper on each character
void inplaceUpper(std::string& s);
//- Split out arguments (named or unnamed) from an input string.
//
// For example,
// \verbatim
// (U)
// -> named = ()
// -> unnamed = (U)
//
// (patch=inlet, p)
// -> named = ((patch inlet))
// -> unnamed = (p)
//
// testing, start=100, stop=200
// -> named = ((start 100)(stop 200))
// -> unnamed = (testing)
// \endverbatim
//
// \return total number of arguments
label splitFunctionArgs
(
const std::string& str,
wordRes& args,
List<Tuple2<word, string>>& namedArgs
);
//- Split string into sub-strings at the delimiter character.
// Empty sub-strings are normally suppressed.

View File

@ -0,0 +1,221 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "stringOps.H"
#include "Pair.H"
#include "Tuple2.H"
#include <vector>
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace
{
inline Foam::word validateVariableName(const std::string& str)
{
return Foam::stringOps::validate<Foam::word>
(
str,
[](char c)
{
return (Foam::word::valid(c) || c == '/' || c == '{' || c == '}');
}
);
}
} // End anonymous namespace
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
Foam::label Foam::stringOps::splitFunctionArgs
(
const std::string& str,
wordRes& args,
List<Tuple2<word, string>>& namedArgs
)
{
args.clear();
namedArgs.clear();
// Similar to code originally in functionObjectList (v2012 and earlier)
// except that the function-name handling is now done prior to calling
// (U)
// -> named = ()
// -> unnamed = (U)
//
// (patch=inlet, p)
// -> named = ((patch inlet))
// -> unnamed = (p)
//
// start=100, stop=200
// -> named = ((start 100) (stop 200) )
// -> unnamed = ()
//
// origin=(0 0 0) , scale=2 , normal=(0 0 1)
// Use begin/end parse positions
typedef Pair<std::string::size_type> rangeType;
// For unnamed: beg/end range of each arg
std::vector<rangeType> unnamed;
// For named: list of beg/end ranges for (name, arg)
std::vector<rangeType> named;
// The beg/end range of the argument name
rangeType argName(0, 0);
// If argName is valid
bool isNamed = false;
// The depth of the argument parsing
int argLevel = 0;
const auto strLen = str.length();
// Pass 1: parsing begin/end parse positions.
for (std::string::size_type pos = 0, beg = 0; pos < strLen; ++pos)
{
const bool penultimate = ((pos + 1) == strLen);
const char c = str[pos];
if (c == ')')
{
--argLevel;
}
if (c == '=')
{
// Introducer for named argument
argName = rangeType(beg, pos);
isNamed = true;
beg = pos + 1;
}
else if (c == '(')
{
++argLevel;
}
else if (penultimate || (c == ',')) // OR: (c == ',' || c == ';')
{
if (penultimate && (c != ',')) // OR: (c != ',' && c != ';')
{
++pos; // Until the end, but do not include comma
}
if (argLevel == 0)
{
if (isNamed)
{
named.push_back(argName);
named.push_back(rangeType(beg, pos));
}
else
{
unnamed.push_back(rangeType(beg, pos));
}
isNamed = false;
beg = pos + 1;
}
}
}
// Stage 2: Convert to concrete string and store
// unnamed
{
const label nInputArgs = static_cast<label>(unnamed.size());
args.resize(nInputArgs);
label ngood = 0;
for (label i = 0; i < nInputArgs; ++i)
{
const auto& arg = unnamed[i];
args[ngood] = wordRe
(
word::validate
(
str.substr(arg.first(), (arg.second()-arg.first()))
)
);
// Only retain if non-empty
if (!args[ngood].empty())
{
++ngood;
}
}
args.resize(ngood);
}
// named
{
const label nInputArgs = static_cast<label>(named.size());
namedArgs.resize(nInputArgs/2);
label ngood = 0;
for (label i = 0; i < nInputArgs; i += 2)
{
const auto& name = named[i];
const auto& arg = named[i+1];
namedArgs[ngood].first() =
validateVariableName
(
str.substr(name.first(), (name.second()-name.first()))
);
namedArgs[ngood].second() =
stringOps::trim
(
str.substr(arg.first(), (arg.second()-arg.first()))
);
// Only retain if name is non-empty
if (!namedArgs[ngood].first().empty())
{
++ngood;
}
}
namedArgs.resize(ngood);
}
// Return total number of arguments
return (args.size() + namedArgs.size());
}
// ************************************************************************* //

View File

@ -66,6 +66,33 @@ StringType Foam::stringOps::quotemeta
}
template<class StringType, class UnaryPredicate>
StringType Foam::stringOps::validate
(
const std::string& str,
const UnaryPredicate& accept,
const bool invert
)
{
StringType out;
out.resize(str.length());
std::string::size_type len = 0;
for (std::string::size_type i = 0; i < str.length(); ++i)
{
const char c = str[i];
if (accept(c) ? !invert : invert)
{
out[len++] += c;
}
}
out.erase(len);
return out;
}
template<class StringType>
Foam::SubStrings<StringType> Foam::stringOps::split
(

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -120,8 +120,8 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
return *this;
}
OFstream::write(static_cast<char>(token::BEGIN_STRING));
// Output with surrounding quotes and backslash escaping
OFstream::write(static_cast<char>(token::DQUOTE));
unsigned backslash = 0;
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
@ -138,7 +138,7 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
++lineNumber_;
++backslash; // backslash escape for newline
}
else if (c == token::END_STRING)
else if (c == token::DQUOTE)
{
++backslash; // backslash escape for quote
}
@ -155,7 +155,7 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
// silently drop any trailing backslashes
// they would otherwise appear like an escaped end-quote
OFstream::write(static_cast<char>(token::END_STRING));
OFstream::write(static_cast<char>(token::DQUOTE));
return *this;
}

View File

@ -16,9 +16,27 @@ FoamFile
scale 1;
// Front/back locations
zmin -0.5;
zmax 0.5;
// Geometric parameters
rInner 0.5;
rOuter 1;
xmax 2;
ymax 2;
zmin -0.5; // Back/front locations
zmax 0.5;
// Divisions: Radial, quarter circumference, outer region and z-directions.
nRadial 10;
nQuarter 10;
nxOuter 20;
nyOuter 20;
nz 1;
// ----------------
// Derived quantities
rInner45 ${{ $rInner * sqrt(0.5) }};
rOuter45 ${{ $rOuter * sqrt(0.5) }};
vertices #codeStream
{
@ -29,30 +47,27 @@ vertices #codeStream
code
#{
// sin(45), cos(45)
const scalar sqrt05 = sqrt(0.5);
pointField points
({
/* 0*/ {0.5, 0, $zmin},
/* 1*/ {1, 0, $zmin},
/* 2*/ {2, 0, $zmin},
/* 3*/ {2, sqrt05, $zmin},
/* 4*/ {sqrt05, sqrt05, $zmin},
/* 5*/ {sqrt05/2, sqrt05/2, $zmin},
/* 6*/ {2, 2, $zmin},
/* 7*/ {sqrt05, 2, $zmin},
/* 8*/ {0, 2, $zmin},
/* 9*/ {0, 1, $zmin},
/*10*/ {0, 0.5, $zmin},
/*11*/ {-0.5, 0, $zmin},
/*12*/ {-1, 0, $zmin},
/*13*/ {-2, 0, $zmin},
/*14*/ {-2, sqrt05, $zmin},
/*15*/ {-sqrt05, sqrt05, $zmin},
/*16*/ {-sqrt05/2, sqrt05/2, $zmin},
/*17*/ {-2, 2, $zmin},
/*18*/ {-sqrt05, 2, $zmin}
/* 0*/ { $rInner, 0, $zmin },
/* 1*/ { $rOuter, 0, $zmin },
/* 2*/ { $xmax, 0, $zmin },
/* 3*/ { $xmax, $rOuter45, $zmin },
/* 4*/ { $rOuter45, $rOuter45, $zmin },
/* 5*/ { $rInner45, $rInner45, $zmin },
/* 6*/ { $xmax, $ymax, $zmin },
/* 7*/ { $rOuter45, $ymax, $zmin },
/* 8*/ { 0, $ymax, $zmin },
/* 9*/ { 0, $rOuter, $zmin },
/*10*/ { 0, $rInner, $zmin },
/*11*/ { -$rInner, 0, $zmin },
/*12*/ { -$rOuter, 0, $zmin },
/*13*/ { -$xmax, 0, $zmin },
/*14*/ { -$xmax, $rOuter45, $zmin },
/*15*/ { -$rOuter45, $rOuter45, $zmin },
/*16*/ { -$rInner45, $rInner45, $zmin },
/*17*/ { -$xmax, $ymax, $zmin },
/*18*/ { -$rOuter45, $ymax, $zmin }
});
// Duplicate z points for zmax
@ -68,19 +83,21 @@ vertices #codeStream
#};
};
// Can remove unneeded variables
#remove ( "r(Inner|Outer).*" "[xy](min|max)" )
blocks
(
hex (5 4 9 10 24 23 28 29) (10 10 1) simpleGrading (1 1 1)
hex (0 1 4 5 19 20 23 24) (10 10 1) simpleGrading (1 1 1)
hex (1 2 3 4 20 21 22 23) (20 10 1) simpleGrading (1 1 1)
hex (4 3 6 7 23 22 25 26) (20 20 1) simpleGrading (1 1 1)
hex (9 4 7 8 28 23 26 27) (10 20 1) simpleGrading (1 1 1)
hex (15 16 10 9 34 35 29 28) (10 10 1) simpleGrading (1 1 1)
hex (12 11 16 15 31 30 35 34) (10 10 1) simpleGrading (1 1 1)
hex (13 12 15 14 32 31 34 33) (20 10 1) simpleGrading (1 1 1)
hex (14 15 18 17 33 34 37 36) (20 20 1) simpleGrading (1 1 1)
hex (15 9 8 18 34 28 27 37) (10 20 1) simpleGrading (1 1 1)
hex (5 4 9 10 24 23 28 29) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (0 1 4 5 19 20 23 24) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (1 2 3 4 20 21 22 23) ($nxOuter $nQuarter $nz) grading (1 1 1)
hex (4 3 6 7 23 22 25 26) ($nxOuter $nyOuter $nz) grading (1 1 1)
hex (9 4 7 8 28 23 26 27) ($nQuarter $nyOuter $nz) grading (1 1 1)
hex (15 16 10 9 34 35 29 28) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (12 11 16 15 31 30 35 34) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (13 12 15 14 32 31 34 33) ($nxOuter $nQuarter $nz) grading (1 1 1)
hex (14 15 18 17 33 34 37 36) ($nxOuter $nyOuter $nz) grading (1 1 1)
hex (15 9 8 18 34 28 27 37) ($nQuarter $nyOuter $nz) grading (1 1 1)
);
edges

View File

@ -0,0 +1,27 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
method simple;
coeffs
{
n ( 2 2 1 );
}
// ************************************************************************* //

View File

@ -40,22 +40,20 @@ nz #eval{ round($nz / 5) };
#endif
zmin #eval{ -$zmax };
mrad0 #eval{ -$rad0 };
mrad1 #eval{ -$rad1 };
vertices
(
// back-plane:
// inlet region
( $xin $rad0 $zmin) // pt 0
( 0 $rad0 $zmin) // pt 1
( 0 $rad1 $zmin) // pt 2
( $xin $rad1 $zmin) // pt 3
( $xin $rad0 $zmin) // pt 0
( 0 $rad0 $zmin) // pt 1
( 0 $rad1 $zmin) // pt 2
( $xin $rad1 $zmin) // pt 3
// outlet region
( $xout $mrad1 $zmin) // pt 4
( 0 $mrad1 $zmin) // pt 5
( 0 $mrad0 $zmin) // pt 6
( $xout $mrad0 $zmin) // pt 7
( $xout -$rad1 $zmin) // pt 4
( 0 -$rad1 $zmin) // pt 5
( 0 -$rad0 $zmin) // pt 6
( $xout -$rad0 $zmin) // pt 7
// bend mid-points
( $rad0 0 $zmin) // pt 8
( $rad1 0 $zmin) // pt 9
@ -66,13 +64,13 @@ vertices
( 0 $rad1 $zmax) // pt 2 + 10
( $xin $rad1 $zmax) // pt 3 + 10
// outlet region
( $xout $mrad1 $zmax) // pt 4 + 10
( 0 $mrad1 $zmax) // pt 5 + 10
( 0 $mrad0 $zmax) // pt 6 + 10
( $xout $mrad0 $zmax) // pt 7 + 10
( $xout -$rad1 $zmax) // pt 4 + 10
( 0 -$rad1 $zmax) // pt 5 + 10
( 0 -$rad0 $zmax) // pt 6 + 10
( $xout -$rad0 $zmax) // pt 7 + 10
// bend mid-points
( $rad0 0 $zmax) // pt 8 + 10
( $rad1 0 $zmax) // pt 9 + 10
( $rad0 0 $zmax) // pt 8 + 10
( $rad1 0 $zmax) // pt 9 + 10
);
blocks

View File

@ -40,22 +40,20 @@ nz #eval{ round($nz / 5) };
#endif
zmin #eval{ -$zmax };
mrad0 #eval{ -$rad0 };
mrad1 #eval{ -$rad1 };
vertices
(
// back-plane:
// inlet region
( $xin $rad0 $zmin) // pt 0
( 0 $rad0 $zmin) // pt 1
( 0 $rad1 $zmin) // pt 2
( $xin $rad1 $zmin) // pt 3
( $xin $rad0 $zmin) // pt 0
( 0 $rad0 $zmin) // pt 1
( 0 $rad1 $zmin) // pt 2
( $xin $rad1 $zmin) // pt 3
// outlet region
( $xout $mrad1 $zmin) // pt 4
( 0 $mrad1 $zmin) // pt 5
( 0 $mrad0 $zmin) // pt 6
( $xout $mrad0 $zmin) // pt 7
( $xout -$rad1 $zmin) // pt 4
( 0 -$rad1 $zmin) // pt 5
( 0 -$rad0 $zmin) // pt 6
( $xout -$rad0 $zmin) // pt 7
// bend mid-points
( $rad0 0 $zmin) // pt 8
( $rad1 0 $zmin) // pt 9
@ -66,13 +64,13 @@ vertices
( 0 $rad1 $zmax) // pt 2 + 10
( $xin $rad1 $zmax) // pt 3 + 10
// outlet region
( $xout $mrad1 $zmax) // pt 4 + 10
( 0 $mrad1 $zmax) // pt 5 + 10
( 0 $mrad0 $zmax) // pt 6 + 10
( $xout $mrad0 $zmax) // pt 7 + 10
( $xout -$rad1 $zmax) // pt 4 + 10
( 0 -$rad1 $zmax) // pt 5 + 10
( 0 -$rad0 $zmax) // pt 6 + 10
( $xout -$rad0 $zmax) // pt 7 + 10
// bend mid-points
( $rad0 0 $zmax) // pt 8 + 10
( $rad1 0 $zmax) // pt 9 + 10
( $rad0 0 $zmax) // pt 8 + 10
( $rad1 0 $zmax) // pt 9 + 10
);
blocks

View File

@ -40,8 +40,6 @@ nz #eval{ round($nz / 5) };
#endif
zmin #eval{ -$zmax };
mrad0 #eval{ -$rad0 };
mrad1 #eval{ -$rad1 };
vertices
(
@ -52,13 +50,13 @@ vertices
( 0 $rad1 $zmin) // pt 2
( $xin $rad1 $zmin) // pt 3
// outlet region
( $xout $mrad1 $zmin) // pt 4
( 0 $mrad1 $zmin) // pt 5
( 0 $mrad0 $zmin) // pt 6
( $xout $mrad0 $zmin) // pt 7
( $xout -$rad1 $zmin) // pt 4
( 0 -$rad1 $zmin) // pt 5
( 0 -$rad0 $zmin) // pt 6
( $xout -$rad0 $zmin) // pt 7
// bend mid-points
( $rad0 0 $zmin) // pt 8
( $rad1 0 $zmin) // pt 9
( $rad0 0 $zmin) // pt 8
( $rad1 0 $zmin) // pt 9
// front-plane:
// inlet region
( $xin $rad0 $zmax) // pt 0 + 10
@ -66,10 +64,10 @@ vertices
( 0 $rad1 $zmax) // pt 2 + 10
( $xin $rad1 $zmax) // pt 3 + 10
// outlet region
( $xout $mrad1 $zmax) // pt 4 + 10
( 0 $mrad1 $zmax) // pt 5 + 10
( 0 $mrad0 $zmax) // pt 6 + 10
( $xout $mrad0 $zmax) // pt 7 + 10
( $xout -$rad1 $zmax) // pt 4 + 10
( 0 -$rad1 $zmax) // pt 5 + 10
( 0 -$rad0 $zmax) // pt 6 + 10
( $xout -$rad0 $zmax) // pt 7 + 10
// bend mid-points
( $rad0 0 $zmax) // pt 8 + 10
( $rad1 0 $zmax) // pt 9 + 10

View File

@ -18,66 +18,91 @@ FoamFile
scale 0.016;
// Front/back locations
zmin 0;
zmax 0.5;
// Geometric parameters
rInner 0.5;
rOuter 1;
xmax 2;
ymax 2;
zmin 0; // Back/front locations
zmax 0.5;
// Divisions: Radial, quarter circumference, outer region and z-directions.
nRadial 10;
nQuarter 10;
nxOuter 20;
nyOuter 20;
nz 1;
// ----------------
// Derived quantities
rInner45 ${{ $rInner * sqrt(0.5) }};
rOuter45 ${{ $rOuter * sqrt(0.5) }};
xmin ${{ -$xmax }};
vertices
(
(0.5 0 $zmin)
(1 0 $zmin)
(2 0 $zmin)
(2 0.707107 $zmin)
(0.707107 0.707107 $zmin)
(0.353553 0.353553 $zmin)
(2 2 $zmin)
(0.707107 2 $zmin)
(0 2 $zmin)
(0 1 $zmin)
(0 0.5 $zmin)
(-0.5 0 $zmin)
(-1 0 $zmin)
(-2 0 $zmin)
(-2 0.707107 $zmin)
(-0.707107 0.707107 $zmin)
(-0.353553 0.353553 $zmin)
(-2 2 $zmin)
(-0.707107 2 $zmin)
(0.5 0 $zmax)
(1 0 $zmax)
(2 0 $zmax)
(2 0.707107 $zmax)
(0.707107 0.707107 $zmax)
(0.353553 0.353553 $zmax)
(2 2 $zmax)
(0.707107 2 $zmax)
(0 2 $zmax)
(0 1 $zmax)
(0 0.5 $zmax)
(-0.5 0 $zmax)
(-1 0 $zmax)
(-2 0 $zmax)
(-2 0.707107 $zmax)
(-0.707107 0.707107 $zmax)
(-0.353553 0.353553 $zmax)
(-2 2 $zmax)
(-0.707107 2 $zmax)
/* 0*/ ( $rInner 0 $zmin )
/* 1*/ ( $rOuter 0 $zmin )
/* 2*/ ( $xmax 0 $zmin )
/* 3*/ ( $xmax $rOuter45 $zmin )
/* 4*/ ( $rOuter45 $rOuter45 $zmin )
/* 5*/ ( $rInner45 $rInner45 $zmin )
/* 6*/ ( $xmax $ymax $zmin )
/* 7*/ ( $rOuter45 $ymax $zmin )
/* 8*/ ( 0 $ymax $zmin )
/* 9*/ ( 0 $rOuter $zmin )
/*10*/ ( 0 $rInner $zmin )
/*11*/ ( -$rInner 0 $zmin )
/*12*/ ( -$rOuter 0 $zmin )
/*13*/ ( -$xmax 0 $zmin )
/*14*/ ( -$xmax $rOuter45 $zmin )
/*15*/ ( -$rOuter45 $rOuter45 $zmin )
/*16*/ ( -$rInner45 $rInner45 $zmin )
/*17*/ ( -$xmax $ymax $zmin )
/*18*/ ( -$rOuter45 $ymax $zmin )
/*19*/ ( $rInner 0 $zmax )
/*20*/ ( $rOuter 0 $zmax )
/*21*/ ( $xmax 0 $zmax )
/*22*/ ( $xmax $rOuter45 $zmax )
/*23*/ ( $rOuter45 $rOuter45 $zmax )
/*24*/ ( $rInner45 $rInner45 $zmax )
/*25*/ ( $xmax $ymax $zmax )
/*26*/ ( $rOuter45 $ymax $zmax )
/*27*/ ( 0 $ymax $zmax )
/*28*/ ( 0 $rOuter $zmax )
/*29*/ ( 0 $rInner $zmax )
/*30*/ ( -$rInner 0 $zmax )
/*31*/ ( -$rOuter 0 $zmax )
/*32*/ ( -$xmax 0 $zmax )
/*33*/ ( -$xmax $rOuter45 $zmax )
/*34*/ ( -$rOuter45 $rOuter45 $zmax )
/*35*/ ( -$rInner45 $rInner45 $zmax )
/*36*/ ( -$xmax $ymax $zmax )
/*37*/ ( -$rOuter45 $ymax $zmax )
);
// Can remove some unneeded variables
#remove ( "r(Inner|Outer).*" "[xy](min|max)" )
blocks
(
hex (5 4 9 10 24 23 28 29) (10 10 1) simpleGrading (1 1 1)
hex (0 1 4 5 19 20 23 24) (10 10 1) simpleGrading (1 1 1)
hex (1 2 3 4 20 21 22 23) (20 10 1) simpleGrading (1 1 1)
hex (4 3 6 7 23 22 25 26) (20 20 1) simpleGrading (1 1 1)
hex (9 4 7 8 28 23 26 27) (10 20 1) simpleGrading (1 1 1)
hex (15 16 10 9 34 35 29 28) (10 10 1) simpleGrading (1 1 1)
hex (12 11 16 15 31 30 35 34) (10 10 1) simpleGrading (1 1 1)
hex (13 12 15 14 32 31 34 33) (20 10 1) simpleGrading (1 1 1)
hex (14 15 18 17 33 34 37 36) (20 20 1) simpleGrading (1 1 1)
hex (15 9 8 18 34 28 27 37) (10 20 1) simpleGrading (1 1 1)
hex (5 4 9 10 24 23 28 29) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (0 1 4 5 19 20 23 24) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (1 2 3 4 20 21 22 23) ($nxOuter $nQuarter $nz) grading (1 1 1)
hex (4 3 6 7 23 22 25 26) ($nxOuter $nyOuter $nz) grading (1 1 1)
hex (9 4 7 8 28 23 26 27) ($nQuarter $nyOuter $nz) grading (1 1 1)
hex (15 16 10 9 34 35 29 28) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (12 11 16 15 31 30 35 34) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (13 12 15 14 32 31 34 33) ($nxOuter $nQuarter $nz) grading (1 1 1)
hex (14 15 18 17 33 34 37 36) ($nxOuter $nyOuter $nz) grading (1 1 1)
hex (15 9 8 18 34 28 27 37) ($nQuarter $nyOuter $nz) grading (1 1 1)
);
edges
(
// Inner cylinder

View File

@ -0,0 +1,27 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
method simple;
coeffs
{
n ( 2 2 1 );
}
// ************************************************************************* //

View File

@ -17,16 +17,13 @@ FoamFile
actions
(
// Heater
heater
{
name heaterCellSet;
type cellSet;
action new;
source boxToCell;
sourceInfo
{
box (-0.01 29e-3 -1 )(4.77e-3 70e-3 1);
}
box (-0.01 29e-3 -1) (4.77e-3 70e-3 1);
}
{
@ -34,10 +31,7 @@ actions
type cellZoneSet;
action new;
source setToCellZone;
sourceInfo
{
set heaterCellSet;
}
set heaterCellSet;
}
{
@ -45,10 +39,7 @@ actions
type cellSet;
action new;
source cellToCell;
sourceInfo
{
set heaterCellSet;
}
set heaterCellSet;
}
{
@ -62,10 +53,7 @@ actions
type cellZoneSet;
action new;
source setToCellZone;
sourceInfo
{
set bottomWaterCellSet;
}
set bottomWaterCellSet;
}
);

View File

@ -46,7 +46,7 @@ timePrecision 6;
runTimeModifiable true;
// Allow 10% run-up before calculating mean
timeStart #eval #{ 0.1 * ${/endTime} #};
timeStart #eval{ 0.1 * ${/endTime} };
functions

View File

@ -40,22 +40,20 @@ nz #eval{ round($nz / 5) };
#endif
zmin #eval{ -$zmax };
mrad0 #eval{ -$rad0 };
mrad1 #eval{ -$rad1 };
vertices
(
// back-plane:
// inlet region
( $xin $rad0 $zmin) // pt 0
( 0 $rad0 $zmin) // pt 1
( 0 $rad1 $zmin) // pt 2
( $xin $rad1 $zmin) // pt 3
( $xin $rad0 $zmin) // pt 0
( 0 $rad0 $zmin) // pt 1
( 0 $rad1 $zmin) // pt 2
( $xin $rad1 $zmin) // pt 3
// outlet region
( $xout $mrad1 $zmin) // pt 4
( 0 $mrad1 $zmin) // pt 5
( 0 $mrad0 $zmin) // pt 6
( $xout $mrad0 $zmin) // pt 7
( $xout -$rad1 $zmin) // pt 4
( 0 -$rad1 $zmin) // pt 5
( 0 -$rad0 $zmin) // pt 6
( $xout -$rad0 $zmin) // pt 7
// bend mid-points
( $rad0 0 $zmin) // pt 8
( $rad1 0 $zmin) // pt 9
@ -66,13 +64,13 @@ vertices
( 0 $rad1 $zmax) // pt 2 + 10
( $xin $rad1 $zmax) // pt 3 + 10
// outlet region
( $xout $mrad1 $zmax) // pt 4 + 10
( 0 $mrad1 $zmax) // pt 5 + 10
( 0 $mrad0 $zmax) // pt 6 + 10
( $xout $mrad0 $zmax) // pt 7 + 10
( $xout -$rad1 $zmax) // pt 4 + 10
( 0 -$rad1 $zmax) // pt 5 + 10
( 0 -$rad0 $zmax) // pt 6 + 10
( $xout -$rad0 $zmax) // pt 7 + 10
// bend mid-points
( $rad0 0 $zmax) // pt 8 + 10
( $rad1 0 $zmax) // pt 9 + 10
( $rad0 0 $zmax) // pt 8 + 10
( $rad1 0 $zmax) // pt 9 + 10
);
blocks

View File

@ -18,64 +18,87 @@ FoamFile
scale 1;
// Front/back locations
zmin -0.5;
zmax 0.5;
// Geometric parameters
rInner 0.5;
rOuter 1;
xmax 2;
ymax 2;
zmin -0.5; // Back/front locations
zmax 0.5;
// Divisions: Radial, quarter circumference, outer region and z-directions.
nRadial 10;
nQuarter 10;
nxOuter 20;
nyOuter 20;
nz 11;
// ----------------
// Derived quantities
rInner45 ${{ $rInner * sqrt(0.5) }};
rOuter45 ${{ $rOuter * sqrt(0.5) }};
vertices
(
(0.5 0 $zmin)
(1 0 $zmin)
(2 0 $zmin)
(2 0.707107 $zmin)
(0.707107 0.707107 $zmin)
(0.353553 0.353553 $zmin)
(2 2 $zmin)
(0.707107 2 $zmin)
(0 2 $zmin)
(0 1 $zmin)
(0 0.5 $zmin)
(-0.5 0 $zmin)
(-1 0 $zmin)
(-2 0 $zmin)
(-2 0.707107 $zmin)
(-0.707107 0.707107 $zmin)
(-0.353553 0.353553 $zmin)
(-2 2 $zmin)
(-0.707107 2 $zmin)
(0.5 0 $zmax)
(1 0 $zmax)
(2 0 $zmax)
(2 0.707107 $zmax)
(0.707107 0.707107 $zmax)
(0.353553 0.353553 $zmax)
(2 2 $zmax)
(0.707107 2 $zmax)
(0 2 $zmax)
(0 1 $zmax)
(0 0.5 $zmax)
(-0.5 0 $zmax)
(-1 0 $zmax)
(-2 0 $zmax)
(-2 0.707107 $zmax)
(-0.707107 0.707107 $zmax)
(-0.353553 0.353553 $zmax)
(-2 2 $zmax)
(-0.707107 2 $zmax)
/* 0*/ ( $rInner 0 $zmin )
/* 1*/ ( $rOuter 0 $zmin )
/* 2*/ ( $xmax 0 $zmin )
/* 3*/ ( $xmax $rOuter45 $zmin )
/* 4*/ ( $rOuter45 $rOuter45 $zmin )
/* 5*/ ( $rInner45 $rInner45 $zmin )
/* 6*/ ( $xmax $ymax $zmin )
/* 7*/ ( $rOuter45 $ymax $zmin )
/* 8*/ ( 0 $ymax $zmin )
/* 9*/ ( 0 $rOuter $zmin )
/*10*/ ( 0 $rInner $zmin )
/*11*/ ( -$rInner 0 $zmin )
/*12*/ ( -$rOuter 0 $zmin )
/*13*/ ( -$xmax 0 $zmin )
/*14*/ ( -$xmax $rOuter45 $zmin )
/*15*/ ( -$rOuter45 $rOuter45 $zmin )
/*16*/ ( -$rInner45 $rInner45 $zmin )
/*17*/ ( -$xmax $ymax $zmin )
/*18*/ ( -$rOuter45 $ymax $zmin )
/*19*/ ( $rInner 0 $zmax )
/*20*/ ( $rOuter 0 $zmax )
/*21*/ ( $xmax 0 $zmax )
/*22*/ ( $xmax $rOuter45 $zmax )
/*23*/ ( $rOuter45 $rOuter45 $zmax )
/*24*/ ( $rInner45 $rInner45 $zmax )
/*25*/ ( $xmax $ymax $zmax )
/*26*/ ( $rOuter45 $ymax $zmax )
/*27*/ ( 0 $ymax $zmax )
/*28*/ ( 0 $rOuter $zmax )
/*29*/ ( 0 $rInner $zmax )
/*30*/ ( -$rInner 0 $zmax )
/*31*/ ( -$rOuter 0 $zmax )
/*32*/ ( -$xmax 0 $zmax )
/*33*/ ( -$xmax $rOuter45 $zmax )
/*34*/ ( -$rOuter45 $rOuter45 $zmax )
/*35*/ ( -$rInner45 $rInner45 $zmax )
/*36*/ ( -$xmax $ymax $zmax )
/*37*/ ( -$rOuter45 $ymax $zmax )
);
// Can remove some unneeded variables
#remove ( "r(Inner|Outer).*" "[xy](min|max)" )
blocks
(
hex (5 4 9 10 24 23 28 29) (10 10 11) simpleGrading (1 1 1)
hex (0 1 4 5 19 20 23 24) (10 10 11) simpleGrading (1 1 1)
hex (1 2 3 4 20 21 22 23) (20 10 11) simpleGrading (1 1 1)
hex (4 3 6 7 23 22 25 26) (20 20 11) simpleGrading (1 1 1)
hex (9 4 7 8 28 23 26 27) (10 20 11) simpleGrading (1 1 1)
hex (15 16 10 9 34 35 29 28) (10 10 11) simpleGrading (1 1 1)
hex (12 11 16 15 31 30 35 34) (10 10 11) simpleGrading (1 1 1)
hex (13 12 15 14 32 31 34 33) (20 10 11) simpleGrading (1 1 1)
hex (14 15 18 17 33 34 37 36) (20 20 11) simpleGrading (1 1 1)
hex (15 9 8 18 34 28 27 37) (10 20 11) simpleGrading (1 1 1)
hex (5 4 9 10 24 23 28 29) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (0 1 4 5 19 20 23 24) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (1 2 3 4 20 21 22 23) ($nxOuter $nQuarter $nz) grading (1 1 1)
hex (4 3 6 7 23 22 25 26) ($nxOuter $nyOuter $nz) grading (1 1 1)
hex (9 4 7 8 28 23 26 27) ($nQuarter $nyOuter $nz) grading (1 1 1)
hex (15 16 10 9 34 35 29 28) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (12 11 16 15 31 30 35 34) ($nRadial $nQuarter $nz) grading (1 1 1)
hex (13 12 15 14 32 31 34 33) ($nxOuter $nQuarter $nz) grading (1 1 1)
hex (14 15 18 17 33 34 37 36) ($nxOuter $nyOuter $nz) grading (1 1 1)
hex (15 9 8 18 34 28 27 37) ($nQuarter $nyOuter $nz) grading (1 1 1)
);
edges

View File

@ -34,20 +34,19 @@ geometry
}
}
// Box sizes
// Box size
vo #eval{ sqrt($outerRadius/3) };
mvo #eval{ -$vo };
vertices
(
($mvo $mvo $mvo)
( $vo $mvo $mvo)
( $vo $vo $mvo)
($mvo $vo $mvo)
($mvo $mvo $vo)
( $vo $mvo $vo)
(-$vo -$vo -$vo)
( $vo -$vo -$vo)
( $vo $vo -$vo)
(-$vo $vo -$vo)
(-$vo -$vo $vo)
( $vo -$vo $vo)
( $vo $vo $vo)
($mvo $vo $vo)
(-$vo $vo $vo)
);
blocks

View File

@ -37,35 +37,33 @@ geometry
}
}
// Outer box sizes
// Outer box size
vo #eval{ sqrt($outerRadius/3) };
mvo #eval{ -$vo };
// Inner box sizes - % of overall dimension
// Inner box size - % of overall dimension
vi #eval{ $vo * $innerRatio };
mvi #eval{ -$vi };
vertices
(
// Inner block
($mvi $mvi $mvi)
( $vi $mvi $mvi)
( $vi $vi $mvi)
($mvi $vi $mvi)
($mvi $mvi $vi)
( $vi $mvi $vi)
(-$vi -$vi -$vi)
( $vi -$vi -$vi)
( $vi $vi -$vi)
(-$vi $vi -$vi)
(-$vi -$vi $vi)
( $vi -$vi $vi)
( $vi $vi $vi)
($mvi $vi $vi)
(-$vi $vi $vi)
// Outer blocks
($mvo $mvo $mvo)
( $vo $mvo $mvo)
( $vo $vo $mvo)
($mvo $vo $mvo)
($mvo $mvo $vo)
( $vo $mvo $vo)
(-$vo -$vo -$vo)
( $vo -$vo -$vo)
( $vo $vo -$vo)
(-$vo $vo -$vo)
(-$vo -$vo $vo)
( $vo -$vo $vo)
( $vo $vo $vo)
($mvo $vo $vo)
(-$vo $vo $vo)
);
blocks

View File

@ -44,35 +44,33 @@ geometry
}
// Outer box sizes (approximate)
// Outer box size (approximate)
vo #eval{ sqrt($outerRadius/3) };
mvo #eval{ -$vo };
// Inner box sizes - % of overall dimension
// Inner box size - % of overall dimension
vi #eval{ $vo * $innerRatio };
mvi #eval{ -$vi };
vertices
(
// Inner block points
project ($mvi $mvi $mvi) (innerSphere)
project ( $vi $mvi $mvi) (innerSphere)
project ( $vi $vi $mvi) (innerSphere)
project ($mvi $vi $mvi) (innerSphere)
project ($mvi $mvi $vi) (innerSphere)
project ( $vi $mvi $vi) (innerSphere)
project (-$vi -$vi -$vi) (innerSphere)
project ( $vi -$vi -$vi) (innerSphere)
project ( $vi $vi -$vi) (innerSphere)
project (-$vi $vi -$vi) (innerSphere)
project (-$vi -$vi $vi) (innerSphere)
project ( $vi -$vi $vi) (innerSphere)
project ( $vi $vi $vi) (innerSphere)
project ($mvi $vi $vi) (innerSphere)
project (-$vi $vi $vi) (innerSphere)
// Outer block points
project ($mvo $mvo $mvo) (sphere)
project ( $vo $mvo $mvo) (sphere)
project ( $vo $vo $mvo) (sphere)
project ($mvo $vo $mvo) (sphere)
project ($mvo $mvo $vo) (sphere)
project ( $vo $mvo $vo) (sphere)
project (-$vo -$vo -$vo) (sphere)
project ( $vo -$vo -$vo) (sphere)
project ( $vo $vo -$vo) (sphere)
project (-$vo $vo -$vo) (sphere)
project (-$vo -$vo $vo) (sphere)
project ( $vo -$vo $vo) (sphere)
project ( $vo $vo $vo) (sphere)
project ($mvo $vo $vo) (sphere)
project (-$vo $vo $vo) (sphere)
);
blocks

View File

@ -44,47 +44,42 @@ geometry
innerSphere
{
$sphere
radius
(
#eval{ $rxo * $innerRatio }
#eval{ $ryo * $innerRatio }
#eval{ $rzo * $innerRatio }
);
radius #eval{ $innerRatio*$[(vector) ../sphere/radius] };
}
}
// Outer box sizes (approximate)
vxo #eval{ sqrt(1.0/3.0) * $rxo }; mvxo #eval{ -$vxo };
vyo #eval{ sqrt(1.0/3.0) * $ryo }; mvyo #eval{ -$vyo };
vzo #eval{ sqrt(1.0/3.0) * $rzo }; mvzo #eval{ -$vzo };
vxo #eval{ sqrt(1.0/3.0) * $rxo };
vyo #eval{ sqrt(1.0/3.0) * $ryo };
vzo #eval{ sqrt(1.0/3.0) * $rzo };
// Inner box sizes - % of overall dimension
vxi #eval{ $vxo * $innerRatio }; mvxi #eval{ -$vxi };
vyi #eval{ $vyo * $innerRatio }; mvyi #eval{ -$vyi };
vzi #eval{ $vzo * $innerRatio }; mvzi #eval{ -$vzi };
vxi #eval{ $vxo * $innerRatio };
vyi #eval{ $vyo * $innerRatio };
vzi #eval{ $vzo * $innerRatio };
vertices
(
// Inner block points
project ($mvxi $mvyi $mvzi) (innerSphere)
project ( $vxi $mvyi $mvzi) (innerSphere)
project ( $vxi $vyi $mvzi) (innerSphere)
project ($mvxi $vyi $mvzi) (innerSphere)
project ($mvxi $mvyi $vzi) (innerSphere)
project ( $vxi $mvyi $vzi) (innerSphere)
project (-$vxi -$vyi -$vzi) (innerSphere)
project ( $vxi -$vyi -$vzi) (innerSphere)
project ( $vxi $vyi -$vzi) (innerSphere)
project (-$vxi $vyi -$vzi) (innerSphere)
project (-$vxi -$vyi $vzi) (innerSphere)
project ( $vxi -$vyi $vzi) (innerSphere)
project ( $vxi $vyi $vzi) (innerSphere)
project ($mvxi $vyi $vzi) (innerSphere)
project (-$vxi $vyi $vzi) (innerSphere)
// Outer block points
project ($mvxo $mvyo $mvzo) (sphere)
project ( $vxo $mvyo $mvzo) (sphere)
project ( $vxo $vyo $mvzo) (sphere)
project ($mvxo $vyo $mvzo) (sphere)
project ($mvxo $mvyo $vzo) (sphere)
project ( $vxo $mvyo $vzo) (sphere)
project (-$vxo -$vyo -$vzo) (sphere)
project ( $vxo -$vyo -$vzo) (sphere)
project ( $vxo $vyo -$vzo) (sphere)
project (-$vxo $vyo -$vzo) (sphere)
project (-$vxo -$vyo $vzo) (sphere)
project ( $vxo -$vyo $vzo) (sphere)
project ( $vxo $vyo $vzo) (sphere)
project ($mvxo $vyo $vzo) (sphere)
project (-$vxo $vyo $vzo) (sphere)
);
blocks

View File

@ -37,21 +37,21 @@ geometry
}
// Box sizes
vxo #eval{sqrt(1.0/3.0) * $rxo}; mvxo #eval{-$vxo};
vyo #eval{sqrt(1.0/3.0) * $ryo}; mvyo #eval{-$vyo};
vzo #eval{sqrt(1.0/3.0) * $rzo}; mvzo #eval{-$vzo};
vxo ${{sqrt(1.0/3.0) * $rxo}};
vyo ${{sqrt(1.0/3.0) * $ryo}};
vzo ${{sqrt(1.0/3.0) * $rzo}};
vertices
(
// Outer block points
project ($mvxo $mvyo $mvzo) (sphere)
project ( $vxo $mvyo $mvzo) (sphere)
project ( $vxo $vyo $mvzo) (sphere)
project ($mvxo $vyo $mvzo) (sphere)
project ($mvxo $mvyo $vzo) (sphere)
project ( $vxo $mvyo $vzo) (sphere)
project (-$vxo -$vyo -$vzo) (sphere)
project ( $vxo -$vyo -$vzo) (sphere)
project ( $vxo $vyo -$vzo) (sphere)
project (-$vxo $vyo -$vzo) (sphere)
project (-$vxo -$vyo $vzo) (sphere)
project ( $vxo -$vyo $vzo) (sphere)
project ( $vxo $vyo $vzo) (sphere)
project ($mvxo $vyo $vzo) (sphere)
project (-$vxo $vyo $vzo) (sphere)
);
blocks

View File

@ -25,7 +25,7 @@ boundaryField
type rotatingWallVelocity;
axis (0 1 0);
origin (0 0 0);
omega constant #eval{ 2.1 * (2*pi()) }; // rev/s -> rads/s
omega constant ${{ 2.1 * (2*pi()) }}; // rev/s -> rads/s
value uniform (0 0 0);
}

View File

@ -26,7 +26,7 @@ boundaryField
type rotatingWallVelocity;
axis (0 1 0);
origin (0 0 0);
omega constant #eval{ 2.1 * (2*pi()) }; // rev/s -> rads/s
omega constant ${{ 2.1 * (2*pi()) }}; // rev/s -> rads/s
value uniform (0 0 0);
}
vessel

View File

@ -42,7 +42,7 @@ solvers
centreOfMass (0.5 0.5 0.4);
cOfGdisplacement CofG;
// Cuboid dimensions
Lx 0.24;
Ly 0.24;

View File

@ -16,29 +16,25 @@ FoamFile
actions
(
pickCells
{
name zone;
type cellSet;
action new;
source boxToCell;
sourceInfo
{
boxes
(
(0 0.4 0) (0.15 0.5 0.1)
);
}
boxes
(
(0 0.4 0) (0.15 0.5 0.1)
);
}
convertToZone
{
name zone;
type cellZoneSet;
action new;
source setToCellZone;
sourceInfo
{
set zone;
}
set zone;
}
);

View File

@ -49,7 +49,7 @@ adjustTimeStep false;
// Allow 10% of time for initialisation before sampling
timeStart #eval #{ 0.1 * ${/endTime} #};
timeStart #eval{ 0.1 * ${/endTime} };
functions
{