functionEntries::calcEntry: Extended the functionality of multi-statement/multi-line #calc

If the code string is delimited by '#{...#}' multiple lines and multiple code
statements can be used to generate the entry using 'os << ...;'.  This is
equivalent to #codeStream but with a more compact syntax, e.g.

maxAngle        30;
nAngles         7;
Us              #calc
    const vector U($<vector>testCalc2!U);
    const int nAngles = $nAngles;
    const scalar angleStep = ($<scalar>maxAngle)/(nAngles - 1);
    List<vector> Us(nAngles);
    for(int i=0; i<nAngles; i++)
    {
        const scalar angle = degToRad(i*angleStep);
        Us[i] = transform(Ry(angle), U);
    }
    os << Us;

Note the 'os << Us;' statement which writes the data to the dictionary entry in
the same manner as #codeStream, this provides flexibility on how the data is
created and written.
This commit is contained in:
Henry Weller
2023-07-06 23:11:36 +01:00
parent 62998bb161
commit 441b60c70d
4 changed files with 73 additions and 28 deletions

View File

@ -65,7 +65,7 @@ Foam::string Foam::functionEntries::calcEntry::calc
Istream& is Istream& is
) )
{ {
Info<< "Using #calcEntry at line " << is.lineNumber() Info<< "Expanding #calc at line " << is.lineNumber()
<< " in file " << dict.name() << endl; << " in file " << dict.name() << endl;
dynamicCode::checkSecurity dynamicCode::checkSecurity
@ -74,16 +74,37 @@ Foam::string Foam::functionEntries::calcEntry::calc
dict dict
); );
// Read string delimited by either '"..."' or '#{...#}'
verbatimString s(is);
// Construct codeDict for codeStream // Construct codeDict for codeStream
// with dict as parent dictionary for string expansion // with dict as parent dictionary for string expansion
// and variable substitution // and variable substitution
dictionary codeDict(dict, dictionary()); dictionary codeDict(dict, dictionary());
calcIncludeEntry::codeInclude(codeDict); // Read the code expression string delimited by either '"..."' or '#{...#}'
codeDict.add("code", "os << (" + s + ");"); token t(is);
if (t.isVerbatimString())
{
const verbatimString& s = t.verbatimStringToken();
calcIncludeEntry::codeInclude(codeDict);
codeDict.add("code", s);
}
else if (t.isString())
{
const string& s = t.stringToken();
calcIncludeEntry::codeInclude(codeDict);
codeDict.add("code", "os << (" + s + ");");
}
else
{
FatalIOErrorInFunction(is)
<< "Wrong string type for #calc" << nl
<< " Expected either a string delimited by '\"...\"' "
"or a verbatim string delimited by '#{...#}' " << nl
<< " found token " << t
<< exit(FatalIOError);
}
codeStream::streamingFunctionType function = codeStream::getFunction codeStream::streamingFunctionType function = codeStream::getFunction
( (

View File

@ -51,18 +51,9 @@ Usage
c #calc "($a)/$b"; c #calc "($a)/$b";
\endverbatim \endverbatim
The code string can be delimited either by '"..."' in which newlines must be
escaped or '#{...#}' which directly supports multi-line strings and is more
convenient when evaluating string expressions by avoiding the need to
escape the quotes, e.g.
\verbatim
c #calc #{ $a*sqrt($b) #};
\endverbatim
\verbatim \verbatim
s "field"; s "field";
fieldName #calc #{ $<string>s + "Name" #}; fieldName #calc "$<string>s + \"Name\" ";
\endverbatim \endverbatim
Additional include files for the #calc code compilation can be specified Additional include files for the #calc code compilation can be specified
@ -77,12 +68,31 @@ Usage
dragDir #calc "transform(Ry($angle), vector(1, 0, 0))"; dragDir #calc "transform(Ry($angle), vector(1, 0, 0))";
\endverbatim \endverbatim
Note: If the code string is delimited by '#{...#}' multiple lines and multiple
Internally this is just a wrapper around codeStream functionality - the code statements can be used to generate the entry using 'os << ...;'.
#calc string is used to construct a dictionary for codeStream. This is equivalent to #codeStream but with a more compact syntax.
\verbatim
#calcInclude "transform.H"
maxAngle 30;
nAngles 7;
Us #calc
#{
const vector U($<vector>testCalc2!U);
const int nAngles = $nAngles;
const scalar angleStep = ($<scalar>maxAngle)/(nAngles - 1);
List<vector> Us(nAngles);
for(int i=0; i<nAngles; i++)
{
const scalar angle = degToRad(i*angleStep);
Us[i] = transform(Ry(angle), U);
}
os << Us;
#};
\endverbatim
See also See also
Foam::functionEntries::calcIncludeEntry Foam::functionEntries::calcIncludeEntry
Foam::functionEntries::codeStream
SourceFiles SourceFiles
calcEntry.C calcEntry.C

View File

@ -18,7 +18,8 @@ max (2.5 1.2 3.0); // Maximum coordinates of the block
nCellsByL 33.3333; // Number of cells per unit length nCellsByL 33.3333; // Number of cells per unit length
// Calculate the number of cells in each block direction // Calculate the number of cells in each block direction
nCells #calc #{ Vector<label>($nCellsByL*($<vector>max - $<vector>min) + vector::one/2) #}; nCells #calc
"Vector<label>($nCellsByL*($<vector>max - $<vector>min) + vector::one/2)";
// Generate the vertices using a boundBox // Generate the vertices using a boundBox
#calcInclude "boundBox.H" #calcInclude "boundBox.H"

View File

@ -29,15 +29,8 @@ c #calc "$a / $b";
c #calc "($a)/$b"; c #calc "($a)/$b";
// The code string can be delimited either by '"..."' in which newlines must be
// escaped or '#{...#}' which directly supports multi-line strings and is more
// convenient when evaluating string expressions by avoiding the need to
// escape the quotes, e.g.
c #calc #{ $a*sqrt($b) #};
s "field"; s "field";
fieldName #calc #{ $<string>s + "Name" #}; fieldName #calc "$<string>s + \"Name\" ";
// Additional include files for the #calc code compilation can be specified // Additional include files for the #calc code compilation can be specified
// using the #calcInclude entry, e.g. if functions from transform.H are used // using the #calcInclude entry, e.g. if functions from transform.H are used
@ -54,4 +47,24 @@ dragDir #calc "transform(Ry($angle), vector(1, 0, 0))";
magU #calc "mag($<vector>testCalc2!U)"; magU #calc "mag($<vector>testCalc2!U)";
k #calc "1.5*magSqr(0.05*$<vector>{${FOAM_CASE}/testCalc2!U})"; k #calc "1.5*magSqr(0.05*$<vector>{${FOAM_CASE}/testCalc2!U})";
// If the code string is delimited by '#{...#}' multiple lines and multiple
// code statements can be used to generate the entry using 'os << ...;'.
// This is equivalent to #codeStream but with a more compact syntax.
#calcInclude "transform.H"
maxAngle 30;
nAngles 7;
Us #calc
#{
const vector U($<vector>testCalc2!U);
const int nAngles = $nAngles;
const scalar angleStep = ($<scalar>maxAngle)/(nAngles - 1);
List<vector> Us(nAngles);
for(int i=0; i<nAngles; i++)
{
const scalar angle = degToRad(i*angleStep);
Us[i] = transform(Ry(angle), U);
}
os << Us;
#};
// ************************************************************************* // // ************************************************************************* //