From 04cab84af6fe13b06dc5be24725cfb4b529bb087 Mon Sep 17 00:00:00 2001 From: Henry Weller Date: Thu, 15 Apr 2021 16:32:50 +0100 Subject: [PATCH] basicThermo: Added support for dynamic compilation of thermophysical property packages If the combination of property models selected in thermophysicalProperties is not already compiled and present in the standard libraries the thermophysical property package will be constructed and compiled automatically using the standard dynamicCode system provided in OpenFOAM. The thermophysical property package is constructed automatically from the etc/codeTemplates/dynamicCode files for the corresponding base thermo type (e.g. fluidThermo), currently these are provided only for fluidThermo but the others will be added shortly. If the corresponding codeTemplates files do not exist the standard thermo lookup error message is generated as before. As with all other dynamicCode options in OpenFOAM (codeStream, codedFunctionObject etc.) dynamic compilation of the thermophysical property package is only enabled if allowSystemOperations is set true. --- etc/codeTemplates/dynamicCode/fluidThermo | 105 +++++++++++++ etc/codeTemplates/dynamicCode/fluidThermo.C | 90 +++++++++++ .../db/dynamicLibrary/codedBase/codedBase.C | 3 +- .../dynamicLibrary/dynamicCode/dynamicCode.C | 28 ++++ .../dynamicLibrary/dynamicCode/dynamicCode.H | 7 +- src/thermophysicalModels/basic/Make/files | 1 + .../basic/basicThermo/basicThermoTemplates.C | 90 +++++++---- .../basic/basicThermo/compileThermo.C | 147 ++++++++++++++++++ .../basic/basicThermo/compileThermo.H | 99 ++++++++++++ 9 files changed, 534 insertions(+), 36 deletions(-) create mode 100644 etc/codeTemplates/dynamicCode/fluidThermo create mode 100644 etc/codeTemplates/dynamicCode/fluidThermo.C create mode 100644 src/thermophysicalModels/basic/basicThermo/compileThermo.C create mode 100644 src/thermophysicalModels/basic/basicThermo/compileThermo.H diff --git a/etc/codeTemplates/dynamicCode/fluidThermo b/etc/codeTemplates/dynamicCode/fluidThermo new file mode 100644 index 0000000000..dfda52b907 --- /dev/null +++ b/etc/codeTemplates/dynamicCode/fluidThermo @@ -0,0 +1,105 @@ +/*--------------------------------*- C++ -*----------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Version: dev + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object fluidThermo; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +type +( + hePsiThermo + heRhoThermo +); + +baseType +( + hePsiThermo psiThermo + heRhoThermo rhoThermo +); + +energy +( + sensibleEnthalpy + absoluteEnthalpy + sensibleInternalEnergy + absoluteInternalEnergy +); + +mixture +( + pureMixture +); + +transport +( + const + icoTabulated + logPolynomial + polynomial + sutherland + tabulated + WLF +); + +thermo +( + eConst + eIcoTabulated + ePolynomial + ePower + eTabulated + hConst + hIcoTabulated + hPolynomial + hPower + hTabulated + janaf +); + +equationOfState +( + adiabaticPerfectFluid + Boussinesq + icoPolynomial + icoTabulated + incompressiblePerfectGas + linear + PengRobinsonGas + perfectFluid + perfectGas + rhoConst + rhoTabulated + rPolynomial +); + +codeOptions +#{ +EXE_INC = \ + -I$(LIB_SRC)/transportModels/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/thermophysicalProperties/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ + -I$(LIB_SRC)/finiteVolume/lnInclude +#}; + +codeLibs +#{ +LIB_LIBS = \ + -ltransportModels \ + -lspecie \ + -lthermophysicalProperties \ + -lfluidThermophysicalModels \ + -lfiniteVolume +#}; + + +// ************************************************************************* // diff --git a/etc/codeTemplates/dynamicCode/fluidThermo.C b/etc/codeTemplates/dynamicCode/fluidThermo.C new file mode 100644 index 0000000000..0fbc47f1a8 --- /dev/null +++ b/etc/codeTemplates/dynamicCode/fluidThermo.C @@ -0,0 +1,90 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) YEAR OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +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 . + +\*---------------------------------------------------------------------------*/ + +#include "forThermo.H" +#include "makeThermo.H" + +#include "thermo.H" + +// EoS +#include "${equationOfState}.H" + +// Thermo +#include "${thermo}Thermo.H" +#include "${energy}.H" + +// Transport +#include "${transport}Transport.H" + +// psi/rho +#include "${baseType}.H" +#include "${type}.H" + +// Mixture +#include "${mixture}.H" + + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +extern "C" +{ + // dynamicCode: + // SHA1 = ${SHA1sum} + // + // Unique function name that can be checked if the correct library version + // has been loaded + void ${typeName}_${SHA1sum}(bool load) + { + if (load) + { + // code that can be explicitly executed after loading + } + else + { + // code that can be explicitly executed before unloading + } + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + forThermo + ( + ${transport}Transport, + ${energy}, + ${thermo}Thermo, + ${equationOfState}, + specie, + makeThermos, + ${baseType}, + ${type}, + ${mixture} + ); +} + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C index 97207b942d..01c624b2a7 100644 --- a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C +++ b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -274,7 +274,6 @@ void Foam::codedBase::createLibrary << endl; } } - reduce(create, orOp()); } diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C index 5ac5b505c8..bd20b0f976 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C @@ -139,6 +139,34 @@ void Foam::dynamicCode::copyAndFilter } +Foam::fileName Foam::dynamicCode::resolveTemplate +( + const fileName& templateName +) +{ + // Try to get template from FOAM_CODESTREAM_TEMPLATES + const fileName templateDir(Foam::getEnv(codeTemplateEnvName)); + + fileName file; + if (!templateDir.empty() && isDir(templateDir)) + { + file = templateDir/templateName; + if (!isFile(file, false, false)) + { + file.clear(); + } + } + + // Not found - fallback to ~OpenFOAM expansion + if (file.empty()) + { + file = findEtcFile(codeTemplateDirName/templateName); + } + + return file; +} + + bool Foam::dynamicCode::resolveTemplates ( const UList& templateNames, diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H index b7e8575778..7aeacaf2a2 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -226,13 +226,11 @@ public: // Corresponds to topDirName/codeDirName() fileName codeRelPath() const; - //- Library path for specified code name relative to \$FOAM_CASE // Corresponds to // dynamicCode/codeDirName()/libSubDir()/lib\.so fileName libRelPath() const; - //- Path for SHA1Digest // Corresponds to codePath()/Make/SHA1Digest fileName digestFile() const @@ -240,6 +238,9 @@ public: return codeRoot_/codeDirName_/"Make/SHA1Digest"; } + //- Resolve code-template via the codeTemplateEnvName + // alternatively in the codeTemplateDirName via Foam::findEtcFile + static fileName resolveTemplate(const fileName& templateName); //- Clear files and variables void clear(); diff --git a/src/thermophysicalModels/basic/Make/files b/src/thermophysicalModels/basic/Make/files index 92dff66672..f3720d753b 100644 --- a/src/thermophysicalModels/basic/Make/files +++ b/src/thermophysicalModels/basic/Make/files @@ -1,4 +1,5 @@ basicThermo/basicThermo.C +basicThermo/compileThermo.C fluidThermo/fluidThermo.C diff --git a/src/thermophysicalModels/basic/basicThermo/basicThermoTemplates.C b/src/thermophysicalModels/basic/basicThermo/basicThermoTemplates.C index ba9e3b808e..79b561473d 100644 --- a/src/thermophysicalModels/basic/basicThermo/basicThermoTemplates.C +++ b/src/thermophysicalModels/basic/basicThermo/basicThermoTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2012-2020 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2021 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,6 +25,7 @@ License #include "basicThermo.H" #include "wordIOList.H" +#include "compileThermo.H" // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // @@ -41,47 +42,74 @@ typename Table::iterator Foam::basicThermo::lookupCstrIter // Lookup the thermo package typename Table::iterator cstrIter = tablePtr->find(thermoTypeName); - // Print error message if package not found in the table if (cstrIter == tablePtr->end()) { - FatalErrorInFunction - << "Unknown " << Thermo::typeName << " type " << nl - << "thermoType" << thermoTypeDict << nl << nl - << "Valid " << Thermo::typeName << " types are:" - << nl << nl; - - // Get the list of all the suitable thermo packages available - wordList validThermoTypeNames(tablePtr->sortedToc()); - - // Build a table of the thermo packages constituent parts - DynamicList validThermoTypeNameCmpts; - - // Set row zero to the column headers - validThermoTypeNameCmpts.append(wordList(nCmpt)); - forAll(validThermoTypeNameCmpts[0], i) + if + ( + dynamicCode::allowSystemOperations + && !dynamicCode::resolveTemplate(Thermo::typeName).empty() + ) { - validThermoTypeNameCmpts[0][i] = cmptNames[i]; - } - - // Split the thermo package names into their constituent parts and add - // them to the table, removing any incompatible entries from the list - forAll(validThermoTypeNames, i) - { - const wordList names + compileThermo thermo ( - Thermo::splitThermoName(validThermoTypeNames[i], nCmpt) + Thermo::typeName, + thermoTypeName, + thermoTypeDict ); + cstrIter = tablePtr->find(thermoTypeName); - if (names.size()) + if (cstrIter == tablePtr->end()) { - validThermoTypeNameCmpts.append(names); + FatalErrorInFunction + << "Compilation and linkage of " + << Thermo::typeName << " type " << nl + << "thermoType" << thermoTypeDict << nl << nl + << "failed." << exit(FatalError); } } + else + { + // Print error message if package not found in the table + FatalErrorInFunction + << "Unknown " << Thermo::typeName << " type " << nl + << "thermoType" << thermoTypeDict << nl << nl + << "Valid " << Thermo::typeName << " types are:" + << nl << nl; - // Print the table of available packages - printTable(validThermoTypeNameCmpts, FatalError); + // Get the list of all the suitable thermo packages available + wordList validThermoTypeNames(tablePtr->sortedToc()); - FatalError<< exit(FatalError); + // Build a table of the thermo packages constituent parts + DynamicList validThermoTypeNameCmpts; + + // Set row zero to the column headers + validThermoTypeNameCmpts.append(wordList(nCmpt)); + forAll(validThermoTypeNameCmpts[0], i) + { + validThermoTypeNameCmpts[0][i] = cmptNames[i]; + } + + // Split the thermo package names into their constituent parts and + // add them to the table, removing any incompatible entries from the + // list + forAll(validThermoTypeNames, i) + { + const wordList names + ( + Thermo::splitThermoName(validThermoTypeNames[i], nCmpt) + ); + + if (names.size()) + { + validThermoTypeNameCmpts.append(names); + } + } + + // Print the table of available packages + printTable(validThermoTypeNameCmpts, FatalError); + + FatalError<< exit(FatalError); + } } return cstrIter; diff --git a/src/thermophysicalModels/basic/basicThermo/compileThermo.C b/src/thermophysicalModels/basic/basicThermo/compileThermo.C new file mode 100644 index 0000000000..cb9aaaaa7d --- /dev/null +++ b/src/thermophysicalModels/basic/basicThermo/compileThermo.C @@ -0,0 +1,147 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2021 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +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 . + +\*---------------------------------------------------------------------------*/ + +#include "basicThermo.H" +#include "compileThermo.H" +#include "dynamicCodeContext.H" +#include "Time.H" +#include "IFstream.H" +#include "OSspecific.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +template<> +const Foam::wordList Foam::CodedBase::codeKeys_ = +{}; + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::dictionary Foam::compileThermo::optionsDict +( + const word& thermoTypeName, + const word& instantiatedThermoName +) const +{ + IFstream optionsFile(dynamicCode::resolveTemplate(thermoTypeName)); + if (!optionsFile.good()) + { + FatalErrorInFunction + << "Failed to open dictionary file " << thermoTypeName + << exit(FatalError); + } + + dictionary dict(optionsFile); + + fileName thermoTypeFileName(instantiatedThermoName); + thermoTypeFileName.replaceAll(',', '_'); + thermoTypeFileName.replaceAll('<', '_'); + thermoTypeFileName.replaceAll('>', '_'); + + dict.add("name", thermoTypeFileName); + + return dict; +} + + +void Foam::compileThermo::setFilterVariable +( + dynamicCode& dynCode, + const dynamicCodeContext& context, + const word& name +) const +{ + const HashSet types(context.dict().lookup(name)); + const word type(thermoTypeDict_.lookup(name)); + if (!types.found(type)) + { + FatalIOErrorInFunction(thermoTypeDict_) + << "Unknown " << name << " type " << type << nl + << "Supported " << name << " types: " << types + << exit(FatalIOError); + } + + dynCode.setFilterVariable(name, type); +} + + +void Foam::compileThermo::prepare +( + dynamicCode& dynCode, + const dynamicCodeContext& context +) const +{ + dynCode.setFilterVariable("typeName", codeName()); + + const HashTable typeToBaseMap(context.dict().lookup("baseType")); + + const word type(thermoTypeDict_.lookup("type")); + dynCode.setFilterVariable("type", type); + + dynCode.setFilterVariable("baseType", typeToBaseMap[type]); + + setFilterVariable(dynCode, context, "mixture"); + setFilterVariable(dynCode, context, "transport"); + setFilterVariable(dynCode, context, "thermo"); + setFilterVariable(dynCode, context, "equationOfState"); + setFilterVariable(dynCode, context, "energy"); + + // Compile filtered C template + dynCode.addCompileFile(thermoTypeName_ + ".C"); + + // Define Make/options + dynCode.setMakeOptions(context.options() + "\n\n" + context.libs()); + + // Debugging: make verbose + if (debug) + { + dynCode.setFilterVariable("verbose", "true"); + Info<<"compile " << codeName() << " sha1: " + << context.sha1() << endl; + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::compileThermo::compileThermo +( + const word& thermoTypeName, + const word& instantiatedThermoName, + const dictionary& thermoTypeDict +) +: + CodedBase + ( + optionsDict(thermoTypeName, instantiatedThermoName) + ), + thermoTypeName_(thermoTypeName), + thermoTypeDict_(thermoTypeDict) +{ + this->updateLibrary(); +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/basicThermo/compileThermo.H b/src/thermophysicalModels/basic/basicThermo/compileThermo.H new file mode 100644 index 0000000000..e9112c3b6e --- /dev/null +++ b/src/thermophysicalModels/basic/basicThermo/compileThermo.H @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2021 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +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 . + +\*---------------------------------------------------------------------------*/ + +#ifndef compileThermo_H +#define compileThermo_H + +#include "CodedBase.H" +#include "dynamicCode.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class compileThermo Declaration +\*---------------------------------------------------------------------------*/ + +class compileThermo +: + public CodedBase +{ + // Private Member Data + + //- Name of the class Thermo basicThermo is instantiated on + const word thermoTypeName_; + + //- Reference to the dictionary containing the thermo components + const dictionary& thermoTypeDict_; + + + // Private Member Functions + + dictionary optionsDict + ( + const word& thermoTypeName, + const word& instantiatedThermoName + ) const; + + void setFilterVariable + ( + dynamicCode& dynCode, + const dynamicCodeContext& context, + const word& name + ) const; + + //- Adapt the context for the current object + virtual void prepare(dynamicCode&, const dynamicCodeContext&) const; + + //- Clear the ptr to the redirected object + virtual void clearRedirect() const + {} + + +public: + + // Constructors + + //- Construct from name and dictionary + compileThermo + ( + const word& thermoTypeName, + const word& instantiatedThermoName, + const dictionary& thermoTypeDict + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //