69 int x0_,
int x1_,
int y0_,
int y1_)
72 int newX0, newX1, newY0, newY1;
76 newX0, newX1, newY0, newY1 ) ) {
77 auto* dynamics =
static_cast<DYNAMICS*
>(tPartner->template getDynamics<DYNAMICS>());
79 tPartner->template getData<OperatorParameters<DYNAMICS>>());
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);
86 T enthalpy = partnerCell.computeRho();
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);
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;
100 T u[DESCRIPTOR::d] { };
102 partnerCell.template setField<descriptors::VELOCITY>(u);
160 int x0_,
int x1_,
int y0_,
int y1_)
163 int newX0, newX1, newY0, newY1;
166 newX0, newX1, newY0, newY1 ) ) {
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) {
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);
181 T phi = phi_cache[blockLattice.
getCellId(iX,iY)];
184 T rho = _rho_L + phi * _delta_rho;
187 T viscosity = _mu_L + phi * (_mu_H - _mu_L);
190 T tau = cell.template getField<descriptors::TAU_EFF>();
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)];
200 laplace_phi += (neighbor_phi - phi) * descriptors::t<T,L>(iPop);
202 neighbor_phi *= descriptors::t<T,L>(iPop);
203 grad_phi += neighbor_phi * descriptors::c<L>(iPop);
205 grad_phi *= descriptors::invCs2<T,L>();
206 laplace_phi *= 2.0 * descriptors::invCs2<T,L>();
210 grad_rho *= grad_phi;
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);
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]};
223 T body_force[] = {0.0, 0.0};
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]};
230 T viscous_force[] = {0.0, 0.0};
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];
244 for (
int iD = 0; iD < L::d; ++iD) {
245 viscous_force[iD] *= - viscosity / rho / tau * descriptors::invCs2<T,L>();
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;
256 cell.computeU(u.data());
257 partnerCell.template setField<descriptors::VELOCITY>(u);
261 tau = viscosity / rho * descriptors::invCs2<T,L>() + 0.5;
262 cell.template setField<descriptors::TAU_EFF>(tau);
335 int x0_,
int x1_,
int y0_,
int y1_)
338 int newX0, newX1, newY0, newY1;
342 newX0, newX1, newY0, newY1 ) ) {
344 for (
int iX=newX0; iX<=newX1; ++iX) {
345 for (
int iY=newY0; iY<=newY1; ++iY) {
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;
355 auto u = tPartner->get(iX,iY).template getField<descriptors::VELOCITY>();
357 auto tauNS = blockLattice.
get(iX,iY).template getFieldPointer<descriptors::TAU_EFF>();
358 auto tauAD = tPartner->get(iX,iY).template getFieldPointer<descriptors::TAU_EFF>();
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];
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;
376 T tau_turb_AD = tau_turb_NS * tauTurbADPrefactor;
377 tauAD[0] = tau_mol_AD+tau_turb_AD;
450 int x0_,
int x1_,
int y0_,
int y1_)
454 const T C_alpha = 0.5;
455 const T deltaT = 1.0;
457 const T invCs2_g = descriptors::invCs2<T,descriptors::D2Q5<descriptors::VELOCITY,descriptors::TAU_EFF,descriptors::CUTOFF_HEAT_FLUX>>();
459 int newX0, newX1, newY0, newY1;
463 newX0, newX1, newY0, newY1 ) ) {
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;
472 T temperatureDifference = temperature - T0;
473 blockLattice.
get(iX,iY).template setField<descriptors::FORCE>(temperatureDifference*forcePrefactor);
476 blockLattice.
get(iX,iY).computeU(u.
data());
477 tPartner->get(iX,iY).template setField<descriptors::VELOCITY>(u);
481 for (
int iX=newX0; iX<=newX1; ++iX) {
482 for (
int iY=newY0; iY<=newY1; ++iY) {
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>();
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)];
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;
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;
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;
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];
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));
527 auto tauNS = blockLattice.
get(iX,iY).template getField<descriptors::TAU_EFF>();
528 auto tauAD = tPartner->get(iX,iY).template getField<descriptors::TAU_EFF>();
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);
534 const T temperature = tPartner->get(iX,iY).computeRho();
537 T temperatureDifference = temperature - T0;
538 blockLattice.
get(iX,iY).template
539 setField<descriptors::FORCE>(temperatureDifference*forcePrefactor);
541 auto u = tPartner->get(iX,iY).template getField<descriptors::VELOCITY>();
544 rho = blockLattice.
get(iX,iY).computeRho();
545 blockLattice.
get(iX,iY).computeStress(pi);
547 auto force = blockLattice.
get(iX,iY).template getField<descriptors::FORCE>();
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]);
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];
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]);
566 const T TnormSqr = jNeqSqr_prefacor*PiNeqNormSqr;
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>();
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;
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;
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);
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_)