From 3ab0e63e6358146b20aa7b1c7019277dfbcea561 Mon Sep 17 00:00:00 2001 From: Chris Greenshields Date: Mon, 20 May 2024 09:25:08 +0100 Subject: [PATCH] New lumpedMassTemperature boundary condition This boundary condition is applied to a patch which bounds a solid body, wholly or partially. It represents the body as a lumped mass, i.e. by a single temperature which is fixed across the patch. The body has a volume which is either specified by the user, or is calculated when the patch describes a closed volume (including in 2D meshes). Starting from an initial temperature, the change in temperature is the calculated over time according to a specified applied power source and the heat transferred across the boundary, using a specified density and specific heat capacity of the lumped mass. --- .../Make/files | 1 + .../lumpedMassTemperatureFvPatchScalarField.C | 219 ++++++++++++++++++ .../lumpedMassTemperatureFvPatchScalarField.H | 213 +++++++++++++++++ 3 files changed, 433 insertions(+) create mode 100644 src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/lumpedMassTemperature/lumpedMassTemperatureFvPatchScalarField.C create mode 100644 src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/lumpedMassTemperature/lumpedMassTemperatureFvPatchScalarField.H diff --git a/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/Make/files b/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/Make/files index 94b29da5a9..637ce28475 100644 --- a/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/Make/files +++ b/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/Make/files @@ -1,4 +1,5 @@ externalTemperature/externalTemperatureFvPatchScalarField.C coupledTemperature/coupledTemperatureFvPatchScalarField.C +lumpedMassTemperature/lumpedMassTemperatureFvPatchScalarField.C LIB = $(FOAM_LIBBIN)/libcoupledThermophysicalTransportModels diff --git a/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/lumpedMassTemperature/lumpedMassTemperatureFvPatchScalarField.C b/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/lumpedMassTemperature/lumpedMassTemperatureFvPatchScalarField.C new file mode 100644 index 0000000000..144c856967 --- /dev/null +++ b/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/lumpedMassTemperature/lumpedMassTemperatureFvPatchScalarField.C @@ -0,0 +1,219 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2024 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 "lumpedMassTemperatureFvPatchScalarField.H" +#include "addToRunTimeSelectionTable.H" +#include "fieldMapper.H" +#include "thermophysicalTransportModel.H" +#include "ZeroConstant.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +bool Foam::lumpedMassTemperatureFvPatchScalarField::closed() const +{ + return mag(gSum(patch().Sf()))/gSum(patch().magSf()) < rootSmall; +} + +Foam::scalar Foam::lumpedMassTemperatureFvPatchScalarField::V() const +{ + return -gSum(patch().Sf() & patch().Cf()) + /patch().boundaryMesh().mesh().nSolutionD(); +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::lumpedMassTemperatureFvPatchScalarField:: +lumpedMassTemperatureFvPatchScalarField +( + const fvPatch& p, + const DimensionedField& iF, + const dictionary& dict +) +: + fixedValueFvPatchScalarField(p, iF), + rho_(dict.lookup("rho")), + Cv_(dict.lookup("Cv")), + T_ + ( + IOobject + ( + "T_" + patch().name(), + db().time().name(), + db() + ), + dimensionedScalar(dimTemperature, dict.lookup("T")) + ), + Q_ + ( + dict.found("Q") + ? Function1::New("Q", dict) + : autoPtr> + ( + new Function1s::ZeroConstant("Q", dict) + ) + ), + V_(NaN) +{ + if (!dict.readIfPresent("volume", V_)) + { + if (closed()) + { + V_ = V(); + Info<< "Volume for the thermal mass, enclosed by patch '" + << patch().name() << "', = " << V_; + } + else + { + FatalErrorInFunction + << "Patch '" << patch().name() + << "' corresponding to a thermal mass is not closed." << nl + << "Please specify the volume with the optional 'volume' entry." + << exit(FatalError); + } + } + + fvPatchScalarField::operator=(T_.value()); +} + + +Foam::lumpedMassTemperatureFvPatchScalarField:: +lumpedMassTemperatureFvPatchScalarField +( + const lumpedMassTemperatureFvPatchScalarField& ptf, + const fvPatch& p, + const DimensionedField& iF, + const fieldMapper& mapper +) +: + fixedValueFvPatchScalarField(ptf, p, iF, mapper), + rho_(ptf.rho_), + Cv_(ptf.Cv_), + T_(ptf.T_), + Q_(ptf.Q_), + V_(ptf.V_) +{} + + +Foam::lumpedMassTemperatureFvPatchScalarField:: +lumpedMassTemperatureFvPatchScalarField +( + const lumpedMassTemperatureFvPatchScalarField& ptf, + const DimensionedField& iF +) +: + fixedValueFvPatchScalarField(ptf, iF), + rho_(ptf.rho_), + Cv_(ptf.Cv_), + T_(ptf.T_), + Q_(ptf.Q_), + V_(ptf.V_) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::lumpedMassTemperatureFvPatchScalarField::map +( + const fvPatchScalarField& ptf, + const fieldMapper& mapper +) +{ + fixedValueFvPatchScalarField::map(ptf, mapper); +} + + +void Foam::lumpedMassTemperatureFvPatchScalarField::reset +( + const fvPatchScalarField& ptf +) +{ + fixedValueFvPatchScalarField::reset(ptf); +} + + +void Foam::lumpedMassTemperatureFvPatchScalarField::updateCoeffs() +{ + if + ( + updated() + ) + { + return; + } + + const thermophysicalTransportModel& ttm = + db().lookupType + ( + internalField().group() + ); + + const label patchi = patch().index(); + const scalarField Hf + ( + ttm.kappaEff(patchi)*patch().magSf()*patch().deltaCoeffs() + ); + const scalar Hs = rho_*Cv_*V_/db().time().deltaTValue(); + + const scalar t = db().time().userTimeValue(); + + T_.value() = + ( + Q_->value(t) + gSum(Hf*patchInternalField()) + + Hs*T_.oldTime().value() + )/(Hs + gSum(Hf)); + + operator==(T_.value()); + + fixedValueFvPatchScalarField::updateCoeffs(); +} + + +void Foam::lumpedMassTemperatureFvPatchScalarField::write +( + Ostream& os +) const +{ + fvPatchScalarField::write(os); + writeEntry(os, "rho", rho_); + writeEntry(os, "Cv", Cv_); + writeEntry(os, "T", T_.value()); + writeEntry(os, Q_()); + writeEntry(os, "volume", V_); + writeEntry(os, "value", *this); +} + + +// * * * * * * * * * * * * * * Build Macro Function * * * * * * * * * * * * // + +namespace Foam +{ + makePatchTypeField + ( + fvPatchScalarField, + lumpedMassTemperatureFvPatchScalarField + ); +} + +// ************************************************************************* // diff --git a/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/lumpedMassTemperature/lumpedMassTemperatureFvPatchScalarField.H b/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/lumpedMassTemperature/lumpedMassTemperatureFvPatchScalarField.H new file mode 100644 index 0000000000..df4c1ce840 --- /dev/null +++ b/src/ThermophysicalTransportModels/coupledThermophysicalTransportModels/lumpedMassTemperature/lumpedMassTemperatureFvPatchScalarField.H @@ -0,0 +1,213 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2024 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 . + +Class + Foam::lumpedMassTemperatureFvPatchScalarField + +Description + This boundary condition is applied to a patch which bounds a solid body, + wholly or partially. It represents the body as a lumped mass, i.e. by a + single temperature \c T which is fixed across the patch. The body has a + volume \c V which is either specified by the user, or is calculated when + the patch describes a closed volume (including in 2D meshes). Starting from + an initial, specified \c T, the change in temperature is calculated over + time according to an applied power source \c Q and the heat transferred + across the boundary \Q_{b} (positive into the lumped mass): + + \f[ + dT/dt = frac{Q + Q_{b}}{\rho C_{v} V} + \f] + + where + \vartable + Q | specified power source [W] + Q_{b} | total calculated heat transferred across the boundary [W] + \rho | density [kg/m^3] + C_{v} | specific heat capacity [J/(kg K)] + V | volume of the lumped mass [m^3} + \endtable + +Usage + \table + Property | Description | Req'd? | Default + rho | density | yes | + Cv | specific heat capacity | yes | + T | temperature | yes | + Q | power source | no | 0 + volume | volume of the lumped mass | no | calculated + \endtable + + Example of the boundary condition specification: + \verbatim + + { + type lumpedMassTemperature; + rho 1000; + Cv 1300; + T 500; + Q constant 0.5; + value uniform $T; // placeholder + } + \endverbatim + +SourceFiles + lumpedMassTemperatureFvPatchScalarField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef BC_H +#define BC_H + +#include "fixedValueFvPatchFields.H" +#include "UniformDimensionedField.H" +#include "Function1.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class lumpedMassTemperatureFvPatchScalarField Declaration +\*---------------------------------------------------------------------------*/ + +class lumpedMassTemperatureFvPatchScalarField +: + public fixedValueFvPatchScalarField +{ + // Private Data + + //- Density + const scalar rho_; + + //- Specific heat capacity + const scalar Cv_; + + //- Temperature of the thermal mass + UniformDimensionedField T_; + + //- Heat source (optional) + autoPtr> Q_; + + //- Volume of the lumped mass, defaults when enclosed by the patch + scalar V_; + + + // Private Member Functions + + //- Does the patch form a closed volume, including in a 2D case? + bool closed() const; + + //- Return volume formed by the enclosed patch + scalar V() const; + + +public: + + //- Runtime type information + TypeName("lumpedMassTemperature"); + + + // Constructors + + //- Construct from patch, internal field and dictionary + lumpedMassTemperatureFvPatchScalarField + ( + const fvPatch&, + const DimensionedField&, + const dictionary& + ); + + //- Construct by mapping given fixedValueTypeFvPatchField + // onto a new patch + lumpedMassTemperatureFvPatchScalarField + ( + const lumpedMassTemperatureFvPatchScalarField&, + const fvPatch&, + const DimensionedField&, + const fieldMapper& + ); + + //- Disallow copy without setting internal field reference + lumpedMassTemperatureFvPatchScalarField + ( + const lumpedMassTemperatureFvPatchScalarField& + ) = delete; + + //- Copy constructor setting internal field reference + lumpedMassTemperatureFvPatchScalarField + ( + const lumpedMassTemperatureFvPatchScalarField&, + const DimensionedField& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp clone + ( + const DimensionedField& iF + ) const + { + return tmp + ( + new lumpedMassTemperatureFvPatchScalarField + ( + *this, + iF + ) + ); + } + + + // Member Functions + + // Mapping functions + + //- Map the given fvPatchField onto this fvPatchField + virtual void map(const fvPatchScalarField&, const fieldMapper&); + + //- Reset the fvPatchField to the given fvPatchField + // Used for mesh to mesh mapping + virtual void reset(const fvPatchScalarField&); + + + // Evaluation functions + + //- Update the coefficients associated with the patch field + virtual void updateCoeffs(); + + + //- Write + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +#endif + +// ************************************************************************* //