/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2022 OpenCFD Ltd. ------------------------------------------------------------------------------- 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 "referenceTemperature.H" #include "fvMesh.H" #include "basicThermo.H" #include "surfaceInterpolate.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { namespace heatExchangerModels { defineTypeNameAndDebug(referenceTemperature, 0); addToRunTimeSelectionTable ( heatExchangerModel, referenceTemperature, dictionary ); } } // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // Foam::scalar Foam::heatExchangerModels::referenceTemperature::primaryNetMassFlux() const { const auto& phi = mesh_.lookupObject(phiName_); scalar sumPhi = 0; forAll(faceId_, i) { const label facei = faceId_[i]; if (facePatchId_[i] != -1) { const label patchi = facePatchId_[i]; sumPhi += phi.boundaryField()[patchi][facei]*faceSign_[i]; } else { sumPhi += phi[facei]*faceSign_[i]; } } reduce(sumPhi, sumOp()); return sumPhi; } Foam::scalar Foam::heatExchangerModels::referenceTemperature::primaryInletTemperature() const { const auto& phi = mesh_.lookupObject(phiName_); const auto& T = mesh_.lookupObject(TName_); const surfaceScalarField Tf(fvc::interpolate(T)); scalar sumMagPhi = 0; scalar primaryInletTfMean = 0; forAll(faceId_, i) { const label facei = faceId_[i]; if (facePatchId_[i] != -1) { const label patchi = facePatchId_[i]; const scalar phii = phi.boundaryField()[patchi][facei]*faceSign_[i]; const scalar magPhii = mag(phii); sumMagPhi += magPhii; const scalar Tfi = Tf.boundaryField()[patchi][facei]; primaryInletTfMean += Tfi*magPhii; } else { const scalar phii = phi[facei]*faceSign_[i]; const scalar magPhii = mag(phii); sumMagPhi += magPhii; primaryInletTfMean += Tf[facei]*magPhii; } } reduce(sumMagPhi, sumOp()); reduce(primaryInletTfMean, sumOp()); return primaryInletTfMean/(sumMagPhi + ROOTVSMALL); } Foam::scalarField Foam::heatExchangerModels::referenceTemperature::temperatureDifferences ( const labelList& cells ) const { const auto& T = mesh_.lookupObject(TName_); const scalarField TCells(T, cells); scalarField deltaTCells(cells.size(), Zero); if (Qt_ > 0) { forAll(deltaTCells, i) { deltaTCells[i] = max(Tref_ - TCells[i], scalar(0)); } } else { forAll(deltaTCells, i) { deltaTCells[i] = max(TCells[i] - Tref_, scalar(0)); } } return deltaTCells; } Foam::scalar Foam::heatExchangerModels::referenceTemperature::weight ( const labelList& cells, const scalarField& deltaTCells ) const { scalar sumWeight = 0; const auto& U = mesh_.lookupObject(UName_); const scalarField& V = mesh_.V(); forAll(cells, i) { const label celli = cells[i]; sumWeight += V[celli]*mag(U[celli])*deltaTCells[i]; } reduce(sumWeight, sumOp()); return sumWeight; } void Foam::heatExchangerModels::referenceTemperature::writeFileHeader ( Ostream& os ) const { writeFile::writeHeader(os, "Effectiveness heat exchanger source"); writeFile::writeCommented(os, "Time"); writeFile::writeTabbed(os, "Net mass flux [kg/s]"); writeFile::writeTabbed(os, "Total heat exchange [W]"); writeFile::writeTabbed(os, "Reference T [K]"); os << endl; } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::heatExchangerModels::referenceTemperature::referenceTemperature ( const fvMesh& mesh, const word& name, const dictionary& coeffs ) : heatExchangerModel(mesh, name, coeffs), targetQdotPtr_ ( Function1::New ( "targetQdot", coeffs, &mesh_ ) ), TrefTablePtr_(nullptr), sumPhi_(0), Qt_(0), Tref_(0) { writeFileHeader(file()); } // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // void Foam::heatExchangerModels::referenceTemperature::initialise() { heatExchangerModel::initialise(); } Foam::tmp Foam::heatExchangerModels::referenceTemperature::energyDensity ( const labelList& cells ) { sumPhi_ = primaryNetMassFlux(); Qt_ = targetQdotPtr_->value(mesh_.time().value()); if (TrefTablePtr_) { const scalar primaryInletT = primaryInletTemperature(); Tref_ = TrefTablePtr_()(mag(sumPhi_), primaryInletT); } const scalarField deltaTCells(temperatureDifferences(cells)); const scalar sumWeight = weight(cells, deltaTCells); return Qt_*deltaTCells/(sumWeight + ROOTVSMALL); } bool Foam::heatExchangerModels::referenceTemperature::read ( const dictionary& dict ) { if (!writeFile::read(dict)) { return false; } Info<< incrIndent << indent << "- using model: " << type() << endl; if (coeffs_.readIfPresent("Tref", Tref_)) { Info<< indent << "- using constant reference temperature: " << Tref_ << endl; } else { TrefTablePtr_.reset(new interpolation2DTable(coeffs_)); Info<< indent << "- using reference temperature table" << endl; } UName_ = coeffs_.getOrDefault("U", "U"); TName_ = coeffs_.getOrDefault("T", "T"); phiName_ = coeffs_.getOrDefault("phi", "phi"); coeffs_.readEntry("faceZone", faceZoneName_); Info<< decrIndent; return true; } void Foam::heatExchangerModels::referenceTemperature::write(const bool log) { if (log) { Info<< nl << type() << ": " << name_ << nl << incrIndent << indent << "Net mass flux [kg/s] : " << sumPhi_ << nl << indent << "Total heat exchange [W] : " << Qt_ << nl << indent << "Reference T [K] : " << Tref_ << decrIndent; } if (Pstream::master()) { Ostream& os = file(); writeCurrentTime(os); os << tab << sumPhi_ << tab << Qt_ << tab << Tref_ << endl; } if (log) Info<< nl << endl; } // ************************************************************************* //