ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_AddTKESources.H
Go to the documentation of this file.
1  // Using Deardorff (see Sullivan et al 1994)
2  // or k-eqn RANS (see Axell & Liungman 2001)
3  //
4  // Note: At this point, the thermal diffusivity ("Khv" field in ERF), the
5  // subgrid heat flux ("hfx_z" here), and the subgrid dissipation
6  // ("diss" here) have been updated by ComputeTurbulentViscosityLES --
7  // at the beginning of each timestep.
8  // The strain rate magnitude is updated at the beginning of the first
9  // RK stage only, therefore the shear production term also does not
10  // change between RK stages.
11  // The surface heat flux hfx_z(i,j,-1) is updated in MOSTStress at
12  // each RK stage, but that does not change the buoyancy production term here.
13  if (l_use_keqn && (start_comp <= RhoKE_comp) && (end_comp >= RhoKE_comp)) {
14  int qty_index = RhoKE_comp;
15  ParallelFor(bx,[=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
16  {
17  // Add Buoyancy Source
18  // where the SGS buoyancy flux tau_{theta,i} = -KH * dtheta/dx_i,
19  // such that for dtheta/dz < 0, there is a positive (upward) heat
20  // flux; the TKE buoyancy production is then
21  // B = g/theta_0 * tau_{theta,w}
22  // for a dry atmosphere.
23  // TODO: To account for moisture, the Brunt-Vaisala frequency,
24  // N^2 = g[1/theta * dtheta/dz + ...]
25  // **should** be a function of the water vapor and total water
26  // mixing ratios, depending on whether conditions are saturated or
27  // not (see the WRF model description, Skamarock et al 2019).
28  cell_rhs(i,j,k,qty_index) += l_abs_g * l_inv_theta0 * hfx_z(i,j,k);
29  if (!use_ref_theta) {
30  // l_inv_theta0 == 1, divide by actual theta
31  cell_rhs(i,j,k,qty_index) /= cell_prim(i,j,k,PrimTheta_comp);
32  }
33 
34  // TKE shear production
35  // P = -tau_ij * S_ij = 2 * mu_turb * S_ij * S_ij
36  // Note: This assumes that the horizontal and vertical diffusivities
37  // of momentum are equal
38  cell_rhs(i,j,k,qty_index) += 2.0*mu_turb(i,j,k,EddyDiff::Mom_v) * SmnSmn_a(i,j,k);
39 
40  // TKE dissipation
41  cell_rhs(i,j,k,qty_index) -= diss(i,j,k);
42  });
43  }
#define PrimTheta_comp
Definition: ERF_IndexDefines.H:50
#define RhoKE_comp
Definition: ERF_IndexDefines.H:38
ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { const auto prob_lo=geomdata.ProbLo();const auto dx=geomdata.CellSize();const Real x=(prob_lo[0]+(i+0.5) *dx[0])/mf_m(i, j, 0);const Real z=z_cc(i, j, k);Real L=std::sqrt(std::pow((x - x_c)/x_r, 2)+std::pow((z - z_c)/z_r, 2));if(L<=1.0) { Real dT=T_pert *(std::cos(PI *L)+1.0)/2.0;Real Tbar_hse=p_hse(i, j, k)/(R_d *r_hse(i, j, k));Real theta_perturbed=(Tbar_hse+dT) *std::pow(p_0/p_hse(i, j, k), rdOcp);Real theta_0=(Tbar_hse) *std::pow(p_0/p_hse(i, j, k), rdOcp);if(const_rho) { state_pert(i, j, k, RhoTheta_comp)=r_hse(i, j, k) *(theta_perturbed - theta_0);} else { state_pert(i, j, k, Rho_comp)=getRhoThetagivenP(p_hse(i, j, k))/theta_perturbed - r_hse(i, j, k);} } })
const int end_comp
Definition: ERF_SetupDiff.H:11
bool l_use_keqn
Definition: ERF_SetupDiff.H:13
const bool use_ref_theta
Definition: ERF_SetupDiff.H:17
const Real l_inv_theta0
Definition: ERF_SetupDiff.H:18
@ Mom_v
Definition: ERF_IndexDefines.H:175