ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ERF_PBLModels.H
Go to the documentation of this file.
1 #ifndef ERF_PBLMODELS_H_
2 #define ERF_PBLMODELS_H_
3 
4 #include "ERF_Thetav.H"
5 
6 /**
7  * Compute eddy diffusivities of momentum (eddy viscosity) and heat using the
8  * Mellor-Yamada-Nakanishi-Niino Level 2.5 PBL scheme
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
24 ComputeDiffusivityMYNN25 (const amrex::MultiFab& xvel,
25  const amrex::MultiFab& yvel,
26  const amrex::MultiFab& cons_in,
27  amrex::MultiFab& eddyViscosity,
28  const amrex::Geometry& geom,
29  const TurbChoice& turbChoice,
30  std::unique_ptr<SurfaceLayer>& SurfLayer,
31  bool use_terrain_fitted_coords,
32  bool use_moisture,
33  int level,
34  const amrex::BCRec* bc_ptr,
35  bool /*vert_only*/,
36  const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
37  const int RhoQv_comp,
38  const int RhoQc_comp,
39  const int RhoQr_comp);
40 
41 /**
42  * Compute eddy diffusivities of momentum (eddy viscosity) and heat using the
43  * Mellor-Yamada-Nakanishi-Niino Level 2.5 PBL scheme
44  *
45  * @param[in] xvel Velocity in x-dir
46  * @param[in] yvel Velocity in y-dir
47  * @param[in] cons_in Cell center conserved quantities
48  * @param[out] eddyViscosity Holds turbulent viscosity
49  * @param[in] geom Problem geometry
50  * @param[in] turbChoice Container with turbulence parameters
51  * @param[in] SurfLayer Pointer to Monin-Obukhov class if instantiated
52  * @param[in] use_moisture If we have microphysics enabled
53  * @param[in] level Current level
54  * @param[in] bc_ptr Pointer to array with boundary condition info
55  * @param[in] vert_only Only compute vertical eddy diffusivities
56  * @param[in] z_phys_nd Physical location of grid nodes, if terrain (or grid stretching) is enabled
57  */
58 void
59 ComputeDiffusivityMYNNEDMF (const amrex::MultiFab& xvel,
60  const amrex::MultiFab& yvel,
61  const amrex::MultiFab& cons_in,
62  amrex::MultiFab& eddyViscosity,
63  const amrex::Geometry& geom,
64  const TurbChoice& turbChoice,
65  std::unique_ptr<SurfaceLayer>& SurfLayer,
66  bool use_terrain_fitted_coords,
67  bool use_moisture,
68  int level,
69  const amrex::BCRec* bc_ptr,
70  bool /*vert_only*/,
71  const std::unique_ptr<amrex::MultiFab>& z_phys_nd,
72  const int RhoQv_comp,
73  const int RhoQc_comp,
74  const int RhoQr_comp);
75 
76 /**
77  * Compute eddy diffusivities of momentum (eddy viscosity) and heat using the
78  * Yonsei University PBL scheme
79  *
80  * @param[in] xvel Velocity in x-dir
81  * @param[in] yvel Velocity in y-dir
82  * @param[in] cons_in Cell center conserved quantities
83  * @param[out] eddyViscosity Holds turbulent viscosity
84  * @param[in] geom Problem geometry
85  * @param[in] turbChoice Container with turbulence parameters
86  * @param[in] SurfLayer Pointer to Monin-Obukhov class if instantiated
87  * @param[in] use_moisture If we have microphysics enabled
88  * @param[in] level Current level
89  * @param[in] bc_ptr Pointer to array with boundary condition info
90  * @param[in] vert_only Only compute vertical eddy diffusivities
91  * @param[in] z_phys_nd Physical location of grid nodes, if terrain (or grid stretching) is enabled
92  */
93 void
94 ComputeDiffusivityYSU (const amrex::MultiFab& xvel,
95  const amrex::MultiFab& yvel,
96  const amrex::MultiFab& cons_in,
97  amrex::MultiFab& eddyViscosity,
98  const amrex::Geometry& geom,
99  const TurbChoice& turbChoice,
100  std::unique_ptr<SurfaceLayer>& SurfLayer,
101  bool use_terrain_fitted_coords,
102  bool use_moisture,
103  int level,
104  const amrex::BCRec* bc_ptr,
105  bool /*vert_only*/,
106  const std::unique_ptr<amrex::MultiFab>& z_phys_nd);
107 
108 
109 /**
110  * Function for computing vertical derivatives for use in PBL model
111  *
112  * @param[in] u velocity in x-dir
113  * @param[in] v velocity in y-dir
114  * @param[in] cell_data conserved cell center vars
115  */
116 AMREX_GPU_DEVICE
117 AMREX_FORCE_INLINE
118 void
119 ComputeVerticalDerivativesPBL (int i, int j, int k,
120  const amrex::Array4<const amrex::Real>& uvel,
121  const amrex::Array4<const amrex::Real>& vvel,
122  const amrex::Array4<const amrex::Real>& cell_data,
123  const int izmin,
124  const int izmax,
125  const amrex::Real& dz_inv,
126  const bool c_ext_dir_on_zlo,
127  const bool c_ext_dir_on_zhi,
128  const bool u_ext_dir_on_zlo,
129  const bool u_ext_dir_on_zhi,
130  const bool v_ext_dir_on_zlo,
131  const bool v_ext_dir_on_zhi,
132  amrex::Real& dthetadz,
133  amrex::Real& dudz,
134  amrex::Real& dvdz,
135  const int RhoQv_comp,
136  const int RhoQc_comp,
137  const int RhoQr_comp)
138 {
139  if ( k==izmax && c_ext_dir_on_zhi ) {
140  dthetadz = (1.0/3.0)*( -Thetav(i,j,k-1,cell_data,RhoQv_comp,RhoQc_comp,RhoQr_comp)
141  - 3.0 * Thetav(i,j,k ,cell_data,RhoQv_comp,RhoQc_comp,RhoQr_comp)
142  + 4.0 * Thetav(i,j,k+1,cell_data,RhoQv_comp,RhoQc_comp,RhoQr_comp) )*dz_inv;
143  } else if ( k==izmin && c_ext_dir_on_zlo ) {
144  dthetadz = (1.0/3.0)*( Thetav(i,j,k+1,cell_data,RhoQv_comp,RhoQc_comp,RhoQr_comp)
145  + 3.0 * Thetav(i,j,k ,cell_data,RhoQv_comp,RhoQc_comp,RhoQr_comp)
146  - 4.0 * Thetav(i,j,k-1,cell_data,RhoQv_comp,RhoQc_comp,RhoQr_comp) )*dz_inv;
147  } else {
148  dthetadz = 0.5*( Thetav(i,j,k+1,cell_data,RhoQv_comp,RhoQc_comp,RhoQr_comp)
149  - Thetav(i,j,k-1,cell_data,RhoQv_comp,RhoQc_comp,RhoQr_comp) )*dz_inv;
150  }
151 
152  if ( k==izmax && u_ext_dir_on_zhi ) {
153  dudz = (1.0/6.0)*( (-uvel(i ,j,k-1) - 3.0 * uvel(i ,j,k ) + 4.0 * uvel(i ,j,k+1))
154  + (-uvel(i+1,j,k-1) - 3.0 * uvel(i+1,j,k ) + 4.0 * uvel(i+1,j,k+1)) )*dz_inv;
155  } else if ( k==izmin && u_ext_dir_on_zlo ) {
156  dudz = (1.0/6.0)*( (uvel(i ,j,k+1) + 3.0 * uvel(i ,j,k ) - 4.0 * uvel(i ,j,k-1))
157  + (uvel(i+1,j,k+1) + 3.0 * uvel(i+1,j,k ) - 4.0 * uvel(i+1,j,k-1)) )*dz_inv;
158  } else {
159  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;
160  }
161 
162  if ( k==izmax && v_ext_dir_on_zhi ) {
163  dvdz = (1.0/6.0)*( (-vvel(i,j ,k-1) - 3.0 * vvel(i,j ,k ) + 4.0 * vvel(i,j ,k+1))
164  + (-vvel(i,j+1,k-1) - 3.0 * vvel(i,j+1,k ) + 4.0 * vvel(i,j+1,k+1)) )*dz_inv;
165  } else if ( k==izmin && v_ext_dir_on_zlo ) {
166  dvdz = (1.0/6.0)*( (vvel(i,j ,k+1) + 3.0 * vvel(i,j ,k ) - 4.0 * vvel(i,j ,k-1))
167  + (vvel(i,j+1,k+1) + 3.0 * vvel(i,j+1,k ) - 4.0 * vvel(i,j+1,k-1)) )*dz_inv;
168  } else {
169  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;
170  }
171 }
172 
173 /**
174  * Function for computing the QKE source terms (NN09, Eqn. 5).
175  *
176  * @param[in] u velocity in x-dir
177  * @param[in] v velocity in y-dir
178  * @param[in] cell_data conserved cell center vars
179  * @param[in] cell_prim primitive cell center vars
180  * @param[in] K_turb turbulent viscosity
181  * @param[in] cellSizeInv inverse cell size array
182  * @param[in] domain box of the whole domain
183  * @param[in] pbl_mynn_B1_l a parameter
184  * @param[in] theta_mean average theta
185  */
186 AMREX_GPU_DEVICE
187 AMREX_FORCE_INLINE
188 amrex::Real
189 ComputeQKESourceTerms (int i, int j, int k,
190  const amrex::Array4<const amrex::Real>& uvel,
191  const amrex::Array4<const amrex::Real>& vvel,
192  const amrex::Array4<const amrex::Real>& cell_data,
193  const amrex::Array4<const amrex::Real>& cell_prim,
194  const amrex::Array4<const amrex::Real>& K_turb,
195  const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& cellSizeInv,
196  const amrex::Box& domain,
197  amrex::Real pbl_mynn_B1_l,
198  const amrex::Real theta_mean,
199  const int RhoQv_comp,
200  const int RhoQc_comp,
201  const int RhoQr_comp,
202  bool c_ext_dir_on_zlo,
203  bool c_ext_dir_on_zhi,
204  bool u_ext_dir_on_zlo,
205  bool u_ext_dir_on_zhi,
206  bool v_ext_dir_on_zlo,
207  bool v_ext_dir_on_zhi,
208  const amrex::Real met_h_zeta=1.0)
209 {
210  // Compute some relevant derivatives
211  amrex::Real dthetadz, dudz, dvdz;
212  amrex::Real source_term = 0.0;
213 
214  amrex::Real dz_inv = cellSizeInv[2];
215  int izmin = domain.smallEnd(2);
216  int izmax = domain.bigEnd(2);
217 
219  uvel, vvel, cell_data, izmin, izmax, dz_inv/met_h_zeta,
220  c_ext_dir_on_zlo, c_ext_dir_on_zhi,
221  u_ext_dir_on_zlo, u_ext_dir_on_zhi,
222  v_ext_dir_on_zlo, v_ext_dir_on_zhi,
223  dthetadz, dudz, dvdz,
224  RhoQv_comp, RhoQc_comp, RhoQr_comp);
225 
226  // Note: Transport terms due to turbulence and pressure are included when
227  // DiffusionSrcForState_* is called from ERF_slow_rhs_post.
228 
229  // Shear Production
230  source_term += K_turb(i,j,k,EddyDiff::Mom_v) * (dudz*dudz + dvdz*dvdz);
231 
232  // Buoyancy Production
233  source_term -= (CONST_GRAV/theta_mean)*K_turb(i,j,k,EddyDiff::Theta_v)*dthetadz;
234 
235  // Dissipation
236  amrex::Real qke = 2.0 * cell_prim(i,j,k,PrimKE_comp);
237  if (std::abs(qke) > 0.0) {
238  source_term -= cell_data(i,j,k,Rho_comp) * std::pow(qke,1.5) /
239  (pbl_mynn_B1_l * K_turb(i,j,k,EddyDiff::Turb_lengthscale));
240  }
241 
242  return source_term;
243 }
244 #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 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 int RhoQv_comp, const int RhoQc_comp, const int RhoQr_comp, 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:189
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)
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 int RhoQv_comp, const int RhoQc_comp, const int RhoQr_comp)
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 int RhoQv_comp, const int RhoQc_comp, const int RhoQr_comp)
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 int RhoQv_comp, const int RhoQc_comp, const int RhoQr_comp)
Definition: ERF_PBLModels.H:119
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Thetav(int i, int j, int k, const amrex::Array4< const amrex::Real > &cell_data, const int RhoQv_comp, const int RhoQc_comp, const int RhoQr_comp)
Definition: ERF_Thetav.H:10
@ 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_TurbStruct.H:31