dictionary::lookupCompoundScoped: New member function to return a reference to a compound token type

lookupCompoundScoped is used by dictionary via stringOps to provide fast access
to compound tokens without the need to construct the container for every access,
e.g.

listU           List<vector> ((1.1 2.1 1.1) (2.1 3.2 4.1) (4.3 5.3 0));
magU1           #calc "mag($listU[1])";
magU2           #calc "mag($listU[2])";

where the listU is declared as a List<vector> compound token which is then
accessed directly by $listU without the need to specify the type and the data is
accessed directly by reference which is more efficient, particularly if the list
is large.
This commit is contained in:
Henry Weller
2024-05-05 17:42:20 +01:00
parent ff7fce900c
commit fb4d7abf42
4 changed files with 78 additions and 14 deletions

View File

@ -521,6 +521,19 @@ public:
bool patternMatch=true bool patternMatch=true
) const; ) const;
//- Find return the reference to the compound T,
// if not found or not a compound throw a fatal error.
// If recursive, search parent dictionaries.
// If patternMatch, use regular expressions.
// Allows scoping using '/' with special handling for '!' and '..'.
template<class T>
const T& lookupCompoundScoped
(
const word& keyword,
bool recursive,
bool patternMatch
) const;
//- Check if entry is a sub-dictionary //- Check if entry is a sub-dictionary
bool isDict(const word&) const; bool isDict(const word&) const;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -248,6 +248,33 @@ T Foam::dictionary::lookupScoped
} }
template<class T>
const T& Foam::dictionary::lookupCompoundScoped
(
const word& keyword,
bool recursive,
bool patternMatch
) const
{
const entry* entryPtr =
lookupScopedEntryPtr(keyword, recursive, patternMatch);
if (entryPtr == nullptr)
{
FatalIOErrorInFunction
(
*this
) << "keyword " << keyword << " is undefined in dictionary "
<< name()
<< exit(FatalIOError);
}
token firstToken(entryPtr->stream());
return dynamicCast<const token::Compound<T>>(firstToken.compoundToken());
}
template<class T> template<class T>
void Foam::dictionary::add(const keyType& k, const T& t, bool overwrite) void Foam::dictionary::add(const keyType& k, const T& t, bool overwrite)
{ {

View File

@ -509,11 +509,10 @@ Foam::string& Foam::stringOps::inplaceExpandCodeString
if (ePtr) if (ePtr)
{ {
OStringStream buf; OStringStream buf;
bool compound = false;
// If the variable type is not specified // Check if variable type can be obtained from the single
// check if it can be obtained from the single token type // token type and if the token is a compound
if (varType.empty())
{
if (!ePtr->isDict()) if (!ePtr->isDict())
{ {
const primitiveEntry& pe = const primitiveEntry& pe =
@ -522,9 +521,16 @@ Foam::string& Foam::stringOps::inplaceExpandCodeString
// Check that the primitive entry is a single token // Check that the primitive entry is a single token
if (pe.size() == 1) if (pe.size() == 1)
{ {
// Map the token type name to the variable type // If the variable type is not specified
// obtain the variable type from the token type name
if (varType.empty())
{
varType = pe[0].typeName(); varType = pe[0].typeName();
} }
// Check if the token is a compound which can be
// accessed directly
compound = pe[0].isCompound();
} }
} }
@ -538,10 +544,24 @@ Foam::string& Foam::stringOps::inplaceExpandCodeString
// code, rather than substituting its value. That // code, rather than substituting its value. That
// way we don't need to recompile this string if the // way we don't need to recompile this string if the
// value changes. // value changes.
//
// Compound types have special handling
// to return as constant reference rather than
// constructing the container
if (compound)
{
buf << dictVar
<< ".lookupCompoundScoped<"
<< varType << ">"
<< "(\"" << varName << "\", true, false)";
}
else
{
buf << dictVar buf << dictVar
<< ".lookupScoped<" << varType << ">" << ".lookupScoped<" << varType << ">"
<< "(\"" << varName << "\", true, false)"; << "(\"" << varName << "\", true, false)";
} }
}
else else
{ {
// If the dictionary is accessible but the // If the dictionary is accessible but the

View File

@ -90,4 +90,8 @@ magSqrU1 #calc "sqr($<Field<scalar>>magUs[1])";
namedU (U0 (1.1 2.1 1.1) U1 (2.1 3.2 4.1) U2 (4.3 5.3 0)); namedU (U0 (1.1 2.1 1.1) U1 (2.1 3.2 4.1) U2 (4.3 5.3 0));
magU2 #calc "mag($<HashTable<vector>>namedU[\"U2\"])"; magU2 #calc "mag($<HashTable<vector>>namedU[\"U2\"])";
// List of vectors stored as a typed compound example
listU2 List<vector> ((1.1 2.1 1.1) (2.1 3.2 4.1) (4.3 5.3 0));
magU21 #calc "mag($listU2[1])";
// ************************************************************************* // // ************************************************************************* //