From 791bf252aa8ffd67b33c9debbe6a57c822d2c923 Mon Sep 17 00:00:00 2001 From: goniva Date: Fri, 25 Jul 2014 13:42:41 +0200 Subject: [PATCH] release on 2014-07-25_13-42-41 --- README | 81 ------ doc/CFDEMcoupling_Manual.html | 32 +-- doc/CFDEMcoupling_Manual.pdf | Bin 511299 -> 517071 bytes doc/CFDEMcoupling_Manual.txt | 7 + doc/forceSubModel.html | 49 ++++ doc/forceSubModel.txt | 45 ++++ doc/forceSubModel_ImEx.html | 45 ++++ doc/forceSubModel_ImEx.txt | 42 ++++ doc/forceSubModel_ImExCorr.html | 46 ++++ doc/forceSubModel_ImExCorr.txt | 43 ++++ doc/githubAccess_public.pdf | Bin 362748 -> 362748 bytes src/lagrangian/cfdemParticle/Make/files | 60 ++++- src/lagrangian/cfdemParticle/Make/options | 11 +- .../cfdemParticle/cfdTools/versionInfo.H | 2 +- .../cfdemParticle/cfdemCloud/cfdemCloud.H | 1 + .../cfdemParticle/etc/OFversion/OFversion.H | 2 +- .../etc/library-liggghts-list.txt | 4 - .../cfdemParticle/etc/library-list.txt | 9 + .../cfdemParticle/etc/solver-list.txt | 12 +- .../cfdemParticle/etc/tutorial-list.txt | 46 +++- .../library/libcoupleMany2Many.a | Bin 4297006 -> 4297006 bytes .../forceModel/Archimedes/Archimedes.C | 25 +- .../forceModel/ArchimedesIB/ArchimedesIB.C | 22 +- .../forceModel/DiFeliceDrag/DiFeliceDrag.C | 59 ++--- .../forceModel/DiFeliceDrag/DiFeliceDrag.H | 2 - .../forceModel/GidaspowDrag/GidaspowDrag.C | 84 ++----- .../forceModel/GidaspowDrag/GidaspowDrag.H | 4 +- .../forceModel/KochHillDrag/KochHillDrag.C | 53 ++-- .../forceModel/KochHillDrag/KochHillDrag.H | 4 + .../KochHillRWDrag/KochHillRWDrag.C | 64 ++--- .../KochHillRWDrag/KochHillRWDrag.H | 4 + .../subModels/forceModel/MeiLift/MeiLift.C | 19 +- .../SchillerNaumannDrag/SchillerNaumannDrag.C | 18 +- .../forceModel/ShirgaonkarIB/ShirgaonkarIB.C | 16 +- .../forceModel/forceModel/forceModel.C | 33 ++- .../forceModel/forceModel/forceModel.H | 23 +- .../forceModel/forceSubModels/ImEx/ImEx.C | 81 ++++++ .../forceModel/forceSubModels/ImEx/ImEx.H | 95 +++++++ .../forceSubModel/forceSubModel.C | 182 ++++++++++++++ .../forceSubModel/forceSubModel.H | 156 ++++++++++++ .../forceSubModel/newForceSubModel.C | 79 ++++++ .../forceModel/gradPForce/gradPForce.C | 25 +- .../forceModel/interface/interface.C | 16 +- .../subModels/forceModel/noDrag/noDrag.C | 20 +- .../virtualMassForce/virtualMassForce.C | 18 +- .../forceModel/viscForce/viscForce.C | 23 +- .../DiFeliceDragMS/DiFeliceDragMS.C | 13 +- .../forceModelMS/forceModelMS/forceModelMS.C | 2 +- .../CFD/constant/dynamicMeshDict | 0 .../CFD/constant/polyMesh/blockMeshDict | 0 .../CFD/system/controlDict | 0 .../DEM/in.liggghts_run | 95 +++++++ .../twoSpheresGlowinskiMPI/parCFDDEMrun.sh | 21 +- .../ErgunTestCG/parCFDDEMrun.sh | 2 +- .../cfdemSolverPiso/ErgunTestMPI/Allrun.sh | 2 +- .../CFD/constant/couplingProperties | 9 + .../ErgunTestMPI/DEM/in.liggghts_run | 66 +++++ .../ErgunTestMPI/DEM/post/restart/.gitignore | 0 .../ErgunTestMPI/parCFDDEMrun.sh | 2 +- .../cfdemSolverPiso/ErgunTestMPI/parDEMrun.sh | 30 +++ .../ErgunTestMPI_cgs/Allrun.sh | 2 +- .../CFD/system/funkySetFieldsDict | 0 .../ErgunTestMPI_cgs/DEM/in.liggghts_run | 66 +++++ .../DEM/post/restart/.gitignore | 0 .../ErgunTestMPI_cgs/parCFDDEMrun.sh | 19 +- .../ErgunTestMPI_cgs/parDEMrun.sh | 28 +++ .../ErgunTestMPI_restart/Allrun.sh | 4 +- .../CFD/constant/couplingProperties_run | 235 ++++++++++++++++++ .../CFD/constant/liggghtsCommands_run | 44 ++++ .../CFD/system/controlDict_run | 117 +++++++++ .../ErgunTestMPI_restart/DEM/in.liggghts_run | 65 +++++ .../DEM/post/restart/.gitignore | 0 .../ErgunTestMPI_restart/parDEMrun.sh | 28 +++ .../settlingTestMPI/DEM/in.liggghts_run | 73 ++++++ .../packedBedTemp/DEM/in.liggghts_run | 75 ++++++ .../packedBedTemp/DEM/post/restart/.gitignore | 0 .../packedBedTemp/parCFDDEMrun.sh | 21 +- .../packedBedTemp/parDEMrun.sh | 28 +++ 78 files changed, 2288 insertions(+), 421 deletions(-) delete mode 100755 README create mode 100644 doc/forceSubModel.html create mode 100644 doc/forceSubModel.txt create mode 100644 doc/forceSubModel_ImEx.html create mode 100644 doc/forceSubModel_ImEx.txt create mode 100644 doc/forceSubModel_ImExCorr.html create mode 100644 doc/forceSubModel_ImExCorr.txt delete mode 100644 src/lagrangian/cfdemParticle/etc/library-liggghts-list.txt create mode 100644 src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.C create mode 100644 src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.H create mode 100644 src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.C create mode 100644 src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.H create mode 100644 src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/newForceSubModel.C mode change 100755 => 100644 tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/CFD/constant/dynamicMeshDict mode change 100755 => 100644 tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/CFD/constant/polyMesh/blockMeshDict mode change 100755 => 100644 tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/CFD/system/controlDict create mode 100644 tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/DEM/in.liggghts_run create mode 100644 tutorials/cfdemSolverPiso/ErgunTestMPI/DEM/in.liggghts_run create mode 100644 tutorials/cfdemSolverPiso/ErgunTestMPI/DEM/post/restart/.gitignore create mode 100755 tutorials/cfdemSolverPiso/ErgunTestMPI/parDEMrun.sh mode change 100755 => 100644 tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/CFD/system/funkySetFieldsDict create mode 100644 tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/DEM/in.liggghts_run create mode 100644 tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/DEM/post/restart/.gitignore create mode 100755 tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/parDEMrun.sh create mode 100644 tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/constant/couplingProperties_run create mode 100644 tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/constant/liggghtsCommands_run create mode 100644 tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/system/controlDict_run create mode 100644 tutorials/cfdemSolverPiso/ErgunTestMPI_restart/DEM/in.liggghts_run create mode 100644 tutorials/cfdemSolverPiso/ErgunTestMPI_restart/DEM/post/restart/.gitignore create mode 100755 tutorials/cfdemSolverPiso/ErgunTestMPI_restart/parDEMrun.sh create mode 100644 tutorials/cfdemSolverPiso/settlingTestMPI/DEM/in.liggghts_run create mode 100644 tutorials/cfdemSolverPisoScalar/packedBedTemp/DEM/in.liggghts_run create mode 100644 tutorials/cfdemSolverPisoScalar/packedBedTemp/DEM/post/restart/.gitignore create mode 100755 tutorials/cfdemSolverPisoScalar/packedBedTemp/parDEMrun.sh diff --git a/README b/README deleted file mode 100755 index fd2ca756..00000000 --- a/README +++ /dev/null @@ -1,81 +0,0 @@ -/*---------------------------------------------------------------------------*\ - CFDEMcoupling - Open Source CFD-DEM coupling - - CFDEMcoupling is part of the CFDEMproject - www.cfdem.com - Christoph Goniva, christoph.goniva@cfdem.com - Copyright 2009-2012 JKU Linz - Copyright 2012- DCS Computing GmbH, Linz -------------------------------------------------------------------------------- -License - This file is part of CFDEMcoupling. - - CFDEMcoupling is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3 of the License, or (at your - option) any later version. - - CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with CFDEMcoupling; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Description - This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS - and OpenFOAM. Note: this code is not part of OpenFOAM (see DISCLAIMER). -\*---------------------------------------------------------------------------*/ - - -CFDEM coupling provides an open source parallel coupled CFD-DEM framework -combining the strengths of LIGGGHTS DEM code and the Open Source -CFD package OpenFOAM(R)(*). The CFDEMcoupling toolbox allows to expand -standard CFD solvers of OpenFOAM(R)(*) to include a coupling to the DEM -code LIGGGHTS. In this toolbox the particle representation within the -CFD solver is organized by "cloud" classes. Key functionalities are organised -in sub-models (e.g. force models, data exchange models, etc.) which can easily -be selected and combined by dictionary settings. - -The coupled solvers run fully parallel on distributed-memory clusters. - -Features are: - -- its modular approach allows users to easily implement new models -- its MPI parallelization enables to use it for large scale problems -- the "forum"_lws on CFD-DEM gives the possibility to exchange with other - users / developers -- the use of GIT allows to easily update to the latest version -- basic documentation is provided - -The file structure: - -- "src" directory including the source files of the coupling toolbox and models -- "applications" directory including the solver files for coupled CFD-DEM simulations -- "doc" directory including the documentation of CFDEMcoupling -- "tutorials" directory including basic tutorial cases showing the functionality - - - -Details on installation are given on the "www.cfdem.com" - -The functionality of this CFD-DEM framwork is described via "tutorial cases" showing -how to use different solvers and models. - -CFDEMcoupling stands for Computational Fluid Dynamics (CFD) - -Discrete Element Method (DEM) coupling. - -CFDEMcoupling is an open-source code, distributed freely under the terms of the -GNU Public License (GPL). - -Core development of CFDEMcoupling is done by -Christoph Goniva and Christoph Kloss, both at DCS Computing GmbH, 2012 - - -\*---------------------------------------------------------------------------*/ -(*) "OpenFOAM(R)"_of is a registered trade mark of the ESI Group. -This offering is not affiliated, approved or endorsed by ESI Group, -the producer of the OpenFOAMĀ® software and owner of the OpenFOAMĀ® trade mark. -\*---------------------------------------------------------------------------*/ diff --git a/doc/CFDEMcoupling_Manual.html b/doc/CFDEMcoupling_Manual.html index 1f776e41..793e3968 100644 --- a/doc/CFDEMcoupling_Manual.html +++ b/doc/CFDEMcoupling_Manual.html @@ -220,21 +220,23 @@ listing below of styles within certain commands. forceModel_SchillerNaumannDragforceModel_ShirgaonkarIB forceModel_gradPForceforceModel_noDrag forceModel_particleCellVolumeforceModel_virtualMassForce -forceModel_viscForceliggghtsCommandModel -liggghtsCommandModel_executeliggghtsCommandModel_readLiggghtsData -liggghtsCommandModel_runLiggghtsliggghtsCommandModel_writeLiggghts -locateModellocateModel_engineSearch -locateModel_engineSearchIBlocateModel_standardSearch -locateModel_turboEngineSearchmeshMotionModel -meshMotionModel_noMeshMotionmomCoupleModel -momCoupleModel_explicitCouplemomCoupleModel_implicitCouple -momCoupleModel_noCoupleprobeModel -probeModel_noProberegionModel -regionModel_allRegionsmoothingModel -smoothingModel_constDiffSmoothingsmoothingModel_noSmoothing -voidfractionModelvoidfractionModel_GaussVoidFraction -voidfractionModel_IBVoidFractionvoidfractionModel_bigParticleVoidFraction -voidfractionModel_centreVoidFractionvoidfractionModel_dividedVoidFraction +forceModel_viscForceforceSubModel +forceSubModel_ImExforceSubModel_ImExCorr +liggghtsCommandModelliggghtsCommandModel_execute +liggghtsCommandModel_readLiggghtsDataliggghtsCommandModel_runLiggghts +liggghtsCommandModel_writeLiggghtslocateModel +locateModel_engineSearchlocateModel_engineSearchIB +locateModel_standardSearchlocateModel_turboEngineSearch +meshMotionModelmeshMotionModel_noMeshMotion +momCoupleModelmomCoupleModel_explicitCouple +momCoupleModel_implicitCouplemomCoupleModel_noCouple +probeModelprobeModel_noProbe +regionModelregionModel_allRegion +smoothingModelsmoothingModel_constDiffSmoothing +smoothingModel_noSmoothingvoidfractionModel +voidfractionModel_GaussVoidFractionvoidfractionModel_IBVoidFraction +voidfractionModel_bigParticleVoidFractionvoidfractionModel_centreVoidFraction +voidfractionModel_dividedVoidFraction diff --git a/doc/CFDEMcoupling_Manual.pdf b/doc/CFDEMcoupling_Manual.pdf index 5194447ce383ce327bd6ee2dc01b641e4b9854ae..334e5e739aff7b79f2f3ef1de5c86b9f5f28e175 100644 GIT binary patch delta 57665 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 OBa~HE)@Y+K>;D0?tX3ZY delta 53574 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 +

CFDEMproject WWW Site - CFDEM Commands +
+ + + + +
+ +

forceSubModel command +

+

Syntax: +

+

Defined in couplingProperties sub-dictionary of the force model in use. If no force sub-model is applied ImEx is used as default. If the keyword "forceSubModels" is provided, a choice of sub model is demanded. +

+
forceSubModels
+(
+    model_x
+    model_y
+); 
+
+
  • model = name of force sub-model to be applied +
+

Examples: +

+
forceSubModels
+(
+    ImEx
+); 
+
+

Note: This examples list might not be complete - please look for other models (forceSubModel_XY) in this documentation. +

+

Description: +

+

The force sub model is designed to hold the settings a force model can have. For now it handles the treatExplicit, treatDEM and implDEM option. +

+

Restrictions: +

+

None. +

+

Related commands: +

+

ImEx +

+

Note: This examples list may be incomplete - please look for other models (forceSubModel_XY) in this documentation. +

+

Default: none. +

+ diff --git a/doc/forceSubModel.txt b/doc/forceSubModel.txt new file mode 100644 index 00000000..8d150a90 --- /dev/null +++ b/doc/forceSubModel.txt @@ -0,0 +1,45 @@ +"CFDEMproject WWW Site"_lws - "CFDEM Commands"_lc :c + +:link(lws,http://www.cfdem.com) +:link(lc,CFDEMcoupling_Manual.html#comm) + +:line + +forceSubModel command :h3 + +[Syntax:] + +Defined in couplingProperties sub-dictionary of the force model in use. If no force sub-model is applied ImEx is used as default. If the keyword "forceSubModels" is provided, a choice of sub model is demanded. + +forceSubModels +( + model_x + model_y +); :pre + +model = name of force sub-model to be applied :ul + +[Examples:] + +forceSubModels +( + ImEx +); :pre + +Note: This examples list might not be complete - please look for other models (forceSubModel_XY) in this documentation. + +[Description:] + +The force sub model is designed to hold the settings a force model can have. For now it handles the treatExplicit, treatDEM and implDEM option. + +[Restrictions:] + +None. + +[Related commands:] + +"ImEx"_forceSubModel_ImEx.html + +Note: This examples list may be incomplete - please look for other models (forceSubModel_XY) in this documentation. + +[Default:] none. diff --git a/doc/forceSubModel_ImEx.html b/doc/forceSubModel_ImEx.html new file mode 100644 index 00000000..43b92d46 --- /dev/null +++ b/doc/forceSubModel_ImEx.html @@ -0,0 +1,45 @@ + +
CFDEMproject WWW Site - CFDEM Commands +
+ + + + +
+ +

forceSubModel_ImEx command +

+

Syntax: +

+

Defined in couplingProperties sub-dictionary of the force model in use. +

+

forceSubModels +( + ImEx; +); +

+

treatExplicit true; // optional for some force models. +treatDEM true; // optional for some force models. +implDEM true; // optional for some force models. +

+

Examples: +

+

forceSubModels +( + ImEx; +); +treatExplicit true; // optional for some force models. +

+

Description: +

+

If no force sub-model is applied ImEx is used as default. If the keyword "forceSubModels" is provided, a choice of sub model is demanded. Depending on the force model different keywords are read and can therefrore be set (see the log file). If the keyword is provided, its value is used. +

+

Restrictions: +

+

none. +

+

Related commands: +

+

forceSubModel +

+ diff --git a/doc/forceSubModel_ImEx.txt b/doc/forceSubModel_ImEx.txt new file mode 100644 index 00000000..e81f55e1 --- /dev/null +++ b/doc/forceSubModel_ImEx.txt @@ -0,0 +1,42 @@ +"CFDEMproject WWW Site"_lws - "CFDEM Commands"_lc :c + +:link(lws,http://www.cfdem.com) +:link(lc,CFDEMcoupling_Manual.html#comm) + +:line + +forceSubModel_ImEx command :h3 + +[Syntax:] + +Defined in couplingProperties sub-dictionary of the force model in use. + +forceSubModels +( + ImEx; +); + +treatExplicit true; // optional for some force models. +treatDEM true; // optional for some force models. +implDEM true; // optional for some force models. + +[Examples:] + +forceSubModels +( + ImEx; +); +treatExplicit true; // optional for some force models. + +[Description:] + + If no force sub-model is applied ImEx is used as default. If the keyword "forceSubModels" is provided, a choice of sub model is demanded. Depending on the force model different keywords are read and can therefrore be set (see the log file). If the keyword is provided, its value is used. + +[Restrictions:] + +none. + +[Related commands:] + +"forceSubModel"_forceSubModel.html + diff --git a/doc/forceSubModel_ImExCorr.html b/doc/forceSubModel_ImExCorr.html new file mode 100644 index 00000000..215cb415 --- /dev/null +++ b/doc/forceSubModel_ImExCorr.html @@ -0,0 +1,46 @@ + +
CFDEMproject WWW Site - CFDEM Commands +
+ + + + +
+ +

forceSubModel_ImExCorr command +

+

Syntax: +

+

Defined in couplingProperties sub-dictionary of the force model in use. +

+

forceSubModels +( + ImExCorr; +); +

+

treatExplicit true; // optional for some force models. +treatDEM true; // optional for some force models. +implDEM true; // optional for some force models. +explicitInterpCorr true; // optional for some force models. +

+

Examples: +

+

forceSubModels +( + ImExCorr; +); +treatExplicit true; // optional for some force models. +

+

Description: +

+

Same as ImEx, but it additionally reads "explicitInterpCorr" to correct the error steming from interpolation of Ufluid and averaging of Uparticles. +

+

Restrictions: +

+

none. +

+

Related commands: +

+

forceSubModel +

+ diff --git a/doc/forceSubModel_ImExCorr.txt b/doc/forceSubModel_ImExCorr.txt new file mode 100644 index 00000000..666ffe11 --- /dev/null +++ b/doc/forceSubModel_ImExCorr.txt @@ -0,0 +1,43 @@ +"CFDEMproject WWW Site"_lws - "CFDEM Commands"_lc :c + +:link(lws,http://www.cfdem.com) +:link(lc,CFDEMcoupling_Manual.html#comm) + +:line + +forceSubModel_ImExCorr command :h3 + +[Syntax:] + +Defined in couplingProperties sub-dictionary of the force model in use. + +forceSubModels +( + ImExCorr; +); + +treatExplicit true; // optional for some force models. +treatDEM true; // optional for some force models. +implDEM true; // optional for some force models. +explicitInterpCorr true; // optional for some force models. + +[Examples:] + +forceSubModels +( + ImExCorr; +); +treatExplicit true; // optional for some force models. + +[Description:] + + Same as ImEx, but it additionally reads "explicitInterpCorr" to correct the error steming from interpolation of Ufluid and averaging of Uparticles. + +[Restrictions:] + +none. + +[Related commands:] + +"forceSubModel"_forceSubModel.html + diff --git a/doc/githubAccess_public.pdf b/doc/githubAccess_public.pdf index 70358f90f8db01fe13f8fdf659904464fb9ff78c..1a83c85c229cec51980aeac4a752b6793d300620 100644 GIT binary patch delta 107 zcmew}QS8q|u?ZaD1XlhI$CMPaWTRw@WJ6;^ jb7SKqbE6dVRI}9NM2i#?3zH->JDVf|DyBc^V3h#?jp8B_ delta 107 zcmew}QS8q|u?ZaD1XlhIM~f8mBy&?^qf|=^ jGt=Z`vs4qK6cYneQ*+BCLj%i1JDVf|DyBc^V3h#?TC^ap diff --git a/src/lagrangian/cfdemParticle/Make/files b/src/lagrangian/cfdemParticle/Make/files index a6bcedac..8b39c90b 100644 --- a/src/lagrangian/cfdemParticle/Make/files +++ b/src/lagrangian/cfdemParticle/Make/files @@ -1,12 +1,13 @@ cfdemCloud = cfdemCloud forceModels = subModels/forceModel +forceSubModels = subModels/forceModel/forceSubModels forceModelsMS = subModels/forceModelMS IOModels = subModels/IOModel voidFractionModels = subModels/voidFractionModel +voidFractionModelsMS = subModels/voidFractionModelMS locateModels = subModels/locateModel meshMotionModels = subModels/meshMotionModel momCoupleModels = subModels/momCoupleModel -regionModels = subModels/regionModel dataExchangeModels = subModels/dataExchangeModel averagingModels = subModels/averagingModel clockModels = subModels/clockModel @@ -15,6 +16,8 @@ smoothingModels = subModels/smoothingModel probeModels = subModels/probeModel $(cfdemCloud)/cfdemCloud.C +derived/cfdemCloudBiDisperse/cfdemCloudBiDisperse.C +derived/cfdemCloudBiDisperseRotation/cfdemCloudBiDisperseRotation.C derived/cfdemCloudIB/cfdemCloudIB.C derived/cfdemCloudMS/cfdemCloudMS.C @@ -23,36 +26,66 @@ $(forceModels)/forceModel/newForceModel.C $(forceModels)/noDrag/noDrag.C $(forceModels)/checkCouplingInterval/checkCouplingInterval.C $(forceModels)/DiFeliceDrag/DiFeliceDrag.C +$(forceModels)/DiFeliceDragNLift/DiFeliceDragNLift.C $(forceModels)/GidaspowDrag/GidaspowDrag.C $(forceModels)/SchillerNaumannDrag/SchillerNaumannDrag.C $(forceModels)/Archimedes/Archimedes.C $(forceModels)/ArchimedesIB/ArchimedesIB.C $(forceModels)/interface/interface.C $(forceModels)/ShirgaonkarIB/ShirgaonkarIB.C +$(forceModels)/interfaceParticleProbe/interfaceParticleProbe.C +$(forceModels)/fieldStore/fieldStore.C +$(forceModels)/fieldTimeAverage/fieldTimeAverage.C +$(forceModels)/fieldBound/fieldBound.C +$(forceModels)/volWeightedAverage/volWeightedAverage.C +$(forceModels)/totalMomentumExchange/totalMomentumExchange.C +$(forceModels)/UStore/UStore.C $(forceModels)/KochHillDrag/KochHillDrag.C $(forceModels)/KochHillRWDrag/KochHillRWDrag.C +$(forceModels)/BeetstraDrag/multiphaseFlowBasic/multiphaseFlowBasic.C +$(forceModels)/BeetstraDrag/BeetstraDrag.C +$(forceModels)/OzelSundaresanDrag/OzelSundaresanDrag.C +$(forceModels)/LaEuScalarLiquid/LaEuScalarLiquid.C $(forceModels)/LaEuScalarTemp/LaEuScalarTemp.C +$(forceModels)/LaEuScalarDust/LaEuScalarDust.C $(forceModels)/virtualMassForce/virtualMassForce.C $(forceModels)/gradPForce/gradPForce.C +$(forceModels)/gradULiftForce/gradULiftForce.C +$(forceModels)/HollowayDrag/HollowayDrag.C $(forceModels)/viscForce/viscForce.C $(forceModels)/MeiLift/MeiLift.C +$(forceModels)/melting/melting.C +/*$(forceModels)/KochHillDragNLift/KochHillDragNLift.C*/ +$(forceModels)/stokesSpheroidDrag/stokesSpheroidDrag.C +$(forceModels)/solidsPressureForce/solidsPressureForce.C +$(forceModels)/periodicPressure/periodicPressure.C +$(forceModels)/periodicPressureControl/periodicPressureControl.C +$(forceModels)/averageSlipVel/averageSlipVel.C $(forceModels)/particleCellVolume/particleCellVolume.C -$(forceModels)/fieldTimeAverage/fieldTimeAverage.C -$(forceModels)/volWeightedAverage/volWeightedAverage.C + +$(forceSubModels)/forceSubModel/newForceSubModel.C +$(forceSubModels)/forceSubModel/forceSubModel.C +$(forceSubModels)/ImEx/ImEx.C +$(forceSubModels)/ImExCorr/ImExCorr.C $(forceModelsMS)/forceModelMS/forceModelMS.C $(forceModelsMS)/forceModelMS/newForceModelMS.C $(forceModelsMS)/DiFeliceDragMS/DiFeliceDragMS.C +$(forceModelsMS)/GidaspowDragMS/GidaspowDragMS.C +$(forceModelsMS)/noDragMS/noDragMS.C $(probeModels)/probeModel/probeModel.C $(probeModels)/probeModel/newProbeModel.C $(probeModels)/noProbe/noProbe.C $(probeModels)/particleProbe/particleProbe.C +/*$(probeModels)/interfaceParticleProbe/interfaceParticleProbe.C*/ $(IOModels)/IOModel/IOModel.C $(IOModels)/IOModel/newIOModel.C $(IOModels)/noIO/noIO.C $(IOModels)/basicIO/basicIO.C +$(IOModels)/tempIO/tempIO.C +$(IOModels)/colorIO/colorIO.C $(IOModels)/trackIO/trackIO.C $(IOModels)/sophIO/sophIO.C @@ -60,46 +93,53 @@ $(voidFractionModels)/voidFractionModel/voidFractionModel.C $(voidFractionModels)/voidFractionModel/newVoidFractionModel.C $(voidFractionModels)/centreVoidFraction/centreVoidFraction.C $(voidFractionModels)/dividedVoidFraction/dividedVoidFraction.C +$(voidFractionModels)/dividedVoidFractionBiDi/dividedVoidFractionBiDi.C $(voidFractionModels)/dividedVoidFractionMS/dividedVoidFractionMS.C $(voidFractionModels)/bigParticleVoidFraction/bigParticleVoidFraction.C $(voidFractionModels)/GaussVoidFraction/GaussVoidFraction.C $(voidFractionModels)/IBVoidFraction/IBVoidFraction.C +$(voidFractionModels)/weightedNeigbhorsVoidFraction/weightedNeigbhorsVoidFraction.C + +$(voidFractionModelsMS)/voidFractionModelMS/voidFractionModelMS.C +$(voidFractionModelsMS)/voidFractionModelMS/newVoidFractionModelMS.C $(locateModels)/locateModel/locateModel.C $(locateModels)/locateModel/newLocateModel.C $(locateModels)/standardSearch/standardSearch.C $(locateModels)/engineSearch/engineSearch.C -$(locateModels)/turboEngineSearch/turboEngineSearch.C $(locateModels)/engineSearchMany2Many/engineSearchMany2Many.C +$(locateModels)/turboEngineSearch/turboEngineSearch.C +$(locateModels)/turboEngineSearchM2M/turboEngineSearchM2M.C $(locateModels)/engineSearchIB/engineSearchIB.C - +$(locateModels)/hyperEngineSearch/hyperEngineSearch.C +$(locateModels)/ijkSearch/ijkSearch.C $(meshMotionModels)/meshMotionModel/meshMotionModel.C $(meshMotionModels)/meshMotionModel/newMeshMotionModel.C $(meshMotionModels)/noMeshMotion/noMeshMotion.C +$(meshMotionModels)/DEMdrivenMeshMotion/DEMdrivenMeshMotion.C $(momCoupleModels)/momCoupleModel/momCoupleModel.C $(momCoupleModels)/momCoupleModel/newMomCoupleModel.C $(momCoupleModels)/explicitCouple/explicitCouple.C +$(momCoupleModels)/explicitCoupleSource/explicitCoupleSource.C $(momCoupleModels)/implicitCouple/implicitCouple.C $(momCoupleModels)/noCouple/noCouple.C -$(regionModels)/regionModel/regionModel.C -$(regionModels)/regionModel/newRegionModel.C -$(regionModels)/allRegion/allRegion.C - $(dataExchangeModels)/dataExchangeModel/dataExchangeModel.C $(dataExchangeModels)/dataExchangeModel/newDataExchangeModel.C $(dataExchangeModels)/oneWayVTK/oneWayVTK.C $(dataExchangeModels)/twoWayFiles/twoWayFiles.C $(dataExchangeModels)/noDataExchange/noDataExchange.C $(dataExchangeModels)/twoWayMPI/twoWayMPI.C +$(dataExchangeModels)/twoWayM2M/twoWayM2M.C $(dataExchangeModels)/twoWayMany2Many/twoWayMany2Many.C $(averagingModels)/averagingModel/averagingModel.C $(averagingModels)/averagingModel/newAveragingModel.C $(averagingModels)/dilute/dilute.C $(averagingModels)/dense/dense.C +$(averagingModels)/denseBiDi/denseBiDi.C $(clockModels)/clockModel/clockModel.C $(clockModels)/clockModel/newClockModel.C @@ -108,6 +148,7 @@ $(clockModels)/noClock/noClock.C $(liggghtsCommandModels)/liggghtsCommandModel/liggghtsCommandModel.C $(liggghtsCommandModels)/liggghtsCommandModel/newLiggghtsCommandModel.C +$(liggghtsCommandModels)/colorParticles/colorParticles.C $(liggghtsCommandModels)/execute/execute.C $(liggghtsCommandModels)/runLiggghts/runLiggghts.C $(liggghtsCommandModels)/writeLiggghts/writeLiggghts.C @@ -117,5 +158,6 @@ $(smoothingModels)/smoothingModel/smoothingModel.C $(smoothingModels)/smoothingModel/newSmoothingModel.C $(smoothingModels)/noSmoothing/noSmoothing.C $(smoothingModels)/constDiffSmoothing/constDiffSmoothing.C +$(smoothingModels)/localPSizeDiffSmoothing/localPSizeDiffSmoothing.C LIB = $(CFDEM_LIB_DIR)/lib$(CFDEM_LIB_NAME) diff --git a/src/lagrangian/cfdemParticle/Make/options b/src/lagrangian/cfdemParticle/Make/options index ce6613b3..4d01d3d8 100644 --- a/src/lagrangian/cfdemParticle/Make/options +++ b/src/lagrangian/cfdemParticle/Make/options @@ -14,11 +14,12 @@ EXE_INC = \ -I$(LIB_SRC)/OpenFOAM/containers/HashTables/labelHashSet \ -I$(CFDEM_LIGGGHTS_SRC_DIR) \ -I$(CFDEM_M2MLIB_PATH) \ + -I$(CFDEM_Many2ManyLIB_PATH) \ -I$(CFDEM_SRC_DIR)/cfdTools \ LIB_LIBS = \ $(PLIBS) \ - -L$(CFDEM_LIB_DIR) \ + -L$(FOAM_USER_LIBBIN) \ -lfiniteVolume \ -lincompressibleRASModels \ -lincompressibleLESModels \ @@ -27,5 +28,11 @@ LIB_LIBS = \ -lmpi_cxx \ -L$(CFDEM_LIGGGHTS_SRC_DIR) \ -Wl,--whole-archive -l$(CFDEM_LIGGGHTS_LIB_NAME) -Wl,--no-whole-archive \ + -L$(CFDEM_M2MLIB_PATH) \ + -lcouple \ -L$(CFDEM_Many2ManyLIB_PATH) \ - -lcoupleMany2Many + -lcoupleMany2Many \ + +/* add -I$(CFDEM_POEMSLIB_PATH) \ to EXE_INC */ +/* -L$(CFDEM_POEMSLIB_PATH) \ */ +/* -lpoems */ diff --git a/src/lagrangian/cfdemParticle/cfdTools/versionInfo.H b/src/lagrangian/cfdemParticle/cfdTools/versionInfo.H index 4fbc1beb..6fe49f4f 100755 --- a/src/lagrangian/cfdemParticle/cfdTools/versionInfo.H +++ b/src/lagrangian/cfdemParticle/cfdTools/versionInfo.H @@ -1,4 +1,4 @@ -word CFDEMversion="cfdem-2.7.1"; +word CFDEMversion="cfdem-2.7.2"; word compatibleLIGGGHTSversion="3.0.2"; word OFversion="2.3.x-commit-4d6f4a3115ff76ec4154c580eb041bc95ba4ec09"; diff --git a/src/lagrangian/cfdemParticle/cfdemCloud/cfdemCloud.H b/src/lagrangian/cfdemParticle/cfdemCloud/cfdemCloud.H index e658f99e..d53dd867 100644 --- a/src/lagrangian/cfdemParticle/cfdemCloud/cfdemCloud.H +++ b/src/lagrangian/cfdemParticle/cfdemCloud/cfdemCloud.H @@ -202,6 +202,7 @@ public: friend class dataExchangeModel; friend class voidFractionModel; friend class forceModel; + friend class forceSubModel; // Constructors diff --git a/src/lagrangian/cfdemParticle/etc/OFversion/OFversion.H b/src/lagrangian/cfdemParticle/etc/OFversion/OFversion.H index aa7bbb96..233ee974 100644 --- a/src/lagrangian/cfdemParticle/etc/OFversion/OFversion.H +++ b/src/lagrangian/cfdemParticle/etc/OFversion/OFversion.H @@ -8,7 +8,7 @@ //#define comp // if comp is on - you must use Make/options_comp! //define multi sphere -#define multisphere +//#define multisphere // features of 2.1 work also in 2.3 #if defined(version23) diff --git a/src/lagrangian/cfdemParticle/etc/library-liggghts-list.txt b/src/lagrangian/cfdemParticle/etc/library-liggghts-list.txt deleted file mode 100644 index a5db17a9..00000000 --- a/src/lagrangian/cfdemParticle/etc/library-liggghts-list.txt +++ /dev/null @@ -1,4 +0,0 @@ -#syntax: makefileName/dir -#note: dir is not a path, just a keyword here -############################################### -Many2Many/dir diff --git a/src/lagrangian/cfdemParticle/etc/library-list.txt b/src/lagrangian/cfdemParticle/etc/library-list.txt index 560f1060..e34c2541 100644 --- a/src/lagrangian/cfdemParticle/etc/library-list.txt +++ b/src/lagrangian/cfdemParticle/etc/library-list.txt @@ -1,2 +1,11 @@ lagrangian/cfdemParticle/dir + +#=====================================================' +#- RADL +fvOptions/dir +cylPorousMedia/dir + +#=====================================================' +#- other finiteVolume/dir + diff --git a/src/lagrangian/cfdemParticle/etc/solver-list.txt b/src/lagrangian/cfdemParticle/etc/solver-list.txt index 925e9976..960eff2f 100644 --- a/src/lagrangian/cfdemParticle/etc/solver-list.txt +++ b/src/lagrangian/cfdemParticle/etc/solver-list.txt @@ -1,4 +1,14 @@ -cfdemSolverPisoMS/dir cfdemSolverPiso/dir cfdemSolverIB/dir cfdemSolverPisoScalar/dir +cfdemSolverPimpleImEx/dir +cfdemSolverIBInterLubrication/dir +cfdemSolverIBScalar/dir +cfdemSolverInterDyM/dir +cfdemSolverInterDyMPC/dir +cfdemSolverBubble/dir +cfdemSolverPisoMS/dir +cfdemSolverPimpleDyM_22x/dir +cfdemSolverPimpleDyMMS_22x/dir +cfdemSolverPimpleDyMScalar_22x/dir +myPimpleDyMFoam/dir diff --git a/src/lagrangian/cfdemParticle/etc/tutorial-list.txt b/src/lagrangian/cfdemParticle/etc/tutorial-list.txt index d893faf1..c1d72a76 100644 --- a/src/lagrangian/cfdemParticle/etc/tutorial-list.txt +++ b/src/lagrangian/cfdemParticle/etc/tutorial-list.txt @@ -7,15 +7,51 @@ #===================================================================# cfdemSolverPiso/settlingTestMPI/dir - cfdemSolverPiso/ErgunTestMPI/dir - cfdemSolverPiso/ErgunTestMPI_cgs/dir - cfdemSolverPiso/ErgunTestMPI_restart/dir - cfdemSolverIB/twoSpheresGlowinskiMPI/dir - cfdemSolverPisoScalar/packedBedTemp/dir +#===================================================================# +# RADL +#cfdemSolverPimpleImEx/settlingTestMPI/dir +#cfdemSolverPimpleImEx/ErgunTestMPI/dir +#cfdemSolverPimpleImEx/crossFlow/dir +#cfdemSolverIB/periodicCase/dir +#cfdemSolverIB/cfdemIBPeriodicCubicalBox_fullyPeriodic/dir +#cfdemSolverIBInterLubrication/twoCoatedParticlesRelMotion_smallTest/dir +#cfdemSolverIBScalar/cfdemIBPeriodicCubicalBoxScalar/dir + +#===================================================================# +# NesteJacobs +#Projects/Neste/cfdemSolverBubble/3pFBreactor/dir +#Projects/Neste/cfdemSolverInterDyM/3pFBreactor/dir + +#===================================================================# +# not in release: + +#cfdemSolverPiso/settlingTestBigParticleMPI/dir cfdemSolverPiso/ErgunTestCG/dir +cfdemSolverPiso/ErgunTestM2M/dir +#cfdemSolverPiso/HopperEmptying/dir + +cfdemSolverPimpleDyM/ErgunTestMPI/dir + +#cfdemSolverPisoMS/settlingTestMPI/dir +#cfdemSolverPisoMS/ErgunTestMPI/dir + +#cfdemSolverInterDyM/twoPhaseSettlingTest/dir +#cfdemSolverInterDyM/ErgunTestMPI/dir +#cfdemSolverInterDyM/granularPiston/dir +#cfdemSolverInterDyM/sugarNcoffee/dir + +#cfdemSolverBubble/ErgunTestMPI_pureLiquid/dir + +#- these examples are already designed for 2.3.x +#cfdemSolverInterDyMPC/sugarNcoffee/dir +#cfdemSolverInterDyMPC/granularPiston/dir +#cfdemSolverInterDyMPC/meltingPot/dir + + + diff --git a/src/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayMany2Many/library/libcoupleMany2Many.a b/src/lagrangian/cfdemParticle/subModels/dataExchangeModel/twoWayMany2Many/library/libcoupleMany2Many.a index 2ef5eb43476242361cc1e3ff6c54e92d97187a1a..4cb55c6f3ac3cdc778c8a269863d05149f609f5c 100644 GIT binary patch delta 425 zcmXxg$xgyh6vpvT2WmyF6QF=Y(N-L>&?3$c1qq1@!^XRD!N#!f1GFo1-@t_Q3D}YJ z9h!9KpU^ITi*xgRIXB1mz7!v$O5U}bPS~&B{T+5|*)oRpg~+ zsh=NNToSK!vS~asjgknbD%PN39R+M)6I(Kz>VMU=(ppr4SQkOOjUDV_5Bn&hB!jqI zETon8q7o?wB2o@fK@~L|;TR`4m62k^^{giN9O^j3IZRl%kTbK<_tK;@Ur-jkNduR- z!ZmJii#yqyG=Kaw?h1Wy4;wAC;b8vW!GqKX-Tp93FAnS_UEw89iVlb7=e+nZQg&t1}+CYF=oy3=}M387o*t zR%$i%<9!jA#4GJ|>W*ioQ4qmY#TqoMBZm!aVoL^7{kQzT;zzphqiyV97kk)89tG(~ z#e6QQ*jBP7R1QR_9HN9WDmcP1PH-wi#fYkD%@%wPRh;1*CTh5lGqc`z7s>g8qUcTP zxWpB%af4gj$=<~J_R@Gm=mQ(`w}}=U+@p<-)Cb-EFikg;1G{loxbXuX@q}l*;8nWu H+t>IHnZu;0 diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/Archimedes/Archimedes.C b/src/lagrangian/cfdemParticle/subModels/forceModel/Archimedes/Archimedes.C index b65f4833..74625881 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/Archimedes/Archimedes.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/Archimedes/Archimedes.C @@ -86,13 +86,22 @@ Archimedes::Archimedes Info << "2-dimensional simulation - make sure DEM side is 2D" << endl; } - if (propsDict_.found("treatExplicit")) treatExplicit_=true; + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + forceSubM(0).setSwitchesList(1,true); // activate treatDEM switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + if (modelType_=="A"){ - treatDEM_=true; + forceSubM(0).setSwitches(1,true); // treatDEM = true Info << "accounting for Archimedes only on DEM side!" << endl; } if (modelType_=="B"){ - treatDEM_=false; + forceSubM(0).setSwitches(1,false); // treatDEM = false Info << "accounting for Archimedes on DEM and CFD side!" << endl; } @@ -143,14 +152,8 @@ void Archimedes::setForce() const } } - if(!treatDEM_) - { - if(treatExplicit_) - for(int j=0;j<3;j++) expForces()[index][j] += force[j]; - else - for(int j=0;j<3;j++) impForces()[index][j] += force[j]; - } - for(int j=0;j<3;j++) DEMForces()[index][j] += force[j]; + // write particle based data to global array + forceSubM(0).partToArray(index,force,vector::zero); //} } } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/ArchimedesIB/ArchimedesIB.C b/src/lagrangian/cfdemParticle/subModels/forceModel/ArchimedesIB/ArchimedesIB.C index d2ab3da3..e8915b7b 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/ArchimedesIB/ArchimedesIB.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/ArchimedesIB/ArchimedesIB.C @@ -85,9 +85,18 @@ ArchimedesIB::ArchimedesIB Info << "2-dimensional simulation - make sure DEM side is 2D" << endl; } - if (propsDict_.found("treatExplicit")) treatExplicit_=true; - treatDEM_=true; + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + + forceSubM(0).setSwitches(1,true); // treatDEM = true Info << "accounting for Archimedes only on DEM side!" << endl; + particleCloud_.checkCG(true); } @@ -131,12 +140,9 @@ void ArchimedesIB::setForce() const // set force on particle if(twoDimensional_) Warning<<"ArchimedesIB model doesn't work for 2D right now!!\n"<< endl; - if(!treatDEM_) - { - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += force[j]; - else for(int j=0;j<3;j++) impForces()[index][j] += force[j]; - } - for(int j=0;j<3;j++) DEMForces()[index][j] += force[j]; + + // write particle based data to global array + forceSubM(0).partToArray(index,force,vector::zero); //} } } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/DiFeliceDrag/DiFeliceDrag.C b/src/lagrangian/cfdemParticle/subModels/forceModel/DiFeliceDrag/DiFeliceDrag.C index b5b7c4c7..d31e980f 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/DiFeliceDrag/DiFeliceDrag.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/DiFeliceDrag/DiFeliceDrag.C @@ -72,7 +72,6 @@ DiFeliceDrag::DiFeliceDrag voidfractionFieldName_(propsDict_.lookup("voidfractionFieldName")), voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), interpolation_(false), - splitImplicitExplicit_(false), UsFieldName_(propsDict_.lookup("granVelFieldName")), UsField_(sm.mesh().lookupObject (UsFieldName_)), scaleDia_(1.), @@ -88,24 +87,26 @@ DiFeliceDrag::DiFeliceDrag particleCloud_.probeM().writeHeader(); if (propsDict_.found("verbose")) verbose_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; if (propsDict_.found("interpolation")) { Info << "using interpolated value of U." << endl; interpolation_=true; } - if (propsDict_.found("splitImplicitExplicit")) - { - Info << "will split implicit / explicit force contributions." << endl; - splitImplicitExplicit_ = true; - if(!interpolation_) - Info << "WARNING: will only consider fluctuating particle velocity in implicit / explicit force split!" << endl; - } particleCloud_.checkCG(true); if (propsDict_.found("scale")) scaleDia_=scalar(readScalar(propsDict_.lookup("scale"))); if (propsDict_.found("scaleDrag")) scaleDrag_=scalar(readScalar(propsDict_.lookup("scaleDrag"))); + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + forceSubM(0).setSwitchesList(2,true); // activate implDEM switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); } @@ -137,6 +138,8 @@ void DiFeliceDrag::setForce() const scalar voidfraction(1); vector Ufluid(0,0,0); vector drag(0,0,0); + vector dragExplicit(0,0,0); + scalar dragCoefficient(0); label cellI=0; vector Us(0,0,0); vector Ur(0,0,0); @@ -147,11 +150,6 @@ void DiFeliceDrag::setForce() const scalar Rep(0); scalar Cd(0); - vector UfluidFluct(0,0,0); - vector UsFluct(0,0,0); - vector dragExplicit(0,0,0); - scalar dragCoefficient(0); - interpolationCellPoint voidfractionInterpolator_(voidfraction_); interpolationCellPoint UInterpolator_(U_); @@ -164,6 +162,9 @@ void DiFeliceDrag::setForce() const cellI = particleCloud_.cellIDs()[index][0]; drag = vector(0,0,0); + dragExplicit = vector(0,0,0); + dragCoefficient=0; + Ufluid =vector(0,0,0); if (cellI > -1) // particle Found { @@ -186,7 +187,6 @@ void DiFeliceDrag::setForce() const magUr = mag(Ur); Rep = 0; Cd = 0; - dragCoefficient = 0; if (magUr > 0) { @@ -212,13 +212,7 @@ void DiFeliceDrag::setForce() const drag = dragCoefficient*Ur; //total drag force! - //Split forces - if(splitImplicitExplicit_) - { - UfluidFluct = Ufluid - U_[cellI]; - UsFluct = Us - UsField_[cellI]; - dragExplicit = dragCoefficient*(UfluidFluct - UsFluct); //explicit part of force - } + forceSubM(0).explicitInterpCorr(dragExplicit,dragCoefficient,Ufluid,U_[cellI],Us,UsField_[cellI],verbose_,index); } if(verbose_ && index >-1 && index <102) @@ -233,12 +227,6 @@ void DiFeliceDrag::setForce() const Pout << "Rep = " << Rep << endl; Pout << "Cd = " << Cd << endl; Pout << "drag (total) = " << drag << endl; - if(splitImplicitExplicit_) - { - Pout << "UfluidFluct = " << UfluidFluct << endl; - Pout << "UsFluct = " << UsFluct << endl; - Pout << "dragExplicit = " << dragExplicit << endl; - } } //Set value fields and write the probe @@ -253,18 +241,9 @@ void DiFeliceDrag::setForce() const particleCloud_.probeM().writeProbe(index, sValues, vValues); } } - // set force on particle - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j]; - else //implicit treatment, taking explicit force contribution into account - { - for(int j=0;j<3;j++) - { - impForces()[index][j] += drag[j] - dragExplicit[j]; //only consider implicit part! - expForces()[index][j] += dragExplicit[j]; - } - } - - for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j]; + + // write particle based data to global array + forceSubM(0).partToArray(index,drag,dragExplicit,Ufluid,dragCoefficient); } //} } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/DiFeliceDrag/DiFeliceDrag.H b/src/lagrangian/cfdemParticle/subModels/forceModel/DiFeliceDrag/DiFeliceDrag.H index 5d788bf6..be593035 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/DiFeliceDrag/DiFeliceDrag.H +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/DiFeliceDrag/DiFeliceDrag.H @@ -76,8 +76,6 @@ private: bool interpolation_; // use interpolated U field values - bool splitImplicitExplicit_; // use splitting of implicit and explict force contribution - word UsFieldName_; const volVectorField& UsField_; // the average particle velocity field (for implicit/expliti force split) diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/GidaspowDrag/GidaspowDrag.C b/src/lagrangian/cfdemParticle/subModels/forceModel/GidaspowDrag/GidaspowDrag.C index ce2c02ea..e5d661ed 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/GidaspowDrag/GidaspowDrag.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/GidaspowDrag/GidaspowDrag.C @@ -72,7 +72,6 @@ GidaspowDrag::GidaspowDrag voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), phi_(readScalar(propsDict_.lookup("phi"))), interpolation_(false), - splitImplicitExplicit_(false), UsFieldName_(propsDict_.lookup("granVelFieldName")), UsField_(sm.mesh().lookupObject (UsFieldName_)), scaleDia_(1.), @@ -89,22 +88,18 @@ GidaspowDrag::GidaspowDrag particleCloud_.probeM().writeHeader(); if (propsDict_.found("verbose")) verbose_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; if (propsDict_.found("interpolation")) interpolation_=true; - if (propsDict_.found("splitImplicitExplicit")) - { - Info << "will split implicit / explicit force contributions." << endl; - splitImplicitExplicit_ = true; - if(!interpolation_) - Info << "WARNING: will only consider fluctuating particle velocity in implicit / explicit force split!" << endl; - } - if (propsDict_.found("implDEM")) - { - treatExplicit_=false; - implDEM_=true; - setImpDEMdrag(); - Info << "Using implicit DEM drag formulation." << endl; - } + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + forceSubM(0).setSwitchesList(2,true); // activate implDEM switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + particleCloud_.checkCG(true); if (propsDict_.found("scale")) scaleDia_=scalar(readScalar(propsDict_.lookup("scale"))); @@ -162,8 +157,7 @@ void GidaspowDrag::setForce() const scalar betaP(0); //momentum exchange of the very particle vector dragExplicit(0,0,0); - vector UfluidFluct(0,0,0); - vector UsFluct(0,0,0); + scalar dragCoefficient(0); interpolationCellPoint voidfractionInterpolator_(voidfraction_); interpolationCellPoint UInterpolator_(U_); @@ -176,10 +170,12 @@ void GidaspowDrag::setForce() const //{ cellI = particleCloud_.cellIDs()[index][0]; drag = vector(0,0,0); + dragExplicit = vector(0,0,0); betaP = 0; Vs = 0; Ufluid =vector(0,0,0); voidfraction=0; + dragCoefficient = 0; if (cellI > -1) // particle Found { @@ -234,21 +230,14 @@ void GidaspowDrag::setForce() const } // calc particle's drag - drag = Vs * betaP * Ur * scaleDrag_; - + dragCoefficient = Vs*betaP*scaleDrag_; if (modelType_=="B") - drag /= voidfraction; + dragCoefficient /= voidfraction; - //Split forces - if(splitImplicitExplicit_) - { - UfluidFluct = Ufluid - U_[cellI]; - UsFluct = Us - UsField_[cellI]; - dragExplicit = Vs * betaP * (UfluidFluct - UsFluct); //explicit part of force - - if (modelType_=="B") - dragExplicit /= voidfraction; - } + drag = dragCoefficient * Ur; + + // explicitInterpCorr + forceSubM(0).explicitInterpCorr(dragExplicit,dragCoefficient,Ufluid,U_[cellI],Us,UsField_[cellI],verbose_); if(verbose_ && index >=0 && index <2) { @@ -265,13 +254,6 @@ void GidaspowDrag::setForce() const Pout << "Rep = " << Rep << endl; Pout << "betaP = " << betaP << endl; Pout << "drag = " << drag << endl; - - if(splitImplicitExplicit_) - { - Pout << "UfluidFluct = " << UfluidFluct << endl; - Pout << "UsFluct = " << UsFluct << endl; - Pout << "dragExplicit = " << dragExplicit << endl; - } } //Set value fields and write the probe @@ -287,30 +269,8 @@ void GidaspowDrag::setForce() const } } - // set force on particle - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j]; - else //implicit treatment, taking explicit force contribution into account - { - for(int j=0;j<3;j++) - { - impForces()[index][j] += drag[j] - dragExplicit[j]; //only consider implicit part! - expForces()[index][j] += dragExplicit[j]; - } - } - - // set Cd - if(implDEM_) - { - for(int j=0;j<3;j++) fluidVel()[index][j]=Ufluid[j]; - - if (modelType_=="B" && cellI > -1) - Cds()[index][0] = Vs*betaP/voidfraction*scaleDrag_; - else - Cds()[index][0] = Vs*betaP*scaleDrag_; - - }else{ - for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j]; - } + // write particle based data to global array + forceSubM(0).partToArray(index,drag,dragExplicit,Ufluid,dragCoefficient); //}// end if mask }// end loop particles diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/GidaspowDrag/GidaspowDrag.H b/src/lagrangian/cfdemParticle/subModels/forceModel/GidaspowDrag/GidaspowDrag.H index 7e612df6..db45472e 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/GidaspowDrag/GidaspowDrag.H +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/GidaspowDrag/GidaspowDrag.H @@ -82,11 +82,9 @@ private: bool interpolation_; // use interpolated field values - bool splitImplicitExplicit_; // use splitting of implicit and explict force contribution - word UsFieldName_; - const volVectorField& UsField_; // the average particle velocity field (for implicit/expliti force split) + const volVectorField& UsField_; // the average particle velocity field mutable scalar scaleDia_; diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.C b/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.C index 0b4780dd..d0c12c85 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.C @@ -71,6 +71,8 @@ KochHillDrag::KochHillDrag rho_(sm.mesh().lookupObject (densityFieldName_)), voidfractionFieldName_(propsDict_.lookup("voidfractionFieldName")), voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), + UsFieldName_(propsDict_.lookupOrDefault("granVelFieldName",word("Us"))), + UsField_(sm.mesh().lookupObject (UsFieldName_)), interpolation_(false), scaleDia_(1.), scaleDrag_(1.) @@ -85,15 +87,18 @@ KochHillDrag::KochHillDrag particleCloud_.probeM().writeHeader(); if (propsDict_.found("verbose")) verbose_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; if (propsDict_.found("interpolation")) interpolation_=true; - if (propsDict_.found("implDEM")) - { - treatExplicit_=false; - implDEM_=true; - setImpDEMdrag(); - Info << "Using implicit DEM drag formulation." << endl; - } + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + forceSubM(0).setSwitchesList(2,true); // activate implDEM switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + particleCloud_.checkCG(true); if (propsDict_.found("scale")) @@ -131,6 +136,8 @@ void KochHillDrag::setForce() const scalar voidfraction(1); vector Ufluid(0,0,0); vector drag(0,0,0); + vector dragExplicit(0,0,0); + scalar dragCoefficient(0); label cellI=0; vector Us(0,0,0); @@ -155,6 +162,8 @@ void KochHillDrag::setForce() const //{ cellI = particleCloud_.cellIDs()[index][0]; drag = vector(0,0,0); + dragExplicit = vector(0,0,0); + dragCoefficient=0; betaP = 0; Vs = 0; Ufluid =vector(0,0,0); @@ -217,10 +226,14 @@ void KochHillDrag::setForce() const betaP = 18.*nuf*rho/(ds/scaleDia_*ds/scaleDia_)*voidfraction*F; // calc particle's drag - drag = Vs*betaP*Ur*scaleDrag_; - + dragCoefficient = Vs*betaP*scaleDrag_; if (modelType_=="B") - drag /= voidfraction; + dragCoefficient /= voidfraction; + + drag = dragCoefficient * Ur; + + // explicitInterpCorr + forceSubM(0).explicitInterpCorr(dragExplicit,dragCoefficient,Ufluid,U_[cellI],Us,UsField_[cellI],verbose_); } if(verbose_ && index >=0 && index <2) @@ -251,23 +264,9 @@ void KochHillDrag::setForce() const particleCloud_.probeM().writeProbe(index, sValues, vValues); } } - // set force on particle - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j]; - else for(int j=0;j<3;j++) impForces()[index][j] += drag[j]; - // set Cd - if(implDEM_) - { - for(int j=0;j<3;j++) fluidVel()[index][j]=Ufluid[j]; - - if (modelType_=="B" && cellI > -1) - Cds()[index][0] = Vs*betaP/voidfraction*scaleDrag_; - else - Cds()[index][0] = Vs*betaP*scaleDrag_; - - }else{ - for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j]; - } + // write particle based data to global array + forceSubM(0).partToArray(index,drag,dragExplicit,Ufluid,dragCoefficient); //} } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.H b/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.H index 8937a456..77b6cec1 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.H +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillDrag/KochHillDrag.H @@ -78,6 +78,10 @@ private: const volScalarField& voidfraction_; + word UsFieldName_; + + const volVectorField& UsField_; + bool interpolation_; // use interpolated field values mutable scalar scaleDia_; diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillRWDrag/KochHillRWDrag.C b/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillRWDrag/KochHillRWDrag.C index 187fb0b1..994e005e 100755 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillRWDrag/KochHillRWDrag.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillRWDrag/KochHillRWDrag.C @@ -71,6 +71,8 @@ KochHillRWDrag::KochHillRWDrag rho_(sm.mesh().lookupObject (densityFieldName_)), voidfractionFieldName_(propsDict_.lookup("voidfractionFieldName")), voidfraction_(sm.mesh().lookupObject (voidfractionFieldName_)), + UsFieldName_(propsDict_.lookupOrDefault("granVelFieldName",word("Us"))), + UsField_(sm.mesh().lookupObject (UsFieldName_)), interpolation_(false), scale_(1.), randomTauE_(false), @@ -80,16 +82,19 @@ KochHillRWDrag::KochHillRWDrag { if (propsDict_.found("verbose")) verbose_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; if (propsDict_.found("interpolation")) interpolation_=true; if (propsDict_.found("randomTauE")) randomTauE_=true; - if (propsDict_.found("implDEM")) - { - treatExplicit_=false; - implDEM_=true; - setImpDEMdrag(); - Info << "Using implicit DEM drag formulation." << endl; - } + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + forceSubM(0).setSwitchesList(2,true); // activate implDEM switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + particleCloud_.checkCG(true); if (propsDict_.found("scale")) @@ -162,6 +167,8 @@ void KochHillRWDrag::setForce() const scalar voidfraction(1); vector Ufluid(0,0,0); vector drag(0,0,0); + vector dragExplicit(0,0,0); + scalar dragCoefficient(0); label cellI=0; vector Us(0,0,0); @@ -211,12 +218,13 @@ void KochHillRWDrag::setForce() const //{ cellI = particleCloud_.cellIDs()[index][0]; drag = vector(0,0,0); + dragExplicit = vector(0,0,0); + dragCoefficient=0; betaP = 0; Vs = 0; Ufluid =vector(0,0,0); // Pout << "RW-TEST: cellI = " << cellI << endl; // TEST-Output -Info << "haha1" << endl; if (cellI > -1) // particle Found { if(interpolation_) @@ -285,7 +293,6 @@ Info << "haha1" << endl; } else { minDeltaT = timeE; } -Info << "haha3" << endl; //Pout << "RW-TEST: timeE = " << timeE << " timeCR = " << timeCr << endl; // TEST-Output // calculate time step of next update @@ -300,11 +307,9 @@ Info << "haha3" << endl; //Pout << "RW-TEST: Ufluid[" << dim << "] = " << Ufluid[dim] << " Ufluct = " << partUfluct_[index][dim] << " k = " << k << endl; // TEST-Output Ufluid[dim] = Ufluid[dim] + partUfluct_[index][dim]; } -Info << "haha4" << endl; } else { -Info << "haha5" << endl; // no update of the turbulent velocity part // modify current fluid velocity for(int dim=0;dim<3;dim++) @@ -322,7 +327,6 @@ Info << "haha5" << endl; Rep = 0; Vs = ds*ds*ds*M_PI/6; volumefraction = 1-voidfraction+SMALL; -Info << "haha6" << endl; if (magUr > 0) { // calc particle Re Nr @@ -352,11 +356,14 @@ Info << "haha6" << endl; betaP = 18.*nuf*rho/(ds/scale_*ds/scale_)*voidfraction*F; // calc particle's drag - drag = Vs*betaP*Ur; - + dragCoefficient = Vs*betaP;//*scaleDrag_; if (modelType_=="B") - drag /= voidfraction; -Info << "haha7" << endl; + dragCoefficient /= voidfraction; + + drag = dragCoefficient * Ur; + + // explicitInterpCorr + forceSubM(0).explicitInterpCorr(dragExplicit,dragCoefficient,Ufluid,U_[cellI],Us,UsField_[cellI],verbose_); } if(verbose_ && index >=0 && index <2) @@ -372,30 +379,11 @@ Info << "haha7" << endl; Pout << "Rep = " << Rep << endl; Pout << "drag = " << drag << endl; } -Info << "haha8" << endl; } -Info << "haha9" << endl; - // set force on particle - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j]; - else for(int j=0;j<3;j++) impForces()[index][j] += drag[j]; - - // set Cd - if(implDEM_) - { - for(int j=0;j<3;j++) fluidVel()[index][j]=Ufluid[j]; - - if (modelType_=="B") - Cds()[index][0] = Vs*betaP/voidfraction; - else - Cds()[index][0] = Vs*betaP; - - }else{ - for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j]; - } -Info << "haha10" << endl; + // write particle based data to global array + forceSubM(0).partToArray(index,drag,dragExplicit,Ufluid,dragCoefficient); //} } -Info << "haha11" << endl; } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillRWDrag/KochHillRWDrag.H b/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillRWDrag/KochHillRWDrag.H index 23d9239e..a78f04b9 100755 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillRWDrag/KochHillRWDrag.H +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/KochHillRWDrag/KochHillRWDrag.H @@ -79,6 +79,10 @@ private: const volScalarField& voidfraction_; + word UsFieldName_; + + const volVectorField& UsField_; // the average particle velocity field + bool interpolation_; // use interpolated field values mutable scalar scale_; diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/MeiLift/MeiLift.C b/src/lagrangian/cfdemParticle/subModels/forceModel/MeiLift/MeiLift.C index 38d5527d..05d12b02 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/MeiLift/MeiLift.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/MeiLift/MeiLift.C @@ -76,7 +76,15 @@ MeiLift::MeiLift vorticity_(sm.mesh().lookupObject (vorticityFieldName_))*/ { if (propsDict_.found("useSecondOrderTerms")) useSecondOrderTerms_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); if (propsDict_.found("interpolation")) interpolation_=true; if (propsDict_.found("verbose")) verbose_=true; @@ -261,13 +269,8 @@ void MeiLift::setForce() const //********************************** } - // set force on particle - if(!treatDEM_) - { - if(!treatExplicit_) for(int j=0;j<3;j++) impForces()[index][j] += lift[j]; - else for(int j=0;j<3;j++) expForces()[index][j] += lift[j]; - } - for(int j=0;j<3;j++) DEMForces()[index][j] += lift[j]; + // write particle based data to global array + forceSubM(0).partToArray(index,lift,vector::zero); //} } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/SchillerNaumannDrag/SchillerNaumannDrag.C b/src/lagrangian/cfdemParticle/subModels/forceModel/SchillerNaumannDrag/SchillerNaumannDrag.C index 0630b0f9..e034b8d9 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/SchillerNaumannDrag/SchillerNaumannDrag.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/SchillerNaumannDrag/SchillerNaumannDrag.C @@ -79,7 +79,16 @@ SchillerNaumannDrag::SchillerNaumannDrag particleCloud_.probeM().writeHeader(); if (propsDict_.found("verbose")) verbose_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + particleCloud_.checkCG(false); } @@ -163,10 +172,9 @@ void SchillerNaumannDrag::setForce() const particleCloud_.probeM().writeProbe(index, sValues, vValues); } } - // set force on particle - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j]; - else for(int j=0;j<3;j++) impForces()[index][j] += drag[j]; - for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j]; + + // write particle based data to global array + forceSubM(0).partToArray(index,drag,vector::zero); //} } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/ShirgaonkarIB/ShirgaonkarIB.C b/src/lagrangian/cfdemParticle/subModels/forceModel/ShirgaonkarIB/ShirgaonkarIB.C index 43968692..33ac3f19 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/ShirgaonkarIB/ShirgaonkarIB.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/ShirgaonkarIB/ShirgaonkarIB.C @@ -86,7 +86,16 @@ ShirgaonkarIB::ShirgaonkarIB Info << "2-dimensional simulation - make sure DEM side is 2D" << endl; Info << "depth of domain is assumed to be :" << depth_ << endl; } - if (propsDict_.found("treatExplicit")) treatExplicit_=true; + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + particleCloud_.checkCG(false); } @@ -146,9 +155,8 @@ void ShirgaonkarIB::setForce() const particleCloud_.probeM().writeProbe(index, sValues, vValues); } - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += drag[j]; - else for(int j=0;j<3;j++) impForces()[index][j] += drag[j]; - for(int j=0;j<3;j++) DEMForces()[index][j] += drag[j]; + // write particle based data to global array + forceSubM(0).partToArray(index,drag,vector::zero); if(verbose_) Info << "impForces = " << impForces()[index][0]<<","<[nrForceSubModels()]) {} @@ -165,6 +167,29 @@ void forceModel::treatVoidCells() const } } +void forceModel::setForceSubModels(dictionary& dict) +{ + if (dict.found("forceSubModels")) + forceSubModels_ = wordList(dict.lookup("forceSubModels")); + else{ + forceSubModels_ = wordList(1); + forceSubModels_[0] = "ImEx"; + } + + delete[] forceSubModel_; + forceSubModel_ = new autoPtr[nrForceSubModels()]; + Info << "nrForceSubModels()=" << nrForceSubModels() << endl; + for (int i=0;i* forceSubModel_; + public: //- Runtime type information @@ -150,13 +153,19 @@ public: inline const bool& coupleForce() const { return coupleForce_;}; - void const setImpDEMdrag() const {particleCloud_.impDEMdrag_=true;}; - virtual inline bool& requiresEx() { return requiresEx_;}; void repartitionImExForces() const; //Repartition Implixit/Explicit forces void treatVoidCells() const; + + inline const wordList& forceSubModels(){ return forceSubModels_; }; + + inline const forceSubModel& forceSubM(int i) const { return forceSubModel_[i]; }; + + inline int nrForceSubModels(){ return forceSubModels_.size(); }; + + void setForceSubModels(dictionary& dict); }; diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.C b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.C new file mode 100644 index 00000000..63595bb1 --- /dev/null +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.C @@ -0,0 +1,81 @@ +/*---------------------------------------------------------------------------*\ + CFDEMcoupling - Open Source CFD-DEM coupling + + CFDEMcoupling is part of the CFDEMproject + www.cfdem.com + Christoph Goniva, christoph.goniva@cfdem.com + Copyright 2009-2012 JKU Linz + Copyright 2012- DCS Computing GmbH, Linz +------------------------------------------------------------------------------- +License + This file is part of CFDEMcoupling. + + CFDEMcoupling is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with CFDEMcoupling; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Description + This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS + and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). +\*---------------------------------------------------------------------------*/ + +#include "error.H" + +#include "ImEx.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(ImEx, 0); + +addToRunTimeSelectionTable +( + forceSubModel, + ImEx, + dictionary +); + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +// Construct from components +ImEx::ImEx +( + const dictionary& dict, + cfdemCloud& sm, + forceModel& fm +) +: + forceSubModel(dict,sm,fm) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +ImEx::~ImEx() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.H b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.H new file mode 100644 index 00000000..7d017b99 --- /dev/null +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/ImEx/ImEx.H @@ -0,0 +1,95 @@ +/*---------------------------------------------------------------------------*\ + CFDEMcoupling - Open Source CFD-DEM coupling + + CFDEMcoupling is part of the CFDEMproject + www.cfdem.com + Christoph Goniva, christoph.goniva@cfdem.com + Copyright 2009-2012 JKU Linz + Copyright 2012- DCS Computing GmbH, Linz +------------------------------------------------------------------------------- +License + This file is part of CFDEMcoupling. + + CFDEMcoupling is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with CFDEMcoupling; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Description + This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS + and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). + +Class + ImEx + +SourceFiles + ImEx.C + +\*---------------------------------------------------------------------------*/ + +#ifndef ImEx_H +#define ImEx_H + +#include "forceSubModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class ImEx Declaration +\*---------------------------------------------------------------------------*/ + +class ImEx +: + public forceSubModel +{ +private: + + +public: + + //- Runtime type information + TypeName("ImEx"); + + + // Constructors + + //- Construct from components + ImEx + ( + const dictionary& dict, + cfdemCloud& sm, + forceModel& fm + ); + + // Destructor + + ~ImEx(); + + + // Member Functions + + word myType() const{return typeName; }; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.C b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.C new file mode 100644 index 00000000..9f8b696a --- /dev/null +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.C @@ -0,0 +1,182 @@ +/*---------------------------------------------------------------------------*\ + CFDEMcoupling - Open Source CFD-DEM coupling + + CFDEMcoupling is part of the CFDEMproject + www.cfdem.com + Christoph Goniva, christoph.goniva@cfdem.com + Copyright 2009-2012 JKU Linz + Copyright 2012- DCS Computing GmbH, Linz +------------------------------------------------------------------------------- +License + This file is part of CFDEMcoupling. + + CFDEMcoupling is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with CFDEMcoupling; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Description + This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS + and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). +\*---------------------------------------------------------------------------*/ + +#include "error.H" +#include "forceSubModel.H" +#include "forceModel.H" +#include "mathExtra.H" +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineTypeNameAndDebug(forceSubModel, 0); + +defineRunTimeSelectionTable(forceSubModel, dictionary); + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +// Construct from components +forceSubModel::forceSubModel +( + const dictionary& dict, + cfdemCloud& sm, + forceModel& fm +) +: + dict_(dict), + particleCloud_(sm), + forceModel_(fm), + nrDefaultSwitches_(3), + switchesNameList_(wordList(nrDefaultSwitches_)), + switchesList_(List(nrDefaultSwitches_)), + switches_(List(nrDefaultSwitches_)) +{ + // init switches lists + switchesNameList_[0]="treatExplicit"; + switchesNameList_[1]="treatDEM"; + switchesNameList_[2]="implDEM"; + for(int i=0;i 0+SMALL) + { + Info << " looking for " << switchesNameList_[i] << " ..." << endl; + if (dict_.found(switchesNameList_[i])) + switches_[i]=Switch(dict_.lookup(switchesNameList_[i])); + + Info << "\t" << switchesNameList_[i] << " = " << switches_[i] << endl; + } + } + Info << endl; + + if(switches_[2]) // implDEM=true + { + // communicate implDEM to particleCloud + particleCloud_.impDEMdrag_=true; + + // do sanity check + if(switches_[0]) // treatExplicit=true + { + Warning<< "please check your settings, treatExplicit together with implDEM does not work! (using treatExplicit=false)" << endl; + switches_[0]=false; + } + } +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.H b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.H new file mode 100644 index 00000000..fb383d6b --- /dev/null +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/forceSubModel.H @@ -0,0 +1,156 @@ +/*---------------------------------------------------------------------------*\ + CFDEMcoupling - Open Source CFD-DEM coupling + + CFDEMcoupling is part of the CFDEMproject + www.cfdem.com + Christoph Goniva, christoph.goniva@cfdem.com + Copyright 2009-2012 JKU Linz + Copyright 2012- DCS Computing GmbH, Linz +------------------------------------------------------------------------------- +License + This file is part of CFDEMcoupling. + + CFDEMcoupling is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with CFDEMcoupling; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Description + This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS + and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). + +Class + forceSubModel + +SourceFiles + forceSubModel.C + +\*---------------------------------------------------------------------------*/ + +#ifndef forceSubModel_H +#define forceSubModel_H + +#include "fvCFD.H" +#include "cfdemCloud.H" +#include "probeModel.H" +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class forceSubModel Declaration +\*---------------------------------------------------------------------------*/ + +class forceSubModel +{ + +protected: + + // Protected data + const dictionary& dict_; + + cfdemCloud& particleCloud_; + + forceModel& forceModel_; + + label nrDefaultSwitches_; // nr of switches defined in mother class + + wordList switchesNameList_; // names of switches available + + mutable List switchesList_; // switches which are requested in dict + + mutable List switches_; + + +public: + + //- Runtime type information + TypeName("forceSubModel"); + + // Declare runtime constructor selection table + + declareRunTimeSelectionTable + ( + autoPtr, + forceSubModel, + dictionary, + ( + const dictionary& dict, + cfdemCloud& sm, + forceModel& fm + ), + (dict,sm,fm) + ); + + + // Constructors + + //- Construct from components + forceSubModel + ( + const dictionary& dict, + cfdemCloud& sm, + forceModel& fm + ); + + + // Destructor + + virtual ~forceSubModel(); + + + // Selector + + static autoPtr New + ( + const dictionary& dict, + cfdemCloud& sm, + forceModel& fm, + word forceType + ); + + + // Member Functions + void partToArray(label&, vector&, const vector&, const vector& Ufluid=vector::zero, scalar Cd=scalar(0)) const; + + virtual void explicitInterpCorr(vector&, scalar&, vector&, const vector&, vector&, const vector&, bool,label index=100) const; + + // Access + + virtual word myType() const=0; + + inline forceModel& myForceM() const { return forceModel_;}; + + inline const List& switches() const { return switches_;}; + + inline const wordList& switchesNameList() const { return switchesNameList_;}; + + void setSwitchesList(label i, bool v) const { switchesList_[i] = label(v);}; + + void setSwitches(label i, Switch v) const { switches_[i] = v;}; + + virtual void readSwitches() const; + + const label& nrDefaultSwitches() const {return nrDefaultSwitches_;}; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/newForceSubModel.C b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/newForceSubModel.C new file mode 100644 index 00000000..cc2d34f5 --- /dev/null +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/forceSubModels/forceSubModel/newForceSubModel.C @@ -0,0 +1,79 @@ +/*---------------------------------------------------------------------------*\ + CFDEMcoupling - Open Source CFD-DEM coupling + + CFDEMcoupling is part of the CFDEMproject + www.cfdem.com + Christoph Goniva, christoph.goniva@cfdem.com + Copyright 2009-2012 JKU Linz + Copyright 2012- DCS Computing GmbH, Linz +------------------------------------------------------------------------------- +License + This file is part of CFDEMcoupling. + + CFDEMcoupling is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with CFDEMcoupling; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Description + This code is designed to realize coupled CFD-DEM simulations using LIGGGHTS + and OpenFOAM(R). Note: this code is not part of OpenFOAM(R) (see DISCLAIMER). +\*---------------------------------------------------------------------------*/ + +#include "error.H" + +#include "forceSubModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +autoPtr forceSubModel::New +( + const dictionary& dict, + cfdemCloud& sm, + forceModel& fm, + word forceType +) +{ + Info<< "Selecting forceSubModel " + << forceType << endl; + + dictionaryConstructorTable::iterator cstrIter = + dictionaryConstructorTablePtr_->find(forceType); + + if (cstrIter == dictionaryConstructorTablePtr_->end()) + { + FatalError + << "forceSubModel::New(const dictionary&, const spray&) : " + << endl + << " unknown forceSubModelType type " + << forceType + << ", constructor not in hash table" << endl << endl + << " Valid forceSubModel types are :" + << endl; + Info<< dictionaryConstructorTablePtr_->toc() + << abort(FatalError); + } + + return autoPtr(cstrIter()(dict,sm,fm)); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/gradPForce/gradPForce.C b/src/lagrangian/cfdemParticle/subModels/forceModel/gradPForce/gradPForce.C index a4db6cdf..560036bd 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/gradPForce/gradPForce.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/gradPForce/gradPForce.C @@ -74,16 +74,26 @@ gradPForce::gradPForce addedMassCoeff_(0.0), interpolation_(false) { + if (propsDict_.found("verbose")) verbose_=true; + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + if (modelType_ == "B") { FatalError <<"using model gradPForce with model type B is not valid\n" << abort(FatalError); }else { - treatDEM_=true; + forceSubM(0).setSwitches(1,true); // treatDEM = true Info << "gradPForce is applied only to DEM side" << endl; } - if (propsDict_.found("verbose")) verbose_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; + if (propsDict_.found("useU")) useU_=true; if (propsDict_.found("useAddedMass")) { @@ -131,7 +141,6 @@ void gradPForce::setForce() const gradPField = fvc::grad(0.5*rho_*U2); }*/ vector gradP; - scalar ds; scalar Vs; scalar rho; vector position; @@ -188,12 +197,8 @@ void gradPForce::setForce() const } } - // set force on particle - if(!treatDEM_){ - if(!treatExplicit_) for(int j=0;j<3;j++) impForces()[index][j] += force[j]; - else for(int j=0;j<3;j++) expForces()[index][j] += force[j]; - } - for(int j=0;j<3;j++) DEMForces()[index][j] += force[j]; + // write particle based data to global array + forceSubM(0).partToArray(index,force,vector::zero); //} } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/interface/interface.C b/src/lagrangian/cfdemParticle/subModels/forceModel/interface/interface.C index 23d2c7fc..3507f08d 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/interface/interface.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/interface/interface.C @@ -78,7 +78,15 @@ interface::interface { if (propsDict_.found("C")) C_=readScalar(propsDict_.lookup("C")); if (propsDict_.found("interpolation")) interpolation_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); Info << "check if interpolation really works - use directly interpolationCellPoint ???" << endl; particleCloud_.checkCG(false); @@ -179,9 +187,9 @@ Info << "interface::setForce" << endl; Info << "interface force is limited to " << interfaceForce << endl; }*/ - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += interfaceForce[j]; - else for(int j=0;j<3;j++) impForces()[index][j] += interfaceForce[j]; - for(int j=0;j<3;j++) DEMForces()[index][j] += interfaceForce[j]; + // write particle based data to global array + forceSubM(0).partToArray(index,interfaceForce,vector::zero); + } // end if particle found on proc domain //}// end if in mask }// end loop particles diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/noDrag/noDrag.C b/src/lagrangian/cfdemParticle/subModels/forceModel/noDrag/noDrag.C index e3073a21..0a403a02 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/noDrag/noDrag.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/noDrag/noDrag.C @@ -68,6 +68,15 @@ noDrag::noDrag if(dict.found(word(typeName + "Props"))) propsDict_=dictionary(dict.subDict(typeName + "Props")); + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + if (propsDict_.found("noDEMForce")) noDEMForce_=true; if (propsDict_.found("keepCFDForce")) keepCFDForce_=true; @@ -89,15 +98,21 @@ void noDrag::setForce() const // Do nothing Info << "noDrag::setForce" << endl; label cellI=0; + bool treatExplicit=forceSubM(0).switches()[0]; for(int index = 0;index < particleCloud_.numberOfParticles(); ++index) { cellI = particleCloud_.cellIDs()[index][0]; if (cellI > -1) // particle Found { - // set force on particle + //========================== + // set force on particle (new code) + // write particle based data to global array + //forceSubM(0).partToArray(index,drag,dragExplicit); + //========================== + // set force on particle (old code) if(!keepCFDForce_) { - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] = 0.; + if(treatExplicit) for(int j=0;j<3;j++) expForces()[index][j] = 0.; else for(int j=0;j<3;j++) impForces()[index][j] = 0.; } if(noDEMForce_) @@ -109,6 +124,7 @@ void noDrag::setForce() const for(int j=0;j<3;j++) fluidVel()[index][j] = 0.; } } + //========================== } } } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/virtualMassForce/virtualMassForce.C b/src/lagrangian/cfdemParticle/subModels/forceModel/virtualMassForce/virtualMassForce.C index 89ab4a70..b55c3206 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/virtualMassForce/virtualMassForce.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/virtualMassForce/virtualMassForce.C @@ -77,7 +77,16 @@ virtualMassForce::virtualMassForce // get memory for 2d array particleCloud_.dataExchangeM().allocateArray(UrelOld_,0.,3); } - if (propsDict_.found("treatExplicit")) treatExplicit_=true; + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + particleCloud_.checkCG(true); //Append the field names to be probed @@ -146,10 +155,9 @@ void virtualMassForce::setForce() const particleCloud_.probeM().writeProbe(index, sValues, vValues); } } - // set force on particle - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += virtualMassForce[j]; - else for(int j=0;j<3;j++) impForces()[index][j] += virtualMassForce[j]; - for(int j=0;j<3;j++) DEMForces()[index][j] += virtualMassForce[j]; + + // write particle based data to global array + forceSubM(0).partToArray(index,virtualMassForce,vector::zero); //} } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModel/viscForce/viscForce.C b/src/lagrangian/cfdemParticle/subModels/forceModel/viscForce/viscForce.C index a35ed3e1..ed87267a 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModel/viscForce/viscForce.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModel/viscForce/viscForce.C @@ -70,16 +70,25 @@ viscForce::viscForce addedMassCoeff_(0.0), interpolation_(false) { + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + if (modelType_ == "B") { FatalError <<"using model viscForce with model type B is not valid\n" << abort(FatalError); }else { - treatDEM_=true; + forceSubM(0).setSwitches(1,true); // treatDEM = true Info << "viscForce is applied only to DEM side" << endl; } if (propsDict_.found("verbose")) verbose_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; if (propsDict_.found("useAddedMass")) { @@ -132,7 +141,6 @@ void viscForce::setForce() const #endif vector divTau; - scalar ds; scalar Vs; vector position; vector force; @@ -185,13 +193,8 @@ void viscForce::setForce() const } } - // set force on particle - if(!treatDEM_){ - if(!treatExplicit_) for(int j=0;j<3;j++) impForces()[index][j] += force[j]; - else for(int j=0;j<3;j++) expForces()[index][j] += force[j]; - } - for(int j=0;j<3;j++) DEMForces()[index][j] += force[j]; - + // write particle based data to global array + forceSubM(0).partToArray(index,force,vector::zero); //} } } diff --git a/src/lagrangian/cfdemParticle/subModels/forceModelMS/DiFeliceDragMS/DiFeliceDragMS.C b/src/lagrangian/cfdemParticle/subModels/forceModelMS/DiFeliceDragMS/DiFeliceDragMS.C index 06b64221..1399a5f6 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModelMS/DiFeliceDragMS/DiFeliceDragMS.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModelMS/DiFeliceDragMS/DiFeliceDragMS.C @@ -88,7 +88,16 @@ DiFeliceDragMS::DiFeliceDragMS particleCloud_.probeM().writeHeader(); if (propsDict_.found("verbose")) verbose_=true; - if (propsDict_.found("treatExplicit")) treatExplicit_=true; + + // init force sub model + setForceSubModels(propsDict_); + + // define switches which can be read from dict + forceSubM(0).setSwitchesList(0,true); // activate treatExplicit switch + + // read those switches defined above, if provided in dict + forceSubM(0).readSwitches(); + if (propsDict_.found("interpolation")) { Info << "using interpolated value of U." << endl; @@ -246,7 +255,7 @@ void DiFeliceDragMS::setForce() const } } // set force on bodies - if(treatExplicit_) for(int j=0;j<3;j++) cloudRefMS().expForcesCM()[index][j] += drag[j]; + if(forceSubM(0).switches()[0]) for(int j=0;j<3;j++) cloudRefMS().expForcesCM()[index][j] += drag[j]; else //implicit treatment, taking explicit force contribution into account { for(int j=0;j<3;j++) diff --git a/src/lagrangian/cfdemParticle/subModels/forceModelMS/forceModelMS/forceModelMS.C b/src/lagrangian/cfdemParticle/subModels/forceModelMS/forceModelMS/forceModelMS.C index caabdf1d..ea0d1156 100644 --- a/src/lagrangian/cfdemParticle/subModels/forceModelMS/forceModelMS/forceModelMS.C +++ b/src/lagrangian/cfdemParticle/subModels/forceModelMS/forceModelMS/forceModelMS.C @@ -92,7 +92,7 @@ void forceModelMS::setForcesOnParticle() const << nrigidC <<", ind = " << ind <<", index=" << index <<"\n" << endl; nrigidC = 1000; } - if(treatExplicit_) for(int j=0;j<3;j++) expForces()[index][j] += cloudRefMS().expForcesCM()[ind][j] / nrigidC; + if(forceSubM(0).switches()[0]) for(int j=0;j<3;j++) expForces()[index][j] += cloudRefMS().expForcesCM()[ind][j] / nrigidC; else{ for(int j=0;j<3;j++){ impForces()[index][j] += cloudRefMS().impForcesCM()[ind][j] / nrigidC; diff --git a/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/CFD/constant/dynamicMeshDict b/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/CFD/constant/dynamicMeshDict old mode 100755 new mode 100644 diff --git a/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/CFD/constant/polyMesh/blockMeshDict b/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/CFD/constant/polyMesh/blockMeshDict old mode 100755 new mode 100644 diff --git a/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/CFD/system/controlDict b/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/CFD/system/controlDict old mode 100755 new mode 100644 diff --git a/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/DEM/in.liggghts_run b/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/DEM/in.liggghts_run new file mode 100644 index 00000000..9259bbee --- /dev/null +++ b/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/DEM/in.liggghts_run @@ -0,0 +1,95 @@ +#echo both +log ../DEM/log.liggghts +thermo_log ../DEM/post/thermo.txt + +atom_style granular +atom_modify map array +communicate single vel yes + +boundary f f f +newton off + +units si +processors 2 2 1 + +region reg block 0. 1. 0. 1. 0. 4. units box +create_box 1 reg + +neighbor 0.3 bin +neigh_modify delay 0 binsize 0.01 + + +# Material properties required for new pair styles + +fix m1 all property/global youngsModulus peratomtype 5.e7 +fix m2 all property/global poissonsRatio peratomtype 0.45 +fix m3 all property/global coefficientRestitution peratomtypepair 1 0.9 +fix m4 all property/global coefficientFriction peratomtypepair 1 0.5 + +# pair style +pair_style gran model hertz tangential history #Hertzian without cohesion +pair_coeff * * + +# timestep, gravity +timestep 0.00003 + +fix gravi all gravity 981 vector 0.0 0.0 -1.0 + +# walls +fix xwalls1 all wall/gran model hertz tangential history primitive type 1 xplane 0. +fix xwalls2 all wall/gran model hertz tangential history primitive type 1 xplane 1. +fix ywalls1 all wall/gran model hertz tangential history primitive type 1 yplane 0. +fix ywalls2 all wall/gran model hertz tangential history primitive type 1 yplane 1. +fix zwalls1 all wall/gran model hertz tangential history primitive type 1 zplane 0. +fix zwalls2 all wall/gran model hertz tangential history primitive type 1 zplane 4. + +# cfd coupling +fix cfd all couple/cfd couple_every 10 mpi +fix cfd2 all couple/cfd/force + + +# create single partciles +create_atoms 1 single .5 .5 3.5 units box +create_atoms 1 single .5 .5 3.16 units box +set atom 1 diameter 0.167 density 1.5 vx 0 vy 0 vz 0 +set atom 2 diameter 0.167 density 1.5 vx 0 vy 0 vz 0 + +variable vx1 equal vx[1] +variable vy1 equal vy[1] +variable vz1 equal vz[1] +variable vx2 equal vx[2] +variable vy2 equal vy[2] +variable vz2 equal vz[2] +variable x1 equal x[1] +variable y1 equal y[1] +variable z1 equal z[1] +variable x2 equal x[2] +variable y2 equal y[2] +variable z2 equal z[2] +variable time equal step*dt + +fix extra1 all print 100 "${time} ${vx1} ${vy1} ${vz1}" file ../DEM/post/velocity_particle_1.txt title "%" screen no +fix extra2 all print 100 "${time} ${vx2} ${vy2} ${vz2}" file ../DEM/post/velocity_particle_2.txt title "%" screen no +fix extra3 all print 100 "${time} ${x1} ${y1} ${z1}" file ../DEM/post/position_particle_1.txt title "%" screen no +fix extra4 all print 100 "${time} ${x2} ${y2} ${z2}" file ../DEM/post/position_particle_2.txt title "%" screen no + + +# apply nve integration to all particles that are inserted as single particles +fix integr all nve/sphere #wenn das ausgeblendet, dann kein vel update + +# screen output +compute rke all erotate/sphere +thermo_style custom step atoms ke c_rke vol +thermo 1000 +thermo_modify lost ignore norm no +compute_modify thermo_temp dynamic yes + +# insert the first particles so that dump is not empty +dump dmp all custom 100 ../DEM/post/dump.liggghts_run id type x y z ix iy iz vx vy vz fx fy fz omegax omegay omegaz radius + +#force : f_couple_cfd[0] f_couple_cfd[1] f_couple_cfd[2] +#node : f_couple_cfd[6] +#cell id : f_couple_cfd[7] + +run 1 + diff --git a/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/parCFDDEMrun.sh b/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/parCFDDEMrun.sh index 4e0e5095..47d3b2c9 100644 --- a/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/parCFDDEMrun.sh +++ b/tutorials/cfdemSolverIB/twoSpheresGlowinskiMPI/parCFDDEMrun.sh @@ -65,20 +65,13 @@ cp ../../$logfileName $testHarnessPath #- clean up case echo "deleting data at: $casePath" -rm -r $casePath/CFD/0.* -rm -r $casePath/CFD/callgrind.* -rm -r $casePath/CFD/*.out -rm -r $casePath/CFD/VTK -rm -r $casePath/CFD/couplingFiles/* -rm -r $casePath/CFD/processor* -rm -r $casePath/CFD/particles* -rm -r $casePath/CFD/probes -rm -r $casePath/DEM/post/* -rm -r $casePath/DEM/log.* -rm -r $casePath/log_* -echo "done" - +source $WM_PROJECT_DIR/bin/tools/CleanFunctions +cd $casePath/CFD +cleanCase +rm -r $casePath/CFD/clockData +rm $casePath/DEM/post/*.* +#rm -r $casePath/DEM/post/restart/*.* #- preserve post directory touch $casePath/DEM/post/.gitignore - +echo "done" diff --git a/tutorials/cfdemSolverPiso/ErgunTestCG/parCFDDEMrun.sh b/tutorials/cfdemSolverPiso/ErgunTestCG/parCFDDEMrun.sh index e5f4aa70..dee36df1 100644 --- a/tutorials/cfdemSolverPiso/ErgunTestCG/parCFDDEMrun.sh +++ b/tutorials/cfdemSolverPiso/ErgunTestCG/parCFDDEMrun.sh @@ -87,7 +87,7 @@ cd $casePath/CFD cleanCase rm -r $casePath/CFD/clockData rm -r $casePath/DEM/post/*.* -rm -r $casePath/DEM/post/restart/*.* +#rm -r $casePath/DEM/post/restart/*.* touch $casePath/DEM/post/.gitignore touch $casePath/DEM/post/restart/.gitignore echo "done" diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI/Allrun.sh b/tutorials/cfdemSolverPiso/ErgunTestMPI/Allrun.sh index ad29c48e..d1ebdd40 100755 --- a/tutorials/cfdemSolverPiso/ErgunTestMPI/Allrun.sh +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI/Allrun.sh @@ -22,7 +22,7 @@ if [ -f "$casePath/DEM/post/restart/liggghts.restart" ]; then echo "LIGGGHTS init was run before - using existing restart file" else #- run DEM in new terminal - $casePath/DEMrun.sh + $casePath/parDEMrun.sh fi #- run parallel CFD-DEM in new terminal diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI/CFD/constant/couplingProperties b/tutorials/cfdemSolverPiso/ErgunTestMPI/CFD/constant/couplingProperties index 5453b2fe..399fe8f7 100644 --- a/tutorials/cfdemSolverPiso/ErgunTestMPI/CFD/constant/couplingProperties +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI/CFD/constant/couplingProperties @@ -149,9 +149,12 @@ GidaspowDragProps } DiFeliceDragProps { + //verbose; velFieldName "U"; densityFieldName "rho"; voidfractionFieldName "voidfraction"; + granVelFieldName "Us"; + interpolation; } KochHillDragProps @@ -161,6 +164,12 @@ KochHillDragProps densityFieldName "rho"; voidfractionFieldName "voidfraction"; interpolation; + //forceSubModels + //( + // ImExCorr + //); + //implDEM true; + //explicitInterpCorr true; } BeetstraDragProps diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI/DEM/in.liggghts_run b/tutorials/cfdemSolverPiso/ErgunTestMPI/DEM/in.liggghts_run new file mode 100644 index 00000000..1e1b64ec --- /dev/null +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI/DEM/in.liggghts_run @@ -0,0 +1,66 @@ +# Pour granular particles into chute container, then induce flow +log ../DEM/log.liggghts +thermo_log ../DEM/post/thermo.txt + +atom_style granular +atom_modify map array +communicate single vel yes + +boundary m m m +newton off + +units si +processors 2 2 1 + +# read the restart file +read_restart ../DEM/post/restart/liggghts.restart + +neighbor 0.0005 bin +neigh_modify delay 0 + +# Material properties required for granular pair styles + +fix m1 all property/global youngsModulus peratomtype 5.e6 +fix m2 all property/global poissonsRatio peratomtype 0.45 +fix m3 all property/global coefficientRestitution peratomtypepair 1 0.3 +fix m4 all property/global coefficientFriction peratomtypepair 1 0.5 + +# pair style +pair_style gran model hertz tangential history # Hertzian without cohesion +pair_coeff * * + +# timestep, gravity +timestep 0.00001 +fix gravi all gravity 9.81 vector 0.0 0.0 -1.0 + +# walls +fix zwalls1 all wall/gran model hertz tangential history primitive type 1 zplane 0.0 +fix zwalls2 all wall/gran model hertz tangential history primitive type 1 zplane 0.0553 +fix cylwalls all wall/gran model hertz tangential history primitive type 1 zcylinder 0.01385 0. 0. + +# change the particles density +set group all density 2000 + +# cfd coupling +fix cfd all couple/cfd couple_every 100 mpi +fix cfd2 all couple/cfd/force/implicit + +# apply nve integration to all particles that are inserted as single particles +fix integr all nve/sphere + +# center of mass +compute centerOfMass all com + +# compute total dragforce +compute dragtotal all reduce sum f_dragforce[1] f_dragforce[2] f_dragforce[3] + +# screen output +compute rke all erotate/sphere +thermo_style custom step atoms ke c_rke vol c_centerOfMass[3] c_dragtotal[1] c_dragtotal[2] c_dragtotal[3] +thermo 10 +thermo_modify lost ignore norm no +compute_modify thermo_temp dynamic yes + +dump dmp all custom 5000 ../DEM/post/dump*.liggghts_run id type x y z vx vy vz fx fy fz f_dragforce[1] f_dragforce[2] f_dragforce[3] radius + +run 1 diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI/DEM/post/restart/.gitignore b/tutorials/cfdemSolverPiso/ErgunTestMPI/DEM/post/restart/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI/parCFDDEMrun.sh b/tutorials/cfdemSolverPiso/ErgunTestMPI/parCFDDEMrun.sh index b8a2c12d..a2a32a16 100644 --- a/tutorials/cfdemSolverPiso/ErgunTestMPI/parCFDDEMrun.sh +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI/parCFDDEMrun.sh @@ -87,7 +87,7 @@ cd $casePath/CFD cleanCase rm -r $casePath/CFD/clockData rm $casePath/DEM/post/*.* -rm -r $casePath/DEM/post/restart/*.* +#rm -r $casePath/DEM/post/restart/*.* touch $casePath/DEM/post/.gitignore touch $casePath/DEM/post/restart/.gitignore echo "done" diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI/parDEMrun.sh b/tutorials/cfdemSolverPiso/ErgunTestMPI/parDEMrun.sh new file mode 100755 index 00000000..d1e3a033 --- /dev/null +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI/parDEMrun.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +#===================================================================# +# DEMrun script for ErgunTestMPI testcase +# init ErgunTestMPI +# Christoph Goniva - July 2014 +#===================================================================# + +#- source CFDEM env vars +. ~/.bashrc + +#- include functions +source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh + +echo "starting DEM run in parallel..." +#--------------------------------------------------------------------------------# +#- define variables +casePath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" +logpath="$casePath" +headerText="run_liggghts_init_DEM" +logfileName="log_$headerText" +solverName="in.liggghts_init" +nrProcs=4 +machineFileName="none" +debugMode="off" +#--------------------------------------------------------------------------------# + +#- call function to run DEM case +parDEMrun $logpath $logfileName $casePath $headerText $solverName $nrProcs $machineFileName $debugMode + diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/Allrun.sh b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/Allrun.sh index 1d3a6bdc..95e8b6cc 100755 --- a/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/Allrun.sh +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/Allrun.sh @@ -22,7 +22,7 @@ if [ -f "$casePath/DEM/post/restart/liggghts.restart" ]; then echo "LIGGGHTS init was run before - using existing restart file" else #- run DEM - $casePath/DEMrun.sh + $casePath/parDEMrun.sh fi #- run parallel CFD-DEM in new terminal diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/CFD/system/funkySetFieldsDict b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/CFD/system/funkySetFieldsDict old mode 100755 new mode 100644 diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/DEM/in.liggghts_run b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/DEM/in.liggghts_run new file mode 100644 index 00000000..1eeccc1c --- /dev/null +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/DEM/in.liggghts_run @@ -0,0 +1,66 @@ +# Pour granular particles into chute container, then induce flow +log ../DEM/log.liggghts +thermo_log ../DEM/post/thermo.txt + +atom_style granular +atom_modify map array +communicate single vel yes + +boundary m m m +newton off + +units cgs +processors 2 2 1 + +# read the restart file +read_restart ../DEM/post/restart/liggghts.restart + +neighbor 0.1 bin +neigh_modify delay 0 + +# Material properties required for granular pair styles + +fix m1 all property/global youngsModulus peratomtype 5.e6 +fix m2 all property/global poissonsRatio peratomtype 0.45 +fix m3 all property/global coefficientRestitution peratomtypepair 1 0.3 +fix m4 all property/global coefficientFriction peratomtypepair 1 0.5 + +# pair style +pair_style gran model hertz tangential history # Hertzian without cohesion +pair_coeff * * + +# timestep, gravity +timestep 0.00001 +fix gravi all gravity 981 vector 0.0 0.0 -1.0 + +# walls +fix zwalls1 all wall/gran model hertz tangential history primitive type 1 zplane 0.0 +fix zwalls2 all wall/gran model hertz tangential history primitive type 1 zplane 5.53 +fix cylwalls all wall/gran model hertz tangential history primitive type 1 zcylinder 1.385 0. 0. + +# change the particles density +set group all density 2.0 + +# cfd coupling +fix cfd all couple/cfd couple_every 100 mpi +fix cfd2 all couple/cfd/force + +# apply nve integration to all particles that are inserted as single particles +fix integr all nve/sphere + +# center of mass +compute centerOfMass all com + +# compute total dragforce +compute dragtotal all reduce sum f_dragforce[1] f_dragforce[2] f_dragforce[3] + +# screen output +compute rke all erotate/sphere +thermo_style custom step atoms ke c_rke vol c_centerOfMass[3] c_dragtotal[1] c_dragtotal[2] c_dragtotal[3] +thermo 10 +thermo_modify lost ignore norm no +compute_modify thermo_temp dynamic yes + +dump dmp all custom 5000 ../DEM/post/dump*.liggghts_run id type x y z vx vy vz fx fy fz f_dragforce[1] f_dragforce[2] f_dragforce[3] radius + +run 1 diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/DEM/post/restart/.gitignore b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/DEM/post/restart/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/parCFDDEMrun.sh b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/parCFDDEMrun.sh index cf5f3b20..e6c4a062 100644 --- a/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/parCFDDEMrun.sh +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/parCFDDEMrun.sh @@ -82,21 +82,12 @@ fi #- clean up case echo "deleting data at: $casePath :\n" -rm -r $casePath/CFD/0.* -rm -r $casePath/CFD/callgrind.* -rm -r $casePath/CFD/*.out -rm -r $casePath/CFD/log.* -rm -r $casePath/CFD/octave/octave-core -rm -r $casePath/CFD/VTK -rm -r $casePath/CFD/processor* -rm -r $casePath/CFD/couplingFiles/* -rm -r $casePath/CFD/probes -rm -r $casePath/CFD/postProcessing -rm -r $casePath/CFD/lagrangian +source $WM_PROJECT_DIR/bin/tools/CleanFunctions +cd $casePath/CFD +cleanCase rm -r $casePath/CFD/clockData -rm -r $casePath/DEM/log.* -rm -r $casePath/DEM/post/*.* -rm -r $casePath/DEM/post/restart/*.* +rm $casePath/DEM/post/*.* +#rm -r $casePath/DEM/post/restart/*.* touch $casePath/DEM/post/.gitignore touch $casePath/DEM/post/restart/.gitignore echo "done" diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/parDEMrun.sh b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/parDEMrun.sh new file mode 100755 index 00000000..9b431c5b --- /dev/null +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_cgs/parDEMrun.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +#===================================================================# +# DEMrun script for ErgunTestMPI testcase +# init ErgunTestMPI +# Daniel Queteschiner - June 2014 +#===================================================================# + +#- source CFDEM env vars +. ~/.bashrc + +#- include functions +source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh + +#--------------------------------------------------------------------------------# +#- define variables +casePath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" +logpath="$casePath" +headerText="run_liggghts_init_DEM" +logfileName="log_$headerText" +solverName="in.liggghts_init" +nrProcs="4" +machineFileName="none" # yourMachinefileName | none +#--------------------------------------------------------------------------------# + +#- call function to run DEM case +parDEMrun $logpath $logfileName $casePath $headerText $solverName $nrProcs $machineFileName + diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/Allrun.sh b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/Allrun.sh index a05c80b7..f2dee44f 100755 --- a/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/Allrun.sh +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/Allrun.sh @@ -24,7 +24,7 @@ if [ -f "$casePath/DEM/post/restart/liggghts.restart" ]; then echo "LIGGGHTS init was run before - using existing restart file" else #- run DEM in new terminal - $casePath/DEMrun.sh + $casePath/parDEMrun.sh fi #-------------------------------------------------------# @@ -110,7 +110,7 @@ cd $casePath/CFD cleanCase rm -r $casePath/CFD/clockData rm -r $casePath/DEM/post/*.* -rm -r $casePath/DEM/post/restart/*.* +#rm -r $casePath/DEM/post/restart/*.* touch $casePath/DEM/post/.gitignore touch $casePath/DEM/post/restart/.gitignore echo "done" diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/constant/couplingProperties_run b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/constant/couplingProperties_run new file mode 100644 index 00000000..75dedb9f --- /dev/null +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/constant/couplingProperties_run @@ -0,0 +1,235 @@ +/*---------------------------------------------------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.4 | +| \\ / A nd | Web: http://www.openfoam.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ + + +FoamFile +{ + version 2.0; + format ascii; + + root ""; + case ""; + instance ""; + local ""; + + class dictionary; + object couplingProperties; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//===========================================================================// +// sub-models & settings + +modelType "A"; // A or B + +couplingInterval 100; + +voidFractionModel divided;//centre;// + +locateModel engine;//turboEngineM2M;// + +meshMotionModel noMeshMotion; + +regionModel allRegion; + +IOModel basicIO; + +probeModel off; + +dataExchangeModel twoWayMPI;//twoWayM2M;//twoWayFiles;//oneWayVTK;// + +averagingModel dense;//dilute;// + +clockModel standardClock;//off; + +smoothingModel off;// localPSizeDiffSmoothing;// constDiffSmoothing; // + +forceModels +( + //GidaspowDrag + //BeetstraDrag + //DiFeliceDrag + KochHillDrag + gradPForce + viscForce + //Archimedes + //volWeightedAverage + //totalMomentumExchange + //particleCellVolume +); + +momCoupleModels +( + implicitCouple +); + +turbulenceModelType "RASProperties";//"LESProperties";// + +//===========================================================================// +// sub-model properties + +localPSizeDiffSmoothingProps +{ + lowerLimit 0.1; + upperLimit 1e10; + dSmoothingLength 1.5e-3; + Csmoothing 1.0; +} + +constDiffSmoothingProps +{ + lowerLimit 0.1; + upperLimit 1e10; + smoothingLength 1.5e-3; +} + +implicitCoupleProps +{ + velFieldName "U"; + granVelFieldName "Us"; + voidfractionFieldName "voidfraction"; +} + +ArchimedesProps +{ + densityFieldName "rho"; + gravityFieldName "g"; +} +gradPForceProps +{ + pFieldName "p"; + densityFieldName "rho"; + voidfractionFieldName "voidfraction"; + velocityFieldName "U"; + //interpolation; +} + +viscForceProps +{ + velocityFieldName "U"; + densityFieldName "rho"; + interpolation; +} +volWeightedAverageProps +{ + scalarFieldNames + ( + voidfraction + ); + vectorFieldNames + ( + ); + upperThreshold 0.999; + lowerThreshold 0; + verbose; +} +totalMomentumExchangeProps +{ + implicitMomExFieldName "Ksl"; + explicitMomExFieldName "none"; + fluidVelFieldName "U"; + granVelFieldName "Us"; + densityFieldName "rho"; +} +GidaspowDragProps +{ + verbose; + velFieldName "U"; + densityFieldName "rho"; + voidfractionFieldName "voidfraction"; + phi 1; +} +DiFeliceDragProps +{ + velFieldName "U"; + densityFieldName "rho"; + voidfractionFieldName "voidfraction"; +} + +KochHillDragProps +{ + //verbose; + velFieldName "U"; + densityFieldName "rho"; + voidfractionFieldName "voidfraction"; +} + +BeetstraDragProps +{ + velFieldName "U"; + densityFieldName "rho"; + gravityFieldName "g"; + rhoParticle 2000.; + voidfractionFieldName "voidfraction"; + interpolation ; + useFilteredDragModel ; + useParcelSizeDependentFilteredDrag ; + k 0.05; + aLimit 0.0; +// verbose ; +} + +virtualMassForceProps +{ + velFieldName "U"; + densityFieldName "rho"; +} + +particleCellVolumeProps +{ + upperThreshold 0.999; + lowerThreshold 0.; + verbose; +} + +oneWayVTKProps +{ + couplingFilename "vtk_out%4.4d.vtk"; + maxNumberOfParticles 30000; +} + +twoWayFilesProps +{ + maxNumberOfParticles 10100; +} + +centreProps +{ + alphaMin 0.10; +} + +engineProps +{ + treeSearch true; +} + +turboEngineM2MProps +{ + turboEngineProps + { + treeSearch true; + } +} + +dividedProps +{ + alphaMin 0.01; + scaleUpVol 1.0; +} + +twoWayMPIProps +{ + liggghtsPath "../DEM/in.liggghts_run"; +} +twoWayM2MProps +{ + maxNumberOfParticles 10100; + liggghtsPath "../DEM/in.liggghts_run"; +} +// ************************************************************************* // diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/constant/liggghtsCommands_run b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/constant/liggghtsCommands_run new file mode 100644 index 00000000..4a02d58c --- /dev/null +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/constant/liggghtsCommands_run @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.4 | +| \\ / A nd | Web: http://www.openfoam.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ + + +FoamFile +{ + version 2.0; + format ascii; + + root ""; + case ""; + instance ""; + local ""; + + class dictionary; + object liggghtsCommands; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +liggghtsCommandModels +( + runLiggghts + writeLiggghts +); + +runLiggghtsProps +{ + preNo false; +} + +//- optional +writeLiggghtsProps +{ + writeLast on; + writeName "post/restart/liggghts.restartCFDEM"; +} + +// ************************************************************************* // diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/system/controlDict_run b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/system/controlDict_run new file mode 100644 index 00000000..1d2f9b52 --- /dev/null +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/CFD/system/controlDict_run @@ -0,0 +1,117 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application pisoFoam; + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 0.05; + +deltaT 0.001; + +writeControl adjustableRunTime; + +writeInterval 0.01; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 6; + +writeCompression uncompressed; + +timeFormat general; + +timePrecision 6; + +runTimeModifiable yes; + +adjustTimeStep no; + +maxCo 0.1; + +//libs ( "libgroovyBC.so" "libfiniteVolumeCFDEM.so"); + +functions +( + + probes + { + type probes; + // Where to load it from + functionObjectLibs ( "libsampling.so" ); + // Name of the directory for probe data + name probes; + probeLocations + ( + (0 0 0.0001) + (0 0 0.0026) + (0 0 0.0051) + (0 0 0.0076) + (0 0 0.0101) + (0 0 0.0126) + (0 0 0.0151) + (0 0 0.0176) + (0 0 0.0201) + (0 0 0.0226) + (0 0 0.0251) + (0 0 0.0276) + (0 0 0.0301) + (0 0 0.0326) + (0 0 0.0351) + (0 0 0.0375) + (0 0 0.0401) + (0 0 0.0426) + (0 0 0.0451) + (0 0 0.0476) + (0 0 0.0529) + ); + + // Fields to be probed + fields ( p U voidfraction volAverage_voidfraction voidfractionNext voidfractionPrev); + + // Write at same frequency as fields + outputControl timeStep;//outputTime; + outputInterval 1; + } + + /*pressureDrop + { + type patchAverage; + functionObjectLibs + ( + "libsimpleFunctionObjects.so" + ); + verbose true; + patches + ( + inlet + outlet + ); + fields + ( + p + ); + factor 1; + }*/ +); +// ************************************************************************* // diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/DEM/in.liggghts_run b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/DEM/in.liggghts_run new file mode 100644 index 00000000..1a1d48ce --- /dev/null +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/DEM/in.liggghts_run @@ -0,0 +1,65 @@ +# Pour granular particles into chute container, then induce flow +log ../DEM/log.liggghts +thermo_log ../DEM/post/thermo.txt + +atom_style granular +atom_modify map array +communicate single vel yes + +boundary m m m +newton off + +units si +processors 2 2 1 + +# read the restart file +read_restart ../DEM/post/restart/liggghts.restart + +neighbor 0.0005 bin +neigh_modify delay 0 + +# Material properties required for granular pair styles + +fix m1 all property/global youngsModulus peratomtype 5.e6 +fix m2 all property/global poissonsRatio peratomtype 0.45 +fix m3 all property/global coefficientRestitution peratomtypepair 1 0.3 +fix m4 all property/global coefficientFriction peratomtypepair 1 0.5 + +# pair style +pair_style gran model hertz tangential history # Hertzian without cohesion +pair_coeff * * + +# timestep, gravity +timestep 0.00001 +fix gravi all gravity 9.81 vector 0.0 0.0 -1.0 + +fix zwalls1 all wall/gran model hertz tangential history primitive type 1 zplane 0.0 +fix zwalls2 all wall/gran model hertz tangential history primitive type 1 zplane 0.0553 +fix cylwalls all wall/gran model hertz tangential history primitive type 1 zcylinder 0.01385 0. 0. + +# change the particles density +set group all density 2000 + +# cfd coupling +fix cfd all couple/cfd couple_every 100 mpi +fix cfd2 all couple/cfd/force + +# apply nve integration to all particles that are inserted as single particles +fix integr all nve/sphere + +# center of mass +compute centerOfMass all com + +# compute total dragforce +compute dragtotal all reduce sum f_dragforce[1] f_dragforce[2] f_dragforce[3] + +# screen output +compute rke all erotate/sphere +thermo_style custom step atoms ke c_rke vol c_centerOfMass[3] c_dragtotal[1] c_dragtotal[2] c_dragtotal[3] +thermo 10 +thermo_modify lost ignore norm no +compute_modify thermo_temp dynamic yes + +dump dmp all custom 5000 ../DEM/post/dump*.liggghts_restart id type x y z vx vy vz fx fy fz f_dragforce[1] f_dragforce[2] f_dragforce[3] radius + +run 1 diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/DEM/post/restart/.gitignore b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/DEM/post/restart/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/parDEMrun.sh b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/parDEMrun.sh new file mode 100755 index 00000000..138c7400 --- /dev/null +++ b/tutorials/cfdemSolverPiso/ErgunTestMPI_restart/parDEMrun.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +#===================================================================# +# DEMrun script for ErgunTestMPI_restart testcase +# init ErgunTestMPI_restart +# Daniel Queteschiner - June 2014, DCS Computing GmbH +#===================================================================# + +#- source CFDEM env vars +. ~/.bashrc + +#- include functions +source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh + +#--------------------------------------------------------------------------------# +#- define variables +casePath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" +logpath="$casePath" +headerText="run_liggghts_init_DEM" +logfileName="log_$headerText" +solverName="in.liggghts_init" +nrProcs="2" +machineFileName="none" # yourMachinefileName | none +#--------------------------------------------------------------------------------# + +#- call function to run DEM case +parDEMrun $logpath $logfileName $casePath $headerText $solverName $nrProcs $machineFileName + diff --git a/tutorials/cfdemSolverPiso/settlingTestMPI/DEM/in.liggghts_run b/tutorials/cfdemSolverPiso/settlingTestMPI/DEM/in.liggghts_run new file mode 100644 index 00000000..e0d3326b --- /dev/null +++ b/tutorials/cfdemSolverPiso/settlingTestMPI/DEM/in.liggghts_run @@ -0,0 +1,73 @@ +# Pour granular particles into chute container, then induce flow +echo both +log ../DEM/log.liggghts +thermo_log ../DEM/post/thermo.txt + +atom_style granular +atom_modify map array sort 0 0 +communicate single vel yes + +boundary f f f +newton off + +units si + +region reg block 0 0.1 0 0.1 0 0.1 units box +create_box 1 reg + +neighbor 0.003 bin +neigh_modify delay 0 binsize 0.01 + + +# Material properties required for granular pair styles +fix m1 all property/global youngsModulus peratomtype 5.e6 +fix m2 all property/global poissonsRatio peratomtype 0.45 +fix m3 all property/global coefficientRestitution peratomtypepair 1 0.3 +fix m4 all property/global coefficientFriction peratomtypepair 1 0.5 +#fix m5 all property/global characteristicVelocity scalar 2.0 + +# pair style +pair_style gran model hertz tangential history # hertz without cohesion +pair_coeff * * + +# timestep, gravity +timestep 0.00001 +fix gravi all gravity 9.81 vector 0.0 -1.0 0.0 + +# walls +fix xwalls1 all wall/gran model hertz tangential history primitive type 1 xplane 0.0 +fix xwalls2 all wall/gran model hertz tangential history primitive type 1 xplane 0.1 +fix ywalls1 all wall/gran model hertz tangential history primitive type 1 yplane 0.0 +fix ywalls2 all wall/gran model hertz tangential history primitive type 1 yplane 0.1 +fix zwalls1 all wall/gran model hertz tangential history primitive type 1 zplane 0.0 +fix zwalls2 all wall/gran model hertz tangential history primitive type 1 zplane 0.01 + +# create single partciles +create_atoms 1 single 0.05 0.025 0.05 units box +set group all diameter 0.0001 density 3000 + +# cfd coupling +fix cfd all couple/cfd couple_every 100 mpi +fix cfd2 all couple/cfd/force + +variable vx equal vx[1] +variable vy equal vy[1] +variable vz equal vz[1] +variable time equal step*dt +fix extra all print 100 "${time} ${vx} ${vy} ${vz}" file ../DEM/post/velocity.txt title "#" screen no + +# apply nve integration to all particles that are inserted as single particles +fix integr all nve/sphere + +# screen output +compute rke all erotate/sphere +thermo_style custom step atoms ke c_rke vol +thermo 1000 +thermo_modify lost ignore norm no +compute_modify thermo_temp dynamic yes + +# insert the first particles so that dump is not empty +run 1 +dump dmp all custom 1000 ../DEM/post/dump.liggghts_run id type x y z ix iy iz vx vy vz fx fy fz omegax omegay omegaz radius + +run 1 upto diff --git a/tutorials/cfdemSolverPisoScalar/packedBedTemp/DEM/in.liggghts_run b/tutorials/cfdemSolverPisoScalar/packedBedTemp/DEM/in.liggghts_run new file mode 100644 index 00000000..7350ff11 --- /dev/null +++ b/tutorials/cfdemSolverPisoScalar/packedBedTemp/DEM/in.liggghts_run @@ -0,0 +1,75 @@ +# read packed bed and calc convective heat transfer +log ../DEM/log.liggghts +thermo_log ../DEM/post/thermo.txt + +atom_style granular +atom_modify map array +communicate single vel yes +boundary m m m +newton off +echo both +units si +processors 1 1 2 + +# read the restart file +read_restart ../DEM/post/restart/liggghts.restart + +neighbor 0.003 bin +neigh_modify delay 0 binsize 0.01 + + +# Material properties required for granular pair styles + +fix m1 all property/global youngsModulus peratomtype 5.e6 +fix m2 all property/global poissonsRatio peratomtype 0.45 +fix m3 all property/global coefficientRestitution peratomtypepair 1 0.3 +fix m4 all property/global coefficientFriction peratomtypepair 1 0.5 + +# pair style +pair_style gran model hertz tangential history # Hertzian without cohesion +pair_coeff * * + +# timestep, gravity +timestep 0.00001 +fix gravi all gravity 9.81 vector 0. 0. -1. + +# walls +fix xwalls1 all wall/gran model hertz tangential history primitive type 1 xplane 0.0 +fix xwalls2 all wall/gran model hertz tangential history primitive type 1 xplane 0.1 +fix ywalls1 all wall/gran model hertz tangential history primitive type 1 yplane 0.0 +fix ywalls2 all wall/gran model hertz tangential history primitive type 1 yplane 0.1 +fix zwalls1 all wall/gran model hertz tangential history primitive type 1 zplane 0.0 +fix zwalls2 all wall/gran model hertz tangential history primitive type 1 zplane 1.1 + + +# heat transfer +fix ftco all property/global thermalConductivity peratomtype 5. # lambda in [W/(K*m)] +fix ftca all property/global thermalCapacity peratomtype 0.1 # cp in [J/(kg*K)] +fix heattransfer all heat/gran initial_temperature 600. + +# set particle temperature for the bed +run 0 +region total block INF INF INF INF INF INF units box +set region total property/atom Temp 600. + +# cfd coupling +fix cfd all couple/cfd couple_every 100 mpi +fix cfd2 all couple/cfd/force + +# this one invokes heat transfer calculation, transfers per-particle temperature and adds convective heat flux to particles +fix cfd3 all couple/cfd/convection T0 600 + +# apply nve integration to all particles that are inserted as single particles +fix integr all nve/sphere + + +# screen output +compute rke all erotate/sphere +thermo_style custom step atoms ke c_rke vol +thermo 1000 +thermo_modify lost ignore norm no +compute_modify thermo_temp dynamic yes + +dump dmp all custom 100 ../DEM/post/dump.liggghts_run id type x y z ix iy iz vx vy vz fx fy fz omegax omegay omegaz radius f_Temp[0] f_heatFlux[0] + +run 1 diff --git a/tutorials/cfdemSolverPisoScalar/packedBedTemp/DEM/post/restart/.gitignore b/tutorials/cfdemSolverPisoScalar/packedBedTemp/DEM/post/restart/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/tutorials/cfdemSolverPisoScalar/packedBedTemp/parCFDDEMrun.sh b/tutorials/cfdemSolverPisoScalar/packedBedTemp/parCFDDEMrun.sh index 7c402d46..c0073d9a 100644 --- a/tutorials/cfdemSolverPisoScalar/packedBedTemp/parCFDDEMrun.sh +++ b/tutorials/cfdemSolverPisoScalar/packedBedTemp/parCFDDEMrun.sh @@ -84,21 +84,12 @@ fi #- clean up case echo "deleting data at: $casePath : ???\n" -rm -r $casePath/CFD/0.* -rm -r $casePath/CFD/1 -rm -r $casePath/CFD/callgrind.* -rm -r $casePath/CFD/*.out -rm -r $casePath/CFD/octave/*.eps -rm -r $casePath/CFD/octave/octave-core -rm -r $casePath/CFD/VTK -rm -r $casePath/CFD/processor* -rm -r $casePath/DEM/post/*.* -rm -r $casePath/DEM/post/restart/*.* -rm -r $casePath/DEM/log.* -rm -r $casePath/CFD/log.* -rm -r $casePath/CFD/probes -rm -r $casePath/CFD/postProcessing -rm -r $casePath/log_* +source $WM_PROJECT_DIR/bin/tools/CleanFunctions +cd $casePath/CFD +cleanCase +rm -r $casePath/CFD/clockData +rm $casePath/DEM/post/*.* +#rm -r $casePath/DEM/post/restart/*.* echo "done" #- preserve post directory diff --git a/tutorials/cfdemSolverPisoScalar/packedBedTemp/parDEMrun.sh b/tutorials/cfdemSolverPisoScalar/packedBedTemp/parDEMrun.sh new file mode 100755 index 00000000..660b45a1 --- /dev/null +++ b/tutorials/cfdemSolverPisoScalar/packedBedTemp/parDEMrun.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +#===================================================================# +# DEMrun script for ErgunTestMPI testcase +# init ErgunTestMPI +# Daniel Queteschiner - June 2014 +#===================================================================# + +#- source CFDEM env vars +. ~/.bashrc + +#- include functions +source $CFDEM_SRC_DIR/lagrangian/cfdemParticle/etc/functions.sh + +#--------------------------------------------------------------------------------# +#- define variables +casePath="$(dirname "$(readlink -f ${BASH_SOURCE[0]})")" +logpath="$casePath" +headerText="run_liggghts_init_DEM" +logfileName="log_$headerText" +solverName="in.liggghts_init" +nrProcs="2" +machineFileName="none" # yourMachinefileName | none +#--------------------------------------------------------------------------------# + +#- call function to run DEM case +parDEMrun $logpath $logfileName $casePath $headerText $solverName $nrProcs $machineFileName +