From 2ec3a3efe74ecebf53511231315e90cebd232da4 Mon Sep 17 00:00:00 2001 From: Thomas Lichtenegger Date: Fri, 21 Aug 2015 12:49:30 +0200 Subject: [PATCH] Included heat transfer between particles and fluid, thermal conductivity of fluid; --- .../solvers/cfdemSolverRhoPimple/EEqn.H | 16 +- .../cfdemSolverRhoPimple.C | 5 +- .../cfdemSolverRhoPimple/createFields.H | 14 + src/lagrangian/cfdemParticle/Make/files | 1 + .../LaEuScalarEnergy/LaEuScalarEnergy.C | 264 ++++++++++++++++++ .../LaEuScalarEnergy/LaEuScalarEnergy.H | 134 +++++++++ src/lagrangian/cfdemParticleComp/Make/files | 1 + 7 files changed, 430 insertions(+), 5 deletions(-) create mode 100644 src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarEnergy/LaEuScalarEnergy.C create mode 100644 src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarEnergy/LaEuScalarEnergy.H diff --git a/applications/solvers/cfdemSolverRhoPimple/EEqn.H b/applications/solvers/cfdemSolverRhoPimple/EEqn.H index 71cf5f7d..b31d32e5 100644 --- a/applications/solvers/cfdemSolverRhoPimple/EEqn.H +++ b/applications/solvers/cfdemSolverRhoPimple/EEqn.H @@ -2,6 +2,11 @@ // Crowe et al.: "Multiphase flows with droplets and particles", CRC Press 1998 { volScalarField& he = thermo.he(); + volScalarField& T = thermo.T(); + volScalarField keff = voidfraction*turbulence->kappaEff() + + (1-voidfraction)*particleCloud.forceM(1).thermCondPart(); + particleCloud.forceM(1).partFluidHeatTrans(Qsource); + Qsource.correctBoundaryConditions(); fvScalarMatrix EEqn ( @@ -17,10 +22,15 @@ ) : -dpdt ) - // + particle-fluid energy transfer (work + heat) - - fvm::laplacian(voidfraction*turbulence->alphaEff(), he) + // + particle-fluid energy transfer due to work: + //- fvc::div(fvc::interpolate(Us),(1-voidfraction)*p) + + // + fluid energy dissipation due to shearing + // net heat transfer from particles to fluid + - Qsource + // thermal conduction of the fluid with effective conductivity + - fvc::laplacian(keff, T) == - fvOptions(rho, he) + fvOptions(rho, he, T) ); EEqn.relax(); diff --git a/applications/solvers/cfdemSolverRhoPimple/cfdemSolverRhoPimple.C b/applications/solvers/cfdemSolverRhoPimple/cfdemSolverRhoPimple.C index 01188b0c..0cfafb3e 100644 --- a/applications/solvers/cfdemSolverRhoPimple/cfdemSolverRhoPimple.C +++ b/applications/solvers/cfdemSolverRhoPimple/cfdemSolverRhoPimple.C @@ -46,7 +46,8 @@ Description #include "implicitCouple.H" #include "clockModel.H" #include "smoothingModel.H" -#include "forceModel.H" +// #include "forceModel.H" +#include "LaEuScalarEnergy.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -113,7 +114,7 @@ int main(int argc, char *argv[]) { #include "rhoEqn.H" } - volScalarField rhoeps("rhoeps",rho*voidfraction); + volScalarField rhoeps("rhoeps",rho*voidfraction); // --- Pressure-velocity PIMPLE corrector loop while (pimple.loop()) { diff --git a/applications/solvers/cfdemSolverRhoPimple/createFields.H b/applications/solvers/cfdemSolverRhoPimple/createFields.H index 02e2960f..0244af93 100644 --- a/applications/solvers/cfdemSolverRhoPimple/createFields.H +++ b/applications/solvers/cfdemSolverRhoPimple/createFields.H @@ -51,6 +51,20 @@ mesh ); + Info<< "\nCreating fluid-particle heat flux field\n" << endl; + volScalarField Qsource + ( + IOobject + ( + "Qsource", + runTime.timeName(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh + ); + #ifndef compressibleCreatePhi_H #define compressibleCreatePhi_H Info<< "Reading/calculating face flux field phi\n" << endl; diff --git a/src/lagrangian/cfdemParticle/Make/files b/src/lagrangian/cfdemParticle/Make/files index 1ff832db..d7c96660 100644 --- a/src/lagrangian/cfdemParticle/Make/files +++ b/src/lagrangian/cfdemParticle/Make/files @@ -39,6 +39,7 @@ $(forceModels)/ShirgaonkarIB/ShirgaonkarIB.C $(forceModels)/KochHillDrag/KochHillDrag.C $(forceModels)/KochHillRWDrag/KochHillRWDrag.C $(forceModels)/LaEuScalarTemp/LaEuScalarTemp.C +$(forceModels)/LaEuScalarEnergy/LaEuScalarEnergy.C $(forceModels)/virtualMassForce/virtualMassForce.C $(forceModels)/gradPForce/gradPForce.C $(forceModels)/viscForce/viscForce.C diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarEnergy/LaEuScalarEnergy.C b/src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarEnergy/LaEuScalarEnergy.C new file mode 100644 index 00000000..9da0824f --- /dev/null +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarEnergy/LaEuScalarEnergy.C @@ -0,0 +1,264 @@ +/*---------------------------------------------------------------------------*\ + CFDEMcoupling - Open Source CFD-DEM coupling + + CFDEMcoupling is part of the CFDEMproject + Thomas Lichtenegger, thomas.lichtenegger@jku.at + Copyright 2009-2012 JKU Linz + Copyright 2012-2015 DCS Computing GmbH, Linz + Copyright 2015- JKU Linz +------------------------------------------------------------------------------- +License + This file is part of CFDEMcoupling. + + CFDEMcoupling 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. + + CFDEMcoupling 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 CFDEMcoupling; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Description + This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS + and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). +\*---------------------------------------------------------------------------*/ + +#include "error.H" + +#include "LaEuScalarEnergy.H" +#include "addToRunTimeSelectionTable.H" +#include "dataExchangeModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(LaEuScalarEnergy, 0); + +addToRunTimeSelectionTable +( + forceModel, + LaEuScalarEnergy, + dictionary +); + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +// Construct from components +LaEuScalarEnergy::LaEuScalarEnergy +( + const dictionary& dict, + cfdemCloud& sm +) +: + forceModel(dict,sm), + propsDict_(dict.subDict(typeName + "Props")), + tempFieldName_(propsDict_.lookup("tempFieldName")), + tempField_(sm.mesh().lookupObject (tempFieldName_)), + voidfractionFieldName_(propsDict_.lookup("voidfractionFieldName")), + voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), + maxSource_(1e30), + velFieldName_(propsDict_.lookup("velFieldName")), + U_(sm.mesh().lookupObject (velFieldName_)), + partTempName_(propsDict_.lookup("partTempName")), + partTemp_(NULL), + partHeatFluxName_(propsDict_.lookup("partHeatFluxName")), + partHeatFlux_(NULL), + lambda_(readScalar(propsDict_.lookup("lambda"))), + lambdaPart_(readScalar(propsDict_.lookup("lambdaPart"))), + Cp_(readScalar(propsDict_.lookup("Cp"))) +{ + allocateMyArrays(); + + if (propsDict_.found("maxSource")) + { + maxSource_=readScalar(propsDict_.lookup ("maxSource")); + Info << "limiting eulerian source field to: " << maxSource_ << endl; + } + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(3,true); // activate search for verbose switch + forceSubM(0).setSwitchesList(4,true); // activate search for interpolate switch + forceSubM(0).setSwitchesList(8,true); // activate scalarViscosity switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + + + particleCloud_.checkCG(false); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +LaEuScalarEnergy::~LaEuScalarEnergy() +{ + delete partTemp_; + delete partHeatFlux_; +} + +// * * * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * * // +void LaEuScalarEnergy::allocateMyArrays() const +{ + // get memory for 2d arrays + double initVal=0.0; + particleCloud_.dataExchangeM().allocateArray(partTemp_,initVal,1); // field/initVal/with/lenghtFromLigghts + particleCloud_.dataExchangeM().allocateArray(partHeatFlux_,initVal,1); +} +// * * * * * * * * * * * * * * * public Member Functions * * * * * * * * * * * * * // + +void LaEuScalarEnergy::setForce() const +{ + // do nothing +} + +void LaEuScalarEnergy::partFluidHeatTrans(volScalarField& EuField) const +{ + // realloc the arrays + allocateMyArrays(); + + // reset Scalar field + EuField.internalField() = 0.0; + + // get DEM data + particleCloud_.dataExchangeM().getData(partTempName_,"scalar-atom",partTemp_); + + const volScalarField& nufField = forceSubM(0).nuField(); + const volScalarField& rhoField = forceSubM(0).rhoField(); + + // calc La based heat flux + scalar voidfraction(1); + vector Ufluid(0,0,0); + scalar Tfluid(0); + label cellI=0; + vector Us(0,0,0); + scalar ds(0); + scalar nuf(0); + scalar magUr(0); + scalar Rep(0); + scalar Pr(0); + scalar Nup(0); + const scalar n = 3.5; // model parameter (found suitable for 3-mm polymer pellets when modelling dilute flows) + + interpolationCellPoint voidfractionInterpolator_(voidfraction_); + interpolationCellPoint UInterpolator_(U_); + interpolationCellPoint TInterpolator_(tempField_); + + for(int index = 0;index < particleCloud_.numberOfParticles(); ++index) + { + //if(particleCloud_.regionM().inRegion()[index][0]) + //{ + cellI = particleCloud_.cellIDs()[index][0]; + if(cellI >= 0) + { + if(forceSubM(0).interpolation()) + { + vector position = particleCloud_.position(index); + voidfraction = voidfractionInterpolator_.interpolate(position,cellI); + Ufluid = UInterpolator_.interpolate(position,cellI); + Tfluid = TInterpolator_.interpolate(position,cellI); + } + else + { + voidfraction = voidfraction_[cellI]; + Ufluid = U_[cellI]; + Tfluid = tempField_[cellI]; + } + + // calc relative velocity + Us = particleCloud_.velocity(index); + magUr = mag(Ufluid - Us); + ds = 2.*particleCloud_.radius(index); + nuf = nufField[cellI]; + Rep = ds * magUr / nuf; + Pr = max(SMALL, Cp_ * nuf * rhoField[cellI] / lambda_); + + if (Rep < 200.) + { + Nup = 2. + 0.6 * pow(voidfraction,n) * sqrt(Rep) * pow(Pr,0.33); + } + else if (Rep < 1500.) + { + Nup = 2. + (0.5 * sqrt(Rep) + 0.02 * pow(Rep,0.8)) * pow(voidfraction,n) * pow(Pr,0.33); + } + else + { + Nup = 2. + 0.000045 * pow(voidfraction,n) * pow(Rep,1.8); + } + + scalar h = lambda_ * Nup / ds; + scalar As = ds * ds * M_PI; // surface area of sphere + + // calc convective heat flux [W] + scalar partHeatFlux = h * As * (Tfluid - partTemp_[index][0]); + partHeatFlux_[index][0] = partHeatFlux; + + + if(forceSubM(0).verbose() && index >=0 && index <2) + { + Info << "partHeatFlux = " << partHeatFlux << endl; + Info << "magUr = " << magUr << endl; + Info << "As = " << As << endl; + Info << "nuf = " << nuf << endl; + Info << "Rep = " << Rep << endl; + Info << "Pr = " << Pr << endl; + Info << "Nup = " << Nup << endl; + Info << "voidfraction = " << voidfraction << endl; + Info << "partTemp_[index][0] = " << partTemp_[index][0] << endl; + Info << "Tfluid = " << Tfluid << endl ; + } + } + //} + } + + particleCloud_.averagingM().setScalarSum + ( + EuField, + partHeatFlux_, + particleCloud_.particleWeights(), + NULL + ); + + // scale with -1/(Vcell*rho) + EuField.internalField() /= -EuField.mesh().V(); + + // limit source term + forAll(EuField,cellI) + { + scalar EuFieldInCell = EuField[cellI]; + + if(mag(EuFieldInCell) > maxSource_ ) + { + EuField[cellI] = sign(EuFieldInCell) * maxSource_; + } + } + + // Info << "total convective particle-fluid heat flux [W] (Eulerian) = " << gSum(EuField*EuField.mesh().V()) << endl; + + // give DEM data + particleCloud_.dataExchangeM().giveData(partHeatFluxName_,"scalar-atom", partHeatFlux_); +} + +scalar LaEuScalarEnergy::thermCondPart() const +{ + return lambdaPart_; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarEnergy/LaEuScalarEnergy.H b/src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarEnergy/LaEuScalarEnergy.H new file mode 100644 index 00000000..7c13d8b9 --- /dev/null +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/LaEuScalarEnergy/LaEuScalarEnergy.H @@ -0,0 +1,134 @@ +/*---------------------------------------------------------------------------*\ + CFDEMcoupling - Open Source CFD-DEM coupling + + CFDEMcoupling is part of the CFDEMproject + Thomas Lichtenegger, thomas.lichtenegger@jku.at + Copyright 2009-2012 JKU Linz + Copyright 2012-2015 DCS Computing GmbH, Linz + Copyright 2015- JKU Linz +------------------------------------------------------------------------------- +License + This file is part of CFDEMcoupling. + + CFDEMcoupling 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. + + CFDEMcoupling 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 CFDEMcoupling; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Description + This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS + and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). + + two way LaEu Scalar Exchange between DEM and CFD + convective heat transfer model following + Li and Mason (2000), A computational investigation of transient heat + transfer in pneumatic transport of granular particles, Pow.Tech 112 + +Class + LaEuScalarEnergy + +SourceFiles + LaEuScalarEnergy.C + +\*---------------------------------------------------------------------------*/ + +#ifndef LaEuScalarEnergy_H +#define LaEuScalarEnergy_H + +#include "forceModel.H" +#include "averagingModel.H" +#include "interpolationCellPoint.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class LaEuScalarEnergy Declaration +\*---------------------------------------------------------------------------*/ + +class LaEuScalarEnergy +: + public forceModel +{ +private: + + dictionary propsDict_; + + word tempFieldName_; + + const volScalarField& tempField_; // ref to temperature field + + word voidfractionFieldName_; + + const volScalarField& voidfraction_; // ref to voidfraction field + + scalar maxSource_; // max (limited) value of src field + + word velFieldName_; + + const volVectorField& U_; + + word partTempName_; + + mutable double **partTemp_; // Lagrangian array + + word partHeatFluxName_; + + mutable double **partHeatFlux_; // Lagrangian array + + scalar lambda_; // fluid thermal conductivity [W/(m*K)] + + scalar lambdaPart_; // particle thermal conductivity + + scalar Cp_; // specific heat capacity [W*s/(kg*K)] + + void allocateMyArrays() const; + +public: + + //- Runtime type information + TypeName("LaEuScalarEnergy"); + + // Constructors + + //- Construct from components + LaEuScalarEnergy + ( + const dictionary& dict, + cfdemCloud& sm + ); + + // Destructor + + ~LaEuScalarEnergy(); + + + // Member Functions + void setForce() const; + + void partFluidHeatTrans(volScalarField&) const; + + scalar thermCondPart() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/lagrangian/cfdemParticleComp/Make/files b/src/lagrangian/cfdemParticleComp/Make/files index e58e997c..90607ef0 100644 --- a/src/lagrangian/cfdemParticleComp/Make/files +++ b/src/lagrangian/cfdemParticleComp/Make/files @@ -37,6 +37,7 @@ $(forceModels)/interface/interface.C $(forceModels)/ShirgaonkarIB/ShirgaonkarIB.C $(forceModels)/KochHillDrag/KochHillDrag.C $(forceModels)/LaEuScalarTemp/LaEuScalarTemp.C +$(forceModels)/LaEuScalarEnergy/LaEuScalarEnergy.C $(forceModels)/virtualMassForce/virtualMassForce.C $(forceModels)/gradPForce/gradPForce.C $(forceModels)/viscForce/viscForce.C