ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_PBLModels.H
Go to the documentation of this file.
1 #ifndef ERF_PBLMODELS_H_
2 #define ERF_PBLMODELS_H_
3 
4 #include "ERF_DataStruct.H"
5 
6 /**
7  * Compute eddy diffusivities of momentum (eddy viscosity) and heat using the
8  * Mellor-Yamada-Janjic scheme (Janjic (2002), NCEP Office Note 437)
9  *
10  * @param[in] xvel Velocity in x-dir
11  * @param[in] yvel Velocity in y-dir
12  * @param[in] cons_in Cell center conserved quantities
13  * @param[out] eddyViscosity Holds turbulent viscosity
14  * @param[in] geom Problem geometry
15  * @param[in] turbChoice Container with turbulence parameters
16  * @param[in] SurfLayer Pointer to Monin-Obukhov class if instantiated
17  * @param[in] use_moisture If we have microphysics enabled
18  * @param[in] level Current level
19  * @param[in] bc_ptr Pointer to array with boundary condition info
20  * @param[in] vert_only Only compute vertical eddy diffusivities
21  * @param[in] z_phys_nd Physical location of grid nodes, if terrain (or grid stretching) is enabled
22  */
23 void
25  const amrex::MultiFab& xvel,
26  const amrex::MultiFab& yvel,
27  amrex::MultiFab& cons_in,
28  amrex::MultiFab& eddyViscosity,
29  const amrex::Geometry& geom,
30  const TurbChoice& turbChoice,
31  std::unique_ptr<SurfaceLayer>& SurfLayer,
32  bool use_terrain_fitted_coords,
33  bool use_moisture,
34  int level,
35  const amrex::BCRec* bc_ptr,
36  bool /*vert_only*/,
37  const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
38  const MoistureComponentIndices& moisture_indices);
39 
40 /**
41  * Compute eddy diffusivities of momentum (eddy viscosity) and heat using the
42  * Mellor-Yamada-Nakanishi-Niino Level 2.5 PBL scheme
43  *
44  * @param[in] xvel Velocity in x-dir
45  * @param[in] yvel Velocity in y-dir
46  * @param[in] cons_in Cell center conserved quantities
47  * @param[out] eddyViscosity Holds turbulent viscosity
48  * @param[in] geom Problem geometry
49  * @param[in] turbChoice Container with turbulence parameters
50  * @param[in] SurfLayer Pointer to Monin-Obukhov class if instantiated
51  * @param[in] use_moisture If we have microphysics enabled
52  * @param[in] level Current level
53  * @param[in] bc_ptr Pointer to array with boundary condition info
54  * @param[in] vert_only Only compute vertical eddy diffusivities
55  * @param[in] z_phys_nd Physical location of grid nodes, if terrain (or grid stretching) is enabled
56  */
57 void
58 ComputeDiffusivityMYNN25 (const amrex::MultiFab& xvel,
59  const amrex::MultiFab& yvel,
60  const amrex::MultiFab& cons_in,
61  amrex::MultiFab& eddyViscosity,
62  const amrex::Geometry& geom,
63  const TurbChoice& turbChoice,
64  std::unique_ptr<SurfaceLayer>& SurfLayer,
65  bool use_terrain_fitted_coords,
66  bool use_moisture,
67  int level,
68  const amrex::BCRec* bc_ptr,
69  bool /*vert_only*/,
70  const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
71  const MoistureComponentIndices& moisture_indices);
72 
73 /**
74  * Compute eddy diffusivities of momentum (eddy viscosity) and heat using the
75  * Mellor-Yamada-Nakanishi-Niino Level 2.5 PBL scheme
76  *
77  * @param[in] xvel Velocity in x-dir
78  * @param[in] yvel Velocity in y-dir
79  * @param[in] cons_in Cell center conserved quantities
80  * @param[out] eddyViscosity Holds turbulent viscosity
81  * @param[in] geom Problem geometry
82  * @param[in] turbChoice Container with turbulence parameters
83  * @param[in] SurfLayer Pointer to Monin-Obukhov class if instantiated
84  * @param[in] use_moisture If we have microphysics enabled
85  * @param[in] level Current level
86  * @param[in] bc_ptr Pointer to array with boundary condition info
87  * @param[in] vert_only Only compute vertical eddy diffusivities
88  * @param[in] z_phys_nd Physical location of grid nodes, if terrain (or grid stretching) is enabled
89  */
90 void
91 ComputeDiffusivityMYNNEDMF (const amrex::MultiFab& xvel,
92  const amrex::MultiFab& yvel,
93  const amrex::MultiFab& cons_in,
94  amrex::MultiFab& eddyViscosity,
95  const amrex::Geometry& geom,
96  const TurbChoice& turbChoice,
97  std::unique_ptr<SurfaceLayer>& SurfLayer,
98  bool use_terrain_fitted_coords,
99  bool use_moisture,
100  int level,
101  const amrex::BCRec* bc_ptr,
102  bool /*vert_only*/,
103  const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
104  const MoistureComponentIndices& moisture_indices);
105 
106 /**
107  * Compute eddy diffusivities of momentum (eddy viscosity) and heat using the
108  * Yonsei University PBL scheme
109  *
110  * @param[in] xvel Velocity in x-dir
111  * @param[in] yvel Velocity in y-dir
112  * @param[in] cons_in Cell center conserved quantities
113  * @param[out] eddyViscosity Holds turbulent viscosity
114  * @param[in] geom Problem geometry
115  * @param[in] turbChoice Container with turbulence parameters
116  * @param[in] SurfLayer Pointer to Monin-Obukhov class if instantiated
117  * @param[in] use_moisture If we have microphysics enabled
118  * @param[in] level Current level
119  * @param[in] bc_ptr Pointer to array with boundary condition info
120  * @param[in] vert_only Only compute vertical eddy diffusivities
121  * @param[in] z_phys_nd Physical location of grid nodes, if terrain (or grid stretching) is enabled
122  */
123 void
124 ComputeDiffusivityYSU (const amrex::MultiFab& xvel,
125  const amrex::MultiFab& yvel,
126  const amrex::MultiFab& cons_in,
127  amrex::MultiFab& eddyViscosity,
128  const amrex::Geometry& geom,
129  const TurbChoice& turbChoice,
130  std::unique_ptr<SurfaceLayer>& SurfLayer,
131  bool use_terrain_fitted_coords,
132  bool use_moisture,
133  int level,
134  const amrex::BCRec* bc_ptr,
135  bool /*vert_only*/,
136  const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
137  const MoistureComponentIndices& moisture_indices);
138 /**
139  * Compute eddy diffusivities of momentum (eddy viscosity) and heat using the
140  * older version of Yonsei University PBL scheme
141  *
142  * @param[in] xvel Velocity in x-dir
143  * @param[in] yvel Velocity in y-dir
144  * @param[in] cons_in Cell center conserved quantities
145  * @param[out] eddyViscosity Holds turbulent viscosity
146  * @param[in] geom Problem geometry
147  * @param[in] turbChoice Container with turbulence parameters
148  * @param[in] SurfLayer Pointer to Monin-Obukhov class if instantiated
149  * @param[in] use_moisture If we have microphysics enabled
150  * @param[in] level Current level
151  * @param[in] bc_ptr Pointer to array with boundary condition info
152  * @param[in] vert_only Only compute vertical eddy diffusivities
153  * @param[in] z_phys_nd Physical location of grid nodes, if terrain (or grid stretching) is enabled
154  */
155 void
156 ComputeDiffusivityMRF (const amrex::MultiFab& xvel,
157  const amrex::MultiFab& yvel,
158  const amrex::MultiFab& cons_in,
159  amrex::MultiFab& eddyViscosity,
160  const amrex::Geometry& geom,
161  const TurbChoice& turbChoice,
162  std::unique_ptr<SurfaceLayer>& SurfLayer,
163  bool use_terrain_fitted_coords,
164  bool use_moisture,
165  int level,
166  const amrex::BCRec* bc_ptr,
167  bool /*vert_only*/,
168  const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
169  const MoistureComponentIndices& moisture_indices);
170 
171 /**
172  * Function for computing vertical derivatives for use in PBL model
173  *
174  * @param[in] u velocity in x-dir
175  * @param[in] v velocity in y-dir
176  * @param[in] cell_data conserved cell center vars
177  */
178 AMREX_GPU_DEVICE
179 AMREX_FORCE_INLINE
180 void
181 ComputeVerticalDerivativesPBL (int i, int j, int k,
182  const amrex::Array4<const amrex::Real>& uvel,
183  const amrex::Array4<const amrex::Real>& vvel,
184  const amrex::Array4<const amrex::Real>& cell_data,
185  const int izmin,
186  const int izmax,
187  const amrex::Real& dz_inv,
188  const bool c_ext_dir_on_zlo,
189  const bool c_ext_dir_on_zhi,
190  const bool u_ext_dir_on_zlo,
191  const bool u_ext_dir_on_zhi,
192  const bool v_ext_dir_on_zlo,
193  const bool v_ext_dir_on_zhi,
194  amrex::Real& dthetadz,
195  amrex::Real& dudz,
196  amrex::Real& dvdz,
197  const MoistureComponentIndices& moisture_indices)
198 {
199  if ( k==izmax && c_ext_dir_on_zhi ) {
200  dthetadz = (1.0/3.0)*( -GetThetav(i,j,k-1,cell_data,moisture_indices)
201  - 3.0 * GetThetav(i,j,k ,cell_data,moisture_indices)
202  + 4.0 * GetThetav(i,j,k+1,cell_data,moisture_indices) )*dz_inv;
203  } else if ( k==izmin && c_ext_dir_on_zlo ) {
204  dthetadz = (1.0/3.0)*( GetThetav(i,j,k+1,cell_data,moisture_indices)
205  + 3.0 * GetThetav(i,j,k ,cell_data,moisture_indices)
206  - 4.0 * GetThetav(i,j,k-1,cell_data,moisture_indices) )*dz_inv;
207  } else {
208  dthetadz = 0.5*( GetThetav(i,j,k+1,cell_data,moisture_indices)
209  - GetThetav(i,j,k-1,cell_data,moisture_indices) )*dz_inv;
210  }
211 
212  if ( k==izmax && u_ext_dir_on_zhi ) {
213  dudz = (1.0/6.0)*( (-uvel(i ,j,k-1) - 3.0 * uvel(i ,j,k ) + 4.0 * uvel(i ,j,k+1))
214  + (-uvel(i+1,j,k-1) - 3.0 * uvel(i+1,j,k ) + 4.0 * uvel(i+1,j,k+1)) )*dz_inv;
215  } else if ( k==izmin && u_ext_dir_on_zlo ) {
216  dudz = (1.0/6.0)*( (uvel(i ,j,k+1) + 3.0 * uvel(i ,j,k ) - 4.0 * uvel(i ,j,k-1))
217  + (uvel(i+1,j,k+1) + 3.0 * uvel(i+1,j,k ) - 4.0 * uvel(i+1,j,k-1)) )*dz_inv;
218  } else {
219  dudz = 0.25*( uvel(i,j,k+1) - uvel(i,j,k-1) + uvel(i+1,j,k+1) - uvel(i+1,j,k-1) )*dz_inv;
220  }
221 
222  if ( k==izmax && v_ext_dir_on_zhi ) {
223  dvdz = (1.0/6.0)*( (-vvel(i,j ,k-1) - 3.0 * vvel(i,j ,k ) + 4.0 * vvel(i,j ,k+1))
224  + (-vvel(i,j+1,k-1) - 3.0 * vvel(i,j+1,k ) + 4.0 * vvel(i,j+1,k+1)) )*dz_inv;
225  } else if ( k==izmin && v_ext_dir_on_zlo ) {
226  dvdz = (1.0/6.0)*( (vvel(i,j ,k+1) + 3.0 * vvel(i,j ,k ) - 4.0 * vvel(i,j ,k-1))
227  + (vvel(i,j+1,k+1) + 3.0 * vvel(i,j+1,k ) - 4.0 * vvel(i,j+1,k-1)) )*dz_inv;
228  } else {
229  dvdz = 0.25*( vvel(i,j,k+1) - vvel(i,j,k-1) + vvel(i,j+1,k+1) - vvel(i,j+1,k-1) )*dz_inv;
230  }
231 }
232 
233 /**
234  * Function for computing the QKE source terms (NN09, Eqn. 5).
235  *
236  * @param[in] u velocity in x-dir
237  * @param[in] v velocity in y-dir
238  * @param[in] cell_data conserved cell center vars
239  * @param[in] cell_prim primitive cell center vars
240  * @param[in] K_turb turbulent viscosity
241  * @param[in] cellSizeInv inverse cell size array
242  * @param[in] domain box of the whole domain
243  * @param[in] pbl_mynn_B1_l a parameter
244  * @param[in] theta_mean average theta
245  */
246 AMREX_GPU_DEVICE
247 AMREX_FORCE_INLINE
249 ComputeQKESourceTerms (int i, int j, int k,
250  const amrex::Array4<const amrex::Real>& uvel,
251  const amrex::Array4<const amrex::Real>& vvel,
252  const amrex::Array4<const amrex::Real>& cell_data,
253  const amrex::Array4<const amrex::Real>& cell_prim,
254  const amrex::Array4<const amrex::Real>& K_turb,
255  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
256  const amrex::Box& domain,
257  amrex::Real pbl_mynn_B1_l,
258  const amrex::Real theta_mean,
259  const MoistureComponentIndices& moisture_indices,
260  bool c_ext_dir_on_zlo,
261  bool c_ext_dir_on_zhi,
262  bool u_ext_dir_on_zlo,
263  bool u_ext_dir_on_zhi,
264  bool v_ext_dir_on_zlo,
265  bool v_ext_dir_on_zhi,
266  const amrex::Real met_h_zeta=1.0)
267 {
268  // Compute some relevant derivatives
269  amrex::Real dthetadz, dudz, dvdz;
270  amrex::Real source_term = 0.0;
271 
272  amrex::Real dz_inv = cellSizeInv[2];
273  int izmin = domain.smallEnd(2);
274  int izmax = domain.bigEnd(2);
275 
277  uvel, vvel, cell_data, izmin, izmax, dz_inv/met_h_zeta,
278  c_ext_dir_on_zlo, c_ext_dir_on_zhi,
279  u_ext_dir_on_zlo, u_ext_dir_on_zhi,
280  v_ext_dir_on_zlo, v_ext_dir_on_zhi,
281  dthetadz, dudz, dvdz,
282  moisture_indices);
283 
284  // Notes:
285  // - We transport TKE = 0.5*QKE rather than QKE, so the RHS terms do not
286  // have a factor of two.
287  // - Transport terms due to turbulence and pressure are included when
288  // DiffusionSrcForState_* is called from ERF_slow_rhs_post.
289  // - Eddy diffusivities are updated at the beginning of each time step only.
290 
291  // Second-order turbulent fluxes, e.g.:
292  // -<uw> = L q SM dU/dz (NN09, Eqn. 18)
293  // = Kmv/rho dU/dz
294 
295  // Shear Production
296  source_term += K_turb(i,j,k,EddyDiff::Mom_v) * (dudz*dudz + dvdz*dvdz);
297 
298  // Buoyancy Production
299  source_term -= (CONST_GRAV/theta_mean)*K_turb(i,j,k,EddyDiff::Theta_v)*dthetadz;
300 
301  // Dissipation (NN09, Eqn. 12)
302  amrex::Real qke = 2.0 * cell_prim(i,j,k,PrimKE_comp);
303  if (std::abs(qke) > 0.0) {
304  source_term -= cell_data(i,j,k,Rho_comp) * std::pow(qke,1.5) /
305  (pbl_mynn_B1_l * K_turb(i,j,k,EddyDiff::Turb_lengthscale));
306  }
307 
308  return source_term;
309 }
310 #endif
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:21
TurbChoice turbChoice
Definition: ERF_DiffSetup.H:2
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define PrimKE_comp
Definition: ERF_IndexDefines.H:51
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real GetThetav(int i, int j, int k, const amrex::Array4< amrex::Real const > &cell_data, const MoistureComponentIndices &moisture_indices)
Definition: ERF_MoistUtils.H:72
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real ComputeQKESourceTerms(int i, int j, int k, const amrex::Array4< const amrex::Real > &uvel, const amrex::Array4< const amrex::Real > &vvel, const amrex::Array4< const amrex::Real > &cell_data, const amrex::Array4< const amrex::Real > &cell_prim, const amrex::Array4< const amrex::Real > &K_turb, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Box &domain, amrex::Real pbl_mynn_B1_l, const amrex::Real theta_mean, const MoistureComponentIndices &moisture_indices, bool c_ext_dir_on_zlo, bool c_ext_dir_on_zhi, bool u_ext_dir_on_zlo, bool u_ext_dir_on_zhi, bool v_ext_dir_on_zlo, bool v_ext_dir_on_zhi, const amrex::Real met_h_zeta=1.0)
Definition: ERF_PBLModels.H:249
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void ComputeVerticalDerivativesPBL(int i, int j, int k, const amrex::Array4< const amrex::Real > &uvel, const amrex::Array4< const amrex::Real > &vvel, const amrex::Array4< const amrex::Real > &cell_data, const int izmin, const int izmax, const amrex::Real &dz_inv, const bool c_ext_dir_on_zlo, const bool c_ext_dir_on_zhi, const bool u_ext_dir_on_zlo, const bool u_ext_dir_on_zhi, const bool v_ext_dir_on_zlo, const bool v_ext_dir_on_zhi, amrex::Real &dthetadz, amrex::Real &dudz, amrex::Real &dvdz, const MoistureComponentIndices &moisture_indices)
Definition: ERF_PBLModels.H:181
void ComputeDiffusivityMYNN25(const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const MoistureComponentIndices &moisture_indices)
void ComputeDiffusivityYSU(const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const MoistureComponentIndices &moisture_indices)
void ComputeDiffusivityMYNNEDMF(const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const MoistureComponentIndices &moisture_indices)
void ComputeDiffusivityMRF(const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const MoistureComponentIndices &moisture_indices)
void ComputeDiffusivityMYJ(amrex::Real dt, const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, amrex::MultiFab &cons_in, amrex::MultiFab &eddyViscosity, const amrex::Geometry &geom, const TurbChoice &turbChoice, std::unique_ptr< SurfaceLayer > &SurfLayer, bool use_terrain_fitted_coords, bool use_moisture, int level, const amrex::BCRec *bc_ptr, bool, const std::unique_ptr< amrex::MultiFab > &z_phys_nd, const MoistureComponentIndices &moisture_indices)
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ Theta_v
Definition: ERF_IndexDefines.H:176
@ Turb_lengthscale
Definition: ERF_IndexDefines.H:180
@ Mom_v
Definition: ERF_IndexDefines.H:175
@ xvel
Definition: ERF_IndexDefines.H:141
@ yvel
Definition: ERF_IndexDefines.H:142
Definition: ERF_DataStruct.H:99
Definition: ERF_TurbStruct.H:41