OpenLB 1.7
Loading...
Searching...
No Matches
backCouplingModels.hh
Go to the documentation of this file.
1/* Lattice Boltzmann sample, written in C++, using the OpenLB
2 * library
3 *
4 * Copyright (C) 2019 Davide Dapelo
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25/* Models for Lagrangian back-coupling methods -- generic implementation.
26 */
27
28#ifndef LB_BACK_COUPLING_MODELS_HH
29#define LB_BACK_COUPLING_MODELS_HH
30
31namespace olb {
32
33
35
36template<typename T, typename Lattice, template<typename V> class Particle>
40 SuperGeometry<T,3>& sGeometry,
41 int overlap )
42 : _converter(converter),
43 _sGeometry(sGeometry),
44 _sLattice(sLattice),
45 _commPopulation(_sLattice)
46{
47 _commPopulation.template requestField<olb::descriptors::POPULATION>();
48 _commPopulation.requestOverlap(overlap);
49 _commPopulation.exchangeRequests();
50
51 _zeroAnalytical = std::make_shared<AnalyticalConst3D<T, T> > (T());
52 _zeroField = std::make_shared<AnalyticalComposed3D<T, T> > (*_zeroAnalytical, *_zeroAnalytical, *_zeroAnalytical);
53}
54
55template<typename T, typename Lattice, template<typename V> class Particle>
57{
58 // resets external field
59 this->_sLattice.template defineField<descriptors::FORCE>(this->_sGeometry, material, *_zeroField);
60
61 // NECESSARY to communicate values before using them in operator()
62 _commPopulation.communicate();
63}
64
65
67
68template<typename T, typename Lattice, template<typename V> class Particle>
72 SuperGeometry<T,3>& sGeometry,
73 int overlap )
74 : BaseBackCouplingModel<T,Lattice,Particle>(converter, sLattice, sGeometry, overlap)
75{}
76
77template<typename T, typename Lattice, template<typename V> class Particle>
82
83
85
86template<typename T, typename Lattice, template<typename V> class Particle>
90 SuperGeometry<T,3>& sGeometry,
91 int overlap )
92 : BaseBackCouplingModel<T,Lattice,Particle>(converter, sLattice, sGeometry, overlap),
93 _commForce(sLattice)
94{
95 _commForce.template requestField<olb::descriptors::FORCE>();
96 _commForce.requestOverlap(overlap);
97 _commForce.exchangeRequests();
98}
99
100template<typename T, typename Lattice, template<typename V> class Particle>
102{
103 this->_commPopulation.communicate();
104 _commForce.communicate();
105}
106
107
109
110template<typename T, typename Lattice, template<typename V> class Particle>
112 UnitConverter<T, Lattice>& converter,
113 SuperLattice<T, Lattice>& sLattice,
114 SuperGeometry<T,3>& sGeometry,
115 int overlap )
116 : BaseLocalBackCouplingModel<T,Lattice,Particle>(converter, sLattice, sGeometry, overlap)
117{}
118
119template<typename T, typename Lattice, template<typename V> class Particle>
120bool LocalBackCouplingModel<T,Lattice,Particle>::operator() (Particle<T>* p, int globic, int material, int subCycles)
121{
122 int locIC = this->_sLattice.getLoadBalancer().loc(globic);
123
124 // reading the force from the value stored inside the particle
125 std::vector<T> physForceP = p->getStoreForce(); // physical force acting on the particle
126
127 T latticeForceP[3] = { physForceP[0] / this->_converter.getConversionFactorForce(),
128 physForceP[1] / this->_converter.getConversionFactorForce(),
129 physForceP[2] / this->_converter.getConversionFactorForce()
130 }; // dimensionless force acting on the particle
131
132 T physPosP[3] = { (p->getPos()[0]),
133 (p->getPos()[1]),
134 (p->getPos()[2])
135 }; // particle's physical position
136
137 // particle's dimensionless position, rounded at neighbouring voxel
138 int latticeRoundedPosP[3] = {0, 0, 0};
139 this->_sLattice.getCuboidGeometry().get(globic).getLatticeR( latticeRoundedPosP, physPosP );
140
141 if (this->_sGeometry.getBlockGeometry(locIC).getMaterial( latticeRoundedPosP[0], latticeRoundedPosP[1], latticeRoundedPosP[2] ) == material) {
143 -latticeForceP[0] / (T)(subCycles),
144 -latticeForceP[1] / (T)(subCycles),
145 -latticeForceP[2] / (T)(subCycles)
146 }; // dimensionless smoothed force
147
148 this->_sLattice.getBlock(locIC).get(
149 latticeRoundedPosP[0],
150 latticeRoundedPosP[1],
151 latticeRoundedPosP[2]
152 ).template getFieldPointer<descriptors::FORCE>() += F;
153 }
154
155 return true;
156}
157
158
160
161template<typename T, typename Lattice, template<typename V> class Particle>
163 UnitConverter<T, Lattice>& converter,
164 SuperLattice<T, Lattice>& sLattice,
165 SuperGeometry<T,3>& sGeometry,
166 int overlap )
167 : BaseNonLocalBackCouplingModel<T,Lattice,Particle>(converter, sLattice, sGeometry, overlap)
168{
169 _cubicDeltaFunctional = std::make_shared<SuperLatticeSmoothDiracDelta3D<T, Lattice> > (
170 this->_sLattice, this->_converter, this->_sGeometry );
171}
172
173template<typename T, typename Lattice, template<typename V> class Particle>
174bool CubicDeltaBackCouplingModel<T,Lattice,Particle>::operator() (Particle<T>* p, int globic, int material, int subCycles)
175{
176 int locIC = this->_sLattice.getLoadBalancer().loc(globic);
177
178 // reading the force from the value stored inside the particle
179 std::vector<T> physForceP = p->getStoreForce(); // physical force acting on the particle
180
181 T latticeForceP[3] = { physForceP[0] / this->_converter.getConversionFactorForce(),
182 physForceP[1] / this->_converter.getConversionFactorForce(),
183 physForceP[2] / this->_converter.getConversionFactorForce()
184 }; // dimensionless force acting on the particle
185
186 T physPosP[3] = { p->getPos()[0],
187 p->getPos()[1],
188 p->getPos()[2]
189 }; // particle's physical position
190
191 // particle's dimensionless position, rounded at neighbouring voxel
192 int latticeRoundedPosP[3] = {0, 0, 0};
193 this->_sLattice.getCuboidGeometry().get(globic).getLatticeR( latticeRoundedPosP, physPosP );
194
195 // smooth Dirac delta
196 this->_cubicDeltaFunctional->operator() (_delta, physPosP, globic);
197
198 T tempDelta = T();
199 FieldD<T,Lattice,descriptors::FORCE> F; // dimensionless smoothed force
200
201 for (int i = -_range; i <= _range; ++i) {
202 for (int j = -_range; j <= _range; ++j) {
203 for (int k = -_range; k <= _range; ++k) {
204 if (this->_sGeometry.getBlockGeometry(locIC).getMaterial(
205 latticeRoundedPosP[0] + i, latticeRoundedPosP[1] + j,
206 latticeRoundedPosP[2] + k) == material) {
207
208 tempDelta = _delta[i + _range][j + _range][k + _range];
209
210 F[0] = -latticeForceP[0] * tempDelta / (T)(subCycles);
211 F[1] = -latticeForceP[1] * tempDelta / (T)(subCycles);
212 F[2] = -latticeForceP[2] * tempDelta / (T)(subCycles);
213
214 this->_sLattice.getBlock(locIC).get(
215 latticeRoundedPosP[0] + i,
216 latticeRoundedPosP[1] + j,
217 latticeRoundedPosP[2] + k
218 ).template getFieldPointer<descriptors::FORCE>() += F;
219 }
220 }
221 }
222 }
223 return true;
224}
225
226
228
229template<typename T, typename Lattice, template<typename V> class Particle>
231 UnitConverter<T, Lattice>& converter,
232 SuperLattice<T, Lattice>& sLattice,
233 SuperGeometry<T,3>& sGeometry,
234 std::shared_ptr<SmoothingFunctional<T, Lattice>> smoothingFunctional,
235 int overlap )
236 : BaseNonLocalBackCouplingModel<T,Lattice,Particle>(converter, sLattice, sGeometry, overlap),
237 _smoothingFunctional(smoothingFunctional)
238{}
239
240template<typename T, typename Lattice, template<typename V> class Particle>
241bool NonLocalBaseBackCouplingModel<T,Lattice,Particle>::operator() (Particle<T>* p, int globic, int material, int subCycles)
242{
243 int locIC = this->_sLattice.getLoadBalancer().loc(globic);
244
245 // reading the force from the value stored inside the particle
246 std::vector<T> physForceP = p->getStoreForce(); // physical force acting on the particle
247 T latticeForceP[3] = { physForceP[0] / this->_converter.getConversionFactorForce(),
248 physForceP[1] / this->_converter.getConversionFactorForce(),
249 physForceP[2] / this->_converter.getConversionFactorForce()
250 }; // dimensionless force acting on the particle
251
252 // Updating force through voxels within kernel smoothing length from the bubble's position
253 for (auto&& i : this->_smoothingFunctional->getData()) {
254
255 // Updating iterated voxel
256 if ( this->_sGeometry.getBlockGeometry(locIC).getMaterial(i.latticePos[0], i.latticePos[1], i.latticePos[2]) == material ) {
257
258 // Weighted force acting on the iterated voxel
260 -latticeForceP[0] * i.weight / (T)(subCycles),
261 -latticeForceP[1] * i.weight / (T)(subCycles),
262 -latticeForceP[2] * i.weight / (T)(subCycles)
263 }; // dimensionless smoothed force
264
265 this->_sLattice.getBlock(locIC).get(
266 i.latticePos[0], i.latticePos[1], i.latticePos[2]
267 ).template getFieldPointer<descriptors::FORCE>() += F;
268 }
269 }
270 return true;
271}
272
273}
274
275#endif
virtual void communicate()=0
Communicates POPULATION and FORCE fields if the model is non-local.
Abstact class for all the back-coupling models, viz., momentum coupling from particle to fluid.
BaseBackCouplingModel(UnitConverter< T, Lattice > &converter, SuperLattice< T, Lattice > &sLattice, SuperGeometry< T, 3 > &sGeometry, int overlap)
Constructor.
UnitConverter< T, Lattice > & _converter
SuperLattice< T, Lattice > & _sLattice
virtual void resetExternalField(int material) override
Resets external field.
SuperGeometry< T, 3 > & _sGeometry
SuperCommunicator< T, SuperLattice< T, Lattice > > _commPopulation
Abstact class for all the local back-coupling models.
virtual void communicate() override
Communicates POPULATION and FORCE fields if the model is non-local.
BaseLocalBackCouplingModel(UnitConverter< T, Lattice > &converter, SuperLattice< T, Lattice > &sLattice, SuperGeometry< T, 3 > &sGeometry, int overlap)
Constructor.
Abstact class for all the non-local back-coupling models.
virtual void communicate() override
Communicates POPULATION and FORCE fields if the model is non-local.
BaseNonLocalBackCouplingModel(UnitConverter< T, Lattice > &converter, SuperLattice< T, Lattice > &sLattice, SuperGeometry< T, 3 > &sGeometry, int overlap)
Constructor.
CubicDeltaBackCouplingModel(UnitConverter< T, Lattice > &converter, SuperLattice< T, Lattice > &sLattice, SuperGeometry< T, 3 > &sGeometry, int overlap)
Constructor.
std::shared_ptr< SuperLatticeSmoothDiracDelta3D< T, Lattice > > _cubicDeltaFunctional
virtual bool operator()(Particle< T > *p, int globic, int material, int subCycles=1) override
Class operator to apply the coupling.
LocalBackCouplingModel(UnitConverter< T, Lattice > &converter, SuperLattice< T, Lattice > &sLattice, SuperGeometry< T, 3 > &sGeometry, int overlap)
Constructor.
virtual bool operator()(Particle< T > *p, int globic, int material, int subCycles=1) override
Class operator to apply the coupling.
NonLocalBaseBackCouplingModel(UnitConverter< T, Lattice > &converter, SuperLattice< T, Lattice > &sLattice, SuperGeometry< T, 3 > &sGeometry, std::shared_ptr< SmoothingFunctional< T, Lattice > > smoothingFunctional, int overlap)
Constructor.
virtual bool operator()(Particle< T > *p, int globic, int material, int subCycles=1) override
Class operator to apply the coupling.
Abstact class for all the smoothing functionals.
Representation of a statistic for a parallel 2D geometry.
Super class maintaining block lattices for a cuboid decomposition.
Conversion between physical and lattice units, as well as discretization.
Plain old scalar vector.
Definition vector.h:47
bool * getBlock(std::size_t iBlock, std::size_t &sizeBlock, bool loadingMode)
Definition vector.h:201
Top level namespace for all of OpenLB.