168 Commits
21.11 ... 23.02

Author SHA1 Message Date
86753f2823 Merge pull request #146 from ParticulateFlow/release
Release 23.02
2023-02-15 12:26:45 +01:00
13e5989216 shorter simulation times on test harness for redBloodCell cases
with the original simulation time the case gets to long/large for
reasonable testing ...
2023-02-15 10:19:24 +01:00
01117a7a87 fix comments in input script
test harness does not like the degree sign
2023-02-15 10:19:24 +01:00
6c3290f75c fix output of kinetic energy in settling test
in case of a single particle, we need to specify the option 'extra 0';
since we just create one particle at the start of the simulation, we can
also set 'dynamic' to 'no';
2023-02-14 14:05:39 +01:00
9bc6333c1e reduce info output
remove some info output of mediocre use
2023-02-14 11:11:05 +01:00
66015ee916 bump version number to 23.02 [ci skip] 2023-02-13 09:56:55 +01:00
a3dcb037b4 Merge pull request #145 from ParticulateFlow/feature/fluidized_bed_chemistry_cases
Add fluidized bed chemistry cases
2023-02-13 09:48:11 +01:00
61e746470f add .gitignore file in FeO->Fe reduction case
preserve DEM/post/restart folder
2023-02-10 11:20:39 +01:00
4e65f19d5f add FeO->Fe reduction case
based on R1 case described by Spreitzer 2016 / Kinaci 2020
2023-02-10 11:12:17 +01:00
78852efc7a add Fe2O3->Fe3O4 reduction case
based on R3 case described by Spreitzer 2016 / Kinaci 2020, but with the
reaction point shifted from 0.434 to 0.516 to avoid any Fe formation via
CO reaction
2023-02-09 15:50:44 +01:00
561092cc46 adjust plotting of chemistry data [ci skip]
adjust step size for data selection; add plot of experimental data
2023-02-09 15:05:55 +01:00
65dde56334 change computation from sum to average of molar fractions
average makes more sense than sum here
2023-02-09 14:53:52 +01:00
d227090570 adjust particle properties in R2_FB case 2023-02-09 14:51:57 +01:00
69234a1451 Merge branch 'develop' into feature/fluidized_bed_chemistry_cases
tutorials/cfdemSolverRhoPimpleChem/PolydisperseFluidizedBed/R2_FB/DEM/in.liggghts_run
2023-02-03 12:37:51 +01:00
7ef990e025 turn fix property/atom into fix property/global for k0 and Ea [ci skip]
as of
6e96c2ccab
these properties should be defined via fix property/global
2023-01-13 13:36:44 +01:00
3d0ac6d079 skip postFlow() method if we ignore particle interaction
resolve #129
2023-01-10 17:22:53 +01:00
3becf58e3c remove cfdemCloudEnergy::solve() method
none of the current energy or mass transfer models implements the
solve() method, so remove it
2023-01-10 17:14:37 +01:00
5d272decba add run.config file for redBloodCellShearFlow case for testharness [ci skip] 2023-01-10 14:49:43 +01:00
ed20344d03 add run.config file for redBloodCellPoiseuilleFlow case for testharness [ci skip] 2023-01-10 14:26:24 +01:00
e0917bdc38 fix typo [ci skip] 2023-01-10 14:24:51 +01:00
d350ae01d6 add run.config file for falling_sphere_two_way_coupling case for test harness 2023-01-10 12:24:19 +01:00
4283ff09e7 change data plotting of falling_sphere_two_way_coupling case
simply plot particle's omega-z and pos-y of actual case instead of
comparing omega-z of actual case to a case without torque coupling
(requiring a 2nd simulation with modified setup)
2023-01-10 12:23:29 +01:00
29410326d1 avoid library interface change
let LIGGGHTS allocate the memory, delete it in CFDEMcoupling if no
longer needed;
2023-01-09 17:17:38 +01:00
2d061dc1c1 Merge pull request #142 from tmjnijssen/feature/fixOne2One
fix deadlock and memory leaks in one2one
2023-01-09 17:11:38 +01:00
7b8e4eab3a make constDiffAndTemporalSmoothing work without refField again
revert constDiffAndTemporalSmoothing to previous behavior if no refField
is specified; this is required e.g. in ParmarBassetForce where Urel_ and
ddtUrel_ get smoothed using the same smoothing model;
2023-01-09 13:46:50 +01:00
ff42a04be1 Merge branch 'develop' of github.com:ParticulateFlow/CFDEMcoupling into develop 2023-01-03 09:31:37 +01:00
68318ab863 Fixed settings in tutorial cfdemSolverRhoPimple/FinesColumn. 2023-01-03 09:31:25 +01:00
c05732bb45 add -Wno-deprecated-copy to options files
to silence warnings stemming from OpenFOAM in g++ 9
2022-12-22 17:53:49 +01:00
b343711954 Merge pull request #136 from tmjnijssen/feature/updateParmarBassetForce
Feature/update parmar basset force
2022-12-22 17:10:00 +01:00
cbabd0aa50 Merge branch 'develop' of github.com:ParticulateFlow/CFDEMcoupling into develop 2022-12-06 08:16:09 +01:00
6af30fe0e5 Allow displacement field computation for polydisperse systems. 2022-12-06 08:15:50 +01:00
9a4bf92207 fix memleak 2022-12-05 13:38:37 +01:00
60983f8e96 fix memory leak 2022-12-02 14:52:16 +01:00
6ce64cf663 update debug output 2022-11-30 11:49:59 +01:00
a00d3fdec1 use nonblocking sends 2022-11-30 11:49:59 +01:00
e7db2ab2f0 use unique tags 2022-11-30 11:49:58 +01:00
c1bff32b4f Merge pull request #141 from tmjnijssen/multiphaseMixture_bugfix
rename cfdemSolverMultiphaseScalar/multiphaseMixture to cfdemSolverMu…
2022-11-21 12:54:27 +01:00
153d1e353b rename cfdemSolverMultiphaseScalar/multiphaseMixture to cfdemSolverMultiphaseScalar/multiphaseMixtureScalar 2022-11-17 14:38:54 +01:00
25115b0e33 Merge pull request #137 from tmjnijssen/feature/lubrication
Feature/lubrication
2022-11-09 11:41:06 +01:00
41b516c1e8 Check out fields manually checked into registry. 2022-11-08 17:41:17 +01:00
8505c69b94 Merge pull request #135 from tmjnijssen/patch-3
[doc] constDiffSmoothing doc update
2022-11-02 16:37:51 +01:00
3b7724003a Update smoothingModel_constDiffSmoothing.txt 2022-11-02 16:32:00 +01:00
15f111fb11 Merge pull request #138 from tmjnijssen/fix/probe
probe bugfixes
2022-11-02 10:57:09 +01:00
8ba87ddedb probe bugfixes 2022-10-26 16:34:05 +02:00
57c8c1c762 add doc 2022-10-24 14:46:01 +02:00
d6dab59bfd add interpolation 2022-10-24 14:46:01 +02:00
4ddf691936 add transfer of fluid properties to LIGGGHTS 2022-10-24 14:46:01 +02:00
20e75cf64f eliminate pow() for performance 2022-10-24 14:34:05 +02:00
2aa5c7880b rework input 2022-10-24 14:34:05 +02:00
0fdb464d73 remove unneeded component of rHist to save memory 2022-10-24 14:34:05 +02:00
ab73bf86ac reorder ddtUrelHist and rHist to save memory 2022-10-24 14:34:05 +02:00
dc2be65fe3 reorder FHist to save memory 2022-10-24 14:34:05 +02:00
a10c773e31 [DOC] added verbose mode for ParmarBassetForce 2022-10-24 14:34:05 +02:00
19e780f93b added verbose mode for ParmarBassetForce 2022-10-24 14:34:05 +02:00
7ce49bf21c minor cleanup 2022-10-24 14:34:05 +02:00
c3f609b0e9 allocate uRelOld only when needed, save memory 2022-10-24 14:34:05 +02:00
f2306d2037 use particleProperty + cleanup 2022-10-24 14:34:05 +02:00
d35249aa3c clean up ParmarBassetForce 2022-10-24 14:34:05 +02:00
e95e1ec6ad clean up ParmarBassetForce 2022-10-24 14:34:05 +02:00
fb798eb92f Update rCFD fluidized bed case to improve stability. 2022-08-02 11:30:51 +02:00
056b121f21 Minor modifications for rcfdemSolverCoupledHeattransfer to improve stability. 2022-08-02 09:52:51 +02:00
3107a9ce10 Update smoothingModel_constDiffSmoothing.txt 2022-07-29 13:57:58 +02:00
389b44d0e5 [doc] constDiffSmoothing doc update 2022-07-29 13:46:33 +02:00
507f24145e dSauter is constructed by submodel dSauter. If another one is constructed by the solver, force models looking up dSauter may get confused. 2022-07-06 12:14:32 +02:00
9e54b3f94f Merge pull request #134 from ParticulateFlow/fix/gradPForceSmooth
Make sure gradPForceSmooth  can be used with any smoothing model.
2022-06-30 15:29:29 +02:00
d7fb907a8a Instead of throwing an error if gradPForceSmooth uses any smoothing model other than a temporal one, make it optional. If spatial smoothing is used, updated pSmooth in every time step. 2022-06-30 15:26:40 +02:00
3bd3fb1e00 Make sure gradPForceSmooth only uses certain smoothing models. Also fixed some inconsistencies in constDiffAndTemporalSmoothing. 2022-06-30 10:04:32 +02:00
08bb2b41ff add experimental data for comparison
data extracted from reduction test MWS16 performed by Spreitzer
2016-03-15
2022-04-22 15:38:57 +02:00
5a1c957ba5 move blockMeshDict to system folder
and remove m4 file
2022-04-22 15:32:41 +02:00
c7532c919c fix up path to data files [ci skip] 2022-03-28 10:37:45 +02:00
9ef314c961 revert dump custom/vtk to dump custom
in case user has not compiled  LIGGGHTS with VTK library
2022-03-25 15:20:32 +01:00
2b69485204 move post-processing scripts to usual CFD/octave folder
move scripts and invoke plotData after CFD-DEM run
2022-03-25 15:19:31 +01:00
f0454797af add post-processing scripts for DEM data in R2_FB 2022-03-25 15:02:17 +01:00
06b0585ab1 clean up DEM scripts in R2_FB
clean up, slightly rearrange commands
2022-03-25 14:55:54 +01:00
6834013deb move additional DEM data processing to separate file in R2_FB
move data averaging and output to separate file for better readability;
perform averaging for each size group and use mass-based (vs. number-
based) averages for global properties such as overall reduction,
resistance terms etc.
2022-03-25 14:48:13 +01:00
d3a01f0872 fix initial layer radii in R2_FB
R2 means reduction from magnetite to wüstite and like in Kinaci et al.
(2020) we should assume that reduction from hematite to magnetite is
already completed to avoid mixing the reaction processes;
hence, start the simulation with a negligible hematite layer
2022-03-25 14:17:23 +01:00
7d70846fa3 remove artificial temperature limiter in R2_FB
enforcing a temperature range should not be necessary in a stable
simulation
2022-03-25 13:18:24 +01:00
ccbbdba41f clean up R2_FB system dicts 2022-03-25 13:15:43 +01:00
5e8a7e9475 clean up R2_FB 0 dicts 2022-03-25 13:10:13 +01:00
7fb38309e1 remove R2_FB unneeded 0 dicts 2022-03-25 13:00:50 +01:00
ea81e6d806 clean up R2_FB constant dicts
remove unneeded entries, update header to indicate actually used OF
version
2022-03-25 12:59:23 +01:00
5245083201 remove remaining traces of 'dummy' files [ci skip]
using .gitignore instead
2022-03-25 09:32:29 +01:00
32e41e2fa6 Merge pull request #130 from ParticulateFlow/feature/immersed_multisphere
close #127
2022-03-25 09:14:06 +01:00
8cb7184a7c only look up fieldname and field if required
only look up solidVolFractionName_ and lambda_ field if calculation of
multisphere drag (in calcForce() method) is requested via the option
'multisphere' - otherwise just set both to null
this way, specifying solidVolFractionName is optional and old case
setups will still work without modifications
2022-03-24 16:56:20 +01:00
937dcc2023 use Pout instead of printf
I suppose the original author's intention was to print out the forces
from all procs, but Info just prints on master proc. Pout is the proper
alternative here.
2022-03-24 16:49:43 +01:00
3e1126a55d make ShirgaonkarIB::calcForce method private
currently not used by other classes
2022-03-24 16:41:24 +01:00
f8ea7e5bc2 clean up couplingProperties file
particle limit option is only used in file-based communication
2022-03-24 15:51:41 +01:00
e1245147fe clean up tutorial run/clean scripts 2022-03-24 15:43:56 +01:00
1f5c8f6492 add a tutorial for cfdemSolverIBContinuousForcing
simulating the deformation of a red blood cell (bonded particles) in
shear flow
2022-03-24 15:39:10 +01:00
38b8d6c8b8 fix up path of python post-processing 2022-03-24 14:35:09 +01:00
cc19fd3a46 clean up Allclean.sh of redBloodCellPoiseuilleFlow case 2022-03-24 11:06:35 +01:00
188bc3e230 adjust plot range to shortened simulation time 2022-03-24 10:48:37 +01:00
ed997ec9a8 add a tutorial for cfdemSolverIBContinuousForcing
simulating a red blood cell (bonded particles) in a Poiseuille flow
2022-03-23 17:59:36 +01:00
28d9dfacac clear Us field to zero each time step
clear particle velocity values from previous time step
2022-03-23 17:26:02 +01:00
7698e20c8f Merge pull request #132 from ParticulateFlow/bugfix/iomodel_deadlock
Fix potential deadlock in IOModel
2022-03-23 13:47:04 +01:00
521b95520d update documentation of IO model
document cartesianOutput option
2022-03-22 17:27:29 +01:00
43cc5a9ecd add option to enforce cartesian coordinates in lagrangian position output
add the option 'cartesianOutput' for the couplingProperties dict to
output particle positions as cartesian coordinates + cell index instead
of barycentric coordinates + cell index + tet face index + tet point
index in  OF > 4
this format does not require parafoam but works fine with paraview, plus
it avoids the temporary creation of OF particles for writing the output
2022-03-22 17:20:30 +01:00
6fdda583c2 fix deadlock in IOModel
force construction of face-diagonal decomposition (called from all procs!) before call of particle constructor (potentially not on all procs!) to avoid blocking sync operation, when it looks for tet face index and tet point index.
fix #131
2022-03-18 13:25:04 +01:00
d47e4d01a7 Changed way to read in large data file. 2022-03-08 16:28:14 +01:00
aa42bb9a28 increase stability of cfdemSolverRhoPimpleChem
analogous to 16560cfe4f
VSMALL is typically DBL_MIN (1e-37 or smaller) which is actually too
small here
2022-03-01 10:13:52 +01:00
c96e0cc6fd Fixed issue in tutorial LIGGGHTS script: Deactivate building of neighbor lists. 2022-02-22 13:54:19 +01:00
461be2f193 Merge branch 'develop' of https://github.com/ParticulateFlow/CFDEMcoupling into develop 2022-02-21 11:06:17 +01:00
a908ffc979 Added maximum number of search layers to initialize multi-layer shrinking core model. 2022-02-21 11:05:56 +01:00
ede9546e80 merge cfdemCloudIB and cfdemCloudIBContinuousForcing
note that Us field is only use by cfdemSolverIBContinuousForcing but not
by cfdemSolverIB, so it may be better to call
cfdemCloudIB::calcForcingTerm(...) from cfdemSolverIBContinuousForcing
instead of cfdemCloudIB::evolve()
2022-02-16 15:56:15 +01:00
5ebb7e18cb correct BC of Us filed after setting
add a call to correctBoundaryConditions() once we have finished setting
the velocities from the particle data
2022-02-16 14:59:34 +01:00
0820d99e85 move calculation of Us field to separate function in cfdemCloudIB
refactoring, use same name as the function doing Us field calculations
in cfdemCloudIBContinuousForcing;
note that cfdemCloudIB is considering angular velocities of particles
while cfdemCloudIBContinuousForcing does not
2022-02-16 14:58:23 +01:00
d1dad545ae update headers of tutorial case
indicate that this case is intended to be used with OF 6
2022-02-14 15:21:28 +01:00
8437714660 update documentation 2022-02-14 15:05:35 +01:00
4bb95e66a8 merge ShirgaonkarIB and ShirgaonkarIBTorque models
reduce code duplication
2022-02-14 14:15:04 +01:00
3463f5ccc0 update handling of model options in ShirgaonkarIB*
make options const bool if possible and bring in line with rest of code,
i.e. read values from dict already in initializer list
2022-02-14 13:43:05 +01:00
a38dba8cfd add compiler flag
add -Wno-deprecated-copy flag to deactivate respective compiler warning
2022-02-09 17:14:45 +01:00
21b338fb05 Merge branch 'develop' into feature/immersed_multisphere
resolved Conflicts:
- applications/solvers/cfdemSolverIB/Make/options
- etc/solver-list.txt
- src/lagrangian/cfdemParticle/Make/files
- src/lagrangian/cfdemParticle/derived/cfdemCloudIB/cfdemCloudIB.C
resolved Issues:
src/lagrangian/cfdemParticle/subModels/ShirgaonkarIBTorque/ShirgaonkarIBTorque.C
2022-02-09 16:37:40 +01:00
e3ec594f73 rename cfdemSolverIBRO.C to cfdemSolverIBContinuousForcing.C
more appropriate naming:
RO (reduced order) referred to the RO model of red blood cells, but the
key difference in this solver is the momentum forcing term in the UEqn
2022-02-09 16:05:21 +01:00
88f79a57c4 move solver from cfdemSolverIBRO to cfdemSolverIBContinuousForcing
more appropriate naming:
RO (reduced order) referred to the RO model of red blood cells, but the
key difference in this solver is the momentum forcing term in the UEqn
2022-02-09 15:57:05 +01:00
7d2f5067c2 rename cfdemCloudIBmodified.* files to cfdemCloudIBContinuousForcing.*
more appropriate naming
2022-02-09 15:40:58 +01:00
f7e7c1ab06 rename class cfdemCloudIBmodified to cfdemCloudIBContinuousForcing
more appropriate naming
2022-02-09 15:33:24 +01:00
aaf9c17608 Merge branch 'feature/immersed_multisphere' of https://github.com/ParticulateFlow/CFDEMcoupling into feature/immersed_multisphere
resolved Conflicts:
- etc/solver-list.txt
2022-02-09 15:02:34 +01:00
508450007b clean up whitespaces 2022-02-09 14:57:51 +01:00
093c292570 remove outdated Info message
particle rotational velocity is taken into account now
2022-02-09 14:56:28 +01:00
83949a2f06 fix up controlDict
using cfdemSolverIB instead of the removed cfdemSolverIBTorque
2022-02-09 14:38:28 +01:00
8530b6d303 remove inclusion of mpi.h file
there is no need to include mpi.h in these files
2022-02-09 14:37:42 +01:00
50e27e2ac9 use different solver to run tutorial case
use cfdemSolverIB instead of the removed cfdemSolverIBTorque to run the
case
2022-02-09 14:25:31 +01:00
d38be10d99 move tutorial to different folder
move falling_sphere_two_way_coupling from cfdemSolverIBTorque to
cfdemSolverIB folder
2022-02-09 14:23:07 +01:00
5291dfb1bc remove cfdemSolverIBTorque
remove cfdemSolverIBTorque as it is essentially a copy of cfdemSolverIB
2022-02-09 14:13:01 +01:00
127c21e548 update comment sections [ci skip]
fix up copyrights and contributions
2022-02-09 14:09:38 +01:00
7f5e596271 update .gitignore file
also ignore folders generated by compiling with icc
2022-02-08 09:42:38 +01:00
ff2ff4d251 Merge branch 'develop' of https://github.com/ParticulateFlow/CFDEMcoupling into develop 2022-01-19 09:50:46 +01:00
845cbdd34c Removed unnecessary voidfraction limiter. In this case, even negative values (from massive overpacking) could be tolerated and should be retained to conserve energy. 2022-01-14 09:10:39 +01:00
5f8ac39fad Removed unnecessary and wrong if-clause from FE. Would always return 1.0. Adapted reliable maximum voidfraction for B-B correlation. TODO: Check literature value from original publication. 2022-01-14 09:09:18 +01:00
764e6bd458 remove test solver cfdemSolverPimpleIB
cfdemSolverPimpleIB was a test solver to see the performance using
pimpleFoam; not intended for use in a production environment
2022-01-13 11:31:55 +01:00
257b9e0f02 Merge pull request #128 from ParticulateFlow/master
Updates from release 21.11
2022-01-11 12:40:23 +01:00
aeef30d615 clean up spacing 2021-06-08 19:18:53 +02:00
9460256fa3 clean up cfdemCloudIBmodified
remove commented code (and methods that are thus no longer needed)
2021-06-08 19:16:26 +02:00
f218d7a23d remove unneeded mutable keywords 2021-06-08 18:43:52 +02:00
3c7160bdbc remove extra whitespace in IBVoidFraction.C
accidentally added in 91dbeb42e4
2021-06-08 18:00:57 +02:00
a20ee5ee34 fix output of kin. energy in cfdemSolverIBTorque test case
set dynamic to 'no' as number of particles does not change;
for a single particle we need to set extra dof to 0 to obtain correct ke
2021-06-08 17:30:15 +02:00
6febaec345 move octave script and adjust paths; disable execution by default
for the octave script to work, the case needs to be run twice (without
cleanup in-between);
(remove the useTorque option of ShirgaonkarIBTorqueProps in the
couplingProperties file and adjust the output filenames of the fix print
commands, i.e. adding "_no_coupling")
2021-06-08 17:23:49 +02:00
064cc9ae3d clean up cfdemSolverIBTorque test case files 2021-06-08 16:54:56 +02:00
c6642c0205 clean up Info messages in creatFields of cfdemSolverIBTorque 2021-06-08 13:12:56 +02:00
5a3f78b5f1 remove output files produced by simulation 2021-06-08 12:37:13 +02:00
998a0cd3d1 fix compilation error in cfdemSolverIBTorque
use proper variant of cfdemCloud
2021-06-08 12:27:31 +02:00
6a7a5fc4fd remove duplicate tutorial files
previous move to sub-folder left files in original place (i.e. was a
copy instead of a move operation)
2021-06-07 12:32:18 +02:00
2af9d37307 Minor changes to the momentum source and particle velocity 2020-03-04 13:06:56 +01:00
74052b2319 Minor change to the particle velocity consideration. 2020-02-25 18:30:50 +01:00
f946fe571d Minor changes to the cfdemSolverIBRO and cfdemCloudIBmodified
Discarded some ideal code lines in cfdemSolverIBRO
Excluded the molecular calculatoins in cfdemCloudIBmodified
2020-02-24 09:48:01 +01:00
2123c18aa4 Clean up the cfdemSolverIBRO code
Code clean up performed for better understanding.
Added a penalization factor 'lambda' for the momentum equation.
'lambda' is the penalization factor representing particle rigidity.
2019-10-29 12:05:51 +01:00
690dacd96b Changed the computation in cfdemSolverIBRO
Switched back to the older formulation of forcing term.
2019-10-01 16:08:45 +02:00
d0445a06ae Included particle rotation in the velocity correction.
Added a particle velocity field to the cfdemSolverIBRO.
Particle velocity considers the particle rotation also.
2019-09-26 13:46:18 +02:00
4a9650c5ff Major changes to the code structure regarding particle data in CFD.
Added the particle velocity as a CFD field variable for cfdemSolverIB.
Added an extra function member in cfdemSolverIBRO to calculate the
particle velocity as a separate field.
2019-07-30 12:38:28 +02:00
5096d599c3 Added a volume ratio basde correction factor for continuous forcing term
Considering the influence of the irregularity in the shape of the actual
RBC and the model RBC a new correction factor based on the volume ratio
has been adopted.
2019-05-28 13:20:43 +02:00
a3c4b45408 Finite volume mesh based multisphere force calculation
Changed the force calculation on the multisphere clump based on the
finite volume mesh field datas.
2019-05-20 17:05:53 +02:00
3eb0fdbc8a Corrected the force calculation on the multisphere particle
Corrected the loop determination for calculating the forcfe acting on a
multispehre particle.
2019-05-20 16:10:30 +02:00
c6815c9156 Added a reduced-order immersed boundary solver with continuous momentum forcing
cfdemSolverIBRO - Immersed boundary method (continuous focring approach)
solver for particulate flows. Does not provide the rigid body constrain
and provides approximate solutions for the faster simulations.
2019-05-15 12:00:21 +02:00
b4f7303337 Added the cfdemSolverPimpleIB to solver list 2019-05-02 14:27:51 +02:00
4815aca55a PIMPLE algorithm based IB solver
New immersed boundary solver based on the PIMPLE algorithm to handle
large Courant number flows. This solver is around 2 times faster than
the PISO algorithm solver.
2019-05-02 14:27:16 +02:00
0a1bf03304 Corrections to the velocity correction implementation
Removed the gamma correction factor
Direct derivation of relative velocity from DEM side
Calculaiton of velocity correction improved
2019-04-26 13:35:04 +02:00
1a36f9c428 Added treatment of com based correction at periodic boundaries
Add switching term for particles crossing periodic boundaries.
Included the swicthing term in the velocity correction operation.
Considers rotation in CFD domain and does not consider rotation at
periodic boundaries.
2019-04-24 15:30:43 +02:00
3d8f32a2a1 Remove reduntant data transfer
Removed the redundant data transfer of angular velocity and DEM torques
Removed the redundant calculations based on sphere angular velocities
2019-04-24 13:38:00 +02:00
99ea82aca3 Changed the definitions of cfdemSolverIB and cfdemSovlerIBTorque
Integrated the two-way coupling into cfdemSolverIB solver.
Changed the functionality of cfdemSovlerIBTorque for the bonded
multisphere solutions.
Added the relative velocity of spheres as a function in
cfdemCloudIBmodified to make it feasible for bonded multisphere clumps.
2019-04-16 13:24:44 +02:00
1d07b2745c Corrected the velocity calculation
Inserted a per-molecule com based velocity calculation instead of using
individual particle velocities. Enables consideration of particle
rotation about molecule com.
2018-12-19 10:34:47 +01:00
846c30fccc Additional atom properties and velocity corrections in IBM solver.
Molecule data considered as per-atom properties. Consideration of
relative motion of atoms with respect to molecule centre of mass.
Rotation about the centre of mass.
2018-12-18 16:00:16 +01:00
15102ac38d Fixed the fvOptions functionality in the cfdemSolverIB and cfdemSolverIBTorque solvers.
Added the functionality to create and utilise fvOptions for the immersed
boundary solvers. This is useful for considering periodic channel flows
with meanVelocityForce momentumSource.
2018-10-09 13:31:03 +02:00
27048a8e72 Included the tutorial for the cfdemSolverIBTorque in the tutorial-list 2018-10-09 11:49:36 +02:00
3e7ddecbbc Corrected the tutorial path for the two way coupled solver. 2018-10-08 17:09:30 +02:00
25b57b978c Tutorial case for the two-way coupled immersed boundary solver.
Consists of a comparison of the angular velocity damping when the two-
way coupling is considered.
2018-10-08 16:57:32 +02:00
91dbeb42e4 Corrected the two-way coupling of the immersed boundary method.
Corrected the torque calculation for the cfdemSolverIBTorque and
modified the ShirgaonkarIBTorque calculations.

Included fvOptions.H in the solvers for activation the usage of
fvOptions.
2018-10-08 16:54:35 +02:00
b5304f26de Delete Qt creator project files (#48)
* Delete CFDEM.config

* Delete CFDEM.creator

* Delete CFDEM.files

* Delete CFDEM.includes
2018-02-28 14:53:09 +01:00
c3c8bc002b Added the two-way torque coupling for the immersed boundary solver to impart the influence of fluid viscosity on particle rotation. 2018-02-28 10:18:07 +01:00
316 changed files with 12811 additions and 22422 deletions

2
.gitignore vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
CFDEMcoupling - Open Source CFD-DEM coupling
CFDEMcoupling is part of the CFDEMproject
www.cfdem.com
Copyright (C) 1991-2009 OpenCFD Ltd.
Copyright (C) 2009-2012 JKU, Linz
Copyright (C) 2012-2015 DCS Computing GmbH,Linz
Copyright (C) 2015- JKU, Linz
-------------------------------------------------------------------------------
License
This file is part of CFDEMcoupling.
CFDEMcoupling is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CFDEMcoupling is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with CFDEMcoupling. If not, see <http://www.gnu.org/licenses/>.
Application
cfdemSolverIBContinuousForcing
Description
Transient solver for incompressible flow.
The code is an evolution of the solver pisoFoam in OpenFOAM(R) 1.6,
where additional functionality for CFD-DEM coupling using immersed body
(fictitious domain) method and a continuous forcing approach is added.
Contributions
Alice Hager
Achuth N. Balachandran Nair
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "singlePhaseTransportModel.H"
#include "turbulentTransportModel.H"
#include "pisoControl.H"
#include "cfdemCloudIB.H"
#include "implicitCouple.H"
#include "averagingModel.H"
#include "regionModel.H"
#include "voidFractionModel.H"
#include "dynamicFvMesh.H"
#include "cellSet.H"
#include "fvOptions.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createDynamicFvMesh.H"
#include "createControl.H"
#include "createTimeControls.H"
#include "createFields.H"
#include "initContinuityErrs.H"
#include "createFvOptions.H"
// create cfdemCloud
#include "readGravitationalAcceleration.H"
cfdemCloudIB particleCloud(mesh);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
//=== dyM ===================
interFace = mag(mesh.lookupObject<volScalarField>("voidfractionNext"));
mesh.update(); //dyM
#include "readTimeControls.H"
#include "CourantNo.H"
#include "setDeltaT.H"
// do particle stuff
Info << "- evolve()" << endl;
particleCloud.evolve(Us);
volScalarField voidfractionNext=mesh.lookupObject<volScalarField>("voidfractionNext");
// Pressure-velocity PISO corrector
{
MRF.correctBoundaryVelocity(U);
// Momentum predictor
#include "UEqn.H"
// --- PISO loop
while (piso.correct())
{
#include "pEqn.H"
}
}
laminarTransport.correct();
turbulence->correct();
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -42,7 +42,7 @@ namespace Foam
class energyModel;
class massTransferModel;
class thermCondModel;
class diffCoeffModel;
class diffCoeffModel;
class chemistryModel;
/*---------------------------------------------------------------------------*\
Class cfdemCloudEnergy Declaration
@ -142,8 +142,6 @@ public:
void postFlow();
void solve();
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
License
This is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with this code. If not, see <http://www.gnu.org/licenses/>.
Copyright (C) 2015- Thomas Lichtenegger, JKU Linz, Austria
Description
transfer fluid properties to LIGGGHTS
SourceFiles
transferFluidProperties.C
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "transferFluidProperties.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(transferFluidProperties, 0);
addToRunTimeSelectionTable
(
forceModel,
transferFluidProperties,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
transferFluidProperties::transferFluidProperties
(
const dictionary& dict,
cfdemCloud& sm
)
:
forceModel(dict,sm),
propsDict_(dict.subDict(typeName + "Props"))
{
particleCloud_.registerParticleProperty<double**>("fluidDensity",1);
particleCloud_.registerParticleProperty<double**>("fluidViscosity",1);
// init force sub model
setForceSubModels(propsDict_);
// define switches which can be read from dict
forceSubM(0).setSwitchesList(SW_VERBOSE,true); // activate search for verbose switch
forceSubM(0).setSwitchesList(SW_INTERPOLATION,true); // activate search for interpolate switch
forceSubM(0).readSwitches();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
transferFluidProperties::~transferFluidProperties()
{
}
// * * * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * public Member Functions * * * * * * * * * * * * * //
void transferFluidProperties::setForce() const
{
double**& fluidDensity_ = particleCloud_.getParticlePropertyRef<double**>("fluidDensity");
double**& fluidViscosity_ = particleCloud_.getParticlePropertyRef<double**>("fluidViscosity");
const volScalarField& rhoField = forceSubM(0).rhoField();
const volScalarField& nufField = forceSubM(0).nuField();
interpolationCellPoint<scalar> rhoInterpolator_(rhoField);
interpolationCellPoint<scalar> nufInterpolator_(nufField);
label cellI = 0;
double rho = 0.;
double nuf = 0.;
vector position(0,0,0);
for(int index = 0; index < particleCloud_.numberOfParticles(); ++index)
{
cellI = particleCloud_.cellIDs()[index][0];
if (cellI >= 0)
{
if(forceSubM(0).interpolation())
{
position = particleCloud_.position(index);
rho = rhoInterpolator_.interpolate(position,cellI);
nuf = nufInterpolator_.interpolate(position,cellI);
}
else
{
rho = rhoField[cellI];
nuf = nufField[cellI];
}
fluidDensity_[index][0] = rho;
fluidViscosity_[index][0] = nuf*rho;
}
}
particleCloud_.dataExchangeM().giveData("fluidDensity","scalar-atom",fluidDensity_);
particleCloud_.dataExchangeM().giveData("fluidViscosity","scalar-atom",fluidViscosity_);
if (forceSubM(0).verbose()) Info << "give data done" << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*\
License
This is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with this code. If not, see <http://www.gnu.org/licenses/>.
Copyright (C) 2015- Thomas Lichtenegger, JKU Linz, Austria
Description
transfer fluid properties to LIGGGHTS
SourceFiles
transferFluidProperties.C
\*---------------------------------------------------------------------------*/
#ifndef transferFluidProperties_H
#define transferFluidProperties_H
#include "forceModel.H"
#include "interpolationCellPoint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class transferFluidProperties Declaration
\*---------------------------------------------------------------------------*/
class transferFluidProperties
:
public forceModel
{
private:
dictionary propsDict_;
public:
//- Runtime type information
TypeName("transferFluidProperties");
// Constructors
//- Construct from components
transferFluidProperties
(
const dictionary& dict,
cfdemCloud& sm
);
// Destructor
~transferFluidProperties();
// Member Functions
void setForce() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@
Christoph Goniva, christoph.goniva@cfdem.com
Copyright 2009-2012 JKU Linz
Copyright 2012- DCS Computing GmbH, Linz
Copyright (C) 2013- Graz University of
Copyright (C) 2013- Graz University of
Technology, IPPT
-------------------------------------------------------------------------------
License
@ -65,6 +65,7 @@ private:
dimensionedScalar smoothingLength_;
dimensionedScalar smoothingLengthReferenceField_;
mutable dimensionedScalar DT_;
word refFieldName_;
scalar gamma_;
bool correctBoundary_;
bool verbose_;
@ -93,7 +94,7 @@ public:
bool doSmoothing() const;
//void dSmoothing(volScalarField&) const;
void smoothen(volScalarField&) const;
void smoothen(volVectorField&) const;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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