OpenLB 1.7
Loading...
Searching...
No Matches
navierStokesAdvectionDiffusionCouplingPostProcessor2D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2008 Orestis Malaspinas, Andrea Parmigiani, 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
24#ifndef NAVIER_STOKES_ADVECTION_DIFFUSION_COUPLING_POST_PROCESSOR_2D_HH
25#define NAVIER_STOKES_ADVECTION_DIFFUSION_COUPLING_POST_PROCESSOR_2D_HH
26
27#include "latticeDescriptors.h"
29#include "core/util.h"
31
32
33namespace olb {
34
35//=====================================================================================
36//============== TotalEnthalpyPhaseChangeCouplingPostProcessor2D ===============
37//=====================================================================================
38
39template<typename T, typename DESCRIPTOR, typename DYNAMICS>
41TotalEnthalpyPhaseChangeCouplingPostProcessor2D(int x0_, int x1_, int y0_, int y1_,
42 T gravity_, T T0_, T deltaTemp_, std::vector<T> dir_,
43 std::vector<BlockStructureD<2>* > partners_)
44 : x0(x0_), x1(x1_), y0(y0_), y1(y1_),
45 gravity(gravity_), T0(T0_), deltaTemp(deltaTemp_),
46 dir(dir_), partners(partners_)
47{
48 this->getName() = "TotalEnthalpyPhaseChangeCouplingPostProcessor2D";
49 // we normalize the direction of force vector
50 T normDir = T();
51 for (unsigned iD = 0; iD < dir.size(); ++iD) {
52 normDir += dir[iD]*dir[iD];
53 }
54 normDir = util::sqrt(normDir);
55 for (unsigned iD = 0; iD < dir.size(); ++iD) {
56 dir[iD] /= normDir;
57 }
58
59 for (unsigned iD = 0; iD < dir.size(); ++iD) {
60 forcePrefactor[iD] = gravity * dir[iD];
61 }
62
64}
65
66template<typename T, typename DESCRIPTOR, typename DYNAMICS>
69 int x0_, int x1_, int y0_, int y1_)
70{
71
72 int newX0, newX1, newY0, newY1;
73 if ( util::intersect (
74 x0, x1, y0, y1,
75 x0_, x1_, y0_, y1_,
76 newX0, newX1, newY0, newY1 ) ) {
77 auto* dynamics = static_cast<DYNAMICS*>(tPartner->template getDynamics<DYNAMICS>());
78 auto& parameters = static_cast<ParametersOfDynamicsD<DYNAMICS>&>(
79 tPartner->template getData<OperatorParameters<DYNAMICS>>());
80
81 for (int iX=newX0; iX<=newX1; ++iX) {
82 for (int iY=newY0; iY<=newY1; ++iY) {
83 auto cell = blockLattice.get(iX,iY);
84 auto partnerCell = tPartner->get(iX,iY);
85
86 T enthalpy = partnerCell.computeRho();
87
88 cell.template setField<descriptors::POROSITY>(
89 dynamics->template computeLiquidFraction<T>(parameters, enthalpy));
90 auto temperature = partnerCell.template getFieldPointer<descriptors::TEMPERATURE>();
91 temperature[0] = dynamics->template computeTemperature<T>(parameters, enthalpy);
92
93 // computation of the bousinessq force
94 auto force = cell.template getFieldPointer<descriptors::FORCE>();
95 T temperatureDifference = temperature[0] - T0;
96 for (unsigned iD = 0; iD < L::d; ++iD) {
97 force[iD] = forcePrefactor[iD] * temperatureDifference;
98 }
99 // Velocity coupling
100 T u[DESCRIPTOR::d] { };
101 cell.computeU(u);
102 partnerCell.template setField<descriptors::VELOCITY>(u);
103 }
104 }
105 }
106}
107
108template<typename T, typename DESCRIPTOR, typename DYNAMICS>
111{
112 processSubDomain(blockLattice, x0, x1, y0, y1);
113}
114
116
117template<typename T, typename DESCRIPTOR, typename DYNAMICS>
119TotalEnthalpyPhaseChangeCouplingGenerator2D(int x0_, int x1_, int y0_, int y1_,
120 T gravity_, T T0_, T deltaTemp_, std::vector<T> dir_)
121 : LatticeCouplingGenerator2D<T,DESCRIPTOR>(x0_, x1_, y0_, y1_),
122 gravity(gravity_), T0(T0_), deltaTemp(deltaTemp_), dir(dir_)
123{ }
124
125template<typename T, typename DESCRIPTOR, typename DYNAMICS>
127 std::vector<BlockStructureD<2>* > partners) const
128{
130 this->x0,this->x1,this->y0,this->y1, gravity, T0, deltaTemp, dir,partners);
131}
132
133template<typename T, typename DESCRIPTOR, typename DYNAMICS>
138
139
140//=====================================================================================
141//============== PhaseFieldCouplingPostProcessor2D ===============
142//=====================================================================================
143
144template<typename T, typename DESCRIPTOR>
146PhaseFieldCouplingPostProcessor2D(int x0_, int x1_, int y0_, int y1_,
147 T rho_L, T rho_H, T mu_L, T mu_H, T surface_tension, T interface_thickness,
148 std::vector<BlockStructureD<2>* > partners_)
149 : x0(x0_), x1(x1_), y0(y0_), y1(y1_),
150 _rho_L(rho_L), _rho_H(rho_H), _delta_rho(rho_H - rho_L), _mu_L(mu_L), _mu_H(mu_H), _surface_tension(surface_tension), _interface_thickness(interface_thickness),
151 _beta(12.0 * surface_tension / interface_thickness), _kappa(1.5 * surface_tension * interface_thickness)
152{
153 this->getName() = "PhaseFieldCouplingPostProcessor2D";
155}
156
157template<typename T, typename DESCRIPTOR>
160 int x0_, int x1_, int y0_, int y1_)
161{
162
163 int newX0, newX1, newY0, newY1;
164 if ( util::intersect ( x0, x1, y0, y1,
165 x0_, x1_, y0_, y1_,
166 newX0, newX1, newY0, newY1 ) ) {
167
168 // generate phi cache
169 auto& phi_cache = blockLattice.template getField<PHI_CACHE>()[0];
170 for (int iX=newX0-1; iX<=newX1+1; ++iX) {
171 for (int iY=newY0-1; iY<=newY1+1; ++iY) {
172 phi_cache[blockLattice.getCellId(iX,iY)] = util::max(util::min(tPartner->get(iX,iY).computeRho(), 1.0), 0.0);
173 }
174 }
175
176 for (int iX=newX0; iX<=newX1; ++iX) {
177 for (int iY=newY0; iY<=newY1; ++iY) {
178 auto cell = blockLattice.get(iX,iY);
179 auto partnerCell = tPartner->get(iX,iY);
180
181 T phi = phi_cache[blockLattice.getCellId(iX,iY)];
182
183 // compute rho from phi
184 T rho = _rho_L + phi * _delta_rho;
185
186 // compute dynamic viscosity
187 T viscosity = _mu_L + phi * (_mu_H - _mu_L);
188
189 // get relaxation time
190 T tau = cell.template getField<descriptors::TAU_EFF>();
191
192 // compute grad phi and laplace phi
193 Vector<T,L::d> grad_phi(0.0, 0.0);
194 T laplace_phi = 0.0;
195 for (int iPop = 1; iPop < L::q; ++iPop) {
196 int nextX = iX + descriptors::c<L>(iPop,0);
197 int nextY = iY + descriptors::c<L>(iPop,1);
198 T neighbor_phi = phi_cache[blockLattice.getCellId(nextX,nextY)];
199
200 laplace_phi += (neighbor_phi - phi) * descriptors::t<T,L>(iPop);
201
202 neighbor_phi *= descriptors::t<T,L>(iPop);
203 grad_phi += neighbor_phi * descriptors::c<L>(iPop);
204 }
205 grad_phi *= descriptors::invCs2<T,L>();
206 laplace_phi *= 2.0 * descriptors::invCs2<T,L>();
207
208 // compute grad rho
209 Vector<T,L::d> grad_rho(_delta_rho, _delta_rho);
210 grad_rho *= grad_phi;
211
212 // compute interphase normal, save to external field
213 T norm_grad_phi = norm(grad_phi);
214 norm_grad_phi = util::max(norm_grad_phi, std::numeric_limits<T>::epsilon());
215 partnerCell.template setField<descriptors::INTERPHASE_NORMAL>(grad_phi / norm_grad_phi);
216
217 // compute forces (F_s, F_b, F_p, F_nu)
218 // F_s (surface tension)
219 T chemical_potential = (4.0 * _beta * (phi - 0.0) * (phi - 0.5) * (phi - 1.0)) - _kappa * laplace_phi;
220 T surface_tension_force[] = {chemical_potential*grad_phi[0], chemical_potential*grad_phi[1]};
221
222 // F_b (body force, e.g. bouyancy)
223 T body_force[] = {0.0, 0.0};
224
225 // F_p (pressure)
226 T pressure = blockLattice.get(iX,iY).computeRho();
227 T pressure_force[] = {-pressure / descriptors::invCs2<T,L>() * grad_rho[0], -pressure / descriptors::invCs2<T,L>() * grad_rho[1]};
228
229 // F_nu (viscous)
230 T viscous_force[] = {0.0, 0.0};
231 T rho_tmp, u_tmp[2];
232 cell.computeRhoU( rho_tmp, u_tmp );
233 T p_tmp = rho_tmp / descriptors::invCs2<T,DESCRIPTOR>();
234 T uSqr_tmp = util::normSqr<T,DESCRIPTOR::d>(u_tmp);
235 for (int iPop = 0; iPop < L::q; ++iPop) {
236 T fEq = cell.getDynamics()->computeEquilibrium( iPop, p_tmp, u_tmp);
237 T fNeq = cell[iPop] - fEq;
238 for (int iD = 0; iD < L::d; ++iD) {
239 for (int jD = 0; jD < L::d; ++jD) {
240 viscous_force[iD] += descriptors::c<L>(iPop,iD) * descriptors::c<L>(iPop,jD) * fNeq * grad_rho[jD];
241 }
242 }
243 }
244 for (int iD = 0; iD < L::d; ++iD) {
245 viscous_force[iD] *= - viscosity / rho / tau * descriptors::invCs2<T,L>();
246 }
247
248 // save force/rho to external field
249 auto force = cell.template getFieldPointer<descriptors::FORCE>();
250 for (int iD = 0; iD < L::d; ++iD) {
251 force[iD] = (surface_tension_force[iD] + body_force[iD] + pressure_force[iD] + viscous_force[iD]) / rho;
252 }
253
254 // compute u, save to external field
256 cell.computeU(u.data());
257 partnerCell.template setField<descriptors::VELOCITY>(u);
258
259 // compute relaxation time, save to external field
260
261 tau = viscosity / rho * descriptors::invCs2<T,L>() + 0.5;
262 cell.template setField<descriptors::TAU_EFF>(tau);
263 }
264 }
265 }
266}
267
268template<typename T, typename DESCRIPTOR>
271{
272 processSubDomain(blockLattice, x0, x1, y0, y1);
273}
274
276
277template<typename T, typename DESCRIPTOR>
279PhaseFieldCouplingGenerator2D(int x0_, int x1_, int y0_, int y1_,
280 T rho_L, T rho_H, T mu_L, T mu_H, T surface_tension, T interface_thickness)
281 : LatticeCouplingGenerator2D<T,DESCRIPTOR>(x0_, x1_, y0_, y1_),
282 _rho_L(rho_L), _rho_H(rho_H), _mu_L(mu_L), _mu_H(mu_H), _surface_tension(surface_tension), _interface_thickness(interface_thickness)
283{ }
284
285template<typename T, typename DESCRIPTOR>
287 std::vector<BlockStructureD<2>* > partners) const
288{
290 this->x0,this->x1,this->y0,this->y1, _rho_L, _rho_H, _mu_L, _mu_H, _surface_tension, _interface_thickness, partners);
291}
292
293template<typename T, typename DESCRIPTOR>
298
299
300//=====================================================================================
301//============== SmagorinskyBoussinesqCouplingPostProcessor2D ===============
302//=====================================================================================
303
304template<typename T, typename DESCRIPTOR>
306SmagorinskyBoussinesqCouplingPostProcessor2D(int x0_, int x1_, int y0_, int y1_,
307 T gravity_, T T0_, T deltaTemp_, std::vector<T> dir_, T PrTurb_, T smagoPrefactor_,
308 std::vector<BlockStructureD<2>* > partners_)
309 : x0(x0_), x1(x1_), y0(y0_), y1(y1_),
310 gravity(gravity_), T0(T0_), deltaTemp(deltaTemp_),
311 dir(dir_), PrTurb(PrTurb_), smagoPrefactor(smagoPrefactor_), partners(partners_)
312{
313 this->getName() = "SmagorinskyBoussinesqCouplingPostProcessor2D";
314 // we normalize the direction of force vector
315 T normDir = T();
316 for (unsigned iD = 0; iD < dir.size(); ++iD) {
317 normDir += dir[iD]*dir[iD];
318 }
319 normDir = util::sqrt(normDir);
320 for (unsigned iD = 0; iD < dir.size(); ++iD) {
321 dir[iD] /= normDir;
322 }
323
324 for (unsigned iD = 0; iD < dir.size(); ++iD) {
325 forcePrefactor[iD] = gravity * dir[iD];
326 }
327
328 tauTurbADPrefactor = descriptors::invCs2<T,descriptors::D2Q5<descriptors::VELOCITY,descriptors::TAU_EFF>>() / descriptors::invCs2<T,DESCRIPTOR>() / PrTurb;
330}
331
332template<typename T, typename DESCRIPTOR>
335 int x0_, int x1_, int y0_, int y1_)
336{
337
338 int newX0, newX1, newY0, newY1;
339 if ( util::intersect (
340 x0, x1, y0, y1,
341 x0_, x1_, y0_, y1_,
342 newX0, newX1, newY0, newY1 ) ) {
343
344 for (int iX=newX0; iX<=newX1; ++iX) {
345 for (int iY=newY0; iY<=newY1; ++iY) {
346
347 // computation of the bousinessq force
348 auto force = blockLattice.get(iX,iY).template getFieldPointer<descriptors::FORCE>();
349 T temperatureDifference = tPartner->get(iX,iY).computeRho() - T0;
350 for (unsigned iD = 0; iD < L::d; ++iD) {
351 force[iD] = forcePrefactor[iD] * temperatureDifference;
352 }
353
354 // Velocity coupling
355 auto u = tPartner->get(iX,iY).template getField<descriptors::VELOCITY>();
356 // tau coupling
357 auto tauNS = blockLattice.get(iX,iY).template getFieldPointer<descriptors::TAU_EFF>();
358 auto tauAD = tPartner->get(iX,iY).template getFieldPointer<descriptors::TAU_EFF>();
359
361 blockLattice.get(iX,iY).computeAllMomenta(rho, u.data(), pi);
362 tPartner->get(iX,iY).template setField<descriptors::VELOCITY>(u);
363 T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
365 PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
366 }
367 T PiNeqNorm = util::sqrt(PiNeqNormSqr);
369 T tau_mol_NS = 1. / blockLattice.get(iX,iY).getDynamics()->getParameters(blockLattice).template getOrFallback<descriptors::OMEGA>(0);
370 T tau_mol_AD = 1. / tPartner->get(iX,iY).getDynamics()->getParameters(*tPartner).template getOrFallback<descriptors::OMEGA>(0);
372 T tau_turb_NS = 0.5*(util::sqrt(tau_mol_NS*tau_mol_NS + smagoPrefactor/rho*PiNeqNorm) - tau_mol_NS);
374 tauNS[0] = tau_mol_NS+tau_turb_NS;
375
376 T tau_turb_AD = tau_turb_NS * tauTurbADPrefactor;
377 tauAD[0] = tau_mol_AD+tau_turb_AD;
378 }
379 }
380 }
381
382}
383
384template<typename T, typename DESCRIPTOR>
387{
388 processSubDomain(blockLattice, x0, x1, y0, y1);
389}
390
392
393template<typename T, typename DESCRIPTOR>
395SmagorinskyBoussinesqCouplingGenerator2D(int x0_, int x1_, int y0_, int y1_,
396 T gravity_, T T0_, T deltaTemp_, std::vector<T> dir_, T PrTurb_, T smagoPrefactor_)
397 : LatticeCouplingGenerator2D<T,DESCRIPTOR>(x0_, x1_, y0_, y1_),
398 gravity(gravity_), T0(T0_), deltaTemp(deltaTemp_), dir(dir_), PrTurb(PrTurb_), smagoPrefactor(smagoPrefactor_)
399{ }
400
401template<typename T, typename DESCRIPTOR>
403 std::vector<BlockStructureD<2>* > partners) const
404{
406 this->x0,this->x1,this->y0,this->y1, gravity, T0, deltaTemp, dir, PrTurb, smagoPrefactor, partners);
407}
408
409template<typename T, typename DESCRIPTOR>
414
415
416//=====================================================================================
417//============== MixedScaleBoussinesqCouplingPostProcessor2D ===============
418//=====================================================================================
419
420template<typename T, typename DESCRIPTOR>
422MixedScaleBoussinesqCouplingPostProcessor2D(int x0_, int x1_, int y0_, int y1_,
423 T gravity_, T T0_, T deltaTemp_, std::vector<T> dir_, T PrTurb_,
424 std::vector<BlockStructureD<2>* > partners_)
425 : x0(x0_), x1(x1_), y0(y0_), y1(y1_),
426 gravity(gravity_), T0(T0_), deltaTemp(deltaTemp_),
427 dir(dir_), PrTurb(PrTurb_), partners(partners_)
428{
429 // we normalize the direction of force vector
430 T normDir = T();
431 for (unsigned iD = 0; iD < dir.size(); ++iD) {
432 normDir += dir[iD]*dir[iD];
433 }
434 normDir = util::sqrt(normDir);
435 for (unsigned iD = 0; iD < dir.size(); ++iD) {
436 dir[iD] /= normDir;
437 }
438
439 for (unsigned iD = 0; iD < dir.size(); ++iD) {
440 forcePrefactor[iD] = gravity * dir[iD];
441 }
442
443 tauTurbADPrefactor = descriptors::invCs2<T,descriptors::D2Q5<descriptors::VELOCITY,descriptors::TAU_EFF,descriptors::CUTOFF_HEAT_FLUX>>() / descriptors::invCs2<T,DESCRIPTOR>() / PrTurb;
445}
446
447template<typename T, typename DESCRIPTOR>
450 int x0_, int x1_, int y0_, int y1_)
451{
452
453 const T C_nu = 0.04;
454 const T C_alpha = 0.5;
455 const T deltaT = 1.0;
456
457 const T invCs2_g = descriptors::invCs2<T,descriptors::D2Q5<descriptors::VELOCITY,descriptors::TAU_EFF,descriptors::CUTOFF_HEAT_FLUX>>();
458
459 int newX0, newX1, newY0, newY1;
460 if ( util::intersect (
461 x0, x1, y0, y1,
462 x0_, x1_, y0_, y1_,
463 newX0, newX1, newY0, newY1 ) ) {
464
465 auto& heatFluxCache = blockLattice.template getField<HEAT_FLUX_CACHE>()[0];
466 for (int iX=newX0-1; iX<=newX1+1; ++iX) {
467 for (int iY=newY0-1; iY<=newY1+1; ++iY) {
468 const T temperature = tPartner->get(iX,iY).computeRho();
469 heatFluxCache[blockLattice.getCellId(iX, iY)] = temperature;
470
471 // computation of the bousinessq force
472 T temperatureDifference = temperature - T0;
473 blockLattice.get(iX,iY).template setField<descriptors::FORCE>(temperatureDifference*forcePrefactor);
474
476 blockLattice.get(iX,iY).computeU(u.data());
477 tPartner->get(iX,iY).template setField<descriptors::VELOCITY>(u);
478 }
479 }
480
481 for (int iX=newX0; iX<=newX1; ++iX) {
482 for (int iY=newY0; iY<=newY1; ++iY) {
483
484 auto u_pp = tPartner->get(iX+1, iY+1).template getField<descriptors::VELOCITY>();
485 auto u_0p = tPartner->get(iX, iY+1).template getField<descriptors::VELOCITY>();
486 auto u_np = tPartner->get(iX-1, iY+1).template getField<descriptors::VELOCITY>();
487 auto u_p0 = tPartner->get(iX+1, iY ).template getField<descriptors::VELOCITY>();
488 auto u_pn = tPartner->get(iX+1, iY-1).template getField<descriptors::VELOCITY>();
489 auto u_00 = tPartner->get(iX, iY ).template getField<descriptors::VELOCITY>();
490 auto u_0n = tPartner->get(iX, iY-1).template getField<descriptors::VELOCITY>();
491 auto u_n0 = tPartner->get(iX-1, iY ).template getField<descriptors::VELOCITY>();
492 auto u_nn = tPartner->get(iX-1, iY-1).template getField<descriptors::VELOCITY>();
493
494 const T *h_pp = & heatFluxCache[blockLattice.getCellId(iX+1, iY+1)];
495 const T *h_0p = & heatFluxCache[blockLattice.getCellId(iX, iY+1)];
496 const T *h_np = & heatFluxCache[blockLattice.getCellId(iX-1, iY+1)];
497 const T *h_p0 = & heatFluxCache[blockLattice.getCellId(iX+1, iY )];
498 const T *h_pn = & heatFluxCache[blockLattice.getCellId(iX+1, iY-1)];
499 const T *h_00 = & heatFluxCache[blockLattice.getCellId(iX, iY )];
500 const T *h_0n = & heatFluxCache[blockLattice.getCellId(iX, iY-1)];
501 const T *h_n0 = & heatFluxCache[blockLattice.getCellId(iX-1, iY )];
502 const T *h_nn = & heatFluxCache[blockLattice.getCellId(iX-1, iY-1)];
503
504 Vector<T, 2> filtered_u;
505 T filtered_h;
506 filtered_h =((h_pp[0] + 2.*h_0p[0] + h_np[0])
507 + 2.*(h_p0[0] + 2.*h_00[0] + h_n0[0])
508 + (h_pn[0] + 2.*h_0n[0] + h_nn[0]))*0.25*0.25;
509
510 filtered_u =((u_pp + 2.*u_0p + u_np)
511 + 2.*(u_p0 + 2.*u_00 + u_n0)
512 + (u_pn + 2.*u_0n + u_nn))*0.25*0.25;
513
514 Vector<T,2> filtered_u_reduced = u_00 - filtered_u;
515 Vector<T,2> filtered_heatFlux_reduced = h_00[0]*u_00 - filtered_h*filtered_u;
516
517 T cutoffKinEnergy = filtered_u_reduced[0]*filtered_u_reduced[0]
518 + filtered_u_reduced[1]*filtered_u_reduced[1];
519 T cutoffHeatFlux = filtered_heatFlux_reduced[0]*filtered_heatFlux_reduced[0]
520 + filtered_heatFlux_reduced[1]*filtered_heatFlux_reduced[1];
521
522 blockLattice.get(iX,iY).template setField<descriptors::CUTOFF_KIN_ENERGY>(util::pow(0.5*cutoffKinEnergy, 0.25));
523 tPartner->get(iX,iY).template setField<descriptors::CUTOFF_HEAT_FLUX>(util::pow(0.5*cutoffHeatFlux, 0.25));
524 // cout << cutoffKinEnergy << " " << u_00[0] << " " << u_00[1] << " " << cutoffKinEnergy_14[0] << std::endl;
525
526 // tau coupling
527 auto tauNS = blockLattice.get(iX,iY).template getField<descriptors::TAU_EFF>();
528 auto tauAD = tPartner->get(iX,iY).template getField<descriptors::TAU_EFF>();
529
531 T tau_mol_NS = 1. / blockLattice.get(iX,iY).getDynamics()->getParameters(blockLattice).template getOrFallback<descriptors::OMEGA>(0);
532 T tau_mol_AD = 1. / tPartner->get(iX,iY).getDynamics()->getParameters(*tPartner).template getOrFallback<descriptors::OMEGA>(0);
533
534 const T temperature = tPartner->get(iX,iY).computeRho();
535
536 // computation of the bousinessq force
537 T temperatureDifference = temperature - T0;
538 blockLattice.get(iX,iY).template
539 setField<descriptors::FORCE>(temperatureDifference*forcePrefactor);
540
541 auto u = tPartner->get(iX,iY).template getField<descriptors::VELOCITY>();
542 T rho, pi[util::TensorVal<DESCRIPTOR>::n], j[DESCRIPTOR::d];
543 // blockLattice.get(iX,iY).computeAllMomenta(rho, u, pi);
544 rho = blockLattice.get(iX,iY).computeRho();
545 blockLattice.get(iX,iY).computeStress(pi);
546
547 auto force = blockLattice.get(iX,iY).template getField<descriptors::FORCE>();
548
549 int iPi = 0;
550 for (int Alpha=0; Alpha<DESCRIPTOR::d; ++Alpha) {
551 for (int Beta=Alpha; Beta<DESCRIPTOR::d; ++Beta) {
552 pi[iPi] += rho/2.*(force[Alpha]*u[Beta] + u[Alpha]*force[Beta]);
553 ++iPi;
554 }
555 }
556 const Vector<T,3> piSqr = {pi[0]*pi[0], pi[1]*pi[1], pi[2]*pi[2]};
557 const T PiNeqNormSqr = piSqr[0] + 2.0*piSqr[1] + piSqr[2];
558 const T PiNeqNorm = util::sqrt(PiNeqNormSqr);
559
560 tPartner->get(iX,iY).computeJ(j);
561 const T tmp_preFactor = invCs2_g / rho / tauAD;
562 const Vector<T,2> jNeq = {(j[0] - temperature * u[0]), (j[1] - temperature * u[1])};
563 const Vector<T,2> jNeqSqr = {jNeq[0]*jNeq[0], jNeq[1]*jNeq[1]};
564 const T jNeqSqr_prefacor = 2. * 0.25 * (jNeq[0] + jNeq[1]) * (jNeq[0] + jNeq[1]);
565
566 const T TnormSqr = jNeqSqr_prefacor*PiNeqNormSqr;
567 const T Tnorm = util::sqrt(TnormSqr);
568
570 // T tau_turb_NS = 0.5*(util::sqrt(tau_mol_NS*tau_mol_NS + dynamic_cast<SmagorinskyDynamics<T,DESCRIPTOR>*>(blockLattice.get(iX,iY).getDynamics())->getPreFactor()/rho*PiNeqNorm) - tau_mol_NS);
571
572 // const T tmp_A = C_nu * util::sqrt(util::sqrt(2.)/2.) * descriptors::invCs2<T,DESCRIPTOR>() * descriptors::invCs2<T,DESCRIPTOR>() * util::sqrt(PiNeqNorm / rho) * cutoffKinEnergy_14[0];
573 // const T tmp_A_2 = tmp_A * tmp_A;
574 // const T tmp_A_4 = tmp_A_2 * tmp_A_2;
575
576 // const T tau_mol_NS_2 = tau_mol_NS * tau_mol_NS;
577 // const T tau_mol_NS_3 = tau_mol_NS_2 * tau_mol_NS;
578
579 // const T tmp_1_3 = 1./3.;
580 // const T tmp_2_13 = util::pow(2., tmp_1_3);
581 // const T tmp_3_3_12 = 3. * util::sqrt(3.);
582
583 // const T tmp_sqrtA = util::sqrt(27.*tmp_A_4-4.*tmp_A_2*tau_mol_NS_3);
584
585 // // T tau_turb_NS = 1/3 ((27 A^2 + 3 util::sqrt(3) util::sqrt(27 A^4 - 4 A^2 b^3) - 2 b^3)^(1/3)/2^(1/3) + (2^(1/3) b^2)/(27 A^2 + 3 util::sqrt(3) util::sqrt(27 A^4 - 4 A^2 b^3) - 2 b^3)^(1/3) - b)
586 // T tau_turb_NS = ( util::pow(27.*tmp_A_2 + tmp_3_3_12*util::sqrt(27.*tmp_A_4-4.*tmp_A_2*tau_mol_NS_3)-2.*tau_mol_NS_3, tmp_1_3) / tmp_2_13
587 // + (tmp_2_13*tau_mol_NS_2) / util::pow(27.*tmp_A_2+tmp_3_3_12*util::sqrt(27.*tmp_A_4-4.*tmp_A_2*tau_mol_NS_3) - 2.*tau_mol_NS_3, tmp_1_3)
588 // - tau_mol_NS
589 // ) * tmp_1_3;
590
591 // if ( tau_turb_NS != tau_turb_NS )
592 // tau_turb_NS = 0.;
593
594 //cout << tau_turb_NS << " " << 27. * tmp_A_2 << " " << 4. * tau_mol_NS_3 << " " << PiNeqNorm << " " << " " << rho << std::endl;
595
596 auto cutoffKinEnergy_14 = blockLattice.get(iX,iY).template getField<descriptors::CUTOFF_KIN_ENERGY>();
597 auto cutoffHeatFlux_14 = tPartner->get(iX,iY).template getField<descriptors::CUTOFF_HEAT_FLUX>();
598
599 const T tmp_A = C_nu * util::sqrt(util::sqrt(2.)/2.) * descriptors::invCs2<T,DESCRIPTOR>() * descriptors::invCs2<T,DESCRIPTOR>() * util::sqrt(PiNeqNorm / rho / tauNS) * cutoffKinEnergy_14;
600 const T tau_turb_NS = tmp_A;
601
602 // T tau_turb_AD = tau_turb_NS * tauTurbADPrefactor;
603 const T tmp_B = C_alpha * descriptors::invCs2<T,DESCRIPTOR>() / rho * util::sqrt(2.0 * Tnorm * invCs2_g / tauNS / tauAD) * cutoffHeatFlux_14;
604 const T tau_turb_AD = tmp_B;
605 // cout << jNeq[0] << " " << jNeq[1] << " " << util::sqrt(Tnorm * invCs2_g / tauNS / tauAD) << " " << TnormSqr << std::endl;
606
608 blockLattice.get(iX,iY).template setField<descriptors::TAU_EFF>(tau_mol_NS+tau_turb_NS);
609 tPartner->get(iX,iY).template setField<descriptors::TAU_EFF>(tau_mol_AD+tau_turb_AD);
610
611 }
612 }
613 }
614
615}
616
617template<typename T, typename DESCRIPTOR>
620{
621 processSubDomain(blockLattice, x0, x1, y0, y1);
622}
623
625
626template<typename T, typename DESCRIPTOR>
628MixedScaleBoussinesqCouplingGenerator2D(int x0_, int x1_, int y0_, int y1_,
629 T gravity_, T T0_, T deltaTemp_, std::vector<T> dir_, T PrTurb_)
630 : LatticeCouplingGenerator2D<T,DESCRIPTOR>(x0_, x1_, y0_, y1_),
631 gravity(gravity_), T0(T0_), deltaTemp(deltaTemp_), dir(dir_), PrTurb(PrTurb_)
632{ }
633
634template<typename T, typename DESCRIPTOR>
636 std::vector<BlockStructureD<2>* > partners) const
637{
639 this->x0,this->x1,this->y0,this->y1, gravity, T0, deltaTemp, dir, PrTurb, partners);
640}
641
642template<typename T, typename DESCRIPTOR>
647
648} // namespace olb
649
650#endif
Platform-abstracted block lattice for external access and inter-block interaction.
Cell< T, DESCRIPTOR > get(CellID iCell)
Get Cell interface for index iCell.
Base of a regular block.
CellID getCellId(LatticeR< D > latticeR) const
Get 1D cell ID.
MixedScaleBoussinesqCouplingGenerator2D(int x0_, int x1_, int y0_, int y1_, T gravity_, T T0_, T deltaTemp_, std::vector< T > dir_, T PrTurb_)
LatticeCouplingGenerator for advectionDiffusion coupling.
PostProcessor2D< T, DESCRIPTOR > * generate(std::vector< BlockStructureD< 2 > * > partners) const override
LatticeCouplingGenerator2D< T, DESCRIPTOR > * clone() const override
MixedScaleBoussinesqCouplingPostProcessor2D(int x0_, int x1_, int y0_, int y1_, T gravity_, T T0_, T deltaTemp_, std::vector< T > dir_, T PrTurb_, std::vector< BlockStructureD< 2 > * > partners_)
void processSubDomain(BlockLattice< T, DESCRIPTOR > &blockLattice, int x0_, int x1_, int y0_, int y1_) override
Execute post-processing step on a sublattice.
void process(BlockLattice< T, DESCRIPTOR > &blockLattice) override
Execute post-processing step.
PostProcessor2D< T, DESCRIPTOR > * generate(std::vector< BlockStructureD< 2 > * > partners) const override
LatticeCouplingGenerator2D< T, DESCRIPTOR > * clone() const override
PhaseFieldCouplingGenerator2D(int x0_, int x1_, int y0_, int y1_, T rho_L, T rho_H, T mu_L, T mu_H, T surface_tension, T interface_thickness)
LatticeCouplingGenerator for advectionDiffusion coupling.
void process(BlockLattice< T, DESCRIPTOR > &blockLattice) override
Execute post-processing step.
PhaseFieldCouplingPostProcessor2D(int x0_, int x1_, int y0_, int y1_, T rho_L, T rho_H, T mu_L, T mu_H, T surface_tension, T interface_thickness, std::vector< BlockStructureD< 2 > * > partners_)
void processSubDomain(BlockLattice< T, DESCRIPTOR > &blockLattice, int x0_, int x1_, int y0_, int y1_) override
Execute post-processing step on a sublattice.
Interface of 2D post-processing steps.
std::string & getName()
read and write access to name
LatticeCouplingGenerator2D< T, DESCRIPTOR > * clone() const override
PostProcessor2D< T, DESCRIPTOR > * generate(std::vector< BlockStructureD< 2 > * > partners) const override
SmagorinskyBoussinesqCouplingGenerator2D(int x0_, int x1_, int y0_, int y1_, T gravity_, T T0_, T deltaTemp_, std::vector< T > dir_, T PrTurb_, T smagoPrefactor_)
LatticeCouplingGenerator for advectionDiffusion coupling.
SmagorinskyBoussinesqCouplingPostProcessor2D(int x0_, int x1_, int y0_, int y1_, T gravity_, T T0_, T deltaTemp_, std::vector< T > dir_, T PrTurb_, T smagoPrefactor_, std::vector< BlockStructureD< 2 > * > partners_)
void processSubDomain(BlockLattice< T, DESCRIPTOR > &blockLattice, int x0_, int x1_, int y0_, int y1_) override
Execute post-processing step on a sublattice.
void process(BlockLattice< T, DESCRIPTOR > &blockLattice) override
Execute post-processing step.
PostProcessor2D< T, DESCRIPTOR > * generate(std::vector< BlockStructureD< 2 > * > partners) const override
TotalEnthalpyPhaseChangeCouplingGenerator2D(int x0_, int x1_, int y0_, int y1_, T gravity_, T T0_, T deltaTemp_, std::vector< T > dir_)
LatticeCouplingGenerator for advectionDiffusion coupling.
LatticeCouplingGenerator2D< T, DESCRIPTOR > * clone() const override
void processSubDomain(BlockLattice< T, DESCRIPTOR > &blockLattice, int x0_, int x1_, int y0_, int y1_) override
Execute post-processing step on a sublattice.
TotalEnthalpyPhaseChangeCouplingPostProcessor2D(int x0_, int x1_, int y0_, int y1_, T gravity_, T T0_, T deltaTemp_, std::vector< T > dir_, std::vector< BlockStructureD< 2 > * > partners_)
void process(BlockLattice< T, DESCRIPTOR > &blockLattice) override
Execute post-processing step.
Plain old scalar vector.
Definition vector.h:47
constexpr const T * data() const any_platform
Definition vector.h:161
Descriptor for all types of 2D and 3D lattices.
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
cpu::simd::Pack< T > min(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
Definition pack.h:124
cpu::simd::Pack< T > max(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
Definition pack.h:130
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
bool intersect(int x0, int x1, int y0, int y1, int x0_, int x1_, int y0_, int y1_, int &newX0, int &newX1, int &newY0, int &newY1)
Definition util.h:89
Top level namespace for all of OpenLB.
constexpr T norm(const ScalarVector< T, D, IMPL > &a)
Euclidean vector norm.
typename ParametersD< typename DYNAMICS::value_t, typename DYNAMICS::descriptor_t >::template include< typename DYNAMICS::parameters > ParametersOfDynamicsD
Deduce ParametersD of DYNAMICS w.r.t. its value type and descriptor.
Compute number of elements of a symmetric d-dimensional tensor.
Definition util.h:210
Set of functions commonly used in LB computations – header file.