OpenLB 1.7
Loading...
Searching...
No Matches
stochasticSGSdynamics.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2013 Mathias J. Krause, Jonas Latt
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
27#ifndef STOCHASTIC_SGS_DYNAMICS_HH
28#define STOCHASTIC_SGS_DYNAMICS_HH
29
30#include <algorithm>
31#include <limits>
33#include "mrtDynamics.h"
34#include "mrt.h"
35#include "core/cell.h"
36#include "core/util.h"
37#include "math.h"
38
39#include <stdlib.h>
40#include <math.h>
41#include <time.h>
42#include <stdio.h>
43
44
45namespace olb {
46
49
51
59template<typename T, typename DESCRIPTOR, typename MOMENTA>
61 T omega_, T turbulenceInt_, T charU_, T smagoConst_, T dx_, T dt_)
62 : MRTdynamics<T,DESCRIPTOR,MOMENTA>(omega_),
63 turbulenceInt(turbulenceInt_),
64 smagoConst(smagoConst_),
65 charU(charU_),
66 preFactor(computePreFactor(omega_,smagoConst_) )
67
68{
69
70 // T invM_S_SGS[DESCRIPTOR::q][DESCRIPTOR::q];
71 // T rtSGS[DESCRIPTOR::q]; // relaxation times vector for SGS approach.
72 // for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop)
73 // {
74 // rtSGS[iPop] = DESCRIPTOR::S[iPop];
75 // }
76 // for (int iPop = 0; iPop < DESCRIPTOR::shearIndexes; ++iPop)
77 // {
78 // rtSGS[DESCRIPTOR::shearViscIndexes[iPop]] = omega;
79 // }
80 // for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop)
81 // {
82 // for (int jPop = 0; jPop < DESCRIPTOR::q; ++jPop)
83 // {
84 // invM_S_SGS[iPop][jPop] = T();
85 // for (int kPop = 0; kPop < DESCRIPTOR::q; ++kPop)
86 // {
87 // if (kPop == jPop)
88 // {
89 // invM_S_SGS[iPop][jPop] += DESCRIPTOR::invM[iPop][kPop] *
90 // rtSGS[kPop];
91 // cout << "wert"<<iPop <<jPop << "= "<< invM_S_SGS[iPop][jPop]<< std::endl;
92 // }
93 // }
94 // }
95 // }
96 //
97
98
99}
100
101
102template<typename T, typename DESCRIPTOR, typename MOMENTA>
104 Cell<T,DESCRIPTOR>& cell,
105 LatticeStatistics<T>& statistics )
106{
107 T rho, u[DESCRIPTOR::d], pi[util::TensorVal<DESCRIPTOR >::n];
108
109
110
111 T drift = computeTimeScale(preFactor, rho, pi, smagoConst, X_lang_n);
112 T result = getRandBMTrans(cell, turbulenceInt, charU);
113
114 // cout << "vor neu setzen: "<<X_lang_n<< std::endl;
115 X_lang_n = getRandomWalk(cell, drift, result);
116 // cout << "nach neu setzen: "<<X_lang_n<< std::endl;
117 //cout << X_lang_n<< std::endl;
118 // cout << drift<< std::endl;
119 // cout << result<< std::endl;
120
121
122 MOMENTA().computeAllMomenta(cell, rho, u, pi);
123 T newOmega = computeOmega(this->getOmega(), preFactor, rho, pi, X_lang_n);
124
125
126 T invM_S_SGS[DESCRIPTOR::q][DESCRIPTOR::q];
127 T rtSGS[DESCRIPTOR::q]; // relaxation times vector for SGS approach.
128 for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
129 rtSGS[iPop] = DESCRIPTOR::S[iPop];
130 }
131 for (int iPop = 0; iPop < DESCRIPTOR::shearIndexes; ++iPop) {
132 rtSGS[DESCRIPTOR::shearViscIndexes[iPop]] = newOmega;
133 }
134 for (int iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
135 for (int jPop = 0; jPop < DESCRIPTOR::q; ++jPop) {
136 invM_S_SGS[iPop][jPop] = T();
137 for (int kPop = 0; kPop < DESCRIPTOR::q; ++kPop) {
138 if (kPop == jPop) {
139 invM_S_SGS[iPop][jPop] += DESCRIPTOR::invM[iPop][kPop] *
140 rtSGS[kPop];
141 //cout << "wert"<<iPop <<jPop << "= "<< invM_S_SGS[iPop][jPop]<< std::endl;
142 }
143 }
144 }
145 }
146
147 T uSqr = mrt<DESCRIPTOR>::mrtSGSCollision(cell, rho, u, newOmega, invM_S_SGS);
148 statistics.incrementStats(rho, uSqr);
149}
150
151template<typename T, typename DESCRIPTOR, typename MOMENTA>
153{
154 this->setOmega(omega);
155 preFactor = computePreFactor(omega, smagoConst);
156}
157
158template<typename T, typename DESCRIPTOR, typename MOMENTA>
160{
161 T rho, uTemp[DESCRIPTOR::d], pi[util::TensorVal<DESCRIPTOR >::n];
162 MOMENTA().computeAllMomenta(cell, rho, uTemp, pi);
163 T newOmega = computeOmega(this->getOmega(), preFactor, rho, pi, X_lang_n);
164 return newOmega;
165}
166
167
168
169template<typename T, typename DESCRIPTOR, typename MOMENTA>
171 Cell<T,DESCRIPTOR>& cell,
172 T turbulenceInt, T CharU )
173{
176
177 T mean = 0.;
178 T TKE_ini = 1.5*turbulenceInt*turbulenceInt*charU*charU;
179 T velStDev = util::sqrt(2./3.*TKE_ini);
180 static double n2 = 0.0;
181 static int n2_cached = 0;
182 if (!n2_cached) {
183 double x, y, r;
184 do {
185 x = 2.0*rand()/RAND_MAX - 1;
186 y = 2.0*rand()/RAND_MAX - 1;
187
188 r = x*x + y*y;
189 }
190 while ( util::nearZero(r) || r > 1.0);
191 {
192 double d = util::sqrt(-2.0*util::log(r)/r);
193 double n1 = x*d;
194 n2 = y*d;
195 double result = n1*velStDev + mean;
196 n2_cached = 1;
197 return result;
198 }
199 }
200 else {
201 n2_cached = 0;
202 return n2*velStDev + mean;
203 }
204}
205
206
208template<typename T, typename DESCRIPTOR, typename MOMENTA>
210 Cell<T,DESCRIPTOR>& cell,
211 T drift, T result)
212{
214 T sigma = 2.3;
215 X_lang_n *=drift;
216
217 X_lang_n += sigma*util::sqrt(drift*2)*result;
218
219 return X_lang_n;
220
221
222}
224
225// template<typename T, typename DESCRIPTOR>
226// void StochasticSGSdynamics<T,DESCRIPTOR>::setRandomWalk(
227// Cell<T,DESCRIPTOR>& cell,
228// T CharU, T drift, T result )
229// {
230// /// initialisation of model standard variation, see Pope pp 484
231// T X_lang_n = getRandomWalk(cell, CharU, drift, result);
232// }
233
234
235// /// get time sclae
236template<typename T, typename DESCRIPTOR, typename MOMENTA>
238 T preFactor, T rho, T pi[util::TensorVal<DESCRIPTOR >::n], T smagoConst, T X_lang_n )
239{
240 T Const = 0.2;
241 T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
243 PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
244 }
245 T PiNeqNorm = util::sqrt(PiNeqNormSqr);
246
248 // for post processing this has to be evaluated seperately with S_ij³
249 T diss_corr = smagoConst*smagoConst*PiNeqNorm*PiNeqNorm*PiNeqNorm*(1+ X_lang_n);
250
251 T tau= Const*util::pow(( 1. / diss_corr ), 1./3.);
252 T drift = 1./tau;
254 return drift;
255
256}
257
258
259// // // /// set timescale
260// template<typename T, typename DESCRIPTOR>
261// void StochasticSGSdynamics<T,DESCRIPTOR>::setTimeScale(
262// T preFactor, T rho, T pi[util::TensorVal<DESCRIPTOR >::n], T smagoConst, T X_lang_n)
263// {
264// T drift = computeTimeScale(preFactor, rho, pi, smagoConst, X_lang_n);
265// }
266
267
268template<typename T, typename DESCRIPTOR, typename MOMENTA>
269T StochasticSGSdynamics<T,DESCRIPTOR,MOMENTA>::computePreFactor(T omega, T smagoConst)
270{
271 return (T)smagoConst*smagoConst*descriptors::invCs2<T,DESCRIPTOR>()*descriptors::invCs2<T,DESCRIPTOR>()*2*util::sqrt(2);
272}
273
274template<typename T, typename DESCRIPTOR, typename MOMENTA>
275T StochasticSGSdynamics<T,DESCRIPTOR,MOMENTA>::computeOmega(T omega0, T preFactor, T rho, T pi[util::TensorVal<DESCRIPTOR >::n], T X_lang_n)
276{
277 T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
279 PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
280 }
281 T PiNeqNorm = util::sqrt(PiNeqNormSqr);
283 T tau_mol = 1. /omega0;
285 T tau_turb = 0.5*(util::sqrt(tau_mol*tau_mol+(preFactor*tau_eff*PiNeqNorm*(1+X_lang_n)))-tau_mol);
287 tau_eff = tau_mol+tau_turb;
288 T omega_new= 1./tau_eff;
289 return omega_new;
290}
291
292}
293
294#endif
Definition of a LB cell – header file.
Highest-level interface to Cell data.
Definition cell.h:148
void incrementStats(T rho, T uSqr)
Implementation of the MRT collision step with stochastic relaxation based on " A stochastic subgrid m...
virtual T getRandomWalk(Cell< T, DESCRIPTOR > &cell_, T drift_, T result_)
Get local Random number of BoxMüllertransform -> returns randBM.
virtual T getSmagorinskyOmega(Cell< T, DESCRIPTOR > &cell_, T X_lang_n_)
Get local smagorinsky relaxation parameter of the dynamics.
virtual CellStatistic< T > collide(Cell< T, DESCRIPTOR > &cell, LatticeStatistics< T > &statistics_)
virtual void setOmega(T omega_)
Set local relaxation parameter of the dynamics.
virtual T getRandBMTrans(Cell< T, DESCRIPTOR > &cell_, T turbulenceInt_, T charU_)
Get local Random number of BoxMüllertransform -> returns randBM.
StochasticSGSdynamics(T omega_, T turbulenceInt_, T charU_, T smagoConst_, T dx_=1, T dt_=1)
Constructor.
This object is a MRT LB dynamics as described in D.Yu et al.
Helper functions for the implementation of LB dynamics.
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
ADf< T, DIM > log(const ADf< T, DIM > &a)
Definition aDiff.h:475
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
bool nearZero(const ADf< T, DIM > &a)
Definition aDiff.h:1087
Top level namespace for all of OpenLB.
MRT Dynamics with adjusted omega – header file.
Return value of any collision.
Definition interface.h:43
Dynamics constructed as a tuple of momenta, equilibrium and collision.
Definition interface.h:182
static V mrtSGSCollision(CELL &cell, const RHO &rho, const U &u, const OMEGA &omega, const INVM_S_SGS &invM_S_SGS)
MRT SGS collision step.
Definition mrt.h:111
Compute number of elements of a symmetric d-dimensional tensor.
Definition util.h:210
static constexpr int n
result stored in n
Definition util.h:211
Set of functions commonly used in LB computations – header file.