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

#include <ERF_MOSTStress.H>

Collaboration diagram for donelan_flux:

Public Member Functions

 donelan_flux (int l_zlo)
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_q_flux (const int &i, const int &j, const int &k, const int &n, const int &icomp, const amrex::Real &dz, const amrex::Real &dz1, const bool &exp_most, const amrex::Array4< const amrex::Real > &eta_arr, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< amrex::Real > &dest_arr) const
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_t_flux (const int &i, const int &j, const int &k, const int &n, const int &icomp, const amrex::Real &dz, const amrex::Real &dz1, const bool &exp_most, const amrex::Array4< const amrex::Real > &eta_arr, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &t_surf_arr, const amrex::Array4< amrex::Real > &dest_arr) const
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_u_flux (const int &i, const int &j, const int &k, const int &icomp, const amrex::Real &dz, const amrex::Real &dz1, const bool &exp_most, const amrex::Array4< const amrex::Real > &eta_arr, 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 > &umm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< amrex::Real > &dest_arr) const
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_v_flux (const int &i, const int &j, const int &k, const int &icomp, const amrex::Real &dz, const amrex::Real &dz1, const bool &exp_most, const amrex::Array4< const amrex::Real > &eta_arr, 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 > &umm_arr, const amrex::Array4< const amrex::Real > &, const amrex::Array4< const amrex::Real > &, const amrex::Array4< amrex::Real > &dest_arr) const
 

Private Attributes

int zlo
 
const amrex::Real eta_eps = 1e-8
 

Detailed Description

Donelan flux formulation

Constructor & Destructor Documentation

◆ donelan_flux()

donelan_flux::donelan_flux ( int  l_zlo)
inline
1569  : zlo(l_zlo) {}
int zlo
Definition: ERF_MOSTStress.H:1839

Member Function Documentation

◆ compute_q_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real donelan_flux::compute_q_flux ( const int &  i,
const int &  j,
const int &  k,
const int &  n,
const int &  icomp,
const amrex::Real &  dz,
const amrex::Real &  dz1,
const bool &  exp_most,
const amrex::Array4< const amrex::Real > &  eta_arr,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< amrex::Real > &  dest_arr 
) const
inline
1593  {
1594  amrex::Real rho, eta;
1595 
1596  int ic, jc;
1597  ic = i < lbound(cons_arr).x ? lbound(cons_arr).x : i;
1598  jc = j < lbound(cons_arr).y ? lbound(cons_arr).y : j;
1599  ic = ic > ubound(cons_arr).x ? ubound(cons_arr).x : ic;
1600  jc = jc > ubound(cons_arr).y ? ubound(cons_arr).y : jc;
1601 
1602  rho = cons_arr(ic,jc,zlo,Rho_comp);
1603 
1604  // TODO: Integrate MOST with moisture and DONELAN FLUX type
1605  amrex::Real deltaz = dz * (zlo - k);
1606 
1607  // NOTE: this is rho*<q'w'> = -K dqdz
1608  amrex::Real moflux = 0.0;
1609 
1610  if (exp_most) {
1611  // surface gradient equal to gradient at first zface
1612  amrex::Real rqvgrad = (cons_arr(ic,jc,zlo+1,RhoQ1_comp) - cons_arr(ic,jc,zlo ,RhoQ1_comp)) / (0.5*(dz+dz1));
1613  dest_arr(i,j,k,icomp+n) = cons_arr(ic,jc,zlo,RhoQ1_comp) - rqvgrad * deltaz;
1614  } else {
1615  int ie, je;
1616  ie = i < lbound(eta_arr).x ? lbound(eta_arr).x : i;
1617  je = j < lbound(eta_arr).y ? lbound(eta_arr).y : j;
1618  ie = ie > ubound(eta_arr).x ? ubound(eta_arr).x : ie;
1619  je = je > ubound(eta_arr).y ? ubound(eta_arr).y : je;
1620  eta = eta_arr(ie,je,zlo,EddyDiff::Q_v); // == rho * alpha [kg/m^3 * m^2/s]
1621  eta = amrex::max(eta,eta_eps);
1622  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,zlo,icomp+n) + moflux*rho/eta*deltaz;
1623  }
1624 
1625  return moflux;
1626  }
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
@ Q_v
Definition: ERF_IndexDefines.H:160
@ rho
Definition: ERF_Kessler.H:30
const amrex::Real eta_eps
Definition: ERF_MOSTStress.H:1840

◆ compute_t_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real donelan_flux::compute_t_flux ( const int &  i,
const int &  j,
const int &  k,
const int &  n,
const int &  icomp,
const amrex::Real &  dz,
const amrex::Real &  dz1,
const bool &  exp_most,
const amrex::Array4< const amrex::Real > &  eta_arr,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  umm_arr,
const amrex::Array4< const amrex::Real > &  tm_arr,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  t_surf_arr,
const amrex::Array4< amrex::Real > &  dest_arr 
) const
inline
1649  {
1650  amrex::Real rho, eta;
1651 
1652  int ic, jc;
1653  ic = i < lbound(cons_arr).x ? lbound(cons_arr).x : i;
1654  jc = j < lbound(cons_arr).y ? lbound(cons_arr).y : j;
1655  ic = ic > ubound(cons_arr).x ? ubound(cons_arr).x : ic;
1656  jc = jc > ubound(cons_arr).y ? ubound(cons_arr).y : jc;
1657 
1658  rho = cons_arr(ic,jc,zlo,Rho_comp);
1659 
1660  amrex::Real Ch = 0.0012;
1661  amrex::Real wsp_mean = umm_arr(ic,jc,zlo);
1662  amrex::Real theta_surf = t_surf_arr(ic,jc,zlo);
1663  amrex::Real theta_mean = tm_arr(ic,jc,zlo);
1664  amrex::Real deltaz = dz * (zlo - k);
1665 
1666  // NOTE: this is rho*<T'w'> = -K dTdz
1667  amrex::Real moflux = -rho * Ch * wsp_mean * (theta_mean - theta_surf);
1668 
1669  if (exp_most) {
1670  // surface gradient equal to gradient at first zface
1671  amrex::Real rthetagrad = (cons_arr(ic,jc,zlo+1,RhoTheta_comp) - cons_arr(ic,jc,zlo,RhoTheta_comp)) / (0.5*(dz+dz1));
1672  dest_arr(i,j,k,icomp+n) = cons_arr(ic,jc,zlo,RhoTheta_comp) - rthetagrad * deltaz;
1673  } else {
1674  int ie, je;
1675  ie = i < lbound(eta_arr).x ? lbound(eta_arr).x : i;
1676  je = j < lbound(eta_arr).y ? lbound(eta_arr).y : j;
1677  ie = ie > ubound(eta_arr).x ? ubound(eta_arr).x : ie;
1678  je = je > ubound(eta_arr).y ? ubound(eta_arr).y : je;
1679  eta = eta_arr(ie,je,zlo,EddyDiff::Theta_v); // == rho * alpha [kg/m^3 * m^2/s]
1680  eta = amrex::max(eta,eta_eps);
1681  // Note: Kh = eta/rho
1682  // hfx = -Kh dT/dz ==> +ve hfx corresponds to heating from the surface
1683  // Extrapolate from klo to ghost cell a distance of -deltaz; negative signs cancel
1684  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,zlo,icomp+n) + moflux*rho/eta*deltaz;
1685  }
1686 
1687  return moflux;
1688  }
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
@ Theta_v
Definition: ERF_IndexDefines.H:157

◆ compute_u_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real donelan_flux::compute_u_flux ( const int &  i,
const int &  j,
const int &  k,
const int &  icomp,
const amrex::Real &  dz,
const amrex::Real &  dz1,
const bool &  exp_most,
const amrex::Array4< const amrex::Real > &  eta_arr,
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 > &  umm_arr,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< amrex::Real > &  dest_arr 
) const
inline
1708  {
1709  amrex::Real velx, vely, rho, eta;
1710  int jy, ic, jc;
1711 
1712  int iylo = i <= lbound(vely_arr).x ? lbound(vely_arr).x : i-1;
1713  int iyhi = i > ubound(vely_arr).x ? ubound(vely_arr).x : i;
1714 
1715  jy = j < lbound(vely_arr).y ? lbound(vely_arr).y : j;
1716  jy = jy > ubound(vely_arr).y-1 ? ubound(vely_arr).y-1 : jy;
1717 
1718  ic = i < lbound(cons_arr).x+1 ? lbound(cons_arr).x+1 : i;
1719  jc = j < lbound(cons_arr).y ? lbound(cons_arr).y : j;
1720  ic = ic > ubound(cons_arr).x ? ubound(cons_arr).x : ic;
1721  jc = jc > ubound(cons_arr).y ? ubound(cons_arr).y : jc;
1722 
1723  velx = velx_arr(i,j,zlo);
1724  vely = 0.25*( vely_arr(iyhi,jy,zlo)+vely_arr(iyhi,jy+1,zlo)
1725  + vely_arr(iylo,jy,zlo)+vely_arr(iylo,jy+1,zlo) );
1726  rho = 0.5 *( cons_arr(ic-1,jc,zlo,Rho_comp)
1727  + cons_arr(ic ,jc,zlo,Rho_comp) );
1728 
1729  amrex::Real Cd = 0.001;
1730  const amrex::Real c = 7e-5;
1731  amrex::Real wsp = sqrt(velx*velx+vely*vely);
1732  amrex::Real wsp_mean = 0.5 * ( umm_arr(ic-1,jc,zlo) + umm_arr(ic,jc,zlo) );
1733  if (wsp_mean <= 5.0) {
1734  Cd = 0.001;
1735  } else if (wsp_mean < 25.0 && wsp_mean > 5.0) {
1736  Cd = 0.001 + c * (wsp_mean - 5.0);
1737  } else {
1738  Cd = 0.0024;
1739  }
1740  amrex::Real deltaz = dz * (zlo - k);
1741 
1742  // NOTE: this is rho*<u'w'> = -K dudz
1743  amrex::Real stressx = -rho * Cd * velx * wsp;
1744 
1745  if (exp_most) {
1746  // surface gradient equal to gradient at first zface
1747  amrex::Real ugrad = (velx_arr(i,j,zlo+1) - velx) / (0.5*(dz+dz1));
1748  dest_arr(i,j,k,icomp) = velx - ugrad * deltaz;
1749  } else {
1750  int ie, je;
1751  ie = i < lbound(eta_arr).x+1 ? lbound(eta_arr).x+1 : i;
1752  je = j < lbound(eta_arr).y ? lbound(eta_arr).y : j;
1753  ie = ie > ubound(eta_arr).x ? ubound(eta_arr).x : ie;
1754  je = je > ubound(eta_arr).y ? ubound(eta_arr).y : je;
1755  eta = 0.5 *( eta_arr(ie-1,je,zlo,EddyDiff::Mom_v)
1756  + eta_arr(ie ,je,zlo,EddyDiff::Mom_v) );
1757  eta = amrex::max(eta,eta_eps);
1758  dest_arr(i,j,k,icomp) = dest_arr(i,j,zlo,icomp) + stressx/eta*deltaz;
1759  }
1760 
1761  return stressx;
1762  }
@ Mom_v
Definition: ERF_IndexDefines.H:156

◆ compute_v_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real donelan_flux::compute_v_flux ( const int &  i,
const int &  j,
const int &  k,
const int &  icomp,
const amrex::Real &  dz,
const amrex::Real &  dz1,
const bool &  exp_most,
const amrex::Array4< const amrex::Real > &  eta_arr,
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 > &  umm_arr,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< const amrex::Real > &  ,
const amrex::Array4< amrex::Real > &  dest_arr 
) const
inline
1782  {
1783  amrex::Real velx, vely, rho, eta;
1784  int ix, ic, jc;
1785 
1786  ix = i < lbound(velx_arr).x ? lbound(velx_arr).x : i;
1787  ix = ix > ubound(velx_arr).x ? ubound(velx_arr).x : ix;
1788 
1789  int jxlo = j <= lbound(velx_arr).y ? lbound(velx_arr).y : j-1;
1790  int jxhi = j > ubound(velx_arr).y ? ubound(velx_arr).y : j;
1791 
1792  ic = i < lbound(cons_arr).x ? lbound(cons_arr).x : i;
1793  jc = j < lbound(cons_arr).y+1 ? lbound(cons_arr).y+1 : j;
1794  ic = ic > ubound(cons_arr).x ? ubound(cons_arr).x : ic;
1795  jc = jc > ubound(cons_arr).y ? ubound(cons_arr).y : jc;
1796 
1797  velx = 0.25*( velx_arr(ix,jxhi,zlo)+velx_arr(ix+1,jxhi,zlo)
1798  + velx_arr(ix,jxlo,zlo)+velx_arr(ix+1,jxlo,zlo) );
1799  vely = vely_arr(i,j,zlo);
1800  rho = 0.5*( cons_arr(ic,jc-1,zlo,Rho_comp)
1801  + cons_arr(ic,jc ,zlo,Rho_comp) );
1802 
1803  amrex::Real Cd = 0.001;
1804  const amrex::Real c = 7e-5;
1805  amrex::Real wsp = sqrt(velx*velx+vely*vely);
1806  amrex::Real wsp_mean = 0.5 * ( umm_arr(ic,jc-1,zlo) + umm_arr(ic,jc,zlo) );
1807  if (wsp_mean <= 5.0) {
1808  Cd = 0.001;
1809  } else if (wsp_mean < 25.0 && wsp_mean > 5.0) {
1810  Cd = 0.001 + c * (wsp_mean - 5.0);
1811  } else {
1812  Cd = 0.0024;
1813  }
1814  amrex::Real deltaz = dz * (zlo - k);
1815 
1816  // NOTE: this is rho*<v'w'> = -K dvdz
1817  amrex::Real stressy = -rho * Cd * vely * wsp;
1818 
1819  if (exp_most) {
1820  // surface gradient equal to gradient at first zface
1821  amrex::Real vgrad = (vely_arr(i,j,zlo+1) - vely) / (0.5*(dz+dz1));
1822  dest_arr(i,j,k,icomp) = vely - vgrad * deltaz;
1823  } else {
1824  int ie, je;
1825  ie = i < lbound(eta_arr).x ? lbound(eta_arr).x : i;
1826  je = j < lbound(eta_arr).y+1 ? lbound(eta_arr).y+1 : j;
1827  ie = ie > ubound(eta_arr).x ? ubound(eta_arr).x : ie;
1828  je = je > ubound(eta_arr).y ? ubound(eta_arr).y : je;
1829  eta = 0.5*( eta_arr(ie,je-1,zlo,EddyDiff::Mom_v)
1830  + eta_arr(ie,je ,zlo,EddyDiff::Mom_v) );
1831  eta = amrex::max(eta,eta_eps);
1832  dest_arr(i,j,k,icomp) = dest_arr(i,j,zlo,icomp) + stressy/eta*deltaz;
1833  }
1834 
1835  return stressy;
1836  }

Member Data Documentation

◆ eta_eps

const amrex::Real donelan_flux::eta_eps = 1e-8
private

◆ zlo

int donelan_flux::zlo
private

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