Included heat transfer between particles and fluid, thermal conductivity of fluid;

This commit is contained in:
Thomas Lichtenegger
2015-08-21 12:49:30 +02:00
parent 993af3bea9
commit 2ec3a3efe7
7 changed files with 430 additions and 5 deletions

View File

@ -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();

View File

@ -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())
{

View File

@ -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;

View File

@ -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

View File

@ -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<volScalarField> (tempFieldName_)),
voidfractionFieldName_(propsDict_.lookup("voidfractionFieldName")),
voidfraction_(sm.mesh().lookupObject<volScalarField> (voidfractionFieldName_)),
maxSource_(1e30),
velFieldName_(propsDict_.lookup("velFieldName")),
U_(sm.mesh().lookupObject<volVectorField> (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<scalar> voidfractionInterpolator_(voidfraction_);
interpolationCellPoint<vector> UInterpolator_(U_);
interpolationCellPoint<scalar> 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
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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