25#ifndef DYNAMICS_COLLISION_LES_H
26#define DYNAMICS_COLLISION_LES_H
47template <
typename COLLISION,
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
49 using MomentaF =
typename MOMENTA::template type<DESCRIPTOR>;
50 using CollisionO =
typename COLLISION::template type<DESCRIPTOR, MOMENTA, EQUILIBRIUM>;
52 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
55 MomentaF().computePiNeqNormSqr(cell, piNeqNormSqr);
56 const V rho =
MomentaF().computeRho(cell);
57 const V omega = parameters.template get<descriptors::OMEGA>();
58 const V smagorinsky = parameters.template get<collision::LES::Smagorinsky>();
60 V preFactor = smagorinsky*smagorinsky
61 * descriptors::invCs2<V,DESCRIPTOR>()*descriptors::invCs2<V,DESCRIPTOR>()
64 V tauMol = V{1} / omega;
66 V tauTurb = V{0.5} * (
util::sqrt(tauMol*tauMol + preFactor / rho * piNeqNorm) - tauMol);
68 V tauEff = tauMol + tauTurb;
72 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
74 parameters.template set<descriptors::OMEGA>(
80template <
typename COLLISION,
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
82 using MomentaF =
typename MOMENTA::template type<DESCRIPTOR>;
83 using CollisionO =
typename COLLISION::template type<DESCRIPTOR, MOMENTA, EQUILIBRIUM>;
85 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
88 MomentaF().computePiNeqNormSqr(cell, piNeqNormSqr);
89 const V rho =
MomentaF().computeRho(cell);
90 const auto iT = parameters.template get<descriptors::LATTICE_TIME>();
91 const V omega = parameters.template get<descriptors::OMEGA>();
92 const V smagorinsky = parameters.template get<collision::LES::Smagorinsky>();
93 V avShear = cell.template getField<descriptors::AV_SHEAR>();
95 V preFactor = smagorinsky*smagorinsky
96 * descriptors::invCs2<V,DESCRIPTOR>()*descriptors::invCs2<V,DESCRIPTOR>()
98 avShear = (avShear*iT + piNeqNorm) / (iT+1);
99 V tauMol = V{1} / omega;
100 V piNeqNormSISM = piNeqNorm - avShear;
101 V tauTurb = V{0.5} * (
util::sqrt(tauMol*tauMol+(preFactor*piNeqNormSISM/rho))-tauMol);
102 V tauEff = tauMol + tauTurb;
103 return V{1} / tauEff;
106 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
108 parameters.template set<descriptors::OMEGA>(
110 const auto iT = parameters.template get<descriptors::LATTICE_TIME>();
112 MomentaF().computePiNeqNormSqr(cell, piNeqNormSqr);
113 V avShear = cell.template getField<descriptors::AV_SHEAR>();
114 avShear = (avShear*iT +
util::sqrt(piNeqNormSqr)) / (iT+1);
115 cell.template setField<descriptors::AV_SHEAR>(avShear);
120template <
typename COLLISION,
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
122 using MomentaF =
typename MOMENTA::template type<DESCRIPTOR>;
123 using CollisionO =
typename COLLISION::template type<DESCRIPTOR, MOMENTA, EQUILIBRIUM>;
125 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
130 MomentaF().computePiNeqNormSqr(cell, piNeqNormSqr);
131 const V rho =
MomentaF().computeRho(cell);
132 const V omega = parameters.template get<descriptors::OMEGA>();
133 const V smagorinsky = parameters.template get<collision::LES::Smagorinsky>();
136 V cs2 = V{1} / descriptors::invCs2<V,DESCRIPTOR>();
137 V tauMol = V{1} / omega;
139 V Phi = (-0.5*(-rho*tauMol*cs2+
util::sqrt(rho*rho*tauMol*tauMol*cs2*cs2+V{2}*(smagorinsky*smagorinsky)*rho*piNeqNorm))/(smagorinsky*smagorinsky*rho*piNeqNorm));
140 for (
int n=0; n < util::TensorVal<DESCRIPTOR>::n; ++n) {
144 V SNormSqr = S[0]*S[0] + 2.0*S[1]*S[1] + S[2]*S[2];
146 SNormSqr += S[2]*S[2] + S[3]*S[3] + 2.0*S[4]*S[4] + S[5]*S[5];
150 V tauTurb = smagorinsky*smagorinsky*SNorm/cs2;
152 V tauEff = tauMol + tauTurb;
153 return V{1} / tauEff;
156 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
158 parameters.template set<descriptors::OMEGA>(
165template <
typename COLLISION,
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
167 using MomentaF =
typename MOMENTA::template type<DESCRIPTOR>;
168 using CollisionO =
typename COLLISION::template type<DESCRIPTOR, MOMENTA, EQUILIBRIUM>;
170 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
175 MomentaF().computePiNeqNormSqr(cell, piNeqNormSqr);
176 const V rho =
MomentaF().computeRho(cell);
177 const V omega = parameters.template get<descriptors::OMEGA>();
178 const V smagorinsky = parameters.template get<collision::LES::Smagorinsky>();
180 V conSmagoR[DESCRIPTOR::q];
182 V tauMol = V{1} / omega;
183 V cs2 = V{1} / descriptors::invCs2<V,DESCRIPTOR>();
185 V Phi = (-0.5*(-rho*tauMol*cs2+
util::sqrt(rho*rho*tauMol*tauMol*cs2*cs2+V{2}*(smagorinsky*smagorinsky)*rho*piNeqNorm))/(smagorinsky*smagorinsky*rho*piNeqNorm));
186 for (
int n=0; n < util::TensorVal<DESCRIPTOR>::n; ++n) {
190 V SNormSqr = S[0]*S[0] + 2.0*S[1]*S[1] + S[2]*S[2];
192 SNormSqr += S[2]*S[2] + S[3]*S[3] + 2.0*S[4]*S[4] + S[5]*S[5];
195 V preFactor = smagorinsky*smagorinsky
196 * descriptors::invCs2<V,DESCRIPTOR>()*descriptors::invCs2<V,DESCRIPTOR>()
202 V t = descriptors::t<V,DESCRIPTOR>(q);
204 H[0] = descriptors::c<DESCRIPTOR>(q,0)*descriptors::c<DESCRIPTOR>(q,0)-cs2;
205 H[1] = descriptors::c<DESCRIPTOR>(q,0)*descriptors::c<DESCRIPTOR>(q,1);
206 H[2] = descriptors::c<DESCRIPTOR>(q,1)*descriptors::c<DESCRIPTOR>(q,1)-cs2;
208 H[2] = descriptors::c<DESCRIPTOR>(q,0)*descriptors::c<DESCRIPTOR>(q,2);
209 H[3] = descriptors::c<DESCRIPTOR>(q,1)*descriptors::c<DESCRIPTOR>(q,1)-cs2;
210 H[4] = descriptors::c<DESCRIPTOR>(q,1)*descriptors::c<DESCRIPTOR>(q,2);
211 H[5] = descriptors::c<DESCRIPTOR>(q,2)*descriptors::c<DESCRIPTOR>(q,2)-cs2;
214 V contractHS = H[0]*S[0] + 2.0*H[1]*S[1] + H[2]*S[2];
216 contractHS += H[2]*S[2] + H[3]*S[3] + 2.0*H[4]*S[4] + H[5]*S[5];
219 conSmagoR[q] = t*preFactor*SNorm*contractHS;
224 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
226 parameters.template set<descriptors::OMEGA>(
232template <
typename COLLISION,
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
234 using MomentaF =
typename MOMENTA::template type<DESCRIPTOR>;
235 using CollisionO =
typename COLLISION::template type<DESCRIPTOR, MOMENTA, EQUILIBRIUM>;
237 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
240 MomentaF().computePiNeqNormSqr(cell, piNeqNormSqr);
241 const V omega = parameters.template get<descriptors::OMEGA>();
242 const V smagorinsky = parameters.template get<collision::LES::Smagorinsky>();
243 const auto velocityGradient = cell.template getField<descriptors::VELO_GRAD>();
244 V preFactor = smagorinsky*smagorinsky;
247 for (
unsigned i=0; i < 3; i++) {
248 for (
unsigned j=0; j < 3; j++) {
249 g[i][j] = velocityGradient[i*3 + j];
254 for (
unsigned i = 0; i < 3; i++) {
255 for (
unsigned j = 0; j < 3; j++) {
256 s[i][j] = (g[i][j] + g[j][i]) / V{2};
261 for (
unsigned i = 0; i < 3; i++) {
262 for (
unsigned j = 0; j < 3; j++) {
266 for (
unsigned i = 0; i < 3; i++) {
267 for (
unsigned j = 0; j < 3; j++) {
268 for (
unsigned k = 0; k < 3; k++) {
269 G[i][j] += (g[i][k]*g[k][j] + g[j][k]*g[k][i]) / V{2};
274 for (
unsigned i = 0; i < 3; i++) {
275 trace += V{1}/V{3} * g[i][i] * g[i][i];
277 for (
unsigned i = 0; i < 3; i++) {
282 for (
unsigned i = 0; i < 3; i++) {
283 for (
unsigned j = 0; j < 3; j++) {
284 G_ip = G[i][j] * G[i][j];
289 for (
unsigned i = 0; i < 3; i++) {
290 for (
unsigned j = 0; j < 3; j++) {
291 s_ip = s[i][j] * s[i][j];
304 V tauMol = V{1} / omega;
306 V tauEff = tauMol + tauTurb;
307 return V{1} / tauEff;
310 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
312 parameters.template set<descriptors::OMEGA>(
318template <
typename COLLISION,
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
320 using MomentaF =
typename MOMENTA::template type<DESCRIPTOR>;
321 using CollisionO =
typename COLLISION::template type<DESCRIPTOR, MOMENTA, EQUILIBRIUM>;
323 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
325 V rho, u[DESCRIPTOR::d], fNeq[DESCRIPTOR::q] { };
326 MomentaF().computeRhoU(cell, rho, u);
328 const V omega = parameters.template get<descriptors::OMEGA>();
329 const V smagorinsky = parameters.template get<collision::LES::Smagorinsky>();
330 const V preFactor = smagorinsky*smagorinsky
331 * 3*descriptors::invCs2<V,DESCRIPTOR>()*descriptors::invCs2<V,DESCRIPTOR>()
334 const V tauMol = V{1} / omega;
335 for (
unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
336 V tauTurb = V{0.5}*(
util::sqrt(tauMol*tauMol + preFactor/rho *
util::fabs(fNeq[iPop])) - tauMol);
337 omegaEff[iPop] = V{1} / (tauMol + tauTurb);
340 for (
int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
341 avgOmegaEff += omegaEff[iPop];
343 avgOmegaEff /= DESCRIPTOR::q;
347 template <
typename CELL,
typename PARAMETERS,
typename V=
typename CELL::value_t>
349 V rho, u[DESCRIPTOR::d], fNeq[DESCRIPTOR::q] { };
350 MomentaF().computeRhoU(cell, rho, u);
352 const V omega = parameters.template get<descriptors::OMEGA>();
353 const V smagorinsky = parameters.template get<collision::LES::Smagorinsky>();
354 const V preFactor = smagorinsky*smagorinsky
355 * 3*descriptors::invCs2<V,DESCRIPTOR>()*descriptors::invCs2<V,DESCRIPTOR>()
358 const V tauMol = V{1} / omega;
359 for (
unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
360 V tauTurb = V{0.5}*(
util::sqrt(tauMol*tauMol + preFactor/rho *
util::fabs(fNeq[iPop])) - tauMol);
361 omegaEff[iPop] = V{1} / (tauMol + tauTurb);
363 parameters.template set<typename COLLISION::OMEGA>(omegaEff);
372template <
typename COLLISION>
374 using parameters =
typename COLLISION::parameters::template include<
378 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
379 "COLLISION must be parametrized using relaxation frequency OMEGA");
382 return "SmagorinskyEffectiveOmega<" + COLLISION::getName() +
">";
385 template <
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
390template <
typename COLLISION>
392 using parameters =
typename COLLISION::parameters::template include<
396 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
397 "COLLISION must be parametrized using relaxation frequency OMEGA");
400 return "ShearSmagorinskyEffectiveOmega<" + COLLISION::getName() +
">";
403 template <
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
408template <
typename COLLISION>
410 using parameters =
typename COLLISION::parameters::template include<
414 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
415 "COLLISION must be parametrized using relaxation frequency OMEGA");
418 return "ConStrainSmagorinskyEffectiveOmega<" + COLLISION::getName() +
">";
421 template <
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
426template <
typename COLLISION>
428 using parameters =
typename COLLISION::parameters::template include<
432 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
433 "COLLISION must be parametrized using relaxation frequency OMEGA");
436 return "ConSmagorinskyEffectiveOmega<" + COLLISION::getName() +
">";
439 template <
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
444template <
typename COLLISION>
446 using parameters =
typename COLLISION::parameters::template include<
450 static_assert(COLLISION::parameters::template contains<descriptors::OMEGA>(),
451 "COLLISION must be parametrized using relaxation frequency OMEGA");
454 return "WaleEffectiveOmega<" + COLLISION::getName() +
">";
457 template <
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
462template <
typename COLLISION>
464 using parameters =
typename COLLISION::parameters::template include<
469 return "KrauseEffectiveOmega<" + COLLISION::getName() +
">";
472 template <
typename DESCRIPTOR,
typename MOMENTA,
typename EQUILIBRIUM>
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
cpu::simd::Pack< T > fabs(cpu::simd::Pack< T > value)
Top level namespace for all of OpenLB.
Return value of any collision.
Compute dynamics parameter OMEGA locally using Consistent Smagorinsky LES model.
static std::string getName()
typename COLLISION::parameters::template include< descriptors::OMEGA, LES::Smagorinsky > parameters
Compute dynamics parameter OMEGA locally using Consistent Strain Smagorinsky LES model.
static std::string getName()
typename COLLISION::parameters::template include< descriptors::OMEGA, LES::Smagorinsky > parameters
Compute dynamics parameter OMEGA locally using Krause LES model.
typename COLLISION::parameters::template include< descriptors::OMEGA, LES::Smagorinsky > parameters
static std::string getName()
Compute dynamics parameter OMEGA locally using Shear Smagorinsky LES model.
static std::string getName()
typename COLLISION::parameters::template include< descriptors::LATTICE_TIME, descriptors::OMEGA, LES::Smagorinsky > parameters
Compute dynamics parameter OMEGA locally using Smagorinsky LES model.
static std::string getName()
typename COLLISION::parameters::template include< descriptors::OMEGA, LES::Smagorinsky > parameters
Compute dynamics parameter OMEGA locally using WALE.
typename COLLISION::parameters::template include< descriptors::OMEGA, LES::Smagorinsky > parameters
static std::string getName()
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
typename MOMENTA::template type< DESCRIPTOR > MomentaF
V computeEffectiveOmega(CELL &cell, PARAMETERS ¶meters) any_platform
CellStatistic< V > apply(CELL &cell, PARAMETERS ¶meters) any_platform
V computeEffectiveOmega(CELL &cell, PARAMETERS ¶meters) any_platform
typename MOMENTA::template type< DESCRIPTOR > MomentaF
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
CellStatistic< V > apply(CELL &cell, PARAMETERS ¶meters) any_platform
V computeEffectiveOmega(CELL &cell, PARAMETERS ¶meters) any_platform
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
typename MOMENTA::template type< DESCRIPTOR > MomentaF
CellStatistic< V > apply(CELL &cell, PARAMETERS ¶meters) any_platform
typename MOMENTA::template type< DESCRIPTOR > MomentaF
V computeEffectiveOmega(CELL &cell, PARAMETERS ¶meters) any_platform
CellStatistic< V > apply(CELL &cell, PARAMETERS ¶meters) any_platform
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
V computeEffectiveOmega(CELL &cell, PARAMETERS ¶meters) any_platform
CellStatistic< V > apply(CELL &cell, PARAMETERS ¶meters) any_platform
typename MOMENTA::template type< DESCRIPTOR > MomentaF
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
CellStatistic< V > apply(CELL &cell, PARAMETERS ¶meters) any_platform
typename COLLISION::template type< DESCRIPTOR, MOMENTA, EQUILIBRIUM > CollisionO
typename MOMENTA::template type< DESCRIPTOR > MomentaF
V computeEffectiveOmega(CELL &cell, PARAMETERS ¶meters) any_platform
Base of a field whose size is defined by [C,U_1,...,U_N]^T * [1,V_1,...V_N].
static void computeFneq(CELL &cell, FNEQ &fNeq, const RHO &rho, const U &u) any_platform
Computation of non-equilibrium distribution.
Compute number of elements of a symmetric d-dimensional tensor.