28#ifndef LB_BACK_COUPLING_MODELS_HH
29#define LB_BACK_COUPLING_MODELS_HH
36template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
42 : _converter(converter),
43 _sGeometry(sGeometry),
45 _commPopulation(_sLattice)
51 _zeroAnalytical = std::make_shared<AnalyticalConst3D<T, T> > (T());
52 _zeroField = std::make_shared<AnalyticalComposed3D<T, T> > (*_zeroAnalytical, *_zeroAnalytical, *_zeroAnalytical);
55template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
59 this->_sLattice.template defineField<descriptors::FORCE>(this->_sGeometry, material, *_zeroField);
62 _commPopulation.communicate();
68template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
77template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
86template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
95 _commForce.template requestField<olb::descriptors::FORCE>();
96 _commForce.requestOverlap(overlap);
97 _commForce.exchangeRequests();
100template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
103 this->_commPopulation.communicate();
104 _commForce.communicate();
110template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
119template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
122 int locIC = this->_sLattice.getLoadBalancer().loc(globic);
125 std::vector<T> physForceP = p->getStoreForce();
127 T latticeForceP[3] = { physForceP[0] / this->_converter.getConversionFactorForce(),
128 physForceP[1] / this->_converter.getConversionFactorForce(),
129 physForceP[2] / this->_converter.getConversionFactorForce()
132 T physPosP[3] = { (p->getPos()[0]),
138 int latticeRoundedPosP[3] = {0, 0, 0};
139 this->_sLattice.getCuboidGeometry().get(globic).getLatticeR( latticeRoundedPosP, physPosP );
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)
148 this->_sLattice.
getBlock(locIC).get(
149 latticeRoundedPosP[0],
150 latticeRoundedPosP[1],
151 latticeRoundedPosP[2]
152 ).template getFieldPointer<descriptors::FORCE>() += F;
161template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
173template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
176 int locIC = this->_sLattice.getLoadBalancer().loc(globic);
179 std::vector<T> physForceP = p->getStoreForce();
181 T latticeForceP[3] = { physForceP[0] / this->_converter.getConversionFactorForce(),
182 physForceP[1] / this->_converter.getConversionFactorForce(),
183 physForceP[2] / this->_converter.getConversionFactorForce()
186 T physPosP[3] = { p->getPos()[0],
192 int latticeRoundedPosP[3] = {0, 0, 0};
193 this->_sLattice.getCuboidGeometry().get(globic).getLatticeR( latticeRoundedPosP, physPosP );
196 this->_cubicDeltaFunctional->operator() (_delta, physPosP, globic);
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) {
208 tempDelta = _delta[i + _range][j + _range][k + _range];
210 F[0] = -latticeForceP[0] * tempDelta / (T)(subCycles);
211 F[1] = -latticeForceP[1] * tempDelta / (T)(subCycles);
212 F[2] = -latticeForceP[2] * tempDelta / (T)(subCycles);
214 this->_sLattice.
getBlock(locIC).get(
215 latticeRoundedPosP[0] + i,
216 latticeRoundedPosP[1] + j,
217 latticeRoundedPosP[2] + k
218 ).template getFieldPointer<descriptors::FORCE>() += F;
229template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
237 _smoothingFunctional(smoothingFunctional)
240template<
typename T,
typename Lattice,
template<
typename V>
class Particle>
243 int locIC = this->_sLattice.getLoadBalancer().loc(globic);
246 std::vector<T> physForceP = p->getStoreForce();
247 T latticeForceP[3] = { physForceP[0] / this->_converter.getConversionFactorForce(),
248 physForceP[1] / this->_converter.getConversionFactorForce(),
249 physForceP[2] / this->_converter.getConversionFactorForce()
253 for (
auto&& i : this->_smoothingFunctional->getData()) {
256 if ( this->_sGeometry.getBlockGeometry(locIC).getMaterial(i.latticePos[0], i.latticePos[1], i.latticePos[2]) == material ) {
260 -latticeForceP[0] * i.weight / (T)(subCycles),
261 -latticeForceP[1] * i.weight / (T)(subCycles),
262 -latticeForceP[2] * i.weight / (T)(subCycles)
265 this->_sLattice.
getBlock(locIC).get(
266 i.latticePos[0], i.latticePos[1], i.latticePos[2]
267 ).template getFieldPointer<descriptors::FORCE>() += F;
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.
bool * getBlock(std::size_t iBlock, std::size_t &sizeBlock, bool loadingMode)
Top level namespace for all of OpenLB.