diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H index 59b2d58d59..c866b11cb7 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.H +++ b/src/OpenFOAM/db/dictionary/dictionary.H @@ -521,6 +521,19 @@ public: bool patternMatch=true ) 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 + const T& lookupCompoundScoped + ( + const word& keyword, + bool recursive, + bool patternMatch + ) const; + //- Check if entry is a sub-dictionary bool isDict(const word&) const; diff --git a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C index ead0342f04..b46be240da 100644 --- a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C +++ b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -248,6 +248,33 @@ T Foam::dictionary::lookupScoped } +template +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>(firstToken.compoundToken()); +} + + template void Foam::dictionary::add(const keyType& k, const T& t, bool overwrite) { diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C index 9d1064ae48..75b199d94e 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C @@ -509,22 +509,28 @@ Foam::string& Foam::stringOps::inplaceExpandCodeString if (ePtr) { OStringStream buf; + bool compound = false; - // If the variable type is not specified - // check if it can be obtained from the single token type - if (varType.empty()) + // Check if variable type can be obtained from the single + // token type and if the token is a compound + if (!ePtr->isDict()) { - if (!ePtr->isDict()) - { - const primitiveEntry& pe = - dynamicCast(*ePtr); + const primitiveEntry& pe = + dynamicCast(*ePtr); - // Check that the primitive entry is a single token - if (pe.size() == 1) + // Check that the primitive entry is a single token + if (pe.size() == 1) + { + // If the variable type is not specified + // obtain the variable type from the token type name + if (varType.empty()) { - // Map the token type name to the variable type varType = pe[0].typeName(); } + + // Check if the token is a compound which can be + // accessed directly + compound = pe[0].isCompound(); } } @@ -538,9 +544,23 @@ Foam::string& Foam::stringOps::inplaceExpandCodeString // code, rather than substituting its value. That // way we don't need to recompile this string if the // value changes. - buf << dictVar - << ".lookupScoped<" << varType << ">" - << "(\"" << varName << "\", true, false)"; + // + // 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 + << ".lookupScoped<" << varType << ">" + << "(\"" << varName << "\", true, false)"; + } } else { diff --git a/test/dictionary/testCalc b/test/dictionary/testCalc index 07d3d010c4..1dd6a3b7bd 100644 --- a/test/dictionary/testCalc +++ b/test/dictionary/testCalc @@ -90,4 +90,8 @@ magSqrU1 #calc "sqr($>magUs[1])"; namedU (U0 (1.1 2.1 1.1) U1 (2.1 3.2 4.1) U2 (4.3 5.3 0)); magU2 #calc "mag($>namedU[\"U2\"])"; +// List of vectors stored as a typed compound example +listU2 List ((1.1 2.1 1.1) (2.1 3.2 4.1) (4.3 5.3 0)); +magU21 #calc "mag($listU2[1])"; + // ************************************************************************* //