55 int x0_,
int x1_,
int y0_,
int y1_)
58 int newX0, newX1, newY0, newY1;
61 newX0, newX1, newY0, newY1 ) ) {
64 auto& phi_cache = blockLattice.template getField<PHI_CACHE>()[0];
65 for (
int iX=newX0-1; iX<=newX1+1; ++iX) {
66 for (
int iY=newY0-1; iY<=newY1+1; ++iY) {
67 phi_cache[blockLattice.getCellId(iX,iY)] =
util::max(
util::min(tPartner->get(iX,iY).computeRho(), 1.0), 0.0);
71 for (
int iX=newX0; iX<=newX1; ++iX) {
72 for (
int iY=newY0; iY<=newY1; ++iY) {
73 auto cell = blockLattice.get(iX,iY);
74 auto partnerCell = tPartner->get(iX,iY);
76 T phi = phi_cache[blockLattice.getCellId(iX,iY)];
79 T rho = _rho_L + phi * _delta_rho;
82 T viscosity = _mu_L + phi * (_mu_H - _mu_L);
85 T tau = cell.template getField<descriptors::TAU_EFF>();
90 for (
int iPop = 1; iPop < L::q; ++iPop) {
93 T neighbor_phi = phi_cache[blockLattice.getCellId(nextX,nextY)];
105 grad_rho *= grad_phi;
108 T norm_grad_phi =
norm(grad_phi);
109 norm_grad_phi =
util::max(norm_grad_phi, std::numeric_limits<T>::epsilon());
110 partnerCell.template setField<descriptors::INTERPHASE_NORMAL>(grad_phi / norm_grad_phi);
114 T chemical_potential = (4.0 * _beta * (phi - 0.0) * (phi - 0.5) * (phi - 1.0)) - _kappa * laplace_phi;
115 T surface_tension_force[] = {chemical_potential*grad_phi[0], chemical_potential*grad_phi[1]};
118 T body_force[] = {0.0, 0.0};
121 T pressure = blockLattice.get(iX,iY).computeRho();
125 T viscous_force[] = {0.0, 0.0};
127 cell.computeRhoU( rho_tmp, u_tmp );
130 T fEq[DESCRIPTOR::q] { };
131 cell.getDynamics()->computeEquilibrium(cell, p_tmp, u_tmp, fEq);
132 for (
int iPop = 0; iPop < L::q; ++iPop) {
133 T fNeq = cell[iPop] - fEq[iPop];
134 for (
int iD = 0; iD < L::d; ++iD) {
135 for (
int jD = 0; jD < L::d; ++jD) {
140 for (
int iD = 0; iD < L::d; ++iD) {
145 auto force = cell.template getFieldPointer<descriptors::FORCE>();
146 for (
int iD = 0; iD < L::d; ++iD) {
147 force[iD] = (surface_tension_force[iD] + body_force[iD] + pressure_force[iD] + viscous_force[iD]) / rho;
152 cell.computeU(u.data());
153 partnerCell.template setField<descriptors::VELOCITY>(u);
158 cell.template setField<descriptors::TAU_EFF>(tau);
231 int x0_,
int x1_,
int y0_,
int y1_)
234 int newX0, newX1, newY0, newY1;
238 newX0, newX1, newY0, newY1 ) ) {
240 for (
int iX=newX0; iX<=newX1; ++iX) {
241 for (
int iY=newY0; iY<=newY1; ++iY) {
244 auto force = blockLattice.get(iX,iY).template getFieldPointer<descriptors::FORCE>();
245 T temperatureDifference = tPartner->get(iX,iY).computeRho() - T0;
246 for (
unsigned iD = 0; iD < L::d; ++iD) {
247 force[iD] = forcePrefactor[iD] * temperatureDifference;
251 auto u = tPartner->get(iX,iY).template getField<descriptors::VELOCITY>();
253 auto tauNS = blockLattice.get(iX,iY).template getFieldPointer<descriptors::TAU_EFF>();
254 auto tauAD = tPartner->get(iX,iY).template getFieldPointer<descriptors::TAU_EFF>();
257 blockLattice.get(iX,iY).computeAllMomenta(rho, u.data(), pi);
258 tPartner->get(iX,iY).template setField<descriptors::VELOCITY>(u);
259 T PiNeqNormSqr = pi[0]*pi[0] + 2.0*pi[1]*pi[1] + pi[2]*pi[2];
261 PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2*pi[4]*pi[4] +pi[5]*pi[5];
265 T tau_mol_NS = 1. / blockLattice.get(iX,iY).getDynamics()->getParameters(blockLattice).template getOrFallback<descriptors::OMEGA>(0);
266 T tau_mol_AD = 1. / tPartner->get(iX,iY).getDynamics()->getParameters(*tPartner).template getOrFallback<descriptors::OMEGA>(0);
268 T tau_turb_NS = 0.5*(
util::sqrt(tau_mol_NS*tau_mol_NS + smagoPrefactor/rho*PiNeqNorm) - tau_mol_NS);
270 tauNS[0] = tau_mol_NS+tau_turb_NS;
272 T tau_turb_AD = tau_turb_NS * tauTurbADPrefactor;
273 tauAD[0] = tau_mol_AD+tau_turb_AD;
346 int x0_,
int x1_,
int y0_,
int y1_)
350 const T C_alpha = 0.5;
351 const T deltaT = 1.0;
355 int newX0, newX1, newY0, newY1;
359 newX0, newX1, newY0, newY1 ) ) {
361 auto& heatFluxCache = blockLattice.template getField<HEAT_FLUX_CACHE>()[0];
362 for (
int iX=newX0-1; iX<=newX1+1; ++iX) {
363 for (
int iY=newY0-1; iY<=newY1+1; ++iY) {
364 const T temperature = tPartner->get(iX,iY).computeRho();
365 heatFluxCache[blockLattice.getCellId(iX, iY)] = temperature;
368 T temperatureDifference = temperature - T0;
369 blockLattice.get(iX,iY).template setField<descriptors::FORCE>(temperatureDifference*forcePrefactor);
372 blockLattice.get(iX,iY).computeU(u.
data());
373 tPartner->get(iX,iY).template setField<descriptors::VELOCITY>(u);
377 for (
int iX=newX0; iX<=newX1; ++iX) {
378 for (
int iY=newY0; iY<=newY1; ++iY) {
380 auto u_pp = tPartner->get(iX+1, iY+1).template getField<descriptors::VELOCITY>();
381 auto u_0p = tPartner->get(iX, iY+1).template getField<descriptors::VELOCITY>();
382 auto u_np = tPartner->get(iX-1, iY+1).template getField<descriptors::VELOCITY>();
383 auto u_p0 = tPartner->get(iX+1, iY ).template getField<descriptors::VELOCITY>();
384 auto u_pn = tPartner->get(iX+1, iY-1).template getField<descriptors::VELOCITY>();
385 auto u_00 = tPartner->get(iX, iY ).template getField<descriptors::VELOCITY>();
386 auto u_0n = tPartner->get(iX, iY-1).template getField<descriptors::VELOCITY>();
387 auto u_n0 = tPartner->get(iX-1, iY ).template getField<descriptors::VELOCITY>();
388 auto u_nn = tPartner->get(iX-1, iY-1).template getField<descriptors::VELOCITY>();
390 const T *h_pp = & heatFluxCache[blockLattice.getCellId(iX+1, iY+1)];
391 const T *h_0p = & heatFluxCache[blockLattice.getCellId(iX, iY+1)];
392 const T *h_np = & heatFluxCache[blockLattice.getCellId(iX-1, iY+1)];
393 const T *h_p0 = & heatFluxCache[blockLattice.getCellId(iX+1, iY )];
394 const T *h_pn = & heatFluxCache[blockLattice.getCellId(iX+1, iY-1)];
395 const T *h_00 = & heatFluxCache[blockLattice.getCellId(iX, iY )];
396 const T *h_0n = & heatFluxCache[blockLattice.getCellId(iX, iY-1)];
397 const T *h_n0 = & heatFluxCache[blockLattice.getCellId(iX-1, iY )];
398 const T *h_nn = & heatFluxCache[blockLattice.getCellId(iX-1, iY-1)];
402 filtered_h =((h_pp[0] + 2.*h_0p[0] + h_np[0])
403 + 2.*(h_p0[0] + 2.*h_00[0] + h_n0[0])
404 + (h_pn[0] + 2.*h_0n[0] + h_nn[0]))*0.25*0.25;
406 filtered_u =((u_pp + 2.*u_0p + u_np)
407 + 2.*(u_p0 + 2.*u_00 + u_n0)
408 + (u_pn + 2.*u_0n + u_nn))*0.25*0.25;
410 Vector<T,2> filtered_u_reduced = u_00 - filtered_u;
411 Vector<T,2> filtered_heatFlux_reduced = h_00[0]*u_00 - filtered_h*filtered_u;
413 T cutoffKinEnergy = filtered_u_reduced[0]*filtered_u_reduced[0]
414 + filtered_u_reduced[1]*filtered_u_reduced[1];
415 T cutoffHeatFlux = filtered_heatFlux_reduced[0]*filtered_heatFlux_reduced[0]
416 + filtered_heatFlux_reduced[1]*filtered_heatFlux_reduced[1];
418 blockLattice.get(iX,iY).template setField<descriptors::CUTOFF_KIN_ENERGY>(
util::pow(0.5*cutoffKinEnergy, 0.25));
419 tPartner->get(iX,iY).template setField<descriptors::CUTOFF_HEAT_FLUX>(
util::pow(0.5*cutoffHeatFlux, 0.25));
423 auto tauNS = blockLattice.get(iX,iY).template getField<descriptors::TAU_EFF>();
424 auto tauAD = tPartner->get(iX,iY).template getField<descriptors::TAU_EFF>();
427 T tau_mol_NS = 1. / blockLattice.get(iX,iY).getDynamics()->getParameters(blockLattice).template getOrFallback<descriptors::OMEGA>(0);
428 T tau_mol_AD = 1. / tPartner->get(iX,iY).getDynamics()->getParameters(*tPartner).template getOrFallback<descriptors::OMEGA>(0);
430 const T temperature = tPartner->get(iX,iY).computeRho();
433 T temperatureDifference = temperature - T0;
434 blockLattice.get(iX,iY).template
435 setField<descriptors::FORCE>(temperatureDifference*forcePrefactor);
437 auto u = tPartner->get(iX,iY).template getField<descriptors::VELOCITY>();
440 rho = blockLattice.get(iX,iY).computeRho();
441 blockLattice.get(iX,iY).computeStress(pi);
443 auto force = blockLattice.get(iX,iY).template getField<descriptors::FORCE>();
446 for (
int Alpha=0; Alpha<DESCRIPTOR::d; ++Alpha) {
447 for (
int Beta=Alpha; Beta<DESCRIPTOR::d; ++Beta) {
448 pi[iPi] += rho/2.*(force[Alpha]*u[Beta] + u[Alpha]*force[Beta]);
452 const Vector<T,3> piSqr = {pi[0]*pi[0], pi[1]*pi[1], pi[2]*pi[2]};
453 const T PiNeqNormSqr = piSqr[0] + 2.0*piSqr[1] + piSqr[2];
456 tPartner->get(iX,iY).computeJ(j);
457 const T tmp_preFactor = invCs2_g / rho / tauAD;
458 const Vector<T,2> jNeq = {(j[0] - temperature * u[0]), (j[1] - temperature * u[1])};
459 const Vector<T,2> jNeqSqr = {jNeq[0]*jNeq[0], jNeq[1]*jNeq[1]};
460 const T jNeqSqr_prefacor = 2. * 0.25 * (jNeq[0] + jNeq[1]) * (jNeq[0] + jNeq[1]);
462 const T TnormSqr = jNeqSqr_prefacor*PiNeqNormSqr;
492 auto cutoffKinEnergy_14 = blockLattice.get(iX,iY).template getField<descriptors::CUTOFF_KIN_ENERGY>();
493 auto cutoffHeatFlux_14 = tPartner->get(iX,iY).template getField<descriptors::CUTOFF_HEAT_FLUX>();
496 const T tau_turb_NS = tmp_A;
500 const T tau_turb_AD = tmp_B;
504 blockLattice.get(iX,iY).template setField<descriptors::TAU_EFF>(tau_mol_NS+tau_turb_NS);
505 tPartner->get(iX,iY).template setField<descriptors::TAU_EFF>(tau_mol_AD+tau_turb_AD);
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_)
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.
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_)