Merge pull request #146 from ParticulateFlow/release

Release 23.02
This commit is contained in:
Daniel
2023-02-15 12:26:45 +01:00
committed by GitHub
316 changed files with 12811 additions and 22422 deletions

2
.gitignore vendored
View File

@ -8,7 +8,7 @@ log.*
*.swp *.swp
*.swo *.swo
**/linux*Gcc*/ **/linux*cc*/
**/.vscode **/.vscode
lnInclude lnInclude

View File

@ -9,12 +9,12 @@ EXE_INC = \
-I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \ -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \ -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \ -I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \ -I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \ -I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-Wno-deprecated-copy -Wno-deprecated-copy
EXE_LIBS = \ EXE_LIBS = \
@ -27,6 +27,7 @@ EXE_LIBS = \
-ldynamicFvMesh \ -ldynamicFvMesh \
-ldynamicMesh \ -ldynamicMesh \
-lfvOptions \ -lfvOptions \
-lsampling \
-l$(CFDEM_LIB_NAME) \ -l$(CFDEM_LIB_NAME) \
$(CFDEM_ADD_LIB_PATHS) \ $(CFDEM_ADD_LIB_PATHS) \
$(CFDEM_ADD_LIBS) $(CFDEM_ADD_LIBS)

View File

@ -6,7 +6,8 @@
Christoph Goniva, christoph.goniva@cfdem.com Christoph Goniva, christoph.goniva@cfdem.com
Copyright (C) 1991-2009 OpenCFD Ltd. Copyright (C) 1991-2009 OpenCFD Ltd.
Copyright (C) 2009-2012 JKU, Linz Copyright (C) 2009-2012 JKU, Linz
Copyright (C) 2012- DCS Computing GmbH,Linz Copyright (C) 2012-2015 DCS Computing GmbH,Linz
Copyright (C) 2015- JKU, Linz
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of CFDEMcoupling. This file is part of CFDEMcoupling.
@ -34,6 +35,9 @@ Description
(fictitious domain) method is added. (fictitious domain) method is added.
Contributions Contributions
Alice Hager Alice Hager
Daniel Queteschiner
Thomas Lichtenegger
Achuth N. Balachandran Nair
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -53,23 +57,21 @@ Contributions
#include "cellSet.H" #include "cellSet.H"
#include "fvOptions.H" // added the fvOptions library
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
#include "createDynamicFvMesh.H" #include "createDynamicFvMesh.H"
#include "createControl.H" #include "createControl.H"
#include "createTimeControls.H" #include "createTimeControls.H"
#include "createFields.H" #include "createFields.H"
#include "initContinuityErrs.H" #include "initContinuityErrs.H"
#include "createFvOptions.H"
// create cfdemCloud // create cfdemCloud
#include "readGravitationalAcceleration.H" #include "readGravitationalAcceleration.H"
@ -93,24 +95,31 @@ int main(int argc, char *argv[])
// do particle stuff // do particle stuff
Info << "- evolve()" << endl; Info << "- evolve()" << endl;
particleCloud.evolve(); particleCloud.evolve(Us);
// Pressure-velocity PISO corrector // Pressure-velocity PISO corrector
{ {
MRF.correctBoundaryVelocity(U);
// Momentum predictor // Momentum predictor
fvVectorMatrix UEqn fvVectorMatrix UEqn
( (
fvm::ddt(voidfraction,U) fvm::ddt(voidfraction,U) + MRF.DDt(U)
+ fvm::div(phi, U) + fvm::div(phi, U)
+ turbulence->divDevReff(U) + turbulence->divDevReff(U)
==
fvOptions(U)
); );
UEqn.relax(); UEqn.relax();
fvOptions.constrain(UEqn);
if (piso.momentumPredictor()) if (piso.momentumPredictor())
{ {
solve(UEqn == -fvc::grad(p)); solve(UEqn == -fvc::grad(p));
fvOptions.correct(U);
} }
// --- PISO loop // --- PISO loop
@ -126,6 +135,7 @@ int main(int argc, char *argv[])
adjustPhi(phi, U, p); adjustPhi(phi, U, p);
while (piso.correctNonOrthogonal()) while (piso.correctNonOrthogonal())
{ {
// Pressure corrector // Pressure corrector
@ -152,12 +162,15 @@ int main(int argc, char *argv[])
} }
} }
laminarTransport.correct();
turbulence->correct(); turbulence->correct();
Info << "particleCloud.calcVelocityCorrection() " << endl; Info << "particleCloud.calcVelocityCorrection() " << endl;
volScalarField voidfractionNext=mesh.lookupObject<volScalarField>("voidfractionNext"); volScalarField voidfractionNext=mesh.lookupObject<volScalarField>("voidfractionNext");
particleCloud.calcVelocityCorrection(p,U,phiIB,voidfractionNext); particleCloud.calcVelocityCorrection(p,U,phiIB,voidfractionNext);
fvOptions.correct(U);
runTime.write(); runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"

View File

@ -26,21 +26,6 @@
), ),
mesh mesh
); );
//mod by alice
Info<< "Reading physical velocity field U" << endl;
Info<< "Note: only if voidfraction at boundary is 1, U is superficial velocity!!!\n" << endl;
volVectorField Us
(
IOobject
(
"Us",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
//======================== //========================
// drag law modelling // drag law modelling
@ -76,9 +61,8 @@
mesh mesh
); );
//mod by alice //mod by alice
Info<< "Reading field phiIB\n" << endl; Info<< "Reading field voidfraction\n" << endl;
volScalarField voidfraction volScalarField voidfraction
( (
IOobject IOobject
@ -91,6 +75,21 @@
), ),
mesh mesh
); );
Info<< "Reading particle velocity field Us\n" << endl;
volVectorField Us
(
IOobject
(
"Us",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
//======================== //========================
# include "createPhi.H" # include "createPhi.H"
@ -126,3 +125,5 @@
); );
//=========================== //===========================
#include "createMRF.H"

View File

@ -0,0 +1,3 @@
cfdemSolverIBContinuousForcing.C
EXE=$(CFDEM_APP_DIR)/cfdemSolverIBContinuousForcing

View File

@ -0,0 +1,34 @@
include $(CFDEM_ADD_LIBS_DIR)/additionalLibs
EXE_INC = \
-I$(CFDEM_OFVERSION_DIR) \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-Wno-deprecated-copy
EXE_LIBS = \
-L$(CFDEM_LIB_DIR)\
-lturbulenceModels \
-lincompressibleTurbulenceModels \
-lincompressibleTransportModels \
-lfiniteVolume \
-lmeshTools \
-ldynamicFvMesh \
-ldynamicMesh \
-lfvOptions \
-lsampling \
-l$(CFDEM_LIB_NAME) \
$(CFDEM_ADD_LIB_PATHS) \
$(CFDEM_ADD_LIBS)

View File

@ -0,0 +1,19 @@
fvVectorMatrix UEqn
(
fvm::ddt(voidfractionNext,U) + MRF.DDt(U)
+ fvm::div(phi, U)
+ turbulence->divDevReff(U)
==
fvOptions(U)
+ (lambda*(1-voidfractionNext)/U.mesh().time().deltaT())*(fvc::Sp(1,Us)-fvm::Sp(1,U))
);
UEqn.relax();
fvOptions.constrain(UEqn);
if (piso.momentumPredictor())
{
solve(UEqn == -fvc::grad(p));
fvOptions.correct(U);
}

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
CFDEMcoupling - Open Source CFD-DEM coupling
CFDEMcoupling is part of the CFDEMproject
www.cfdem.com
Copyright (C) 1991-2009 OpenCFD Ltd.
Copyright (C) 2009-2012 JKU, Linz
Copyright (C) 2012-2015 DCS Computing GmbH,Linz
Copyright (C) 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, see <http://www.gnu.org/licenses/>.
Application
cfdemSolverIBContinuousForcing
Description
Transient solver for incompressible flow.
The code is an evolution of the solver pisoFoam in OpenFOAM(R) 1.6,
where additional functionality for CFD-DEM coupling using immersed body
(fictitious domain) method and a continuous forcing approach is added.
Contributions
Alice Hager
Achuth N. Balachandran Nair
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "singlePhaseTransportModel.H"
#include "turbulentTransportModel.H"
#include "pisoControl.H"
#include "cfdemCloudIB.H"
#include "implicitCouple.H"
#include "averagingModel.H"
#include "regionModel.H"
#include "voidFractionModel.H"
#include "dynamicFvMesh.H"
#include "cellSet.H"
#include "fvOptions.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createDynamicFvMesh.H"
#include "createControl.H"
#include "createTimeControls.H"
#include "createFields.H"
#include "initContinuityErrs.H"
#include "createFvOptions.H"
// create cfdemCloud
#include "readGravitationalAcceleration.H"
cfdemCloudIB particleCloud(mesh);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
//=== dyM ===================
interFace = mag(mesh.lookupObject<volScalarField>("voidfractionNext"));
mesh.update(); //dyM
#include "readTimeControls.H"
#include "CourantNo.H"
#include "setDeltaT.H"
// do particle stuff
Info << "- evolve()" << endl;
particleCloud.evolve(Us);
volScalarField voidfractionNext=mesh.lookupObject<volScalarField>("voidfractionNext");
// Pressure-velocity PISO corrector
{
MRF.correctBoundaryVelocity(U);
// Momentum predictor
#include "UEqn.H"
// --- PISO loop
while (piso.correct())
{
#include "pEqn.H"
}
}
laminarTransport.correct();
turbulence->correct();
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,143 @@
Info<< "Reading field p\n" << endl;
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading physical velocity field U" << endl;
Info<< "Note: only if voidfraction at boundary is 1, U is superficial velocity!!!\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading particle velocity field Us\n" << endl;
volVectorField Us
(
IOobject
(
"Us",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading the penalization factor field lambda\n" << endl;
volScalarField lambda
(
IOobject
(
"lambda",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
//========================
// drag law modelling
//========================
Info<< "\nCreating dummy density field rho = 1\n" << endl;
volScalarField rho
(
IOobject
(
"rho",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("0", dimensionSet(1, -3, 0, 0, 0), 1.0)
);
Info<< "Reading field phiIB\n" << endl;
volScalarField phiIB
(
IOobject
(
"phiIB",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
//mod by alice
Info<< "Reading field voidfraction\n" << endl;
volScalarField voidfraction
(
IOobject
(
"voidfraction",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
//========================
# include "createPhi.H"
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue);
singlePhaseTransportModel laminarTransport(U, phi);
autoPtr<incompressible::turbulenceModel> turbulence
(
incompressible::turbulenceModel::New(U, phi, laminarTransport)
);
//=== dyM ===================
Info<< "Reading field interFace\n" << endl;
volScalarField interFace
(
IOobject
(
"interFace",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
//dimensionedScalar("0", dimensionSet(0, -1, 0, 0, 0), 0.0)
dimensionedScalar("0", dimensionSet(0, 0, 0, 0, 0), 0.0)
);
//===========================
#include "createMRF.H"

View File

@ -0,0 +1,35 @@
volScalarField rUA = 1.0/UEqn.A();
surfaceScalarField rUAf(fvc::interpolate(rUA));
U = rUA*UEqn.H();
phi = (fvc::interpolate(U) & mesh.Sf())
+ rUAf*fvc::ddtCorr(U, phi); // Is there additional flux term due to the particle presence?
MRF.makeRelative(phi);
adjustPhi(phi, U, p);
while (piso.correctNonOrthogonal())
{
// Pressure corrector
fvScalarMatrix pEqn
(
fvm::laplacian(rUA, p) == fvc::div(phi) + particleCloud.ddtVoidfraction()
);
pEqn.setReference(pRefCell, pRefValue);
pEqn.solve(mesh.solver(p.select(piso.finalInnerIter())));
if (piso.finalNonOrthogonalIter())
{
phi -= pEqn.flux();
}
}
#include "continuityErrs.H"
U -= rUA*fvc::grad(p); // should we add a pressure correction?
U.correctBoundaryConditions();
fvOptions.correct(U);

View File

@ -2,7 +2,7 @@
cd ${0%/*} || exit 1 # Run from this directory cd ${0%/*} || exit 1 # Run from this directory
set -x set -x
wclean libso multiphaseMixture wclean libso multiphaseMixtureScalar
wclean wclean
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------

View File

@ -6,7 +6,7 @@ targetType=libso
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments . $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
set -x set -x
wmake $targetType multiphaseMixture wmake $targetType multiphaseMixtureScalar
wmake wmake
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------

View File

@ -6,7 +6,7 @@ include $(CFDEM_ADD_LIBS_DIR)/additionalLibs
EXE_INC = \ EXE_INC = \
$(PFLAGS) \ $(PFLAGS) \
-I$(CFDEM_OFVERSION_DIR) \ -I$(CFDEM_OFVERSION_DIR) \
-ImultiphaseMixture/lnInclude \ -ImultiphaseMixtureScalar/lnInclude \
-I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/lnInclude \ -I$(LIB_SRC)/transportModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \ -I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \

View File

@ -30,7 +30,7 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fvCFD.H" #include "fvCFD.H"
#include "multiphaseMixture.H" #include "multiphaseMixtureScalar.H"
#include "turbulentTransportModel.H" #include "turbulentTransportModel.H"
#include "pimpleControl.H" #include "pimpleControl.H"
#include "fvOptions.H" #include "fvOptions.H"

View File

@ -88,7 +88,7 @@ surfaceScalarField phi
linearInterpolate(U*voidfraction) & mesh.Sf() linearInterpolate(U*voidfraction) & mesh.Sf()
); );
multiphaseMixture mixture(U, phi, voidfraction); multiphaseMixtureScalar mixture(U, phi, voidfraction);
// Need to store rho for ddt(rho, U) // Need to store rho for ddt(rho, U)
volScalarField rho volScalarField rho

View File

@ -1,5 +1,5 @@
phase/phase.C phase/phase.C
alphaContactAngle/alphaContactAngleFvPatchScalarField.C alphaContactAngle/alphaContactAngleFvPatchScalarField.C
multiphaseMixture.C multiphaseMixtureScalar.C
LIB = $(CFDEM_LIB_DIR)/libcfdemMultiphaseInterFoamScalar LIB = $(CFDEM_LIB_DIR)/libcfdemMultiphaseInterFoamScalar

View File

@ -26,7 +26,7 @@ Class
Description Description
Contact-angle boundary condition for multi-phase interface-capturing Contact-angle boundary condition for multi-phase interface-capturing
simulations. Used in conjuction with multiphaseMixture. simulations. Used in conjuction with multiphaseMixtureScalar.
SourceFiles SourceFiles
alphaContactAngleFvPatchScalarField.C alphaContactAngleFvPatchScalarField.C
@ -37,7 +37,7 @@ SourceFiles
#define alphaContactAngleFvPatchScalarField_H #define alphaContactAngleFvPatchScalarField_H
#include "zeroGradientFvPatchFields.H" #include "zeroGradientFvPatchFields.H"
#include "multiphaseMixture.H" #include "multiphaseMixtureScalar.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -117,8 +117,8 @@ public:
typedef HashTable typedef HashTable
< <
interfaceThetaProps, interfaceThetaProps,
multiphaseMixture::interfacePair, multiphaseMixtureScalar::interfacePair,
multiphaseMixture::interfacePair::hash multiphaseMixtureScalar::interfacePair::hash
> thetaPropsTable; > thetaPropsTable;

View File

@ -18,7 +18,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "multiphaseMixture.H" #include "multiphaseMixtureScalar.H"
#include "alphaContactAngleFvPatchScalarField.H" #include "alphaContactAngleFvPatchScalarField.H"
#include "Time.H" #include "Time.H"
#include "subCycle.H" #include "subCycle.H"
@ -31,13 +31,13 @@ License
// * * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * //
const Foam::scalar Foam::multiphaseMixture::convertToRad = const Foam::scalar Foam::multiphaseMixtureScalar::convertToRad =
Foam::constant::mathematical::pi/180.0; Foam::constant::mathematical::pi/180.0;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::multiphaseMixture::calcAlphas() void Foam::multiphaseMixtureScalar::calcAlphas()
{ {
scalar level = 0.0; scalar level = 0.0;
alphas_ == 0.0; alphas_ == 0.0;
@ -51,7 +51,7 @@ void Foam::multiphaseMixture::calcAlphas()
Foam::tmp<Foam::volScalarField> Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::calcNu() const Foam::multiphaseMixtureScalar::calcNu() const
{ {
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -74,7 +74,7 @@ Foam::multiphaseMixture::calcNu() const
} }
Foam::tmp<Foam::surfaceScalarField> Foam::tmp<Foam::surfaceScalarField>
Foam::multiphaseMixture::calcStf() const Foam::multiphaseMixtureScalar::calcStf() const
{ {
tmp<surfaceScalarField> tstf tmp<surfaceScalarField> tstf
( (
@ -134,7 +134,7 @@ Foam::multiphaseMixture::calcStf() const
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::multiphaseMixture::multiphaseMixture Foam::multiphaseMixtureScalar::multiphaseMixtureScalar
( (
const volVectorField& U, const volVectorField& U,
const surfaceScalarField& phi, const surfaceScalarField& phi,
@ -230,7 +230,7 @@ Foam::multiphaseMixture::multiphaseMixture
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::rho() const Foam::multiphaseMixtureScalar::rho() const
{ {
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -247,7 +247,7 @@ Foam::multiphaseMixture::rho() const
Foam::tmp<Foam::scalarField> Foam::tmp<Foam::scalarField>
Foam::multiphaseMixture::rho(const label patchi) const Foam::multiphaseMixtureScalar::rho(const label patchi) const
{ {
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -264,9 +264,9 @@ Foam::multiphaseMixture::rho(const label patchi) const
Foam::tmp<Foam::volScalarField> Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::mu() const Foam::multiphaseMixtureScalar::mu() const
{ {
Info << "In multiphasemixture mu()" << endl; Info << "In multiphaseMixtureScalar mu()" << endl;
return rho()*nu(); return rho()*nu();
// PtrDictionary<phase>::const_iterator iter = phases_.begin(); // PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -283,7 +283,7 @@ Foam::multiphaseMixture::mu() const
Foam::tmp<Foam::scalarField> Foam::tmp<Foam::scalarField>
Foam::multiphaseMixture::mu(const label patchi) const Foam::multiphaseMixtureScalar::mu(const label patchi) const
{ {
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -306,7 +306,7 @@ Foam::multiphaseMixture::mu(const label patchi) const
Foam::tmp<Foam::surfaceScalarField> Foam::tmp<Foam::surfaceScalarField>
Foam::multiphaseMixture::muf() const Foam::multiphaseMixtureScalar::muf() const
{ {
return nuf()*fvc::interpolate(rho()); return nuf()*fvc::interpolate(rho());
@ -327,13 +327,13 @@ Foam::multiphaseMixture::muf() const
Foam::tmp<Foam::volScalarField> Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::nu() const Foam::multiphaseMixtureScalar::nu() const
{ {
return nu_; return nu_;
} }
Foam::tmp<Foam::scalarField> Foam::tmp<Foam::scalarField>
Foam::multiphaseMixture::nu(const label patchi) const Foam::multiphaseMixtureScalar::nu(const label patchi) const
{ {
//return nu_.boundaryField()[patchi]; //return nu_.boundaryField()[patchi];
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -355,7 +355,7 @@ Foam::multiphaseMixture::nu(const label patchi) const
Foam::tmp<Foam::surfaceScalarField> Foam::tmp<Foam::surfaceScalarField>
Foam::multiphaseMixture::nuf() const Foam::multiphaseMixtureScalar::nuf() const
{ {
//return muf()/fvc::interpolate(rho()); //return muf()/fvc::interpolate(rho());
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -374,7 +374,7 @@ Foam::multiphaseMixture::nuf() const
} }
Foam::tmp<Foam::volScalarField> Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::Cp() const Foam::multiphaseMixtureScalar::Cp() const
{ {
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -395,7 +395,7 @@ Foam::multiphaseMixture::Cp() const
} }
Foam::tmp<Foam::volScalarField> Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::kf() const Foam::multiphaseMixtureScalar::kf() const
{ {
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -417,7 +417,7 @@ Foam::multiphaseMixture::kf() const
} }
Foam::tmp<Foam::volScalarField> Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::D() const Foam::multiphaseMixtureScalar::D() const
{ {
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -439,7 +439,7 @@ Foam::multiphaseMixture::D() const
} }
Foam::tmp<Foam::volScalarField> Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::Cs() const Foam::multiphaseMixtureScalar::Cs() const
{ {
PtrDictionary<phase>::const_iterator iter = phases_.begin(); PtrDictionary<phase>::const_iterator iter = phases_.begin();
@ -456,7 +456,7 @@ Foam::multiphaseMixture::Cs() const
} }
Foam::tmp<Foam::surfaceScalarField> Foam::tmp<Foam::surfaceScalarField>
Foam::multiphaseMixture::diffusionCorrection() const Foam::multiphaseMixtureScalar::diffusionCorrection() const
{ {
surfaceScalarField numerator surfaceScalarField numerator
@ -517,7 +517,7 @@ Foam::multiphaseMixture::diffusionCorrection() const
return correction; return correction;
} }
void Foam::multiphaseMixture::solve() void Foam::multiphaseMixtureScalar::solve()
{ {
correct(); correct();
@ -570,7 +570,7 @@ void Foam::multiphaseMixture::solve()
} }
void Foam::multiphaseMixture::correct() void Foam::multiphaseMixtureScalar::correct()
{ {
forAllIter(PtrDictionary<phase>, phases_, iter) forAllIter(PtrDictionary<phase>, phases_, iter)
{ {
@ -579,7 +579,7 @@ void Foam::multiphaseMixture::correct()
} }
Foam::tmp<Foam::surfaceVectorField> Foam::multiphaseMixture::nHatfv Foam::tmp<Foam::surfaceVectorField> Foam::multiphaseMixtureScalar::nHatfv
( (
const volScalarField& alpha1, const volScalarField& alpha1,
const volScalarField& alpha2 const volScalarField& alpha2
@ -605,7 +605,7 @@ Foam::tmp<Foam::surfaceVectorField> Foam::multiphaseMixture::nHatfv
} }
Foam::tmp<Foam::surfaceScalarField> Foam::multiphaseMixture::nHatf Foam::tmp<Foam::surfaceScalarField> Foam::multiphaseMixtureScalar::nHatf
( (
const volScalarField& alpha1, const volScalarField& alpha1,
const volScalarField& alpha2 const volScalarField& alpha2
@ -622,7 +622,7 @@ Foam::tmp<Foam::surfaceScalarField> Foam::multiphaseMixture::nHatf
// The dynamic contact angle is calculated from the component of the // The dynamic contact angle is calculated from the component of the
// velocity on the direction of the interface, parallel to the wall. // velocity on the direction of the interface, parallel to the wall.
void Foam::multiphaseMixture::correctContactAngle void Foam::multiphaseMixtureScalar::correctContactAngle
( (
const phase& alpha1, const phase& alpha1,
const phase& alpha2, const phase& alpha2,
@ -726,7 +726,7 @@ void Foam::multiphaseMixture::correctContactAngle
} }
Foam::tmp<Foam::volScalarField> Foam::multiphaseMixture::K Foam::tmp<Foam::volScalarField> Foam::multiphaseMixtureScalar::K
( (
const phase& alpha1, const phase& alpha1,
const phase& alpha2 const phase& alpha2
@ -742,7 +742,7 @@ Foam::tmp<Foam::volScalarField> Foam::multiphaseMixture::K
Foam::tmp<Foam::volScalarField> Foam::tmp<Foam::volScalarField>
Foam::multiphaseMixture::nearInterface() const Foam::multiphaseMixtureScalar::nearInterface() const
{ {
tmp<volScalarField> tnearInt tmp<volScalarField> tnearInt
( (
@ -768,7 +768,7 @@ Foam::multiphaseMixture::nearInterface() const
} }
void Foam::multiphaseMixture::solveAlphas void Foam::multiphaseMixtureScalar::solveAlphas
( (
const scalar cAlpha const scalar cAlpha
) )
@ -901,7 +901,7 @@ void Foam::multiphaseMixture::solveAlphas
} }
bool Foam::multiphaseMixture::read() bool Foam::multiphaseMixtureScalar::read()
{ {
if (transportModel::read()) if (transportModel::read())
{ {

View File

@ -17,10 +17,10 @@ License
Copyright (C) 2018- Mathias Vångö, JKU Linz, Austria Copyright (C) 2018- Mathias Vångö, JKU Linz, Austria
Class Class
multiphaseMixture multiphaseMixtureScalar
Description Description
This class is based on the OpenFOAM(R) Foam::multiphaseMixture class, This class is based on the OpenFOAM(R) Foam::multiphaseMixtureScalar class,
which is an incompressible multi-phase mixture with built in solution which is an incompressible multi-phase mixture with built in solution
for the phase fractions with interface compression for interface-capturing. for the phase fractions with interface compression for interface-capturing.
It has been extended to include the void fraction in the volume fraction It has been extended to include the void fraction in the volume fraction
@ -33,11 +33,11 @@ Description
between each phase-pair. between each phase-pair.
SourceFiles SourceFiles
multiphaseMixture.C multiphaseMixtureScalar.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef multiphaseMixture_H #ifndef multiphaseMixtureScalar_H
#define multiphaseMixture_H #define multiphaseMixtureScalar_H
#include "incompressible/transportModel/transportModel.H" #include "incompressible/transportModel/transportModel.H"
#include "IOdictionary.H" #include "IOdictionary.H"
@ -52,10 +52,10 @@ namespace Foam
{ {
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class multiphaseMixture Declaration Class multiphaseMixtureScalar Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class multiphaseMixture class multiphaseMixtureScalar
: :
public IOdictionary, public IOdictionary,
public transportModel public transportModel
@ -191,7 +191,7 @@ public:
// Constructors // Constructors
//- Construct from components //- Construct from components
multiphaseMixture multiphaseMixtureScalar
( (
const volVectorField& U, const volVectorField& U,
const surfaceScalarField& phi, const surfaceScalarField& phi,
@ -200,7 +200,7 @@ public:
//- Destructor //- Destructor
virtual ~multiphaseMixture() virtual ~multiphaseMixtureScalar()
{} {}

View File

@ -26,7 +26,7 @@ Class
Description Description
Single incompressible phase derived from the phase-fraction. Single incompressible phase derived from the phase-fraction.
Used as part of the multiPhaseMixture for interface-capturing multi-phase Used as part of the multiphaseMixtureScalar for interface-capturing multi-phase
simulations. simulations.
SourceFiles SourceFiles

View File

@ -12,7 +12,8 @@ EXE_INC = \
-I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/lnInclude \
-I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \
-I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/derived/cfdemCloudRec \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/derived/cfdemCloudRec \
-I$(LIB_SRC)/sampling/lnInclude -I$(LIB_SRC)/sampling/lnInclude \
-Wno-deprecated-copy
EXE_LIBS = \ EXE_LIBS = \
-L$(CFDEM_LIB_DIR)\ -L$(CFDEM_LIB_DIR)\

View File

@ -51,8 +51,4 @@
thermo.correct(); thermo.correct();
Info<< "T max/min/ave : " << max(T).value() << " " << min(T).value() << " " << average(T).value() << endl; Info<< "T max/min/ave : " << max(T).value() << " " << min(T).value() << " " << average(T).value() << endl;
particleCloud.clockM().start(31,"energySolve");
particleCloud.solve();
particleCloud.clockM().stop("energySolve");
} }

View File

@ -55,8 +55,4 @@ fvScalarMatrix EEqn
Info << "Cpv :" << max(Cpv).value() << " " << min(Cpv).value() << endl; Info << "Cpv :" << max(Cpv).value() << " " << min(Cpv).value() << endl;
Info<< "T max/min : " << max(T).value() << " " << min(T).value() << endl; Info<< "T max/min : " << max(T).value() << " " << min(T).value() << endl;
Info << "he max/min : " << max(he).value() << " " << min(he).value() << endl; Info << "he max/min : " << max(he).value() << " " << min(he).value() << endl;
particleCloud.clockM().start(31,"energySolve");
particleCloud.solve();
particleCloud.clockM().stop("energySolve");
} }

View File

@ -60,13 +60,13 @@ tmp<fv::convectionScheme<scalar> > mvConvection
if (propagateInertSpecie) if (propagateInertSpecie)
{ {
if (inertIndex!=-1) Yt /= (1-Y[inertIndex] + VSMALL); if (inertIndex!=-1) Yt /= (1-Y[inertIndex] + ROOTVSMALL);
forAll(Y,i) forAll(Y,i)
{ {
if (i!=inertIndex) if (i!=inertIndex)
{ {
volScalarField& Yi = Y[i]; volScalarField& Yi = Y[i];
Yi = Yi/(Yt+VSMALL); Yi = Yi/(Yt+ROOTVSMALL);
} }
} }
} }

View File

@ -303,18 +303,4 @@
mesh, mesh,
dimensionedScalar("zero",dimensionSet(0, -3, 0, 0, 1),0) dimensionedScalar("zero",dimensionSet(0, -3, 0, 0, 1),0)
); );
volScalarField dSauter
(
IOobject
(
"dSauter",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
dimensionedScalar("zero",dimensionSet(0, 1, 0, 0, 0,0,0),0)
);
//=============================== //===============================

View File

@ -1,4 +1,4 @@
volScalarField rhoeps = rhoRec*voidfractionRec; rhoeps = rhoRec*voidfractionRec;
particleCloud.energyContributions(Qsource); particleCloud.energyContributions(Qsource);
@ -23,10 +23,17 @@
fvOptions(rhoeps, T) // no fvOptions support yet fvOptions(rhoeps, T) // no fvOptions support yet
); );
fvOptions.constrain(TEqn); // no fvOptions support yet // fvOptions.constrain(TEqn); // no fvOptions support yet
TEqn.relax();
TEqn.solve(); TEqn.solve();
T = max(T, TMin);
T = min(T, TMax);
Info<< "T max/min/ave : " << max(T).value() << " " << min(T).value() << " " << average(T).value() << endl;
particleCloud.clockM().start(31,"postFlow"); particleCloud.clockM().start(31,"postFlow");
counter++; counter++;

View File

@ -73,6 +73,9 @@
dimensionedVector("zero", dimensionSet(0, 1, -1, 0, 0), vector::zero) dimensionedVector("zero", dimensionSet(0, 1, -1, 0, 0), vector::zero)
); );
volScalarField rhoeps("rhoeps", rhoRec*voidfractionRec);
rhoeps.oldTime(); // switch on saving old time
// heat transfer fields // heat transfer fields
Info << "\nCreating heat transfer fields.\n" << endl; Info << "\nCreating heat transfer fields.\n" << endl;
@ -228,3 +231,25 @@
) )
); );
weightDict.add("weights",scalarList(1,1.0)); weightDict.add("weights",scalarList(1,1.0));
dimensionedScalar TMax
(
dimensionedScalar::lookupOrDefault
(
"TMax",
transportProps,
dimTemperature,
GREAT
)
);
dimensionedScalar TMin
(
dimensionedScalar::lookupOrDefault
(
"TMin",
transportProps,
dimTemperature,
0.0
)
);

View File

@ -98,7 +98,7 @@ int main(int argc, char *argv[])
particleCloud.clockM().start(26,"Flow"); particleCloud.clockM().start(26,"Flow");
#include "updateRho.H" #include "updateRho.H"
#include "TEqImp.H" #include "TEqn.H"
particleCloud.clockM().stop("Flow"); particleCloud.clockM().stop("Flow");
stepCounter++; stepCounter++;

View File

@ -1 +1,2 @@
rhoRec = pRec / (T * R); dimensionedScalar Tave = T.weightedAverage(voidfractionRec);
rhoRec = pRec / (Tave * R);

View File

@ -12,6 +12,7 @@ EXE_INC = \
-I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \
-I$(CFDEM_SRC_DIR)/recurrence/lnInclude \ -I$(CFDEM_SRC_DIR)/recurrence/lnInclude \
-I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/derived/cfdemCloudRec \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/derived/cfdemCloudRec \
-Wno-deprecated-copy
EXE_LIBS = \ EXE_LIBS = \
-L$(CFDEM_LIB_DIR)\ -L$(CFDEM_LIB_DIR)\
@ -24,4 +25,4 @@ EXE_LIBS = \
-lfvOptions \ -lfvOptions \
-l$(CFDEM_LIB_NAME) \ -l$(CFDEM_LIB_NAME) \
$(CFDEM_ADD_LIB_PATHS) \ $(CFDEM_ADD_LIB_PATHS) \
$(CFDEM_ADD_LIBS) $(CFDEM_ADD_LIBS)

View File

@ -60,9 +60,4 @@
thermo.correct(); thermo.correct();
Info<< "T max/min : " << max(T).value() << " " << min(T).value() << endl; Info<< "T max/min : " << max(T).value() << " " << min(T).value() << endl;
particleCloud.clockM().start(31,"energySolve");
particleCloud.solve();
particleCloud.clockM().stop("energySolve");
} }

View File

@ -59,9 +59,4 @@
thermo.correct(); thermo.correct();
Info<< "T max/min : " << max(T).value() << " " << min(T).value() << endl; Info<< "T max/min : " << max(T).value() << " " << min(T).value() << endl;
particleCloud.clockM().start(31,"energySolve");
particleCloud.solve();
particleCloud.clockM().stop("energySolve");
} }

View File

@ -27,6 +27,7 @@ EXE_INC = \
-I$(LIB_SRC)/ODE/lnInclude \ -I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/combustionModels/lnInclude \ -I$(LIB_SRC)/combustionModels/lnInclude \
-I$(CFDEM_SRC_DIR)/recurrence/lnInclude \ -I$(CFDEM_SRC_DIR)/recurrence/lnInclude \
-Wno-deprecated-copy
EXE_LIBS = \ EXE_LIBS = \
-L$(CFDEM_LIB_DIR)\ -L$(CFDEM_LIB_DIR)\

View File

@ -12,6 +12,7 @@ EXE_INC = \
-I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/cfdTools \
-I$(CFDEM_SRC_DIR)/recurrence/lnInclude \ -I$(CFDEM_SRC_DIR)/recurrence/lnInclude \
-I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/derived/cfdemCloudRec \ -I$(CFDEM_SRC_DIR)/lagrangian/cfdemParticle/derived/cfdemCloudRec \
-Wno-deprecated-copy
EXE_LIBS = \ EXE_LIBS = \
-L$(CFDEM_LIB_DIR)\ -L$(CFDEM_LIB_DIR)\

View File

@ -37,11 +37,19 @@ Application
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void findPairs(labelList &, labelList &, labelPairList &); void findPairs(labelList &, labelList &, labelPairList &);
void findPairsUnordered(labelList &, labelList &, labelPairList &); void findPairsUnordered(labelList &, labelList &, labelPairList &);
void fillEmptyCells(fvMesh &, label, label, labelList &, volVectorField &, volVectorField &, scalarList &, volVectorField &, volVectorField &, bool, scalar); void fillEmptyCells(fvMesh &, label, label, scalarList &, volVectorField &, volVectorField &, scalarList &, volVectorField &, volVectorField &, bool, scalar);
void nearestNeighborCells(fvMesh &, label, label, label, labelList &, labelList &); void nearestNeighborCells(fvMesh &, label, label, label, scalarList &, labelList &);
void normalizeFields(labelList &, volVectorField &, volVectorField &); void normalizeFields(scalarList &, volVectorField &, volVectorField &);
void readDump(std::string, labelList &, vectorList &); void readDump(std::string, labelList &, scalarList &, vectorList &);
scalar weightFun(scalar); scalar weightFun(scalar);
label maxNumParticles = 1000000;
scalar minVol = 1e-12;
scalar Pi43 = 4.1888;
label posIndex = -1;
label posRad = -1;
label posX = -1;
label posY = -1;
label posZ = -1;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -88,6 +96,11 @@ int main(int argc, char *argv[])
label dumpIndexDisplacementIncrement(readLabel(displacementProperties.lookup("dumpIndexDisplacementIncrement"))); label dumpIndexDisplacementIncrement(readLabel(displacementProperties.lookup("dumpIndexDisplacementIncrement")));
label nNeighMin(readLabel(displacementProperties.lookup("nNeighMin"))); label nNeighMin(readLabel(displacementProperties.lookup("nNeighMin")));
label maxSearchLayers(displacementProperties.lookupOrDefault<label>("maxSearchLayers",0)); label maxSearchLayers(displacementProperties.lookupOrDefault<label>("maxSearchLayers",0));
posIndex = readLabel(displacementProperties.lookup("posIndex"));
posRad = readLabel(displacementProperties.lookup("posRad"));
posX = readLabel(displacementProperties.lookup("posX"));
posY = readLabel(displacementProperties.lookup("posY"));
posZ = readLabel(displacementProperties.lookup("posZ"));
scalar timePerInputStep(readScalar(displacementProperties.lookup("timePerInputStep"))); scalar timePerInputStep(readScalar(displacementProperties.lookup("timePerInputStep")));
scalar timePerDisplacementStep(readScalar(displacementProperties.lookup("timePerDisplacementStep"))); scalar timePerDisplacementStep(readScalar(displacementProperties.lookup("timePerDisplacementStep")));
scalar startTime(readScalar(displacementProperties.lookup("startTime"))); scalar startTime(readScalar(displacementProperties.lookup("startTime")));
@ -110,11 +123,11 @@ int main(int argc, char *argv[])
dimensionedVector("zero", dimensionSet(0,1,-1,0,0), vector::zero) dimensionedVector("zero", dimensionSet(0,1,-1,0,0), vector::zero)
); );
volVectorField defaultUsDirectedVariance volVectorField defaultUsDirectedStdDev
( (
IOobject IOobject
( (
"defaultUDispDirectedVariance", "defaultUDispDirectedStdDev",
runTime.timeName(), runTime.timeName(),
mesh, mesh,
IOobject::READ_IF_PRESENT, IOobject::READ_IF_PRESENT,
@ -172,11 +185,11 @@ int main(int argc, char *argv[])
dimensionedVector("zero", dimensionSet(0,1,-1,0,0), vector::zero) dimensionedVector("zero", dimensionSet(0,1,-1,0,0), vector::zero)
); );
volVectorField UsDirectedVariance volVectorField UsDirectedStdDev
( (
IOobject IOobject
( (
"UDispDirectedVariance", "UDispDirectedStdDev",
runTime.timeName(), runTime.timeName(),
mesh, mesh,
IOobject::NO_READ, IOobject::NO_READ,
@ -186,7 +199,7 @@ int main(int argc, char *argv[])
dimensionedVector("zero", dimensionSet(0,1,-1,0,0), vector::zero) dimensionedVector("zero", dimensionSet(0,1,-1,0,0), vector::zero)
); );
labelList particlesInCell(mesh.nCells(), 0); scalarList particleVolInCell(mesh.nCells(), 0.0);
scalar currTime=startTime + thisProc * timePerInputStep; scalar currTime=startTime + thisProc * timePerInputStep;
label timeIndex=thisProc; label timeIndex=thisProc;
@ -196,6 +209,7 @@ int main(int argc, char *argv[])
runTime.setTime(currTime,timeIndex); runTime.setTime(currTime,timeIndex);
// read dump files and check which particle indices are present in both // read dump files and check which particle indices are present in both
labelList indices1, indices2; labelList indices1, indices2;
scalarList radii1, radii2;
vectorList positions1, positions2; vectorList positions1, positions2;
std::stringstream ss; std::stringstream ss;
@ -209,13 +223,13 @@ int main(int argc, char *argv[])
{ {
if (averageMode) if (averageMode)
{ {
normalizeFields(particlesInCell, Us, UsDirectedVariance); normalizeFields(particleVolInCell, Us, UsDirectedStdDev);
fillEmptyCells(mesh,nNeighMin,maxSearchLayers,particlesInCell,Us,UsDirectedVariance,boundaries,defaultUs,defaultUsDirectedVariance,interpolate,timePerDisplacementStep); fillEmptyCells(mesh,nNeighMin,maxSearchLayers,particleVolInCell,Us,UsDirectedStdDev,boundaries,defaultUs,defaultUsDirectedStdDev,interpolate,timePerDisplacementStep);
Us /= timePerDisplacementStep; Us /= timePerDisplacementStep;
UsDirectedVariance /= timePerDisplacementStep; UsDirectedStdDev /= timePerDisplacementStep;
Us.write(); Us.write();
UsDirectedVariance.write(); UsDirectedStdDev.write();
} }
break; break;
} }
@ -225,8 +239,8 @@ int main(int argc, char *argv[])
Info << "\t" << filename2 << endl; Info << "\t" << filename2 << endl;
Info << "corresponding to time = " << currTime << "." << endl; Info << "corresponding to time = " << currTime << "." << endl;
readDump(filename1, indices1, positions1); readDump(filename1, indices1, radii1, positions1);
readDump(filename2, indices2, positions2); readDump(filename2, indices2, radii2, positions2);
labelPairList pairs; labelPairList pairs;
findPairs(indices1,indices2,pairs); findPairs(indices1,indices2,pairs);
@ -234,15 +248,16 @@ int main(int argc, char *argv[])
// average particle displacements and their variance // average particle displacements and their variance
Info << "Binning particle displacements on mesh." << endl; Info << "Binning particle displacements on mesh." << endl;
vector position, displacement; vector position, displacement;
scalar radius, volume;
label line1, line2; label line1, line2;
label cellI; label cellI;
if (!averageMode) if (!averageMode)
{ {
Us *= 0.0; Us *= 0.0;
UsDirectedVariance *= 0.0; UsDirectedStdDev *= 0.0;
particlesInCell.clear(); particleVolInCell.clear();
particlesInCell.setSize(mesh.nCells(), 0); particleVolInCell.setSize(mesh.nCells(), 0);
} }
for (label partI = 0; partI < pairs.size(); partI++) for (label partI = 0; partI < pairs.size(); partI++)
@ -250,27 +265,29 @@ int main(int argc, char *argv[])
line1 = pairs[partI].first(); line1 = pairs[partI].first();
line2 = pairs[partI].second(); line2 = pairs[partI].second();
position = positions1[line1]; position = positions1[line1];
displacement = positions2[line2] - positions1[line1];
cellI = mesh.findCell(position); cellI = mesh.findCell(position);
if (cellI < 0) continue; if (cellI < 0) continue;
particlesInCell[cellI] += 1; displacement = positions2[line2] - positions1[line1];
Us[cellI] += displacement; radius = radii1[line1];
volume = Pi43 * radius * radius * radius;
particleVolInCell[cellI] += volume;
Us[cellI] += displacement*volume;
for (label comp=0;comp<3;comp++) for (label comp=0;comp<3;comp++)
{ {
UsDirectedVariance[cellI].component(comp) += displacement.component(comp)*displacement.component(comp); UsDirectedStdDev[cellI].component(comp) += displacement.component(comp)*displacement.component(comp)*volume;
} }
} }
if (!averageMode) if (!averageMode)
{ {
normalizeFields(particlesInCell, Us, UsDirectedVariance); normalizeFields(particleVolInCell, Us, UsDirectedStdDev);
fillEmptyCells(mesh,nNeighMin,maxSearchLayers,particlesInCell,Us,UsDirectedVariance,boundaries,defaultUs,defaultUsDirectedVariance,interpolate,timePerDisplacementStep); fillEmptyCells(mesh,nNeighMin,maxSearchLayers,particleVolInCell,Us,UsDirectedStdDev,boundaries,defaultUs,defaultUsDirectedStdDev,interpolate,timePerDisplacementStep);
Us /= timePerDisplacementStep; Us /= timePerDisplacementStep;
UsDirectedVariance /= timePerDisplacementStep; UsDirectedStdDev /= timePerDisplacementStep;
Us.write(); Us.write();
UsDirectedVariance.write(); UsDirectedStdDev.write();
} }
if (averageMode && monitorProbes) if (averageMode && monitorProbes)
@ -280,7 +297,7 @@ int main(int argc, char *argv[])
{ {
vector pos = probePoints[p]; vector pos = probePoints[p];
label cellP = mesh.findCell(pos); label cellP = mesh.findCell(pos);
monitoringDataFile << " " << particlesInCell[cellP] << " " << Us[cellP]/timePerDisplacementStep << " " << UsDirectedVariance[cellP]/(timePerDisplacementStep*timePerDisplacementStep); monitoringDataFile << " " << particleVolInCell[cellP] << " " << Us[cellP]/timePerDisplacementStep << " " << UsDirectedStdDev[cellP]/(timePerDisplacementStep*timePerDisplacementStep);
} }
monitoringDataFile << endl; monitoringDataFile << endl;
} }
@ -293,30 +310,69 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
void readDump(std::string filename, labelList &indices, vectorList &positions) void readDump(std::string filename, labelList &indices, scalarList &radii, vectorList &positions)
{ {
#include <fstream> #include <fstream>
const label leadingLines = 9; const label leadingLines = 9;
label lineCounter = 0; label lineCounter = 0;
label partIndex; label partIndex;
scalar x, y, z; scalar r = 1.0, x = 0.0, y = 0.0, z = 0.0;
indices.clear(); indices.clear();
radii.clear();
positions.clear(); positions.clear();
indices.setSize(maxNumParticles);
radii.setSize(maxNumParticles);
positions.setSize(maxNumParticles);
std::ifstream file(filename); std::ifstream file(filename);
std::string str; std::string str;
std::string word;
label wordcounter;
while (std::getline(file, str)) while (std::getline(file, str))
{ {
if (lineCounter >= leadingLines) if (lineCounter >= leadingLines)
{ {
sscanf(str.c_str(), "%d %lf %lf %lf", &partIndex, &x, &y, &z); std::istringstream ss(str);
indices.append(partIndex); wordcounter = 0;
positions.append(vector(x,y,z)); while (ss >> word)
{
if (wordcounter == posIndex)
{
partIndex = stoi(word);
}
else if (wordcounter == posRad)
{
r = stod(word);
}
else if (wordcounter == posX)
{
x = stod(word);
}
else if (wordcounter == posY)
{
y = stod(word);
}
else if (wordcounter == posZ)
{
z = stod(word);
}
wordcounter++;
}
// sscanf(str.c_str(), "%d %lf %lf %lf", &partIndex, &x, &y, &z);
indices[lineCounter-leadingLines] = partIndex;
radii[lineCounter-leadingLines] = r;
positions[lineCounter-leadingLines] = vector(x,y,z);
} }
lineCounter++; lineCounter++;
} }
label readLines = lineCounter - leadingLines;
indices.resize(readLines);
radii.resize(readLines);
positions.resize(readLines);
} }
void findPairs(labelList &indices1, labelList &indices2, labelPairList &pairs) void findPairs(labelList &indices1, labelList &indices2, labelPairList &pairs)
@ -324,6 +380,10 @@ void findPairs(labelList &indices1, labelList &indices2, labelPairList &pairs)
// remove all entries from first list if they are not present in second list // remove all entries from first list if they are not present in second list
// this assumes ordered entries // this assumes ordered entries
pairs.clear();
pairs.setSize(maxNumParticles);
label pairCounter = 0;
if (indices2.size() == 0) return; if (indices2.size() == 0) return;
for (label i=0;i<indices1.size();i++) for (label i=0;i<indices1.size();i++)
@ -339,18 +399,23 @@ void findPairs(labelList &indices1, labelList &indices2, labelPairList &pairs)
else if (indices2[jmid] < index1) j1 = jmid; else if (indices2[jmid] < index1) j1 = jmid;
else else
{ {
pairs.append(labelPair(i,jmid)); pairs[pairCounter]=labelPair(i,jmid);
pairCounter++;
break; break;
} }
if (j2-j1 == 1) break; if (j2-j1 == 1) break;
} }
} }
pairs.resize(pairCounter);
Info << "findPairs: " << pairs.size() << " pairs found." << endl; Info << "findPairs: " << pairs.size() << " pairs found." << endl;
} }
void findPairsUnordered(labelList &indices1, labelList &indices2, labelPairList &pairs) void findPairsUnordered(labelList &indices1, labelList &indices2, labelPairList &pairs)
{ {
// remove all entries from first list if they are not present in second list // remove all entries from first list if they are not present in second list
pairs.clear();
pairs.setSize(maxNumParticles);
label pairCounter = 0;
for (label i=0;i<indices1.size();i++) for (label i=0;i<indices1.size();i++)
{ {
@ -358,15 +423,17 @@ void findPairsUnordered(labelList &indices1, labelList &indices2, labelPairList
{ {
if (indices1[i] == indices2[j]) if (indices1[i] == indices2[j])
{ {
pairs.append(labelPair(i,j)); pairs[pairCounter]=labelPair(i,j);
pairCounter++;
break; break;
} }
} }
} }
pairs.resize(pairCounter);
Info << "findPairs: " << pairs.size() << " pairs found." << endl; Info << "findPairs: " << pairs.size() << " pairs found." << endl;
} }
void fillEmptyCells(fvMesh &mesh, label nNeighMin, label maxSearchLayers, labelList &particlesInCell, volVectorField &Us, volVectorField& UsDirectedVariance,scalarList& boundaries, volVectorField &defaultUs, volVectorField &defaultUsDirectedVariance, bool interpolate, scalar dt) void fillEmptyCells(fvMesh &mesh, label nNeighMin, label maxSearchLayers, scalarList &particleVolInCell, volVectorField &Us, volVectorField& UsDirectedStdDev,scalarList& boundaries, volVectorField &defaultUs, volVectorField &defaultUsDirectedStdDev, bool interpolate, scalar dt)
{ {
labelList neighborsWithValues; labelList neighborsWithValues;
scalar neighborSqrDistance; scalar neighborSqrDistance;
@ -377,7 +444,7 @@ void fillEmptyCells(fvMesh &mesh, label nNeighMin, label maxSearchLayers, labelL
Info << "Filling empty cells." << endl; Info << "Filling empty cells." << endl;
forAll(mesh.C(), cellI) forAll(mesh.C(), cellI)
{ {
if (particlesInCell[cellI] > 0) continue; if (particleVolInCell[cellI] > minVol) continue;
vector position = mesh.C()[cellI]; vector position = mesh.C()[cellI];
label outsideBox = 0; label outsideBox = 0;
@ -388,11 +455,11 @@ void fillEmptyCells(fvMesh &mesh, label nNeighMin, label maxSearchLayers, labelL
if (outsideBox > 0 || !interpolate) if (outsideBox > 0 || !interpolate)
{ {
Us[cellI] = defaultUs[cellI]*dt; Us[cellI] = defaultUs[cellI]*dt;
UsDirectedVariance[cellI] = defaultUsDirectedVariance[cellI]*dt; UsDirectedStdDev[cellI] = defaultUsDirectedStdDev[cellI]*dt;
continue; continue;
} }
nearestNeighborCells(mesh, cellI, nNeighMin, maxSearchLayers, particlesInCell, neighborsWithValues); nearestNeighborCells(mesh, cellI, nNeighMin, maxSearchLayers, particleVolInCell, neighborsWithValues);
weightSum = 0.0; weightSum = 0.0;
weights.clear(); weights.clear();
for (label neighI=0; neighI<neighborsWithValues.size(); neighI++) for (label neighI=0; neighI<neighborsWithValues.size(); neighI++)
@ -406,13 +473,13 @@ void fillEmptyCells(fvMesh &mesh, label nNeighMin, label maxSearchLayers, labelL
{ {
weight = weights[neighI]/weightSum; weight = weights[neighI]/weightSum;
Us[cellI] += weight*Us[neighborsWithValues[neighI]]; Us[cellI] += weight*Us[neighborsWithValues[neighI]];
UsDirectedVariance[cellI] += weight*UsDirectedVariance[neighborsWithValues[neighI]]; UsDirectedStdDev[cellI] += weight*UsDirectedStdDev[neighborsWithValues[neighI]];
} }
if (neighborsWithValues.size() == 0) if (neighborsWithValues.size() == 0)
{ {
Us[cellI] = defaultUs[cellI]*dt; Us[cellI] = defaultUs[cellI]*dt;
UsDirectedVariance[cellI] = defaultUsDirectedVariance[cellI]*dt; UsDirectedStdDev[cellI] = defaultUsDirectedStdDev[cellI]*dt;
} }
// make sure no particles are placed outside of domain // make sure no particles are placed outside of domain
@ -429,7 +496,7 @@ void fillEmptyCells(fvMesh &mesh, label nNeighMin, label maxSearchLayers, labelL
} }
} }
void nearestNeighborCells(fvMesh &mesh, label refCell, label nNeighMin, label maxSearchLayers, labelList &particlesInCell, labelList &neighborsWithValues) void nearestNeighborCells(fvMesh &mesh, label refCell, label nNeighMin, label maxSearchLayers, scalarList &particleVolInCell, labelList &neighborsWithValues)
{ {
label numSearchLayers = 0; label numSearchLayers = 0;
std::set<label> neighbors; std::set<label> neighbors;
@ -455,7 +522,7 @@ void nearestNeighborCells(fvMesh &mesh, label refCell, label nNeighMin, label ma
{ {
newNeighbors.insert(adj); newNeighbors.insert(adj);
neighbors.insert(adj); neighbors.insert(adj);
if (particlesInCell[adj] > 0) neighborsWithValues.append(adj); if (particleVolInCell[adj] > minVol) neighborsWithValues.append(adj);
} }
} }
} }
@ -470,18 +537,18 @@ void nearestNeighborCells(fvMesh &mesh, label refCell, label nNeighMin, label ma
} }
} }
void normalizeFields(labelList& particlesInCell, volVectorField& Us, volVectorField & UsDirectedVariance) void normalizeFields(scalarList& particleVolInCell, volVectorField& Us, volVectorField & UsDirectedStdDev)
{ {
for (label cellJ = 0; cellJ<particlesInCell.size(); cellJ++) for (label cellJ = 0; cellJ<particleVolInCell.size(); cellJ++)
{ {
if (particlesInCell[cellJ] > 0) if (particleVolInCell[cellJ] > minVol)
{ {
Us[cellJ] /= particlesInCell[cellJ]; Us[cellJ] /= particleVolInCell[cellJ];
UsDirectedVariance[cellJ] /= particlesInCell[cellJ]; UsDirectedStdDev[cellJ] /= particleVolInCell[cellJ];
for (label comp=0;comp<3;comp++) for (label comp=0;comp<3;comp++)
{ {
UsDirectedVariance[cellJ].component(comp) -= Us[cellJ].component(comp)*Us[cellJ].component(comp); UsDirectedStdDev[cellJ].component(comp) -= Us[cellJ].component(comp)*Us[cellJ].component(comp);
if (UsDirectedVariance[cellJ].component(comp) > 0) UsDirectedVariance[cellJ].component(comp) = Foam::sqrt(UsDirectedVariance[cellJ].component(comp)); if (UsDirectedStdDev[cellJ].component(comp) > 0) UsDirectedStdDev[cellJ].component(comp) = Foam::sqrt(UsDirectedStdDev[cellJ].component(comp));
} }
} }
} }

View File

@ -124,6 +124,7 @@ particleDeformation,
potentialRelaxation, potentialRelaxation,
"surfaceTensionForce"_forceModel_surfaceTensionForce.html, "surfaceTensionForce"_forceModel_surfaceTensionForce.html,
terminalVelocity, terminalVelocity,
"transferFluidProperties"_forceModel_transferFluidProperties.html,
turbulentDispersion, turbulentDispersion,
turbulentVelocityFluctuations, turbulentVelocityFluctuations,
"virtualMassForce"_forceModel_virtualMassForce.html, "virtualMassForce"_forceModel_virtualMassForce.html,

View File

@ -10,6 +10,7 @@
This section lists all CFDEMcoupling solvers alphabetically. This section lists all CFDEMcoupling solvers alphabetically.
"cfdemSolverIB"_cfdemSolverIB.html, "cfdemSolverIB"_cfdemSolverIB.html,
"cfdemSolverIBContinuousForcing"_cfdemSolverIBContinuousForcing.html,
"cfdemSolverMultiphase"_cfdemSolverMultiphase.html, "cfdemSolverMultiphase"_cfdemSolverMultiphase.html,
"cfdemSolverMultiphaseScalar"_cfdemSolverMultiphaseScalar.html, "cfdemSolverMultiphaseScalar"_cfdemSolverMultiphaseScalar.html,
"cfdemSolverPiso"_cfdemSolverPiso.html, "cfdemSolverPiso"_cfdemSolverPiso.html,

View File

@ -17,7 +17,8 @@ IOModel basicIO; :pre
[Examples:] [Examples:]
IOModel basicIO; IOModel basicIO;
serialOutput; :pre serialOutput;
cartesianOutput; :pre
[Description:] [Description:]
@ -29,6 +30,11 @@ Using the keyword {serialOutput;} in the
the IO is serial to the directory {$casePath/CFD/lagrangian}. In this case the IO is serial to the directory {$casePath/CFD/lagrangian}. In this case
only the data on processor 0 is written! only the data on processor 0 is written!
Using the keyword {cartesianOutput;} in the
"couplingProperties"_CFDEMcoupling_dicts.html#couplingProperties dictionary,
particle positions will be written as cartesian coordinates instead of
barycentric coordinates.
Data is written every write time of the CFD simulation. Data is written every write time of the CFD simulation.
[Restrictions:] [Restrictions:]

View File

@ -0,0 +1,82 @@
"CFDEMproject Website"_lws - "Main Page"_main :c
:link(lws,http://www.cfdem.com)
:link(main,CFDEMcoupling_Manual.html)
:line
cfdemSolverIBContinuousForcing command :h3
[Description:]
"cfdemSolverIBContinuousForcing" is a coupled CFD-DEM solver using CFDEMcoupling,
an open-source parallel coupled CFD-DEM framework, for calculating the dynamics
between immersed bodies and the surrounding fluid. Being an implementation of a
continuous forcing immersed boundary method it allows tackling problems where
the body diameter exceeds the maximal size of a fluid cell.
<!-- HTML_ONLY -->
Using the toolbox of OpenFOAM&reg;(*) the governing equations of the fluid are
computed and the corrections of velocity and pressure field with respect to the
body-movement information, gained from LIGGGHTS, are incorporated.
<!-- END_HTML_ONLY -->
<!-- RST
Using the toolbox of OpenFOAM\ |reg|\ (*) the governing equations of the fluid are
computed and the corrections of velocity and pressure field with respect to the
body-movement information, gained from LIGGGHTS, are incorporated.
.. |reg| unicode:: U+000AE .. REGISTERED SIGN
END_RST -->
The code of this solver was contributed by A.N. Balachandran Nair, JKU. For more
details, see "Balachandran Nair et al. (2021)"_#BalachandranNair2021
[Use:]
The solver is realized within the open-source framework CFDEMcoupling. Just as
for the unresolved CFD-DEM solver cfdemSolverPiso the file
CFD/constant/couplingProperties contains information about the settings for the
different models. While IOmodel, DataExchangeModel etc. are applicable for all
CFDEMcoupling-solvers, special locate-, force- and void fraction models were
designed for this solver:
"engineSearchIB"_locateModel_engineSearchIB.html,
"ArchimedesIB"_forceModel_ArchimedesIB.html,
"ShirgaonkarIB"_forceModel_ShirgaonkarIB.html,
"IBVoidfraction"_voidFractionModel_IBVoidFraction.html
:line
:link(BalachandranNair2021)
[(Balachandran Nair, 2021)] Balachandran Nair, A.N., Pirker, S. and Saeedipour, M.,
"Resolved CFD-DEM simulation of blood flow with a reduced-order RBC model",
Comp. Part. Mech. (2021)
:line
<!-- HTML_ONLY -->
NOTE:
(*) This offering is not approved or endorsed by OpenCFD Limited, producer and
distributor of the OpenFOAM software via www.openfoam.com, and owner of the
OPENFOAM&reg; and OpenCFD&reg; trade marks.
OPENFOAM&reg; is a registered trade mark of OpenCFD Limited, producer and
distributor of the OpenFOAM software via www.openfoam.com.
<!-- END_HTML_ONLY -->
<!-- RST
.. note::
(*) This offering is not approved or endorsed by OpenCFD Limited, producer
and distributor of the OpenFOAM software via www.openfoam.com, and owner of
the OPENFOAM\ |reg| and OpenCFD\ |reg| trade marks.
OPENFOAM\ |reg| is a registered trade mark of OpenCFD Limited, producer and
distributor of the OpenFOAM software via www.openfoam.com.
.. |reg| unicode:: U+000AE .. REGISTERED SIGN
END_RST -->

View File

@ -23,17 +23,19 @@ ParmarBassetForceProps
nIntegral scalar1; nIntegral scalar1;
discretisationOrder scalar2; discretisationOrder scalar2;
treatForceExplicit switch1; treatForceExplicit switch1;
interpolation switch2; verbose switch2;
interpolation switch3;
smoothingModel "smoothingModel"; smoothingModel "smoothingModel";
\} :pre \} :pre
{U} = name of the finite volume fluid velocity field :ulb,l {U} = name of the finite volume fluid velocity field :ulb,l
{Us} = name of the finite volume cell averaged particle velocity field :l {Us} = name of the finite volume cell averaged particle velocity field :l
{scalar1} = number of timesteps considered in the near history :l {scalar1} = number of timesteps considered in the near history (integer > 1):l
{scalar2} = (1 or 2) discretisation order of the far history differential equations :l {scalar2} = (optional, default 1) discretisation order of the far history differential equations (1 or 2) :l
{switch1} = (optional, default true) sub model switch, see "forceSubModel"_forceSubModel.html for details :l {switch1} = (optional, default true) sub model switch, see "forceSubModel"_forceSubModel.html for details :l
{switch2} = (optional, default false) sub model switch, see "forceSubModel"_forceSubModel.html for details :l {switch2} = (optional, default false) sub model switch, see "forceSubModel"_forceSubModel.html for details :l
{smoothingModel} = name of smoothing model for the dU/dt field :l {switch3} = (optional, default false) sub model switch, see "forceSubModel"_forceSubModel.html for details :l
{smoothingModel} = name of smoothing model for the dUrel/dt field :l
:ule :ule
[Examples:] [Examples:]

View File

@ -21,12 +21,14 @@ ShirgaonkarIBProps
velFieldName "U"; velFieldName "U";
pressureFieldName "pressure"; pressureFieldName "pressure";
twoDimensional; twoDimensional;
useTorque;
treatForceExplicit switch1; treatForceExplicit switch1;
\} :pre \} :pre
{U} = name of the finite volume fluid velocity field :ulb,l {U} = name of the finite volume fluid velocity field :ulb,l
{pressure} = name of the finite volume pressure field :l {pressure} = name of the finite volume pressure field :l
{twoDimensional} = optional keyword for conducting a two dimensional calculation :l {twoDimensional} = optional keyword for conducting a two dimensional calculation :l
{useTorque} = optional keyword for calculating particle torque :l
{switch1} = (optional, default false) sub model switch, see "forceSubModel"_forceSubModel.html for details :l {switch1} = (optional, default false) sub model switch, see "forceSubModel"_forceSubModel.html for details :l
:ule :ule

View File

@ -0,0 +1,42 @@
"CFDEMproject Website"_lws - "Main Page"_main :c
:link(lws,http://www.cfdem.com)
:link(main,CFDEMcoupling_Manual.html)
:line
forceModel transferFluidProperties command :h3
[Syntax:]
Defined in "couplingProperties"_CFDEMcoupling_dicts.html#couplingProperties
dictionary.
forceModels
(
transferFluidProperties
);
transferFluidPropertiesProps
\{
verbose switch1;
interpolation switch2;
\} :pre
{switch1} = (optional, default false) sub model switch, see "forceSubModel"_forceSubModel.html for details :ulb,l
{switch2} = (optional, default false) sub model switch, see "forceSubModel"_forceSubModel.html for details :l
:ule
[Description:]
This "force model" does not influence the particles or the flow - it transfer to fluid density and (dynamic)
viscosity from OpenFOAM to LIGGGHTS.
[Restrictions:]
This model requires {fix cfd/coupling/fluidproperties} to work.
[Related commands:]
"forceModel"_forceModel.html

View File

@ -18,14 +18,19 @@ constDiffSmoothingProps
lowerLimit number1; lowerLimit number1;
upperLimit number2; upperLimit number2;
smoothingLength lengthScale; smoothingLength lengthScale;
smoothingLengthReferenceField lengthScaleRefField; smoothingLengthReference lengthScaleRef;
smoothingLengthFieldName fieldName1;
smoothingLengthReferenceFieldName fieldName2;
verbose; verbose;
\} :pre \} :pre
{number1} = scalar fields will be bound to this lower value :ulb,l {number1} = scalar fields will be bound to this lower value :ulb,l
{number2} = scalar fields will be bound to this upper value :l {number2} = scalar fields will be bound to this upper value :l
{lengthScale} = length scale over which the exchange fields will be smoothed out :l {lengthScale} = length scale over which the exchange fields will be smoothed out :l
{lengthScaleRefField} = length scale over which reference fields (e.g., the average particle velocity) will be smoothed out. Should be always larger than lengthScale. If not specified, will be equal to lengthScale. :l {lengthScaleRef} = (optional) length scale over which reference fields (e.g., the average particle velocity) will be smoothed out. Should be always larger than lengthScale. If not specified, will be equal to lengthScale. :l
{fieldName1} = (optional) name of scalar field to be used as local smoothing length. :l
{fieldName2} = (optional) name of scalar field to be used as local smoothing length for reference fields. :l
{verbose} = (optional, default false) flag for debugging output :l {verbose} = (optional, default false) flag for debugging output :l
:ule :ule
@ -51,6 +56,11 @@ which these reference fields are not specified. Values calculated in the cells
e.g. the average particle velocity, which are not specified in all cells in case e.g. the average particle velocity, which are not specified in all cells in case
the flow is rather dilute. the flow is rather dilute.
Alternative to {smoothingLength} and {smoothingLengthReference},
{smoothingLengthFieldName} and/or {smoothingLengthReferenceFieldName} can be used
to define spatial variation of the smoothing lengths. Either the scalar or field
options must be used, giving both will result in errors.
[Restrictions:] [Restrictions:]
This model is tested in a limited number of flow situations. This model is tested in a limited number of flow situations.

View File

@ -17,7 +17,7 @@
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
export CFDEM_PROJECT=CFDEM export CFDEM_PROJECT=CFDEM
export CFDEM_VERSION=21.11 export CFDEM_VERSION=23.02
################################################################################ ################################################################################
# USER EDITABLE PART: Changes made here may be lost with the next upgrade # USER EDITABLE PART: Changes made here may be lost with the next upgrade

View File

@ -15,7 +15,7 @@
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
setenv CFDEM_PROJECT CFDEM setenv CFDEM_PROJECT CFDEM
setenv CFDEM_VERSION 21.11 setenv CFDEM_VERSION 23.02
################################################################################ ################################################################################
# USER EDITABLE PART: Changes made here may be lost with the next upgrade # USER EDITABLE PART: Changes made here may be lost with the next upgrade

View File

@ -359,7 +359,7 @@ cleanCFDEMcase()
cd $casePath/CFD cd $casePath/CFD
cleanCase cleanCase
rm -r $casePath/DEM/post/* rm -r $casePath/DEM/post/*
echo "dummyfile" >> $casePath/DEM/post/dummy touch $casePath/DEM/post/.gitignore
cd $casePath cd $casePath
echo "done" echo "done"
} }

View File

@ -3,4 +3,4 @@ lagrangian/cfdemParticleComp/dir
recurrence/dir recurrence/dir
finiteVolume/dir finiteVolume/dir
../applications/solvers/cfdemSolverMultiphase/multiphaseMixture/dir ../applications/solvers/cfdemSolverMultiphase/multiphaseMixture/dir
../applications/solvers/cfdemSolverMultiphaseScalar/multiphaseMixture/dir ../applications/solvers/cfdemSolverMultiphaseScalar/multiphaseMixtureScalar/dir

View File

@ -10,6 +10,7 @@ cfdemSolverPiso/dir
cfdemSolverRhoPimple/dir cfdemSolverRhoPimple/dir
cfdemSolverIB/dir cfdemSolverIB/dir
cfdemSolverPisoScalar/dir cfdemSolverPisoScalar/dir
cfdemSolverIBContinuousForcing/dir
cfdemSolverRhoPimpleChem/dir cfdemSolverRhoPimpleChem/dir
cfdemSolverMultiphase/dir cfdemSolverMultiphase/dir
cfdemSolverMultiphaseScalar/dir cfdemSolverMultiphaseScalar/dir

View File

@ -19,3 +19,5 @@ cfdemSolverIB/twoSpheresGlowinskiMPI/dir
cfdemSolverPisoScalar/packedBedTemp/dir cfdemSolverPisoScalar/packedBedTemp/dir
cfdemSolverPiso/ErgunTestCG/dir cfdemSolverPiso/ErgunTestCG/dir
cfdemSolverIB/falling_sphere_two_way_coupling/dir

View File

@ -96,6 +96,7 @@ $(forceModels)/potentialRelaxation/potentialRelaxation.C
$(forceModels)/BeetstraDrag/BeetstraDrag.C $(forceModels)/BeetstraDrag/BeetstraDrag.C
$(forceModels)/BeetstraDragPoly/BeetstraDragPoly.C $(forceModels)/BeetstraDragPoly/BeetstraDragPoly.C
$(forceModels)/dSauter/dSauter.C $(forceModels)/dSauter/dSauter.C
$(forceModels)/transferFluidProperties/transferFluidProperties.C
$(forceModels)/Fines/Fines.C $(forceModels)/Fines/Fines.C
$(forceModels)/Fines/FinesFields.C $(forceModels)/Fines/FinesFields.C
$(forceModels)/Fines/FanningDynFines.C $(forceModels)/Fines/FanningDynFines.C

View File

@ -34,8 +34,8 @@ Description
#ifndef versionInfo_H #ifndef versionInfo_H
#define versionInfo_H #define versionInfo_H
word CFDEMversion="PFM 21.11"; word CFDEMversion="PFM 23.02";
word compatibleLIGGGHTSversion="PFM 21.11"; word compatibleLIGGGHTSversion="PFM 23.02";
word OFversion="6"; word OFversion="6";
Info << "\nCFDEMcoupling version: " << CFDEMversion << endl; Info << "\nCFDEMcoupling version: " << CFDEMversion << endl;

View File

@ -274,6 +274,8 @@ bool cfdemCloudEnergy::evolve
void cfdemCloudEnergy::postFlow() void cfdemCloudEnergy::postFlow()
{ {
if (ignore()) return;
cfdemCloud::postFlow(); cfdemCloud::postFlow();
forAll(energyModel_, modeli) forAll(energyModel_, modeli)
{ {
@ -285,18 +287,6 @@ void cfdemCloudEnergy::postFlow()
} }
} }
void cfdemCloudEnergy::solve()
{
forAll(energyModel_, modeli)
{
energyModel_[modeli].solve();
}
forAll(massTransferModel_, modeli)
{
massTransferModel_[modeli].solve();
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

View File

@ -142,8 +142,6 @@ public:
void postFlow(); void postFlow();
void solve();
}; };

View File

@ -36,7 +36,6 @@ Description
#include "locateModel.H" #include "locateModel.H"
#include "dataExchangeModel.H" #include "dataExchangeModel.H"
#include "IOModel.H" #include "IOModel.H"
#include <mpi.h>
#include "IOmanip.H" #include "IOmanip.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -58,6 +57,7 @@ cfdemCloudIB::cfdemCloudIB
angularVelocities_(NULL), angularVelocities_(NULL),
pRefCell_(readLabel(mesh.solutionDict().subDict("PISO").lookup("pRefCell"))), pRefCell_(readLabel(mesh.solutionDict().subDict("PISO").lookup("pRefCell"))),
pRefValue_(readScalar(mesh.solutionDict().subDict("PISO").lookup("pRefValue"))), pRefValue_(readScalar(mesh.solutionDict().subDict("PISO").lookup("pRefValue"))),
DEMTorques_(NULL),
haveEvolvedOnce_(false), haveEvolvedOnce_(false),
skipLagrangeToEulerMapping_(false) skipLagrangeToEulerMapping_(false)
{ {
@ -75,6 +75,7 @@ cfdemCloudIB::cfdemCloudIB
cfdemCloudIB::~cfdemCloudIB() cfdemCloudIB::~cfdemCloudIB()
{ {
dataExchangeM().destroy(angularVelocities_,3); dataExchangeM().destroy(angularVelocities_,3);
dataExchangeM().destroy(DEMTorques_,3);
} }
@ -82,8 +83,7 @@ cfdemCloudIB::~cfdemCloudIB()
void cfdemCloudIB::getDEMdata() void cfdemCloudIB::getDEMdata()
{ {
cfdemCloud::getDEMdata(); cfdemCloud::getDEMdata();
Info << "=== cfdemCloudIB::getDEMdata() === particle rotation not considered in CFD" << endl; dataExchangeM().getData("omega","vector-atom",angularVelocities_);
//dataExchangeM().getData("omega","vector-atom",angularVelocities_);
} }
bool cfdemCloudIB::reAllocArrays() bool cfdemCloudIB::reAllocArrays()
@ -92,12 +92,24 @@ bool cfdemCloudIB::reAllocArrays()
{ {
// get arrays of new length // get arrays of new length
dataExchangeM().allocateArray(angularVelocities_,0.,3); dataExchangeM().allocateArray(angularVelocities_,0.,3);
dataExchangeM().allocateArray(DEMTorques_,0.,3);
return true; return true;
} }
return false; return false;
} }
bool cfdemCloudIB::evolve() void cfdemCloudIB::giveDEMdata()
{
cfdemCloud::giveDEMdata();
dataExchangeM().giveData("hdtorque","vector-atom",DEMTorques_);
}
inline double ** cfdemCloudIB::DEMTorques() const
{
return DEMTorques_;
}
bool cfdemCloudIB::evolve(volVectorField& Us)
{ {
numberOfParticlesChanged_ = false; numberOfParticlesChanged_ = false;
arraysReallocated_=false; arraysReallocated_=false;
@ -140,6 +152,10 @@ bool cfdemCloudIB::evolve()
for (int i=0;i<nrForceModels();i++) forceM(i).setForce(); for (int i=0;i<nrForceModels();i++) forceM(i).setForce();
if(verbose_) Info << "setForce done." << endl; if(verbose_) Info << "setForce done." << endl;
// set particle velocity field
if(verbose_) Info << "- setVelocity(velocities_)" << endl;
calcForcingTerm(Us); // only needed for continuous forcing
// write DEM data // write DEM data
if(verbose_) Info << " -giveDEMdata()" << endl; if(verbose_) Info << " -giveDEMdata()" << endl;
giveDEMdata(); giveDEMdata();
@ -148,7 +164,8 @@ bool cfdemCloudIB::evolve()
haveEvolvedOnce_=true; haveEvolvedOnce_=true;
} }
Info << "evolve done." << endl;
if(verbose_) Info << "evolve done." << endl;
//if(verbose_) #include "debugInfo.H"; //if(verbose_) #include "debugInfo.H";
@ -158,6 +175,34 @@ bool cfdemCloudIB::evolve()
return doCouple; return doCouple;
} }
void cfdemCloudIB::calcForcingTerm(volVectorField& Us)
{
label cell = 0;
vector uP(0,0,0);
vector rVec(0,0,0);
vector velRot(0,0,0);
vector angVel(0,0,0);
Us.primitiveFieldRef() = vector::zero;
for (int index = 0; index < numberOfParticles(); ++index)
{
for (int subCell = 0; subCell < voidFractionM().cellsPerParticle()[index][0]; subCell++)
{
cell = cellIDs()[index][subCell];
if (cell >=0)
{
// calc particle velocity
for (int i=0;i<3;i++) rVec[i]=Us.mesh().C()[cell][i]-position(index)[i];
for (int i=0;i<3;i++) angVel[i]=angularVelocities()[index][i];
velRot=angVel^rVec;
for (int i=0;i<3;i++) uP[i] = velocities()[index][i]+velRot[i];
Us[cell] = (1-voidfractions_[index][subCell])*uP;
}
}
}
Us.correctBoundaryConditions();
}
void cfdemCloudIB::calcVelocityCorrection void cfdemCloudIB::calcVelocityCorrection
( (
volScalarField& p, volScalarField& p,
@ -190,7 +235,7 @@ void cfdemCloudIB::calcVelocityCorrection
for(int i=0;i<3;i++) uParticle[i] = velocities()[index][i]+velRot[i]; for(int i=0;i<3;i++) uParticle[i] = velocities()[index][i]+velRot[i];
// impose field velocity // impose field velocity
U[cellI]=(1-voidfractions_[index][subCell])*uParticle+voidfractions_[index][subCell]*U[cellI]; U[cellI]= (1-voidfractions_[index][subCell])*uParticle+voidfractions_[index][subCell]*U[cellI];
} }
} }
//} //}
@ -213,7 +258,7 @@ void cfdemCloudIB::calcVelocityCorrection
U.correctBoundaryConditions(); U.correctBoundaryConditions();
// correct the pressure as well // correct the pressure as well
p=p+phiIB/U.mesh().time().deltaT(); // do we have to account for rho here? p=p+phiIB/U.mesh().time().deltaT(); // no need to account for rho since p=(p/rho) in OF
p.correctBoundaryConditions(); p.correctBoundaryConditions();
if (couplingProperties_.found("checkinterface")) if (couplingProperties_.found("checkinterface"))

View File

@ -62,6 +62,8 @@ protected:
label pRefCell_; label pRefCell_;
scalar pRefValue_; scalar pRefValue_;
double **DEMTorques_;
bool haveEvolvedOnce_; bool haveEvolvedOnce_;
bool skipLagrangeToEulerMapping_; bool skipLagrangeToEulerMapping_;
@ -85,7 +87,13 @@ public:
bool reAllocArrays(); bool reAllocArrays();
bool evolve(); void giveDEMdata();
inline double ** DEMTorques() const;
bool evolve(volVectorField&);
void calcForcingTerm(volVectorField&);
void calcVelocityCorrection(volScalarField&,volVectorField&,volScalarField&,volScalarField&); // this could be moved to an IB mom couple model void calcVelocityCorrection(volScalarField&,volVectorField&,volScalarField&,volScalarField&); // this could be moved to an IB mom couple model
@ -96,7 +104,6 @@ public:
{ {
return angularVelocities_; return angularVelocities_;
} }
}; };

View File

@ -125,6 +125,14 @@ void IOModel::streamDataToPath(const fileName& path, const double* const* array,
else fileStream << "{}" << "\n"; else fileStream << "{}" << "\n";
return; return;
} }
#if OPENFOAM_VERSION_MAJOR > 4
else if (barycentricOutput_ && type == "position")
{
// Force construction of face-diagonal decomposition before construction
// of particle which uses parallel transfers.
(void)particleCloud_.mesh().tetBasePtIs();
}
#endif
fileStream << token::BEGIN_LIST << nl; fileStream << token::BEGIN_LIST << nl;
@ -139,9 +147,9 @@ void IOModel::streamDataToPath(const fileName& path, const double* const* array,
} }
else if (type == "position") else if (type == "position")
{ {
#if OPENFOAM_VERSION_MAJOR < 5 #if OPENFOAM_VERSION_MAJOR > 4
fileStream << "( " << array[index][0] << " " << array[index][1] << " " << array[index][2] << " ) " << cellIDs[index][0] << nl; if (barycentricOutput_)
#else {
particle part particle part
( (
particleCloud_.mesh(), particleCloud_.mesh(),
@ -151,7 +159,12 @@ void IOModel::streamDataToPath(const fileName& path, const double* const* array,
part.writePosition(fileStream); part.writePosition(fileStream);
fileStream << nl; fileStream << nl;
}
else
#endif #endif
{
fileStream << "( " << array[index][0] << " " << array[index][1] << " " << array[index][2] << " ) " << cellIDs[index][0] << nl;
}
} }
else if (type == "vector") else if (type == "vector")
{ {
@ -179,7 +192,8 @@ IOModel::IOModel
dict_(dict), dict_(dict),
particleCloud_(sm), particleCloud_(sm),
time_(sm.mesh().time()), time_(sm.mesh().time()),
parOutput_(true) parOutput_(true),
barycentricOutput_(true)
{ {
if ( if (
particleCloud_.dataExchangeM().type()=="oneWayVTK" || particleCloud_.dataExchangeM().type()=="oneWayVTK" ||
@ -189,6 +203,11 @@ IOModel::IOModel
parOutput_ = false; parOutput_ = false;
Warning << "IO model is in serial write mode, only data on proc 0 is written" << endl; Warning << "IO model is in serial write mode, only data on proc 0 is written" << endl;
} }
if (dict_.found("cartesianOutput"))
{
barycentricOutput_ = false;
}
} }

View File

@ -65,6 +65,8 @@ protected:
bool parOutput_; bool parOutput_;
bool barycentricOutput_;
public: public:
//- Runtime type information //- Runtime type information

View File

@ -246,8 +246,6 @@ void diffusionCoefficient::execute()
double**& diffusionCoefficients_ = particleCloud_.getParticlePropertyRef<double**>(diffusantGasNames_[j]); double**& diffusionCoefficients_ = particleCloud_.getParticlePropertyRef<double**>(diffusantGasNames_[j]);
particleCloud_.dataExchangeM().giveData(pushName,"scalar-atom",diffusionCoefficients_); particleCloud_.dataExchangeM().giveData(pushName,"scalar-atom",diffusionCoefficients_);
} }
Info << "give data done" << endl;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -57,8 +57,10 @@ initMultiLayers::initMultiLayers
mesh_(sm.mesh()), mesh_(sm.mesh()),
verbose_(propsDict_.lookupOrDefault<bool>("verbose",false)), verbose_(propsDict_.lookupOrDefault<bool>("verbose",false)),
maxNumLayers_(0), maxNumLayers_(0),
maxNumParticlesPerType_(propsDict_.lookupOrDefault<label>("maxNumParticlesPerType",1000000)),
numLayers_(propsDict_.lookupOrDefault<labelList>("numLayers",labelList(1,-1))), numLayers_(propsDict_.lookupOrDefault<labelList>("numLayers",labelList(1,-1))),
partTypes_(propsDict_.lookupOrDefault<labelList>("partTypes",labelList(1,-1))), partTypes_(propsDict_.lookupOrDefault<labelList>("partTypes",labelList(1,-1))),
searchLayers_(propsDict_.lookupOrDefault<labelList>("searchLayers",labelList(1,-1))),
relRadiiRegName_(typeName + "relRadii"), relRadiiRegName_(typeName + "relRadii"),
filepath_(string(propsDict_.lookup("filepath"))), filepath_(string(propsDict_.lookup("filepath"))),
initialized_(false) initialized_(false)
@ -107,7 +109,7 @@ bool initMultiLayers::init()
} }
Info << "\nReading" << endl; Info << "\nReading" << endl;
Info << "\t" << filename << endl; Info << "\t" << filename << endl;
readDump(filename, type, indices, positions, relradii); label numLines = readDump(filename, type, indices, positions, relradii);
Info << "Binning particle displacements on mesh for type " << type << endl; Info << "Binning particle displacements on mesh for type " << type << endl;
@ -144,7 +146,7 @@ bool initMultiLayers::init()
); );
label cellI = -1; label cellI = -1;
for (label lineI = 0; lineI < indices.size(); lineI++) for (label lineI = 0; lineI < numLines; lineI++)
{ {
position = positions[lineI]; position = positions[lineI];
relrad = relradii[lineI]; relrad = relradii[lineI];
@ -178,8 +180,8 @@ bool initMultiLayers::init()
if(cellK >= 0 && partType == type) if(cellK >= 0 && partType == type)
{ {
// look for the nearest occupied cell // look for the nearest occupied cell
cellKoccupied = findNearestCellWithValue(cellK, particlesInCell);
listIndex = getListIndex(partType); listIndex = getListIndex(partType);
cellKoccupied = findNearestCellWithValue(cellK, particlesInCell,searchLayers_[listIndex]);
if (cellKoccupied >= 0) if (cellKoccupied >= 0)
{ {
relRadiiLoopVar = relRadiiField[cellKoccupied]; relRadiiLoopVar = relRadiiField[cellKoccupied];
@ -215,7 +217,7 @@ void initMultiLayers::execute()
} }
} }
label initMultiLayers::findNearestCellWithValue(label refCell, volScalarField &particlesInCell) const label initMultiLayers::findNearestCellWithValue(label refCell, volScalarField &particlesInCell, label searchLayers) const
{ {
if (particlesInCell[refCell] > 0.5) return refCell; if (particlesInCell[refCell] > 0.5) return refCell;
@ -226,6 +228,8 @@ label initMultiLayers::findNearestCellWithValue(label refCell, volScalarField &p
neighbors.insert(refCell); neighbors.insert(refCell);
recentNeighbors.insert(refCell); recentNeighbors.insert(refCell);
label layersSearched = 0;
while(true) while(true)
{ {
for (std::set<label>::iterator it=recentNeighbors.begin(); it!=recentNeighbors.end(); ++it) for (std::set<label>::iterator it=recentNeighbors.begin(); it!=recentNeighbors.end(); ++it)
@ -250,6 +254,8 @@ label initMultiLayers::findNearestCellWithValue(label refCell, volScalarField &p
recentNeighbors.clear(); recentNeighbors.clear();
recentNeighbors = newNeighbors; recentNeighbors = newNeighbors;
newNeighbors.clear(); newNeighbors.clear();
layersSearched++;
if (layersSearched >= searchLayers && searchLayers > 0) return -1;
} }
} }
@ -264,7 +270,7 @@ label initMultiLayers::getListIndex(label testElement) const
return -1; return -1;
} }
void initMultiLayers::readDump(std::string filename, label type, labelList &indices, vectorList &positions, vectorList &relradii) label initMultiLayers::readDump(std::string filename, label type, labelList &indices, vectorList &positions, vectorList &relradii)
{ {
#include <fstream> #include <fstream>
@ -281,6 +287,10 @@ void initMultiLayers::readDump(std::string filename, label type, labelList &indi
positions.clear(); positions.clear();
relradii.clear(); relradii.clear();
indices.setSize(maxNumParticlesPerType_);
positions.setSize(maxNumParticlesPerType_);
relradii.setSize(maxNumParticlesPerType_);
std::ifstream file(filename); std::ifstream file(filename);
std::string str; std::string str;
while (std::getline(file, str)) while (std::getline(file, str))
@ -292,12 +302,17 @@ void initMultiLayers::readDump(std::string filename, label type, labelList &indi
{ {
FatalError<< "Particle of type " << partType << " detected in " << filename << abort(FatalError); FatalError<< "Particle of type " << partType << " detected in " << filename << abort(FatalError);
} }
indices.append(partIndex);
positions.append(vector(x,y,z)); indices[lineCounter-leadingLines] = partIndex;
relradii.append(vector(r1,r2,r3)); positions[lineCounter-leadingLines] = vector(x,y,z);
relradii[lineCounter-leadingLines] = vector(r1,r2,r3);
} }
lineCounter++; lineCounter++;
if (lineCounter == maxNumParticlesPerType_) break;
} }
label readLines = lineCounter - leadingLines;
return readLines;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -60,10 +60,14 @@ private:
label maxNumLayers_; label maxNumLayers_;
label maxNumParticlesPerType_;
labelList numLayers_; labelList numLayers_;
labelList partTypes_; labelList partTypes_;
labelList searchLayers_;
vector defaultRelRadii_; vector defaultRelRadii_;
const word relRadiiRegName_; const word relRadiiRegName_;
@ -74,9 +78,9 @@ private:
bool init(); bool init();
void readDump(std::string, label, labelList &, vectorList &, vectorList &); label readDump(std::string, label, labelList &, vectorList &, vectorList &);
label findNearestCellWithValue(label, volScalarField &) const; label findNearestCellWithValue(label, volScalarField &, label) const;
label getListIndex(label) const; label getListIndex(label) const;

View File

@ -174,8 +174,6 @@ void massTransferCoeff::execute()
// give DEM data // give DEM data
particleCloud_.dataExchangeM().giveData(partNuName_, "scalar-atom", partNu_); particleCloud_.dataExchangeM().giveData(partNuName_, "scalar-atom", partNu_);
particleCloud_.dataExchangeM().giveData(partReName_, "scalar-atom", partRe_); particleCloud_.dataExchangeM().giveData(partReName_, "scalar-atom", partRe_);
Info << "give data done" << endl;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -169,8 +169,6 @@ void reactantPerParticle::execute()
// give DEM data // give DEM data
particleCloud_.dataExchangeM().giveData(partReactantName_, "scalar-atom", reactantPerParticle_); particleCloud_.dataExchangeM().giveData(partReactantName_, "scalar-atom", reactantPerParticle_);
Info << "give data done" << endl;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -100,6 +100,7 @@ void One2One::setup
comm_ comm_
); );
// count number of receives
ncollected_ = 0; ncollected_ = 0;
int nrequests = 0; int nrequests = 0;
for (int i = 0; i < nsrc_procs_; i++) for (int i = 0; i < nsrc_procs_; i++)
@ -115,6 +116,18 @@ void One2One::setup
} }
} }
// count number of sends
if (nlocal_ > 0)
{
for (int i = 0; i < ndst_procs_; i++)
{
if (dst_procs_[i] != me_)
{
nrequests++;
}
}
}
if (nrequests > 0) if (nrequests > 0)
{ {
request_ = new MPI_Request[nrequests]; request_ = new MPI_Request[nrequests];
@ -143,23 +156,27 @@ void One2One::exchange(T *&src, T *&dst, int data_length)
{ {
if (src_procs_[i] != me_) if (src_procs_[i] != me_)
{ {
int tag = (src_procs_[i] << 16) | me_;
#ifdef O2ODEBUG #ifdef O2ODEBUG
std::cout<< "[" << me_ << "]" std::cout<< "[" << me_ << "]"
<< " RCV " << i << " RCV " << (i+1)
<< " of " << nsrc_procs_ << " of " << nsrc_procs_
<< " from: " << src_procs_[i] << " from: " << src_procs_[i]
<< " natoms_[src_procs_[i]] " << natoms_[src_procs_[i]] << " natoms_[src_procs_[i]] " << natoms_[src_procs_[i]]
<< " datalength " << data_length << " data_length " << data_length
<< " offset " << offset << " offset " << offset
<< " tag " << tag
<< std::endl; << std::endl;
#endif #endif
MPI_Irecv MPI_Irecv
( (
&dst[offset], &dst[offset],
natoms_[src_procs_[i]]*data_length, natoms_[src_procs_[i]]*data_length,
wrap.mpi_type, wrap.mpi_type,
src_procs_[i], src_procs_[i],
MPI_ANY_TAG, tag,
comm_, comm_,
&request_[requesti] &request_[requesti]
); );
@ -168,16 +185,34 @@ void One2One::exchange(T *&src, T *&dst, int data_length)
else // data is available on-proc else // data is available on-proc
{ {
offset_local = offset; offset_local = offset;
#ifdef O2ODEBUG
std::cout<< "[" << me_ << "]"
<< " RCV " << (i+1)
<< " of " << nsrc_procs_
<< " from: " << src_procs_[i]
<< " skipped (self)"
<< " offset_local " << offset_local
<< std::endl;
#endif
} }
} }
#ifdef O2ODEBUG
else
{
std::cout<< "[" << me_ << "]"
<< " RCV " << (i+1)
<< " of " << nsrc_procs_
<< " from: " << src_procs_[i]
<< " skipped (no data)"
<< std::endl;
}
#endif
offset += natoms_[src_procs_[i]]*data_length; offset += natoms_[src_procs_[i]]*data_length;
} }
// make sure all receives are posted // nonblocking sends
MPI_Barrier(comm_);
// blocking sends - do nonblocking instead
// since doing many-2-many here?
// only do sends if I have particles // only do sends if I have particles
if (nlocal_ > 0) if (nlocal_ > 0)
{ {
@ -185,29 +220,62 @@ void One2One::exchange(T *&src, T *&dst, int data_length)
{ {
if (dst_procs_[i] != me_) if (dst_procs_[i] != me_)
{ {
int tag = (me_ << 16) | dst_procs_[i];
#ifdef O2ODEBUG #ifdef O2ODEBUG
std::cout<< "[" << me_ << "]" std::cout<< "[" << me_ << "]"
<< " SEND to: " << dst_procs_[i] << " SEND to: " << dst_procs_[i]
<< " nlocal_ " << nlocal_ << " nlocal_ " << nlocal_
<< " data_length " << data_length << " data_length " << data_length
<< " tag " << tag
<< std::endl; << std::endl;
#endif #endif
MPI_Send
MPI_Isend
( (
src, src,
nlocal_*data_length, nlocal_*data_length,
wrap.mpi_type, wrap.mpi_type,
dst_procs_[i], dst_procs_[i],
0, tag,
comm_ comm_,
&request_[requesti]
); );
requesti++;
}
#ifdef O2ODEBUG
else
{
std::cout<< "[" << me_ << "]"
<< " SEND to: " << dst_procs_[i]
<< " skipped (self)" << std::endl;
}
#endif
} }
} }
#ifdef O2ODEBUG
else
{
std::cout<< "[" << me_ << "]" << " SEND skipped (no data)" << std::endl;
} }
#endif
// only wait if requests were actually posted // only wait if requests were actually posted
if (requesti > 0) if (requesti > 0)
{
#ifdef O2ODEBUG
std::cout<< "[" << me_ << "]"
<< " WAIT for: " << requesti << " requests" << std::endl;
#endif
MPI_Waitall(requesti, request_, status_); MPI_Waitall(requesti, request_, status_);
}
#ifdef O2ODEBUG
else
{
std::cout<< "[" << me_ << "]" << " WAIT skipped (no requests)" << std::endl;
}
#endif
// copy on-proc data // copy on-proc data
if (offset_local > -1) if (offset_local > -1)
@ -223,6 +291,13 @@ void One2One::exchange(T *&src, T *&dst, int data_length)
dst[locali+offset_local] = src[locali]; dst[locali+offset_local] = src[locali];
} }
} }
// wait for all procs to complete data exchange
#ifdef O2ODEBUG
std::cout<< "[" << me_ << "] BARRIER" << std::endl;
#endif
MPI_Barrier(comm_);
} }
template void One2One::exchange<int>(int*&, int*&, int); template void One2One::exchange<int>(int*&, int*&, int);

View File

@ -183,6 +183,7 @@ void twoWayOne2One::createProcMap()
point(ligbb[0][0], ligbb[0][1], ligbb[0][2]), point(ligbb[0][0], ligbb[0][1], ligbb[0][2]),
point(ligbb[1][0], ligbb[1][1], ligbb[1][2]) point(ligbb[1][0], ligbb[1][1], ligbb[1][2])
); );
delete [] ligbb;
if (boundBoxMargin_ > 0.) if (boundBoxMargin_ > 0.)
{ {
thisLigBox.max() = thisLigBox.max() + boundBoxMargin_ * vector::one; thisLigBox.max() = thisLigBox.max() + boundBoxMargin_ * vector::one;
@ -230,6 +231,7 @@ twoWayOne2One::~twoWayOne2One()
{ {
delete foam2lig_; delete foam2lig_;
delete lig2foam_; delete lig2foam_;
delete [] lig2foam_mask_;
destroy(lig2foam_ids_); destroy(lig2foam_ids_);
destroy(foam2lig_ids_); destroy(foam2lig_ids_);
@ -777,10 +779,7 @@ void twoWayOne2One::locateParticles()
lig2foam_->exchange(my_prev_cell_ids, prev_cell_ids_); lig2foam_->exchange(my_prev_cell_ids, prev_cell_ids_);
} }
if (lig2foam_mask_)
{
delete [] lig2foam_mask_; delete [] lig2foam_mask_;
}
lig2foam_mask_ = new bool[lig2foam_->ncollected_]; lig2foam_mask_ = new bool[lig2foam_->ncollected_];
DynamicList<label> cellIds; DynamicList<label> cellIds;

View File

@ -105,8 +105,6 @@ public:
virtual void postFlow() {} virtual void postFlow() {}
virtual void solve() {}
const volScalarField& kf0Field() const; const volScalarField& kf0Field() const;
const volScalarField& CpField() const; const volScalarField& CpField() const;
@ -116,7 +114,6 @@ public:
return 0.0; return 0.0;
} }
}; };

View File

@ -283,8 +283,6 @@ void heatTransferInterGrain::calcEnergyContribution()
if(cellI >= 0) if(cellI >= 0)
{ {
voidfraction = voidfraction_[cellI]; voidfraction = voidfraction_[cellI];
if (voidfraction < 0.01)
voidfraction = 0.01;
partVolume = particleCloud_.particleVolume(index); partVolume = particleCloud_.particleVolume(index);
QPartPart = QPartPart_[cellI]; QPartPart = QPartPart_[cellI];
@ -426,8 +424,6 @@ void heatTransferInterGrain::calcPartThermRad()
scalar heatTransferInterGrain::FE(scalar voidfraction, scalar emissivity, scalar L) scalar heatTransferInterGrain::FE(scalar voidfraction, scalar emissivity, scalar L)
{ {
if (voidfraction < 1 - SMALL) return 1.0; // limit of voidfraction -> 1.0
scalar B = 1.25 * pow((1-voidfraction)/voidfraction,1.111); scalar B = 1.25 * pow((1-voidfraction)/voidfraction,1.111);
scalar sqrt_aP = sqrt(1-voidfraction); scalar sqrt_aP = sqrt(1-voidfraction);
scalar x = 2.0/emissivity - 1.0; scalar x = 2.0/emissivity - 1.0;

View File

@ -104,7 +104,7 @@ protected:
const scalar TMin = 10.0; const scalar TMin = 10.0;
const scalar voidfracMax = 0.95; const scalar voidfracMax = 0.8; // maximum voidfraction for which B-B correlation is valid; TODO: check value!
const scalar voidfracMin = 0.05; const scalar voidfracMin = 0.05;

View File

@ -77,7 +77,6 @@ BeetstraDrag::BeetstraDrag
particleCloud_.probeM().vectorFields_.append("dragForce"); //first entry must be the force particleCloud_.probeM().vectorFields_.append("dragForce"); //first entry must be the force
particleCloud_.probeM().vectorFields_.append("Urel"); particleCloud_.probeM().vectorFields_.append("Urel");
particleCloud_.probeM().scalarFields_.append("Rep"); particleCloud_.probeM().scalarFields_.append("Rep");
particleCloud_.probeM().scalarFields_.append("betaP");
particleCloud_.probeM().scalarFields_.append("voidfraction"); particleCloud_.probeM().scalarFields_.append("voidfraction");
particleCloud_.probeM().writeHeader(); particleCloud_.probeM().writeHeader();

View File

@ -34,7 +34,6 @@ Description
#include "ParmarBassetForce.H" #include "ParmarBassetForce.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "smoothingModel.H" #include "smoothingModel.H"
#include "constDiffSmoothing.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -71,17 +70,18 @@ ParmarBassetForce::ParmarBassetForce
U_(sm.mesh().lookupObject<volVectorField> (velFieldName_)), U_(sm.mesh().lookupObject<volVectorField> (velFieldName_)),
UsFieldName_(propsDict_.lookup("granVelFieldName")), UsFieldName_(propsDict_.lookup("granVelFieldName")),
Us_(sm.mesh().lookupObject<volVectorField> (UsFieldName_)), Us_(sm.mesh().lookupObject<volVectorField> (UsFieldName_)),
nInt_(readLabel(propsDict_.lookup("nIntegral"))), nInt_(propsDict_.lookupOrDefault<int>("nIntegral", -1)),
discOrder_(readLabel(propsDict_.lookup("discretisationOrder"))), discOrder_(propsDict_.lookupOrDefault<int>("discretisationOrder", 1)),
nHist_(nInt_+discOrder_+1), ddtUrelHistSize_(nInt_+discOrder_),
FHistSize_(2*discOrder_+1), rHistSize_(nInt_),
ddtUrelHist_(nHist_,NULL), // UrelHist_[ndt in past][particle ID][dim] FHistSize_(2*discOrder_),
rHist_(nHist_,NULL), // rHist_[ndt in past][particle ID][0] ddtUrelHistRegName_(typeName + "ddtUrelHist"), // indexed as: ddtUrelHist_[particle ID][iDim*ddtUrelHistSize_+iHist]
FHist_(2,List<double**>(FHistSize_,NULL)), // FHist_[k={1,2}-1][ndt in past][particle ID][dim] rHistRegName_(typeName + "rHist"), // indexed as: rHist_[particle ID][iHist]
gH0_(NULL), FHistRegName_(typeName + "FHist"), // indexed as: ddtUrelHist_[particle ID][iDim*FHistSize_*2+iHist*2+k]
tRef_(NULL), gH0RegName_(typeName + "gH0"),
mRef_(NULL), tRefRegName_(typeName + "tRef"),
lRef_(NULL), mRefRegName_(typeName + "mRef"),
lRefRegName_(typeName + "lRef"),
Urel_ Urel_
( IOobject ( IOobject
( (
@ -115,12 +115,12 @@ ParmarBassetForce::ParmarBassetForce
) )
) )
{ {
// init force sub model // init force sub model
setForceSubModels(propsDict_); setForceSubModels(propsDict_);
// define switches which can be read from dict // define switches which can be read from dict
forceSubM(0).setSwitchesList(SW_TREAT_FORCE_EXPLICIT,true); // activate treatExplicit switch forceSubM(0).setSwitchesList(SW_TREAT_FORCE_EXPLICIT,true); // activate treatExplicit switch
forceSubM(0).setSwitchesList(SW_INTERPOLATION,true); // activate search for interpolate switch forceSubM(0).setSwitchesList(SW_INTERPOLATION,true); // activate search for interpolate switch
forceSubM(0).setSwitchesList(SW_VERBOSE,true); // activate search for verbose switch
forceSubM(0).readSwitches(); forceSubM(0).readSwitches();
//Extra switches/settings //Extra switches/settings
@ -129,15 +129,23 @@ ParmarBassetForce::ParmarBassetForce
if (discOrder_ < 1 || discOrder_ > 2) if (discOrder_ < 1 || discOrder_ > 2)
FatalError << "Parmar Basset Force: Discretisation order > 2 not implemented!" << abort(FatalError); FatalError << "Parmar Basset Force: Discretisation order > 2 not implemented!" << abort(FatalError);
if (nInt_ < 1)
FatalError << "Parmar Basset Force: nIntegral missing or invalid, must be > 1" << abort(FatalError);
// allocate particle properties
particleCloud_.registerParticleProperty<double**>(ddtUrelHistRegName_,3*ddtUrelHistSize_,NOTONCPU,false);
particleCloud_.registerParticleProperty<double**>( rHistRegName_, rHistSize_,NOTONCPU,false);
particleCloud_.registerParticleProperty<double**>( FHistRegName_, 6*FHistSize_,NOTONCPU,false);
particleCloud_.registerParticleProperty<double**>( gH0RegName_, 1 ,NOTONCPU,false);
particleCloud_.registerParticleProperty<double**>( tRefRegName_, 1 ,NOTONCPU,false);
particleCloud_.registerParticleProperty<double**>( mRefRegName_, 1 ,NOTONCPU,false);
particleCloud_.registerParticleProperty<double**>( lRefRegName_, 1 ,NOTONCPU,false);
//Append the field names to be probed //Append the field names to be probed
particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().initialize(typeName, typeName+".logDat");
particleCloud_.probeM().vectorFields_.append("ParmarBassetForce"); //first entry must the be the force particleCloud_.probeM().vectorFields_.append("ParmarBassetForce"); //first entry must the be the force
particleCloud_.probeM().vectorFields_.append("Urel"); particleCloud_.probeM().vectorFields_.append("Urel");
particleCloud_.probeM().vectorFields_.append("ddtUrel"); particleCloud_.probeM().vectorFields_.append("ddtUrel");
//
particleCloud_.probeM().vectorFields_.append("UrelNoSmooth");
particleCloud_.probeM().vectorFields_.append("ddtUrelNoSmooth");
//
particleCloud_.probeM().vectorFields_.append("Fshort"); particleCloud_.probeM().vectorFields_.append("Fshort");
particleCloud_.probeM().vectorFields_.append("Flong1"); particleCloud_.probeM().vectorFields_.append("Flong1");
particleCloud_.probeM().vectorFields_.append("Flong2"); particleCloud_.probeM().vectorFields_.append("Flong2");
@ -158,20 +166,6 @@ ParmarBassetForce::ParmarBassetForce
ParmarBassetForce::~ParmarBassetForce() ParmarBassetForce::~ParmarBassetForce()
{ {
particleCloud_.dataExchangeM().destroy(gH0_, 1);
particleCloud_.dataExchangeM().destroy(tRef_, 1);
particleCloud_.dataExchangeM().destroy(mRef_, 1);
particleCloud_.dataExchangeM().destroy(lRef_, 1);
for (int i=0; i<nHist_; i++)
{
particleCloud_.dataExchangeM().destroy(ddtUrelHist_[i],3);
particleCloud_.dataExchangeM().destroy(rHist_ [i],1);
}
for (int i=0; i<FHistSize_; i++)
for (int k=0; k<2; k++)
particleCloud_.dataExchangeM().destroy(FHist_[k][i],3);
} }
@ -180,16 +174,18 @@ ParmarBassetForce::~ParmarBassetForce()
void ParmarBassetForce::setForce() const void ParmarBassetForce::setForce() const
{ {
// allocate arrays double**& ddtUrelHist_ = particleCloud_.getParticlePropertyRef<double**>(ddtUrelHistRegName_);
if(particleCloud_.numberOfParticlesChanged()) double**& rHist_ = particleCloud_.getParticlePropertyRef<double**>( rHistRegName_);
reAllocArrays(); double**& FHist_ = particleCloud_.getParticlePropertyRef<double**>( FHistRegName_);
double**& gH0_ = particleCloud_.getParticlePropertyRef<double**>( gH0RegName_);
double**& tRef_ = particleCloud_.getParticlePropertyRef<double**>( tRefRegName_);
double**& mRef_ = particleCloud_.getParticlePropertyRef<double**>( mRefRegName_);
double**& lRef_ = particleCloud_.getParticlePropertyRef<double**>( lRefRegName_);
vector position(0,0,0); vector position(0,0,0);
vector Urel(0,0,0); vector Urel(0,0,0);
vector ddtUrel(0,0,0); vector ddtUrel(0,0,0);
scalar t0min = 0.00;
const volScalarField& nufField = forceSubM(0).nuField(); const volScalarField& nufField = forceSubM(0).nuField();
const volScalarField& rhoField = forceSubM(0).rhoField(); const volScalarField& rhoField = forceSubM(0).rhoField();
@ -220,26 +216,17 @@ void ParmarBassetForce::setForce() const
Urel_ = Us_ - U_; Urel_ = Us_ - U_;
ddtUrel_ = fvc::ddt(Us_) - fvc::ddt(U_) - (Us_ & fvc::grad(U_)); ddtUrel_ = fvc::ddt(Us_) - fvc::ddt(U_) - (Us_ & fvc::grad(U_));
//
volVectorField UrelNoSmooth_ = Urel_;
volVectorField ddtUrelNoSmooth_ = ddtUrel_;
//
smoothingM().smoothen(Urel_); smoothingM().smoothen(Urel_);
smoothingM().smoothen(ddtUrel_); smoothingM().smoothen(ddtUrel_);
interpolationCellPoint<vector> UrelInterpolator_(Urel_); interpolationCellPoint<vector> UrelInterpolator_(Urel_);
interpolationCellPoint<vector> ddtUrelInterpolator_(ddtUrel_); interpolationCellPoint<vector> ddtUrelInterpolator_(ddtUrel_);
//
interpolationCellPoint<vector> UrelNoSmoothInterpolator_(UrelNoSmooth_);
interpolationCellPoint<vector> ddtUrelNoSmoothInterpolator_(ddtUrelNoSmooth_);
//
for(int index = 0;index < particleCloud_.numberOfParticles(); index++) for(int index = 0;index < particleCloud_.numberOfParticles(); index++)
{ {
vector ParmarBassetForce(0,0,0); vector ParmarBassetForce(0,0,0);
vector Fshort(0,0,0); vector Fshort(0,0,0);
vector Flong[2]={vector::zero, vector::zero};
label cellI = particleCloud_.cellIDs()[index][0]; label cellI = particleCloud_.cellIDs()[index][0];
if (cellI > -1) // particle Found if (cellI > -1) // particle Found
@ -268,12 +255,13 @@ void ParmarBassetForce::setForce() const
if (gH0_[index][0]!=NOTONCPU) if (gH0_[index][0]!=NOTONCPU)
{ {
r = pow(gH0_[index][0]/gH,1.5); // Eq. 3.4 scalar gHratio = gH0_[index][0]/gH;
r = gHratio*sqrt(gHratio); // gHratio^1.5, Eq. 3.4
if (r<0.25 || r>2.0) if (r<0.25 || r>2.0)
{ {
gH0_[index][0] = NOTONCPU; //reset reference gH0_[index][0] = NOTONCPU; //reset reference
ddtUrelHist_[0][index][0] = NOTONCPU; //reset ddtU history (only component used for checking nKnown) ddtUrelHist_[index][0] = NOTONCPU; //reset ddtU history (only component used for checking nKnown)
} }
} }
@ -298,29 +286,15 @@ void ParmarBassetForce::setForce() const
scalar dt = U_.mesh().time().deltaT().value() / tRef_[index][0]; // dim.less scalar dt = U_.mesh().time().deltaT().value() / tRef_[index][0]; // dim.less
scalar t0 = nInt_*dt; // dim.less scalar t0 = nInt_*dt; // dim.less
//********* update histories *********//
// non-dimensionlise // non-dimensionlise
Urel /= mps; Urel /= mps;
ddtUrel /= mpss; ddtUrel /= mpss;
// update ddtUrel and r history
update_ddtUrelHist(ddtUrel,index); // add current dim.less ddtUrel to history
update_rHist(r,index); // add current r to history
// warning and reset for too small t0
if (t0<t0min)
{
Pout << "ParmarBassetForce WARNING: t0 = " << t0 << " at ID = " << index << endl;
gH0_[index][0] = NOTONCPU; //reset reference
ddtUrelHist_[0][index][0] = NOTONCPU; //reset ddtU history (only component used for checking nKnown)
}
// check length of known history // check length of known history
int nKnown = 0; int nKnown = 1; // we always know the current step
for (int j=0; j<nHist_; j++) // loop over past times for (int j=0; j<ddtUrelHistSize_; j++) // loop over past times
{ {
if (ddtUrelHist_[j][index][0] == NOTONCPU) if (ddtUrelHist_[index][j] == NOTONCPU)
break; break;
else else
nKnown++; nKnown++;
@ -332,117 +306,92 @@ void ParmarBassetForce::setForce() const
int nShort = min(nKnown,nInt_+1); int nShort = min(nKnown,nInt_+1);
// int_0^dt K(r,xi) dxi * ddtU(t) dxi (singularity treated by assuming constant acceleration) // int_0^dt K(r,xi) dxi * ddtU(t) dxi (singularity treated by assuming constant acceleration)
if (nShort>0)
{
for (int i=0; i<3; i++) // loop over dimensions for (int i=0; i<3; i++) // loop over dimensions
Fshort[i] = -calculateK0(r,dt) * ddtUrelHist_[0][index][i]; Fshort[i] = -calculateK0(r,dt) * ddtUrel[i];
}
// int_dt^t0 K(r,xi) * ddtU(t-xi) dxi (trapezoid rule) // int_dt^t0 K(r,xi) * ddtU(t-xi) dxi (trapezoid rule)
if (nShort>2) if (nShort>2)
{ {
for (int j=1; j<nShort; j++) for (int j=0; j<(nShort-1); j++) // we don't use the current step here, hence nShort-1
{ {
scalar xi = j*dt; scalar xi = (j+1)*dt;
scalar K = pow((pow(xi,.25) + rHist_[j][index][0]*xi),-2.); // Eq. 3.4 scalar invsqrtK = sqrt(sqrt(xi)) + rHist_[index][j]*xi; // K^-0.5
scalar K = 1./(invsqrtK*invsqrtK); // Eq. 3.4
for (int i=0; i<3; i++) // loop over dimensions for (int i=0; i<3; i++) // loop over dimensions
Fshort[i] -= trapWeight(j,nShort) * K * ddtUrelHist_[j][index][i] * dt; Fshort[i] -= trapWeight(j,nShort-1) * K * ddtUrelHist_[index][i*ddtUrelHistSize_+j] * dt;
} }
} }
//********* long term force computing (differential form) *********// //********* long term force computing (differential form) *********//
// update F1, F2 history
update_FHist(vector::zero,vector::zero,index);
// initialise ddtUrel(t0) and Flong(:) as 0 and r(t0) as 1 // initialise ddtUrel(t0) and Flong(:) as 0 and r(t0) as 1
if (nKnown == nInt_) if (nKnown == nInt_)
{ {
for (int j=nInt_; j<nHist_; j++) // loop over past times // initialise the histories beyond nInt
{ for (int j=nInt_-1; j<rHistSize_; j++) // loop over past times
rHist_[j][index][0] = 1.; rHist_[index][j] = 1.;
for (int j=nInt_-1; j<ddtUrelHistSize_; j++) // loop over past times
for (int i=0; i<3; i++) // loop over dimensions for (int i=0; i<3; i++) // loop over dimensions
ddtUrelHist_[j][index][i] = 0.0; ddtUrelHist_[index][i*ddtUrelHistSize_+j] = 0.0;
}
for (int k=0; k<2; k++) // loop over F1, F2 for (int k=0; k<2; k++) // loop over F1, F2
for (int j=0; j<FHistSize_; j++) // loop over past times for (int j=0; j<FHistSize_; j++) // loop over past times
for (int i=0; i<3; i++) // loop over dimensions for (int i=0; i<3; i++) // loop over dimensions
FHist_[k][j][index][i] = 0.0; FHist_[index][i*FHistSize_*2+j*2+k] = 0.0;
nKnown = nHist_; nKnown = ddtUrelHistSize_+1;
} }
// solve ODEs // solve ODEs
if (nKnown == nHist_) if (nKnown == ddtUrelHistSize_+1)
{ {
for (int k=0; k<2; k++) // loop over F1, F2 for (int k=0; k<2; k++) // loop over F1, F2
{ {
//calculate coefficients //calculate coefficients
double C[4]; double C[4];
calculateCoeffs(k,t0,rHist_[nInt_][index][0],c,chi,C); calculateCoeffs(k,t0,rHist_[index][nInt_-1],c,chi,C);
// solve Eq. 3.20 // solve Eq. 3.20
solveFlongODE(k,C,dt,index); Flong[k] = solveFlongODE(FHist_,ddtUrelHist_,k,C,dt,index);
} }
} }
//********* update histories *********//
update_ddtUrelHist(ddtUrelHist_,ddtUrel,index); // add current dim.less ddtUrel to history
update_rHist(rHist_,r,index); // add current r to history
update_FHist(FHist_,Flong[0],Flong[1],index);
//********* total force *********// //********* total force *********//
// sum and convert to N // sum and convert to N
for (int i=0; i<3; i++) // loop over dimensions ParmarBassetForce = Fshort;
{
ParmarBassetForce[i] = Fshort[i];
for (int k=0; k<2; k++) // loop over F1, F2 for (int k=0; k<2; k++) // loop over F1, F2
ParmarBassetForce[i] += FHist_[k][0][index][i]; ParmarBassetForce += Flong[k];
}
ParmarBassetForce *= newton; ParmarBassetForce *= newton;
if (forceSubM(0).verbose() && index >= 0 && index < 2)
{
Pout << "cellI = " << cellI << endl;
Pout << "index = " << index << endl;
Pout << "Fshort = " << Fshort*newton << endl;
Pout << "Flong1 = " << Flong[0]*newton << endl;
Pout << "Flong2 = " << Flong[1]*newton << endl;
Pout << "Ftotal = " << ParmarBassetForce << endl;
}
// Set value fields and write the probe // Set value fields and write the probe
if(probeIt_) if(probeIt_)
{ {
scalar ReRef = 0.75/(gH0_[index][0]-0.105); scalar ReRef = 0.75/(gH0_[index][0]-0.105);
vector Flong1(0,0,0);
vector Flong2(0,0,0);
for (int i=0; i<3; i++) // loop over dimensions
{
Flong1[i] = FHist_[0][0][index][i];
Flong2[i] = FHist_[1][0][index][i];
}
//
// relative velocity (m/s)
vector UrelNoSmooth;
vector ddtUrelNoSmooth;
if(forceSubM(0).interpolation())
UrelNoSmooth = UrelNoSmoothInterpolator_.interpolate(position,cellI);
else
UrelNoSmooth = UrelNoSmooth_[cellI];
// acceleration (m/s2)
if(forceSubM(0).interpolation())
ddtUrelNoSmooth = ddtUrelNoSmoothInterpolator_.interpolate(position,cellI);
else
ddtUrelNoSmooth = ddtUrelNoSmooth_[cellI];
UrelNoSmooth /= mps;
ddtUrelNoSmooth /= mpss;
//
#include "setupProbeModelfields.H" #include "setupProbeModelfields.H"
vValues.append(ParmarBassetForce); //first entry must the be the force vValues.append(ParmarBassetForce); //first entry must the be the force
vValues.append(Urel); vValues.append(Urel);
vValues.append(ddtUrel); vValues.append(ddtUrel);
//
vValues.append(UrelNoSmooth);
vValues.append(ddtUrelNoSmooth);
//
vValues.append(Fshort); vValues.append(Fshort);
vValues.append(Flong1); vValues.append(Flong[0]);
vValues.append(Flong2); vValues.append(Flong[1]);
sValues.append(ReRef); sValues.append(ReRef);
sValues.append(tRef_[index][0]); sValues.append(tRef_[index][0]);
sValues.append(mRef_[index][0]); sValues.append(mRef_[index][0]);
@ -457,7 +406,7 @@ void ParmarBassetForce::setForce() const
{ {
// not on CPU // not on CPU
gH0_[index][0] = NOTONCPU; //reset reference gH0_[index][0] = NOTONCPU; //reset reference
ddtUrelHist_[0][index][0] = NOTONCPU; //reset ddtU history (only component used for checking nKnown) ddtUrelHist_[index][0] = NOTONCPU; //reset ddtU history (only component used for checking nKnown)
} }
// write particle based data to global array // write particle based data to global array
@ -465,32 +414,11 @@ void ParmarBassetForce::setForce() const
} }
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::ParmarBassetForce::reAllocArrays() const
{
Pout << "ParmarBassetForce::reAllocArrays..." << endl;
particleCloud_.dataExchangeM().allocateArray(gH0_, NOTONCPU,1);
particleCloud_.dataExchangeM().allocateArray(tRef_, NOTONCPU,1);
particleCloud_.dataExchangeM().allocateArray(mRef_, NOTONCPU,1);
particleCloud_.dataExchangeM().allocateArray(lRef_, NOTONCPU,1);
for (int i=0; i<nHist_; i++)
{
particleCloud_.dataExchangeM().allocateArray(ddtUrelHist_[i],NOTONCPU,3);
particleCloud_.dataExchangeM().allocateArray(rHist_ [i],NOTONCPU,1);
}
for (int i=0; i<2*discOrder_+1; i++)
for (int k=0; k<2; k++)
particleCloud_.dataExchangeM().allocateArray(FHist_[k][i],0.0,3);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scalar Foam::ParmarBassetForce::calculateK0(scalar r, scalar dt) const scalar Foam::ParmarBassetForce::calculateK0(scalar r, scalar dt) const
{ {
scalar cbrtr = cbrt(r); // cube root of r scalar cbrtr = cbrt(r); // cube root of r
scalar gamma = cbrtr*pow(dt,0.25); scalar gamma = cbrtr*sqrt(sqrt(dt));
/* /*
scalar K0 = 2./(9.*pow(r,0.666)) * scalar K0 = 2./(9.*pow(r,0.666)) *
@ -513,44 +441,44 @@ scalar Foam::ParmarBassetForce::calculateK0(scalar r, scalar dt) const
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scalar Foam::ParmarBassetForce::trapWeight(int i, int n) const scalar Foam::ParmarBassetForce::trapWeight(int i, int n) const
{ {
if ( (i==1) || (i==(n-1)) ) if ( (i==0) || (i==(n-1)) )
return 0.5; return 0.5;
else else
return 1.0; return 1.0;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::ParmarBassetForce::update_ddtUrelHist(const vector& ddtUrel, int index) const void Foam::ParmarBassetForce::update_ddtUrelHist(double**& ddtUrelHist_, const vector& ddtUrel, int index) const
{ {
for (int i=0; i<3; i++) // loop over dimensions for (int i=0; i<3; i++) // loop over dimensions
{ {
for (int j=nHist_-1; j>0; j--) // loop over past times for (int j=ddtUrelHistSize_-1; j>0; j--) // loop over past times
ddtUrelHist_[j][index][i] = ddtUrelHist_[j-1][index][i]; ddtUrelHist_[index][i*ddtUrelHistSize_+j] = ddtUrelHist_[index][i*ddtUrelHistSize_+j-1];
ddtUrelHist_[0][index][i] = ddtUrel[i]; ddtUrelHist_[index][i*ddtUrelHistSize_] = ddtUrel[i];
} }
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::ParmarBassetForce::update_rHist(scalar r, int index) const void Foam::ParmarBassetForce::update_rHist(double**& rHist_, scalar r, int index) const
{ {
for (int j=nHist_-1; j>0; j--) // loop over past times for (int j=rHistSize_-1; j>0; j--) // loop over past times
rHist_[j][index][0] = rHist_[j-1][index][0]; rHist_[index][j] = rHist_[index][j-1];
rHist_[0][index][0] = r; rHist_[index][0] = r;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::ParmarBassetForce::update_FHist(const vector& F1, const vector& F2, int index) const void Foam::ParmarBassetForce::update_FHist(double**& FHist_, const vector& F1, const vector& F2, int index) const
{ {
for (int i=0; i<3; i++) // loop over dimensions for (int i=0; i<3; i++) // loop over dimensions
{ {
for (int k=0; k<2; k++) // loop over F1, F2 for (int k=0; k<2; k++) // loop over F1, F2
for (int j=FHistSize_-1; j>0; j--) // loop over past times for (int j=FHistSize_-1; j>0; j--) // loop over past times
FHist_[k][j][index][i] = FHist_[k][j-1][index][i]; FHist_[index][i*FHistSize_*2+j*2+k] = FHist_[index][i*FHistSize_*2+(j-1)*2+k];
FHist_[0][0][index][i] = F1[i]; FHist_[index][i*FHistSize_*2 ] = F1[i];
FHist_[1][0][index][i] = F2[i]; FHist_[index][i*FHistSize_*2+1] = F2[i];
} }
} }
@ -564,18 +492,20 @@ void Foam::ParmarBassetForce::calculateCoeffs(int k, scalar t0, scalar r, double
} }
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::ParmarBassetForce::solveFlongODE(int k, double C[4], scalar dt, int index) const vector Foam::ParmarBassetForce::solveFlongODE(double**& FHist_, double**& ddtUrelHist_, int k, double C[4], scalar dt, int index) const
{ {
vector Flong = vector::zero;
if (discOrder_==1) if (discOrder_==1)
{ {
for (int i=0; i<3; i++) // loop over dimensions for (int i=0; i<3; i++) // loop over dimensions
{ {
FHist_[k][0][index][i] = Flong[i] =
( (
( C[1]/dt+2/(dt*dt)) * FHist_[k][1][index][i] ( C[1]/dt+2/(dt*dt)) * FHist_[index][i*FHistSize_*2 +k]
- ( 1/(dt*dt)) * FHist_[k][2][index][i] - ( 1/(dt*dt)) * FHist_[index][i*FHistSize_*2+2+k]
- (C[2]+C[3]/dt ) * ddtUrelHist_[nInt_ ][index][i] - (C[2]+C[3]/dt ) * ddtUrelHist_[index][i*ddtUrelHistSize_+nInt_-1]
+ ( C[3]/dt ) * ddtUrelHist_[nInt_+1][index][i] + ( C[3]/dt ) * ddtUrelHist_[index][i*ddtUrelHistSize_+nInt_ ]
) / (C[0]+C[1]/dt+1/(dt*dt)); // Eq. 3.20 using first order temporal discretisation ) / (C[0]+C[1]/dt+1/(dt*dt)); // Eq. 3.20 using first order temporal discretisation
} }
} }
@ -583,39 +513,20 @@ void Foam::ParmarBassetForce::solveFlongODE(int k, double C[4], scalar dt, int i
{ {
for (int i=0; i<3; i++) // loop over dimensions for (int i=0; i<3; i++) // loop over dimensions
{ {
FHist_[k][0][index][i] = Flong[i] =
( (
( 4*C[1]/(2*dt) + 24/(4*dt*dt)) * FHist_[k][1][index][i] ( 4*C[1]/(2*dt) + 24/(4*dt*dt)) * FHist_[index][i*FHistSize_*2 +k]
- ( C[1]/(2*dt) + 22/(4*dt*dt)) * FHist_[k][2][index][i] - ( C[1]/(2*dt) + 22/(4*dt*dt)) * FHist_[index][i*FHistSize_*2+2+k]
+ ( 8/(4*dt*dt)) * FHist_[k][3][index][i] + ( 8/(4*dt*dt)) * FHist_[index][i*FHistSize_*2+4+k]
- ( 1/(4*dt*dt)) * FHist_[k][4][index][i] - ( 1/(4*dt*dt)) * FHist_[index][i*FHistSize_*2+6+k]
- (C[2] + 3*C[3]/(2*dt) ) * ddtUrelHist_[nInt_ ][index][i] - (C[2] + 3*C[3]/(2*dt) ) * ddtUrelHist_[index][i*ddtUrelHistSize_+nInt_-1]
+ ( 4*C[3]/(2*dt) ) * ddtUrelHist_[nInt_+1][index][i] + ( 4*C[3]/(2*dt) ) * ddtUrelHist_[index][i*ddtUrelHistSize_+nInt_ ]
- ( C[3]/(2*dt) ) * ddtUrelHist_[nInt_+2][index][i] - ( C[3]/(2*dt) ) * ddtUrelHist_[index][i*ddtUrelHistSize_+nInt_+1]
) / (C[0] + 3*C[1]/(2*dt) + 9/(4*dt*dt)); // Eq. 3.20 using second order temporal discretisation ) / (C[0] + 3*C[1]/(2*dt) + 9/(4*dt*dt)); // Eq. 3.20 using second order temporal discretisation
} }
} }
} return Flong;
void Foam::ParmarBassetForce::rescaleHist(scalar tScale, scalar mScale, scalar lScale, scalar rScale, int index) const
{
for (int i=0; i<3; i++) // loop over dimensions
{
// rescale ddtU history
for (int j=0; j<nHist_; j++) // loop over past times
if (ddtUrelHist_[j][index][i] != NOTONCPU)
ddtUrelHist_[j][index][i] *= lScale/(tScale*tScale);
// rescale F1, F2 history
for (int k=0; k<2; k++) // loop over F1, F2
for (int j=0; j<FHistSize_; j++) // loop over past times
FHist_[k][j][index][i] *= mScale*lScale/(tScale*tScale);
}
// rescale r history
for (int j=0; j<nHist_; j++) // loop over past times
if (rHist_[j][index][0] != NOTONCPU)
rHist_[j][index][0] /= pow(rScale,1.5);
} }
} // End namespace Foam } // End namespace Foam

View File

@ -59,35 +59,37 @@ class ParmarBassetForce
private: private:
dictionary propsDict_; dictionary propsDict_;
word velFieldName_; const word velFieldName_;
const volVectorField& U_; const volVectorField& U_;
word UsFieldName_; const word UsFieldName_;
const volVectorField& Us_; const volVectorField& Us_;
label nInt_; //no of timesteps to solve full integral const int nInt_; //no of timesteps to solve full integral
label discOrder_; //ODE discretisation order const int discOrder_; //ODE discretisation order
label nHist_; //no of timesteps to save ddtUrel history for const int ddtUrelHistSize_; //no of timesteps to save ddtUrel history for
label FHistSize_; const int rHistSize_; //no of timesteps to save r history for
mutable List<double**> ddtUrelHist_; const int FHistSize_; //no of timesteps to save Flong history for
mutable List<double**> rHist_; const word ddtUrelHistRegName_;
mutable List<List<double**>> FHist_; const word rHistRegName_;
mutable double** gH0_; const word FHistRegName_;
mutable double** tRef_; const word gH0RegName_;
mutable double** mRef_; const word tRefRegName_;
mutable double** lRef_; const word mRefRegName_;
const word lRefRegName_;
mutable volVectorField Urel_; mutable volVectorField Urel_;
@ -101,17 +103,15 @@ private:
scalar trapWeight(int i, int n) const; scalar trapWeight(int i, int n) const;
void update_ddtUrelHist(const vector& ddtUrel, int index) const; void update_ddtUrelHist(double**& ddtUrelHist_, const vector& ddtUrel, int index) const;
void update_rHist(scalar r, int index) const; void update_rHist(double**& rHist_, scalar r, int index) const;
void update_FHist(const vector& F1, const vector& F2, int index) const; void update_FHist(double**& FHist_, const vector& F1, const vector& F2, int index) const;
void calculateCoeffs(int k, scalar t0, scalar r, double c[2][4][3], double chi[2][4][2], double C[4]) const; void calculateCoeffs(int k, scalar t0, scalar r, double c[2][4][3], double chi[2][4][2], double C[4]) const;
void solveFlongODE(int k, double C[4], scalar dt, int index) const; vector solveFlongODE(double**& FHist_, double**& ddtUrelHist_, int k, double C[4], scalar dt, int index) const;
void rescaleHist(scalar tScale, scalar mScale, scalar lScale, scalar rScale, int index) const;
public: public:
@ -136,9 +136,6 @@ public:
// Member Functions // Member Functions
void setForce() const; void setForce() const;
void reAllocArrays() const;
inline const smoothingModel& smoothingM() const inline const smoothingModel& smoothingM() const
{ {
return smoothingModel_; return smoothingModel_;

View File

@ -5,7 +5,8 @@
www.cfdem.com www.cfdem.com
Christoph Goniva, christoph.goniva@cfdem.com Christoph Goniva, christoph.goniva@cfdem.com
Copyright 2009-2012 JKU Linz Copyright 2009-2012 JKU Linz
Copyright 2012- DCS Computing GmbH, Linz Copyright 2012-2015 DCS Computing GmbH, Linz
Copyright 2015- JKU Linz
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of CFDEMcoupling. This file is part of CFDEMcoupling.
@ -66,10 +67,14 @@ ShirgaonkarIB::ShirgaonkarIB
verbose_(propsDict_.found("verbose")), verbose_(propsDict_.found("verbose")),
twoDimensional_(propsDict_.found("twoDimensional")), twoDimensional_(propsDict_.found("twoDimensional")),
depth_(1), depth_(1),
multisphere_(propsDict_.found("multisphere")), // drag for a multisphere particle
useTorque_(propsDict_.found("useTorque")),
velFieldName_(propsDict_.lookup("velFieldName")), velFieldName_(propsDict_.lookup("velFieldName")),
U_(sm.mesh().lookupObject<volVectorField> (velFieldName_)), U_(sm.mesh().lookupObject<volVectorField> (velFieldName_)),
pressureFieldName_(propsDict_.lookup("pressureFieldName")), pressureFieldName_(propsDict_.lookup("pressureFieldName")),
p_(sm.mesh().lookupObject<volScalarField> (pressureFieldName_)) p_(sm.mesh().lookupObject<volScalarField> (pressureFieldName_)),
solidVolFractionName_(multisphere_?propsDict_.lookup("solidVolFractionName"):word::null),
lambda_(multisphere_?sm.mesh().lookupObject<volScalarField>(solidVolFractionName_):volScalarField::null())
{ {
//Append the field names to be probed //Append the field names to be probed
particleCloud_.probeM().initialize(typeName, typeName+".logDat"); particleCloud_.probeM().initialize(typeName, typeName+".logDat");
@ -109,6 +114,7 @@ void ShirgaonkarIB::setForce() const
label cellI; label cellI;
vector drag; vector drag;
vector torque;
volVectorField h=forceSubM(0).IBDragPerV(U_,p_); volVectorField h=forceSubM(0).IBDragPerV(U_,p_);
@ -119,6 +125,7 @@ void ShirgaonkarIB::setForce() const
//if(mask[index][0]) //if(mask[index][0])
//{ //{
drag=vector::zero; drag=vector::zero;
torque=vector::zero;
for(int subCell=0;subCell<particleCloud_.voidFractionM().cellsPerParticle()[index][0];subCell++) for(int subCell=0;subCell<particleCloud_.voidFractionM().cellsPerParticle()[index][0];subCell++)
{ {
@ -128,6 +135,12 @@ void ShirgaonkarIB::setForce() const
if (cellI > -1) // particle Found if (cellI > -1) // particle Found
{ {
drag += h[cellI]*h.mesh().V()[cellI]; drag += h[cellI]*h.mesh().V()[cellI];
if(useTorque_)
{
vector rc = particleCloud_.mesh().C()[cellI];
vector positionCenter = particleCloud_.position(index);
torque += (rc - positionCenter)^h[cellI]*h.mesh().V()[cellI];
}
} }
} }
@ -150,10 +163,38 @@ void ShirgaonkarIB::setForce() const
<< "," << particleCloud_.impForces()[index][1] << "," << particleCloud_.impForces()[index][1]
<< "," << particleCloud_.impForces()[index][2] << "," << particleCloud_.impForces()[index][2]
<< endl; << endl;
if(useTorque_)
{
for(int j=0;j<3;j++) particleCloud_.DEMTorques()[index][j] = torque[j]; // Adding to the particle torque;
if(verbose_) Info << "DEMTorques = " << particleCloud_.DEMTorques()[index][0] << "," << particleCloud_.DEMTorques()[index][1] << "," << particleCloud_.DEMTorques()[index][2] << endl;
}
//} //}
} }
// Calculate the force if the particle is multisphere template
if(multisphere_) calcForce();
} }
void ShirgaonkarIB::calcForce() const
{
vector dragMS;
volVectorField h=forceSubM(0).IBDragPerV(U_,p_);
dragMS = vector::zero;
forAll(lambda_,cellI)
{
if(lambda_[cellI] > 0) dragMS += h[cellI]*h.mesh().V()[cellI];
else dragMS = dragMS;
}
Pout << "Drag force on particle clump = " << dragMS[0] << ", " << dragMS[1] << ", " << dragMS[2] << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -5,7 +5,8 @@
www.cfdem.com www.cfdem.com
Christoph Goniva, christoph.goniva@cfdem.com Christoph Goniva, christoph.goniva@cfdem.com
Copyright 2009-2012 JKU Linz Copyright 2009-2012 JKU Linz
Copyright 2012- DCS Computing GmbH, Linz Copyright 2012-2015 DCS Computing GmbH, Linz
Copyright 2015- JKU Linz
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of CFDEMcoupling. This file is part of CFDEMcoupling.
@ -66,6 +67,10 @@ private:
bool depth_; bool depth_;
const bool multisphere_;
const bool useTorque_;
word velFieldName_; word velFieldName_;
const volVectorField& U_; const volVectorField& U_;
@ -74,6 +79,12 @@ private:
const volScalarField& p_; const volScalarField& p_;
word solidVolFractionName_;
const volScalarField& lambda_;
void calcForce() const;
public: public:
//- Runtime type information //- Runtime type information

View File

@ -61,6 +61,7 @@ gradPForceSmooth::gradPForceSmooth
U_(sm.mesh().lookupObject<volVectorField> (velocityFieldName_)), U_(sm.mesh().lookupObject<volVectorField> (velocityFieldName_)),
useRho_(false), useRho_(false),
useU_(false), useU_(false),
temporalSmoothing_(false),
addedMassCoeff_(0.0), addedMassCoeff_(0.0),
smoothingModel_ smoothingModel_
( (
@ -135,6 +136,11 @@ gradPForceSmooth::gradPForceSmooth
particleCloud_.probeM().scalarFields_.append("Vs"); particleCloud_.probeM().scalarFields_.append("Vs");
particleCloud_.probeM().scalarFields_.append("rho"); particleCloud_.probeM().scalarFields_.append("rho");
particleCloud_.probeM().writeHeader(); particleCloud_.probeM().writeHeader();
if ((smoothingM().type() == "temporalSmoothing") || (smoothingM().type() == "constDiffAndTemporalSmoothing"))
{
temporalSmoothing_ = true;
}
} }
@ -150,6 +156,11 @@ gradPForceSmooth::~gradPForceSmooth()
void gradPForceSmooth::setForce() const void gradPForceSmooth::setForce() const
{ {
volVectorField gradPField = fvc::grad(p_); volVectorField gradPField = fvc::grad(p_);
// if temporal smoothing is used, let pSmooth evolve on its own - smoothing model itself looks up p
// else, set pSmooth to current p and apply spatial smoothing
if (!temporalSmoothing_) pSmooth_ = p_;
if (pFieldName_ == "p_rgh") if (pFieldName_ == "p_rgh")
{ {
const volScalarField& rho_ = particleCloud_.mesh().lookupObject<volScalarField>("rho"); const volScalarField& rho_ = particleCloud_.mesh().lookupObject<volScalarField>("rho");

View File

@ -62,6 +62,8 @@ private:
bool useU_; // if false: substitution p=0.5*rho*U^2 bool useU_; // if false: substitution p=0.5*rho*U^2
bool temporalSmoothing_;
mutable double addedMassCoeff_; //added mass coefficient mutable double addedMassCoeff_; //added mass coefficient
autoPtr<smoothingModel> smoothingModel_; autoPtr<smoothingModel> smoothingModel_;

View File

@ -103,7 +103,6 @@ interface::~interface()
void interface::setForce() const void interface::setForce() const
{ {
Info << "interface::setForce" << endl;
for(int index = 0;index < particleCloud_.numberOfParticles(); ++index) for(int index = 0;index < particleCloud_.numberOfParticles(); ++index)
{ {
//if(mask[index][0]) //if(mask[index][0])
@ -193,7 +192,6 @@ Info << "interface::setForce" << endl;
} // end if particle found on proc domain } // end if particle found on proc domain
//}// end if in mask //}// end if in mask
}// end loop particles }// end loop particles
Info << "interface::setForce - done" << endl;
} }

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
License
This 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.
This code 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 this code. If not, see <http://www.gnu.org/licenses/>.
Copyright (C) 2015- Thomas Lichtenegger, JKU Linz, Austria
Description
transfer fluid properties to LIGGGHTS
SourceFiles
transferFluidProperties.C
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "transferFluidProperties.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(transferFluidProperties, 0);
addToRunTimeSelectionTable
(
forceModel,
transferFluidProperties,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
transferFluidProperties::transferFluidProperties
(
const dictionary& dict,
cfdemCloud& sm
)
:
forceModel(dict,sm),
propsDict_(dict.subDict(typeName + "Props"))
{
particleCloud_.registerParticleProperty<double**>("fluidDensity",1);
particleCloud_.registerParticleProperty<double**>("fluidViscosity",1);
// init force sub model
setForceSubModels(propsDict_);
// define switches which can be read from dict
forceSubM(0).setSwitchesList(SW_VERBOSE,true); // activate search for verbose switch
forceSubM(0).setSwitchesList(SW_INTERPOLATION,true); // activate search for interpolate switch
forceSubM(0).readSwitches();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
transferFluidProperties::~transferFluidProperties()
{
}
// * * * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * public Member Functions * * * * * * * * * * * * * //
void transferFluidProperties::setForce() const
{
double**& fluidDensity_ = particleCloud_.getParticlePropertyRef<double**>("fluidDensity");
double**& fluidViscosity_ = particleCloud_.getParticlePropertyRef<double**>("fluidViscosity");
const volScalarField& rhoField = forceSubM(0).rhoField();
const volScalarField& nufField = forceSubM(0).nuField();
interpolationCellPoint<scalar> rhoInterpolator_(rhoField);
interpolationCellPoint<scalar> nufInterpolator_(nufField);
label cellI = 0;
double rho = 0.;
double nuf = 0.;
vector position(0,0,0);
for(int index = 0; index < particleCloud_.numberOfParticles(); ++index)
{
cellI = particleCloud_.cellIDs()[index][0];
if (cellI >= 0)
{
if(forceSubM(0).interpolation())
{
position = particleCloud_.position(index);
rho = rhoInterpolator_.interpolate(position,cellI);
nuf = nufInterpolator_.interpolate(position,cellI);
}
else
{
rho = rhoField[cellI];
nuf = nufField[cellI];
}
fluidDensity_[index][0] = rho;
fluidViscosity_[index][0] = nuf*rho;
}
}
particleCloud_.dataExchangeM().giveData("fluidDensity","scalar-atom",fluidDensity_);
particleCloud_.dataExchangeM().giveData("fluidViscosity","scalar-atom",fluidViscosity_);
if (forceSubM(0).verbose()) Info << "give data done" << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*\
License
This 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.
This code 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 this code. If not, see <http://www.gnu.org/licenses/>.
Copyright (C) 2015- Thomas Lichtenegger, JKU Linz, Austria
Description
transfer fluid properties to LIGGGHTS
SourceFiles
transferFluidProperties.C
\*---------------------------------------------------------------------------*/
#ifndef transferFluidProperties_H
#define transferFluidProperties_H
#include "forceModel.H"
#include "interpolationCellPoint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class transferFluidProperties Declaration
\*---------------------------------------------------------------------------*/
class transferFluidProperties
:
public forceModel
{
private:
dictionary propsDict_;
public:
//- Runtime type information
TypeName("transferFluidProperties");
// Constructors
//- Construct from components
transferFluidProperties
(
const dictionary& dict,
cfdemCloud& sm
);
// Destructor
~transferFluidProperties();
// Member Functions
void setForce() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -99,7 +99,12 @@ virtualMassForce::virtualMassForce
) )
) )
{ {
particleCloud_.registerParticleProperty<double**>(UrelOldRegName_,3,NOTONCPU,false); // allocate UrelOld only if needed
int UrelOldSize = 0;
if(!splitUrelCalculation_ || !useUs_ )
UrelOldSize = 3;
particleCloud_.registerParticleProperty<double**>(UrelOldRegName_,UrelOldSize,NOTONCPU,false);
// init force sub model // init force sub model
setForceSubModels(propsDict_); setForceSubModels(propsDict_);

View File

@ -105,8 +105,6 @@ public:
virtual void postFlow() {} virtual void postFlow() {}
virtual void solve() {}
const volScalarField& D0Field() const; const volScalarField& D0Field() const;
const volScalarField& CsField() const; const volScalarField& CsField() const;

View File

@ -219,7 +219,7 @@ void particleProbe::writeProbe(int index, Field<scalar> sValues, Field<vector> v
*sPtr << setprecision(writePrecision_); *sPtr << setprecision(writePrecision_);
forAll(vValues, iter) forAll(vValues, iter)
{ {
// if(!probeDebug_ && iter>0) break; if(!probeDebug_ && iter>0) break;
*sPtr << vValues[iter][0] << " "; *sPtr << vValues[iter][0] << " ";
*sPtr << vValues[iter][1] << " "; *sPtr << vValues[iter][1] << " ";
*sPtr << vValues[iter][2] << " "; *sPtr << vValues[iter][2] << " ";

View File

@ -68,6 +68,7 @@ constDiffAndTemporalSmoothing::constDiffAndTemporalSmoothing
smoothingLength_(dimensionedScalar("smoothingLength",dimensionSet(0,1,0,0,0,0,0), readScalar(propsDict_.lookup("smoothingLength")))), smoothingLength_(dimensionedScalar("smoothingLength",dimensionSet(0,1,0,0,0,0,0), readScalar(propsDict_.lookup("smoothingLength")))),
smoothingLengthReferenceField_(dimensionedScalar("smoothingLengthReferenceField",dimensionSet(0,1,0,0,0,0,0), readScalar(propsDict_.lookup("smoothingLength")))), smoothingLengthReferenceField_(dimensionedScalar("smoothingLengthReferenceField",dimensionSet(0,1,0,0,0,0,0), readScalar(propsDict_.lookup("smoothingLength")))),
DT_("DT", dimensionSet(0,2,-1,0,0), 0.), DT_("DT", dimensionSet(0,2,-1,0,0), 0.),
refFieldName_(propsDict_.lookupOrDefault<word>("refField","")),
gamma_(readScalar(propsDict_.lookup("smoothingStrength"))), gamma_(readScalar(propsDict_.lookup("smoothingStrength"))),
correctBoundary_(propsDict_.lookupOrDefault<bool>("correctBoundary",false)), correctBoundary_(propsDict_.lookupOrDefault<bool>("correctBoundary",false)),
verbose_(false) verbose_(false)
@ -111,13 +112,44 @@ void constDiffAndTemporalSmoothing::smoothen(volScalarField& fieldSrc) const
double deltaT = sSmoothField.mesh().time().deltaTValue(); double deltaT = sSmoothField.mesh().time().deltaTValue();
DT_.value() = smoothingLength_.value() * smoothingLength_.value() / deltaT; DT_.value() = smoothingLength_.value() * smoothingLength_.value() / deltaT;
// do smoothing if(refFieldName_.empty())
{
// do spatial smoothing
solve solve
( (
fvm::ddt(sSmoothField) fvm::ddt(sSmoothField)
-fvm::laplacian(DT_, sSmoothField) -fvm::laplacian(DT_, sSmoothField)
); );
// create fields for temporal smoothing
volScalarField refField = sSmoothField;
sSmoothField.ref()=fieldSrc.oldTime().internalField();
sSmoothField.correctBoundaryConditions();
sSmoothField.oldTime()=fieldSrc.oldTime();
sSmoothField.oldTime().correctBoundaryConditions();
// do temporal smoothing
solve
(
fvm::ddt(sSmoothField)
-
gamma_/deltaT * (refField - fvm::Sp(1.0,sSmoothField))
);
}
else
{
const volScalarField& refField = particleCloud_.mesh().lookupObject<volScalarField>(refFieldName_);
// do spatial and temporal smoothing
solve
(
fvm::ddt(sSmoothField)
-fvm::laplacian(DT_, sSmoothField)
-gamma_/deltaT * (refField - fvm::Sp(1.0,sSmoothField))
);
}
// bound sSmoothField_ // bound sSmoothField_
forAll(sSmoothField,cellI) forAll(sSmoothField,cellI)
{ {
@ -152,7 +184,9 @@ void constDiffAndTemporalSmoothing::smoothen(volVectorField& fieldSrc) const
dimensionedScalar deltaT = vSmoothField.mesh().time().deltaT(); dimensionedScalar deltaT = vSmoothField.mesh().time().deltaT();
DT_.value() = smoothingLength_.value() * smoothingLength_.value() / deltaT.value(); DT_.value() = smoothingLength_.value() * smoothingLength_.value() / deltaT.value();
// do spacial smoothing if(refFieldName_.empty())
{
// do spatial smoothing
solve solve
( (
fvm::ddt(vSmoothField) fvm::ddt(vSmoothField)
@ -174,6 +208,19 @@ void constDiffAndTemporalSmoothing::smoothen(volVectorField& fieldSrc) const
- -
gamma_/deltaT * (refField - fvm::Sp(1.0,vSmoothField)) gamma_/deltaT * (refField - fvm::Sp(1.0,vSmoothField))
); );
}
else
{
const volVectorField& refField = particleCloud_.mesh().lookupObject<volVectorField>(refFieldName_);
// do spatial and temporal smoothing
solve
(
fvm::ddt(vSmoothField)
-fvm::laplacian(DT_, vSmoothField)
-gamma_/deltaT * (refField - fvm::Sp(1.0,vSmoothField))
);
}
// create temporally smoothened boundary field // create temporally smoothened boundary field
if (correctBoundary_) if (correctBoundary_)

View File

@ -65,6 +65,7 @@ private:
dimensionedScalar smoothingLength_; dimensionedScalar smoothingLength_;
dimensionedScalar smoothingLengthReferenceField_; dimensionedScalar smoothingLengthReferenceField_;
mutable dimensionedScalar DT_; mutable dimensionedScalar DT_;
word refFieldName_;
scalar gamma_; scalar gamma_;
bool correctBoundary_; bool correctBoundary_;
bool verbose_; bool verbose_;

View File

@ -130,7 +130,7 @@ void Foam::temporalSmoothing::smoothen(volVectorField& fieldSrc) const
vSmoothField.oldTime()=fieldSrc; vSmoothField.oldTime()=fieldSrc;
vSmoothField.oldTime().correctBoundaryConditions(); vSmoothField.oldTime().correctBoundaryConditions();
volVectorField refField = particleCloud_.mesh().lookupObject<volVectorField>(refFieldName_); const volVectorField& refField = particleCloud_.mesh().lookupObject<volVectorField>(refFieldName_);
dimensionedScalar deltaT = vSmoothField.mesh().time().deltaT(); dimensionedScalar deltaT = vSmoothField.mesh().time().deltaT();
solve solve

View File

@ -90,6 +90,7 @@ $(forceModels)/directedDiffusiveRelaxation/directedDiffusiveRelaxation.C
$(forceModels)/BeetstraDrag/BeetstraDrag.C $(forceModels)/BeetstraDrag/BeetstraDrag.C
$(forceModels)/BeetstraDragPoly/BeetstraDragPoly.C $(forceModels)/BeetstraDragPoly/BeetstraDragPoly.C
$(forceModels)/dSauter/dSauter.C $(forceModels)/dSauter/dSauter.C
$(forceModels)/transferFluidProperties/transferFluidProperties.C
$(forceModels)/Fines/Fines.C $(forceModels)/Fines/Fines.C
$(forceModels)/Fines/FinesFields.C $(forceModels)/Fines/FinesFields.C
$(forceModels)/Fines/FanningDynFines.C $(forceModels)/Fines/FanningDynFines.C

View File

@ -159,7 +159,24 @@ standardRecModel::standardRecModel
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
standardRecModel::~standardRecModel() standardRecModel::~standardRecModel()
{} {
const objectRegistry& objReg = base_.mesh().thisDb();
for(int j=0; j<volScalarFieldNames_.size(); j++)
{
objReg.checkOut(volScalarFieldList_[j][virtualTimeIndex]);
}
for(int j=0; j<volVectorFieldNames_.size(); j++)
{
objReg.checkOut(volVectorFieldList_[j][virtualTimeIndex]);
}
for(int j=0; j<surfaceScalarFieldNames_.size(); j++)
{
objReg.checkOut(surfaceScalarFieldList_[j][virtualTimeIndex]);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //

View File

@ -0,0 +1,27 @@
#!/bin/bash
#------------------------------------------------------------------------------
# Allclean script for falling sphere test case
# clean CFD and DEM part
# Achuth N. Balachandran Nair - October 2018
#------------------------------------------------------------------------------
#- source environment variables
. ~/.bashrc
#- source CFDEM functions
source $CFDEM_PROJECT_DIR/etc/functions.sh
#- define variables
casePath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")"
#- clean up case
echo "deleting data at: $casePath"
source $WM_PROJECT_DIR/bin/tools/CleanFunctions
cd $casePath/CFD
cleanCase
rm -r $casePath/CFD/clockData
rm $casePath/DEM/post/*.*
#- preserve post directory
touch $casePath/DEM/post/.gitignore
echo "done"

View File

@ -0,0 +1,25 @@
#!/bin/bash
#------------------------------------------------------------------------------
# allrun script for falling sphere testcase
# run falling_sphere_two_way_coupling
# Achuth N. Balachandran Nair - Oct. 2018
#------------------------------------------------------------------------------
source $CFDEM_PROJECT_DIR/etc/functions.sh
#- define variables
casePath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")"
echo $casePath
# check if mesh was built
if [ -f "$casePath/CFD/constant/polyMesh/points" ]; then
echo "mesh was built before - using old mesh"
else
echo "mesh needs to be built"
cd CFD/
blockMesh
fi
#- run parallel CFD-DEM
bash $casePath/parCFDDEMrun.sh

View File

@ -0,0 +1,41 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: 6
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
inlet
{
type fixedValue;
value $internalField;
}
channelWall
{
type zeroGradient;
}
outlet
{
type fixedValue;
value $internalField;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: 6
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object Us;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
inlet
{
type zeroGradient;
}
outlet
{
type zeroGradient;
}
channelWall
{
type zeroGradient;
}
frontAndBack
{
type zeroGradient;
}
}
// ************************************************************************* //

View File

@ -1,38 +1,46 @@
/*--------------------------------*- C++ -*----------------------------------*\ /*--------------------------------*- C++ -*----------------------------------*\
| ========= | | ========= |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
| \\ / O peration | Version: 1.6 | \\ / O peration | Website: https://openfoam.org
| \\ / A nd | Web: http://www.OpenFOAM.org | \\ / A nd | Version: 6
| \\/ M anipulation | | \\/ M anipulation |
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
FoamFile FoamFile
{ {
version 2.0; version 2.0;
format ascii; format ascii;
class volScalarField; class volScalarField;
object dSmoothing; object p;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 0 0 0 0 0]; dimensions [0 2 -2 0 0 0 0];
internalField uniform 0; internalField uniform 0;
boundaryField boundaryField
{ {
side-walls inlet
{ {
type zeroGradient; type fixedValue;
value $internalField;
} }
inlet channelWall
{ {
type zeroGradient; type zeroGradient;
} }
outlet outlet
{ {
type zeroGradient; type fixedValue;
value $internalField;
}
frontAndBack
{
type empty;
} }
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -1,17 +1,16 @@
/*--------------------------------*- C++ -*----------------------------------*\ /*--------------------------------*- C++ -*----------------------------------*\
| ========= | | ========= |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
| \\ / O peration | Version: 1.6 | \\ / O peration | Website: https://openfoam.org
| \\ / A nd | Web: www.OpenFOAM.org | \\ / A nd | Version: 6
| \\/ M anipulation | | \\/ M anipulation |
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
FoamFile FoamFile
{ {
version 2.0; version 2.0;
format ascii; format ascii;
class volScalarField; class volScalarField;
location "0"; object phiIB;
object nut;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -21,24 +20,27 @@ internalField uniform 0;
boundaryField boundaryField
{ {
side-walls inlet
{ {
type fixedValue; type fixedValue;
value uniform 0; value uniform 0;
} }
inlet channelWall
{ {
type calculated; type zeroGradient;
value uniform 0;
} }
outlet outlet
{ {
type calculated; type fixedValue;
value uniform 0; value uniform 0;
} }
frontAndBack
{
type empty;
}
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -1,9 +1,9 @@
/*--------------------------------*- C++ -*----------------------------------*\ /*--------------------------------*- C++ -*----------------------------------*\
| ========= | | ========= |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
| \\ / O peration | Version: 1.6 | \\ / O peration | Website: https://openfoam.org
| \\ / A nd | Web: http://www.OpenFOAM.org | \\ / A nd | Version: 6
| \\/ M anipulation | | \\/ M anipulation |
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
FoamFile FoamFile
{ {
@ -16,16 +16,16 @@ FoamFile
dimensions [1 -3 0 0 0 0 0]; dimensions [1 -3 0 0 0 0 0];
internalField uniform 1.58; internalField uniform 1;
boundaryField boundaryField
{ {
side-walls inlet
{ {
type zeroGradient; type zeroGradient;
} }
inlet channelWall
{ {
type zeroGradient; type zeroGradient;
} }
@ -36,5 +36,4 @@ boundaryField
} }
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,44 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: 6
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object voidfraction;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 0 0 0 0];
internalField uniform 1;
boundaryField
{
inlet
{
type zeroGradient;
}
outlet
{
type zeroGradient;
}
channelWall
{
type zeroGradient;
}
frontAndBack
{
type zeroGradient;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,101 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: 6
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object couplingProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// sub-models & settings
modelType none;
checkPeriodicCells;
verbose;
couplingInterval 10;
depth 0;
voidFractionModel IB;
locateModel engineIB;
meshMotionModel noMeshMotion;
regionModel allRegion;
dataExchangeModel twoWayMPI;
IOModel basicIO;
probeModel off;
averagingModel dilute;
clockModel off;
smoothingModel off;
forceModels
(
ShirgaonkarIB
ArchimedesIB
);
momCoupleModels
(
);
turbulenceModelType "turbulenceProperties";
// sub-model properties
ShirgaonkarIBProps
{
velFieldName "U";
pressureFieldName "p";
densityFieldName "rho";
verbose;
useTorque;
}
ArchimedesIBProps
{
densityFieldName "rho";
gravityFieldName "g";
voidfractionFieldName "voidfractionNext";
}
twoWayMPIProps
{
liggghtsPath "../DEM/in.liggghts_run";
}
IBProps
{
maxCellsPerParticle 20000;
alphaMin 0.30;
scaleUpVol 1.0;
}
engineIBProps
{
engineProps
{
treeSearch false;
}
zSplit 8;
xySplit 16;
}
// ************************************************************************* //

View File

@ -0,0 +1,20 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: 6
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object dynamicMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dynamicFvMesh staticFvMesh;
// ************************************************************************* //

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: 6
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class uniformDimensionedVectorField;
location "constant";
object g;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -2 0 0 0 0];
value (0 -9.81 0);
// ************************************************************************* //

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: 6
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object liggghtsCommands;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
liggghtsCommandModels
(
runLiggghts
);
// ************************************************************************* //

Some files were not shown because too many files have changed in this diff Show More