OpenLB 1.7
Loading...
Searching...
No Matches
twoWayHelperFunctionals.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/* Helper functionals for Lagrangian two-way coupling methods -- generic implementation.
26 */
27
28#ifndef LB_TWO_WAY_HELPER_FUNCTIONALS_HH
29#define LB_TWO_WAY_HELPER_FUNCTIONALS_HH
30
31namespace olb {
32
34
35template<typename T, typename Lattice>
38 SuperLattice<T, Lattice>& sLattice )
39 : _converter(converter),
40 _sLattice(sLattice)
41{}
42
43template<typename T, typename Lattice>
45{
46 _interpLatticeDensity.reset();
47 _interpLatticeVelocity.reset();
48}
49
50
52
53template<typename T, typename Lattice>
57 std::shared_ptr<SuperLatticeInterpDensity3Degree3D<T, Lattice> > interpLatticeDensity )
58 : TwoWayHelperFunctional<T, Lattice>(converter, sLattice)
59{
60 this->_interpLatticeDensity = interpLatticeDensity;
61}
62
63template<typename T, typename Lattice>
64bool NaiveMomentumExchange<T, Lattice>::operator() ( T gF[], T latticeVelF[], T latticeVelP[],
65 T physPosP[], int latticeRoundedP[],
66 int globic )
67{
68 T magU = util::sqrt( util::pow(latticeVelF[0] - latticeVelP[0],2) +
69 util::pow(latticeVelF[1] - latticeVelP[1],2) +
70 util::pow(latticeVelF[2] - latticeVelP[2],2) );
71
72 int locIC = this->_sLattice.getLoadBalancer().loc(globic);
73 T rhoL = this->_sLattice.getBlock(locIC).get(
74 latticeRoundedP[0],
75 latticeRoundedP[1],
76 latticeRoundedP[2]).computeRho();
77
78 gF[0] = rhoL * magU;
79 gF[1] = rhoL * magU;
80 gF[2] = rhoL * magU;
81
82 return true;
83}
84
85
87
88template<typename T, typename Lattice>
92 std::shared_ptr<SuperLatticeInterpDensity3Degree3D<T, Lattice> > interpLatticeDensity,
93 std::shared_ptr<SuperLatticeInterpPhysVelocity3D<T, Lattice> > interpLatticeVelocity )
94 : TwoWayHelperFunctional<T, Lattice>(converter, sLattice)
95{
96 this->_interpLatticeDensity = interpLatticeDensity;
97 this->_interpLatticeVelocity = interpLatticeVelocity;
98}
99
100template<typename T, typename Lattice>
101bool LaddMomentumExchange<T, Lattice>::operator() ( T gF[], T latticeVelF[], T latticeVelP[],
102 T physPosP[], int latticeRoundedP[],
103 int globic )
104{
105 T physLatticeL = this->_converter.getConversionFactorLength();
106
107 // force density gF
108 gF[0] = T();
109 gF[1] = T();
110 gF[2] = T();
111
112 T fiPop = T();
113 T sp = T(); // dot product for particle velocity
114 T faPos[3] = {T(), T(), T()}; // fAlphaPosition = particle position
115 T fbPos[3] = {T(), T(), T()}; // fBetaPosition = neighbor position to particle position in direction iPop
116
117 T fa[Lattice::q] = { T() }; // fAlpha = interpolated density to fAlphaPosition
118 T fb[Lattice::q] = { T() }; // fBeta = interpolated density to fBetaPosition
119 T lFU[3] = {T(), T(), T()};
120
121 // runs through all q discrete velocity directions
122 for (unsigned iPop = 0; iPop < Lattice::q; ++iPop) {
123 // physical position on neighbor to get pre-streaming collision part
124 faPos[0] = physPosP[0] + physLatticeL * descriptors::c<Lattice>(iPop,0);
125 faPos[1] = physPosP[1] + physLatticeL * descriptors::c<Lattice>(iPop,1);
126 faPos[2] = physPosP[2] + physLatticeL * descriptors::c<Lattice>(iPop,2);
127 // Lagrange interpolated polynomial to get density on particle position
128 this->_interpLatticeDensity->operator() (fa, faPos, globic);
129
130 // physical position on neighbor to get pre-streaming collision part
131 fbPos[0] = physPosP[0] - physLatticeL * descriptors::c<Lattice>(iPop,0);
132 fbPos[1] = physPosP[1] - physLatticeL * descriptors::c<Lattice>(iPop,1);
133 fbPos[2] = physPosP[2] - physLatticeL * descriptors::c<Lattice>(iPop,2);
134 // Lagrange interpolated polynomial to get density on particle position
135 this->_interpLatticeDensity->operator() (fb, fbPos, globic);
136
137 // fiPop = density on fBetaPosition in direction iPop
138 fiPop = fb[descriptors::opposite<Lattice >(iPop)];
139 // Get f_l of the boundary cell
140 // add density fAlphaL of opposite direction to iPop
141 fiPop -= fa[iPop];
142
143 // physical velocity
144 lFU[0] = -descriptors::c<Lattice>(iPop,0) * fiPop;
145 lFU[1] = -descriptors::c<Lattice>(iPop,1) * fiPop;
146 lFU[2] = -descriptors::c<Lattice>(iPop,2) * fiPop;
147
148 // point product
149 sp = descriptors::c<Lattice>(iPop,0) * latticeVelP[0] + descriptors::c<Lattice>(iPop,1) * latticeVelP[1]
150 + descriptors::c<Lattice>(iPop,2) * latticeVelP[2];
151 sp *= 2. * descriptors::invCs2<T,Lattice>()
152 * descriptors::t<T,Lattice>(iPop);
153
154 // external force density that acts on particles
155 gF[0] += (lFU[0] - descriptors::c<Lattice>(iPop,0) * (sp));
156 gF[1] += (lFU[1] - descriptors::c<Lattice>(iPop,1) * (sp));
157 gF[2] += (lFU[2] - descriptors::c<Lattice>(iPop,2) * (sp));
158 }
159 gF[0] = util::fabs(gF[0]);
160 gF[1] = util::fabs(gF[1]);
161 gF[2] = util::fabs(gF[2]);
162
163 return true;
164}
165
166
167}
168
169#endif
LaddMomentumExchange(UnitConverter< T, Lattice > &converter, SuperLattice< T, Lattice > &sLattice, std::shared_ptr< SuperLatticeInterpDensity3Degree3D< T, Lattice > > interpLatticeDensity, std::shared_ptr< SuperLatticeInterpPhysVelocity3D< T, Lattice > > interpLatticeVelocity)
Constructor.
virtual bool operator()(T gF[], T latticeVelF[], T latticeVelP[], T physPosP[], int latticeRoundedP[], int globic) override
Computes the momentum transfer from fluid to particle.
NaiveMomentumExchange(UnitConverter< T, Lattice > &converter, SuperLattice< T, Lattice > &sLattice, std::shared_ptr< SuperLatticeInterpDensity3Degree3D< T, Lattice > > interpLatticeDensity)
Constructor.
virtual bool operator()(T gF[], T latticeVelF[], T latticeVelP[], T physPosP[], int latticeRoundedP[], int globic) override
Computes the momentum transfer from fluid to particle.
Super class maintaining block lattices for a cuboid decomposition.
Abstact class for all the local forward-coupling models, viz., momentum coupling from fluid to partic...
std::shared_ptr< SuperLatticeInterpDensity3Degree3D< T, Lattice > > _interpLatticeDensity
TwoWayHelperFunctional(UnitConverter< T, Lattice > &converter, SuperLattice< T, Lattice > &sLattice)
Constructor.
std::shared_ptr< SuperLatticeInterpPhysVelocity3D< T, Lattice > > _interpLatticeVelocity
Conversion between physical and lattice units, as well as discretization.
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
cpu::simd::Pack< T > fabs(cpu::simd::Pack< T > value)
Definition pack.h:106
Top level namespace for all of OpenLB.