ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
moeng_flux Struct Reference

#include <ERF_MOSTStress.H>

Collaboration diagram for moeng_flux:

Public Member Functions

 moeng_flux (const amrex::Real wsmin=0.1, const bool face_is_low=true, const int zlo=0, const int zhi=0)
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_q_flux (const int &i, const int &j, const int &k, const int &dir, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &velz_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< const amrex::Real > &u_star_arr, const amrex::Array4< const amrex::Real > &q_star_arr, const amrex::Array4< const amrex::Real > &q_surf_arr) const
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_t_flux (const int &i, const int &j, const int &k, const int &dir, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &velz_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &u_star_arr, const amrex::Array4< const amrex::Real > &t_star_arr, const amrex::Array4< const amrex::Real > &t_surf_arr) const
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_u_flux (const int &i, const int &j, const int &k, const int &dir, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &velz_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &um_arr, const amrex::Array4< const amrex::Real > &vm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &u_star_arr) const
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_v_flux (const int &i, const int &j, const int &k, const int &dir, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &velz_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &vm_arr, const amrex::Array4< const amrex::Real > &wm_arr, const amrex::Array4< const amrex::Real > &u_star_arr) const
 

Private Attributes

const amrex::Real eps = amrex::Real(1e-15)
 
bool is_low = true
 
amrex::Real WSMIN = most_min_wind_speed
 
int m_zlo = 0
 
int m_zhi = 0
 

Detailed Description

Moeng flux formulation

Constructor & Destructor Documentation

◆ moeng_flux()

moeng_flux::moeng_flux ( const amrex::Real  wsmin = 0.1,
const bool  face_is_low = true,
const int  zlo = 0,
const int  zhi = 0 
)
inline

Construct the Moeng flux calculator.

2106  {
2107  WSMIN = wsmin;
2108  is_low = face_is_low;
2109  m_zlo = zlo;
2110  m_zhi = zhi;
2111  }
int m_zhi
Definition: ERF_MOSTStress.H:2415
int m_zlo
Definition: ERF_MOSTStress.H:2414
amrex::Real WSMIN
Definition: ERF_MOSTStress.H:2413
bool is_low
Definition: ERF_MOSTStress.H:2412

Member Function Documentation

◆ compute_q_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real moeng_flux::compute_q_flux ( const int &  i,
const int &  j,
const int &  k,
const int &  dir,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  velx_arr,
const amrex::Array4< const amrex::Real > &  vely_arr,
const amrex::Array4< const amrex::Real > &  velz_arr,
const amrex::Array4< const amrex::Real > &  umm_arr,
const amrex::Array4< const amrex::Real > &  qvm_arr,
const amrex::Array4< const amrex::Real > &  u_star_arr,
const amrex::Array4< const amrex::Real > &  q_star_arr,
const amrex::Array4< const amrex::Real > &  q_surf_arr 
) const
inline

Compute moisture flux for one surface point.

Calling sequence
i, j, k, cons_arr, velx_arr, vely_arr, umm_arr, qvm_arr, u_star_arr, q_star_arr, q_surf_arr.
2136  {
2137  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
2138  amrex::Real qv = cons_arr(i,j,k,RhoQ1_comp) / rho;
2139 
2140  amrex::Real velx, vely;
2141  if (dir == 0) {
2142  // X-face: y/z velocity, velx = vely, vely = velz here
2143  velx = myhalf * ( vely_arr(i,j,k) + vely_arr(i ,j+1,k) );
2144  vely = myhalf * ( velz_arr(i,j,k) + velz_arr(i ,j ,k+1) );
2145  } else if (dir == 1) {
2146  // Y-face: x/z velocity, vely = velz here
2147  velx = myhalf * ( velx_arr(i,j,k) + velx_arr(i+1,j ,k) );
2148  vely = myhalf * ( velz_arr(i,j,k) + velz_arr(i ,j ,k+1) );
2149  } else {
2150  // Z face: x/y velocity
2151  velx = myhalf * ( velx_arr(i,j,k) + velx_arr(i+1,j ,k) );
2152  vely = myhalf * ( vely_arr(i,j,k) + vely_arr(i ,j+1,k) );
2153  }
2154 
2155  amrex::Real qv_mean = qvm_arr(i,j,k);
2156  amrex::Real ustar = u_star_arr(i,j,k);
2157  amrex::Real qstar = q_star_arr(i,j,k);
2158  amrex::Real qv_surf = q_surf_arr(i,j,k);
2159  amrex::Real wsp_mean = umm_arr(i,j,k);
2160  wsp_mean = std::max(wsp_mean, WSMIN);
2161  if (dir == 2 && !is_low) {
2162  // flip qv_mean and qv_surf for hi-z face
2163  qv_mean = qv_surf;
2164  qv_surf = qvm_arr(i, j, k);
2165  }
2166 
2167  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2168  amrex::Real num1 = wsp * (qv_mean-qv_surf);
2169  amrex::Real num2 = wsp_mean * (qv-qvm_arr(i,j,k));
2170 
2171  // NOTE: this is rho*<Qv'w'> = -K dQvdz
2172  amrex::Real moflux = (std::abs(qstar) > eps) ?
2173  -rho*qstar*ustar*(num1+num2)/((qv_mean-qv_surf)*wsp_mean) : zero;
2174 
2175  return moflux;
2176  }
#define Rho_comp
Definition: ERF_IndexDefines.H:42
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:48
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:41
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ ustar
Definition: ERF_SLM.H:28
@ qstar
Definition: ERF_SLM.H:30
@ rho
Definition: ERF_Kessler.H:25
@ qv
Definition: ERF_Kessler.H:31
const amrex::Real eps
Definition: ERF_MOSTStress.H:2410

◆ compute_t_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real moeng_flux::compute_t_flux ( const int &  i,
const int &  j,
const int &  k,
const int &  dir,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  velx_arr,
const amrex::Array4< const amrex::Real > &  vely_arr,
const amrex::Array4< const amrex::Real > &  velz_arr,
const amrex::Array4< const amrex::Real > &  umm_arr,
const amrex::Array4< const amrex::Real > &  tm_arr,
const amrex::Array4< const amrex::Real > &  u_star_arr,
const amrex::Array4< const amrex::Real > &  t_star_arr,
const amrex::Array4< const amrex::Real > &  t_surf_arr 
) const
inline

Compute heat flux for one surface point.

Calling sequence
i, j, k, cons_arr, velx_arr, vely_arr, umm_arr, tm_arr, u_star_arr, t_star_arr, t_surf_arr.
2201  {
2202  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
2203  amrex::Real theta = cons_arr(i,j,k,RhoTheta_comp) / rho;
2204 
2205  amrex::Real velx, vely;
2206  if (dir == 0) {
2207  // X-face: y/z velocity, velx = vely, vely = velz here
2208  velx = myhalf * ( vely_arr(i,j,k) + vely_arr(i ,j+1,k) );
2209  vely = myhalf * ( velz_arr(i,j,k) + velz_arr(i ,j ,k+1) );
2210  } else if (dir == 1) {
2211  // Y-face: x/z velocity, vely = velz here
2212  velx = myhalf * ( velx_arr(i,j,k) + velx_arr(i+1,j ,k) );
2213  vely = myhalf * ( velz_arr(i,j,k) + velz_arr(i ,j ,k+1) );
2214  } else {
2215  // Z face: x/y velocity
2216  velx = myhalf * ( velx_arr(i,j,k) + velx_arr(i+1,j ,k) );
2217  vely = myhalf * ( vely_arr(i,j,k) + vely_arr(i ,j+1,k) );
2218  }
2219 
2220  amrex::Real theta_mean = tm_arr(i,j,k);
2221  amrex::Real ustar = u_star_arr(i,j,k);
2222  amrex::Real tstar = t_star_arr(i,j,k);
2223  amrex::Real theta_surf = t_surf_arr(i,j,k);
2224  amrex::Real wsp_mean = umm_arr(i,j,k);
2225 
2226  if (dir == 2 && !is_low) {
2227  // flip theta and surf for hi-z face
2228  theta_mean = theta_surf;
2229  theta_surf = tm_arr(i, j, k);
2230  }
2231 
2232  wsp_mean = std::max(wsp_mean, WSMIN);
2233 
2234  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2235  amrex::Real num1 = wsp * (theta_mean-theta_surf);
2236  amrex::Real num2 = wsp_mean * (theta-tm_arr(i,j,k));
2237 
2238  // NOTE: this is rho*<T'w'> = -K dTdz
2239  amrex::Real moflux = (std::abs(tstar) > eps) ?
2240  -rho*tstar*ustar*(num1+num2)/((theta_mean-theta_surf)*wsp_mean) : zero;
2241 
2242  return moflux;
2243  }
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:43
@ tstar
Definition: ERF_SLM.H:29
@ theta
Definition: ERF_Kessler.H:26

◆ compute_u_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real moeng_flux::compute_u_flux ( const int &  i,
const int &  j,
const int &  k,
const int &  dir,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  velx_arr,
const amrex::Array4< const amrex::Real > &  vely_arr,
const amrex::Array4< const amrex::Real > &  velz_arr,
const amrex::Array4< const amrex::Real > &  umm_arr,
const amrex::Array4< const amrex::Real > &  um_arr,
const amrex::Array4< const amrex::Real > &  vm_arr,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  u_star_arr 
) const
inline

Compute x-momentum flux for one surface face.

Calling sequence
i, j, k, cons_arr, velx_arr, vely_arr, umm_arr, um_arr, u_star_arr.
2268  {
2269  // The caller supplies indices on the stress face. On a high wall the
2270  // normal index is one past the adjacent cell, so use the interior cell
2271  // for all input fields while retaining the stress index tangentially.
2272  const int ic = (!is_low && dir == 0) ? i - 1 : i;
2273  const int jc = (!is_low && dir == 1) ? j - 1 : j;
2274  const int kc = (!is_low && dir != 0 && dir != 1) ? k - 1 : k;
2275 
2276  amrex::Real velx, vely, rho, umean, ustar, wsp_mean;
2277  if (dir == 0) {
2278  // X wall: V-momentum flux at tau21. V is already y-nodal;
2279  // interpolate W and the cell-centered fields to that y node.
2280  velx = vely_arr(ic,j,kc);
2281  vely = fourth * ( velz_arr(ic,j-1,kc ) + velz_arr(ic,j,kc )
2282  + velz_arr(ic,j-1,kc+1) + velz_arr(ic,j,kc+1) );
2283  rho = myhalf * (cons_arr(ic,j-1,kc,Rho_comp) + cons_arr(ic,j,kc,Rho_comp));
2284  umean = vm_arr(ic,j,kc);
2285  ustar = myhalf * (u_star_arr(ic,j-1,kc) + u_star_arr(ic,j,kc));
2286  wsp_mean = myhalf * (umm_arr(ic,j-1,kc) + umm_arr(ic,j,kc));
2287  } else if (dir == 1) {
2288  // Y wall: U-momentum flux at tau12. U is already x-nodal;
2289  // interpolate W and the cell-centered fields to that x node.
2290  velx = velx_arr(i,jc,kc);
2291  vely = fourth * ( velz_arr(i-1,jc,kc ) + velz_arr(i,jc,kc )
2292  + velz_arr(i-1,jc,kc+1) + velz_arr(i,jc,kc+1) );
2293  rho = myhalf * (cons_arr(i-1,jc,kc,Rho_comp) + cons_arr(i,jc,kc,Rho_comp));
2294  umean = um_arr(i,jc,kc);
2295  ustar = myhalf * (u_star_arr(i-1,jc,kc) + u_star_arr(i,jc,kc));
2296  wsp_mean = myhalf * (umm_arr(i-1,jc,kc) + umm_arr(i,jc,kc));
2297  } else {
2298  // Z wall: U-momentum flux at tau13.
2299  velx = velx_arr(i,j,kc);
2300  vely = fourth * ( vely_arr(i-1,j ,kc) + vely_arr(i,j ,kc)
2301  + vely_arr(i-1,j+1,kc) + vely_arr(i,j+1,kc) );
2302  rho = myhalf * (cons_arr(i-1,j,kc,Rho_comp) + cons_arr(i,j,kc,Rho_comp));
2303  umean = um_arr(i,j,kc);
2304  ustar = myhalf * (u_star_arr(i-1,j,kc) + u_star_arr(i,j,kc));
2305  wsp_mean = myhalf * (umm_arr(i-1,j,kc) + umm_arr(i,j,kc));
2306  }
2307  wsp_mean = std::max(wsp_mean, WSMIN);
2308 
2309  // Note: The surface mean shear stress is decomposed into tau_xz by
2310  // multiplying the modeled shear stress (rho*ustar^2) with
2311  // a factor of umean/wsp_mean for directionality; this factor
2312  // modifies the denominator from what is in Moeng amrex::Real(1984.)
2313  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2314  amrex::Real num1 = wsp * umean;
2315  amrex::Real num2 = wsp_mean * (velx-umean);
2316 
2317  // NOTE: this is rho*<u'w'> = -K dudz
2318  amrex::Real stressx = -rho*ustar*ustar * (num1+num2)/(wsp_mean*wsp_mean);
2319  stressx = (is_low) ? stressx : -stressx;
2320 
2321  return stressx;
2322  }
constexpr amrex::Real fourth
Definition: ERF_NumericalConstants.H:42

◆ compute_v_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real moeng_flux::compute_v_flux ( const int &  i,
const int &  j,
const int &  k,
const int &  dir,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  velx_arr,
const amrex::Array4< const amrex::Real > &  vely_arr,
const amrex::Array4< const amrex::Real > &  velz_arr,
const amrex::Array4< const amrex::Real > &  umm_arr,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  vm_arr,
const amrex::Array4< const amrex::Real > &  wm_arr,
const amrex::Array4< const amrex::Real > &  u_star_arr 
) const
inline

Compute y-momentum flux for one surface face.

Calling sequence
i, j, k, cons_arr, velx_arr, vely_arr, umm_arr, vm_arr, u_star_arr.
2347  {
2348  // See compute_u_flux: stress indices on high walls must be mapped back
2349  // to the adjacent cell before reading cell-centered or tangential data.
2350  const int ic = (!is_low && dir == 0) ? i - 1 : i;
2351  const int jc = (!is_low && dir == 1) ? j - 1 : j;
2352  const int kc = (!is_low && dir != 0 && dir != 1) ? k - 1 : k;
2353 
2354  amrex::Real velx, vely, rho, vmean, ustar, wsp_mean;
2355  if (dir == 0) {
2356  // X wall: W-momentum flux at tau31. W is already z-nodal;
2357  // interpolate V and the cell-centered fields to that z node.
2358  const int klo = amrex::max(k - 1, m_zlo);
2359  const int khi = amrex::min(k, m_zhi);
2360  velx = fourth * ( vely_arr(ic,j ,klo) + vely_arr(ic,j+1,klo)
2361  + vely_arr(ic,j ,khi) + vely_arr(ic,j+1,khi) );
2362  vely = velz_arr(ic,j,k);
2363  rho = myhalf * (cons_arr(ic,j,klo,Rho_comp) + cons_arr(ic,j,khi,Rho_comp));
2364  vmean = wm_arr(ic,j,k);
2365  ustar = myhalf * (u_star_arr(ic,j,klo) + u_star_arr(ic,j,khi));
2366  wsp_mean = myhalf * (umm_arr(ic,j,klo) + umm_arr(ic,j,khi));
2367  } else if (dir == 1) {
2368  // Y wall: W-momentum flux at tau32. W is already z-nodal;
2369  // interpolate U and the cell-centered fields to that z node.
2370  const int klo = amrex::max(k - 1, m_zlo);
2371  const int khi = amrex::min(k, m_zhi);
2372  velx = fourth * ( velx_arr(i ,jc,klo) + velx_arr(i+1,jc,klo)
2373  + velx_arr(i ,jc,khi) + velx_arr(i+1,jc,khi) );
2374  vely = velz_arr(i,jc,k);
2375  rho = myhalf * (cons_arr(i,jc,klo,Rho_comp) + cons_arr(i,jc,khi,Rho_comp));
2376  vmean = wm_arr(i,jc,k);
2377  ustar = myhalf * (u_star_arr(i,jc,klo) + u_star_arr(i,jc,khi));
2378  wsp_mean = myhalf * (umm_arr(i,jc,klo) + umm_arr(i,jc,khi));
2379  } else {
2380  // Z wall: V-momentum flux at tau23.
2381  velx = fourth * ( velx_arr(i ,j-1,kc) + velx_arr(i+1,j-1,kc)
2382  + velx_arr(i ,j ,kc) + velx_arr(i+1,j ,kc) );
2383  vely = vely_arr(i,j,kc);
2384  rho = myhalf * (cons_arr(i,j-1,kc,Rho_comp) + cons_arr(i,j,kc,Rho_comp));
2385  vmean = vm_arr(i,j,kc);
2386  ustar = myhalf * (u_star_arr(i,j-1,kc) + u_star_arr(i,j,kc));
2387  wsp_mean = myhalf * (umm_arr(i,j-1,kc) + umm_arr(i,j,kc));
2388  }
2389  wsp_mean = std::max(wsp_mean, WSMIN);
2390 
2391  // Note: The surface mean shear stress is decomposed into tau_yz by
2392  // multiplying the modeled shear stress (rho*ustar^2) with
2393  // a factor of vmean/wsp_mean for directionality; this factor
2394  // modifies the denominator from what is in Moeng amrex::Real(1984.)
2395  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
2396  amrex::Real num1 = wsp * vmean;
2397  amrex::Real num2 = wsp_mean * (vely-vmean);
2398 
2399  // NOTE: this is rho*<v'w'> = -K dvdz
2400  amrex::Real stressy = -rho*ustar*ustar * (num1+num2)/(wsp_mean*wsp_mean);
2401  stressy = (is_low) ? stressy : -stressy;
2402 
2403  return stressy;
2404  }
const int klo
Definition: ERF_InitCustomPert_ABL.H:75
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21

Member Data Documentation

◆ eps

const amrex::Real moeng_flux::eps = amrex::Real(1e-15)
private

Referenced by compute_q_flux(), and compute_t_flux().

◆ is_low

bool moeng_flux::is_low = true
private

◆ m_zhi

int moeng_flux::m_zhi = 0
private

Referenced by compute_v_flux(), and moeng_flux().

◆ m_zlo

int moeng_flux::m_zlo = 0
private

Referenced by compute_v_flux(), and moeng_flux().

◆ WSMIN


The documentation for this struct was generated from the following file: