Skip to content

Commit

Permalink
Merge branch 'development' into kestrel
Browse files Browse the repository at this point in the history
  • Loading branch information
baperry2 authored Jun 10, 2024
2 parents baa2e01 + 649d4e7 commit e0eaddd
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 28 deletions.
6 changes: 3 additions & 3 deletions Docs/sphinx_doc/MOST.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,13 @@ In ERF, when the MOST boundary condition is applied, velocity and temperature in

MOST Inputs
~~~~~~~~~~~~~~~~~~~
To evaluate the fluxes with MOST, the surface rougness parameter :math:`z_{0}` must be specified. This quantity may be considered a constant or may be parameterized through the friction velocity :math:`u_{\star}`. ERF supports three methods for parameterizing the surface roughness: ``constant``, ``charnock``, and ``modified_charnock``. The latter two methods parameterize :math:`z_{0} = f(u_{\star})` and are described in `Jimenez & Dudhia, American Meteorological Society, 2018 <https://doi.org/10.1175/JAMC-D-17-0137.1>`_. The rougness calculation method may be specified with
To evaluate the fluxes with MOST, the surface rougness parameter :math:`z_{0}` must be specified. This quantity may be considered a constant or may be parameterized through the friction velocity :math:`u_{\star}`. ERF supports four methods for parameterizing the surface roughness: ``constant``, ``charnock``, ``modified_charnock``, and ``wave_coupled``. The latter three methods parameterize :math:`z_{0} = f(u_{\star})` and are described in `Jimenez & Dudhia, American Meteorological Society, 2018 <https://doi.org/10.1175/JAMC-D-17-0137.1>`_ and `Warner et. al, Ocean Modelling, 2010 <https://doi.org/10.1016/j.ocemod.2010.07.010>`_. The rougness calculation method may be specified with

::

erf.most.roughness_type = STRING #Z_0 type (constant, charnock, modified_charnock)
erf.most.roughness_type = STRING #Z_0 type (constant, charnock, modified_charnock, wave_couples)

If the ``charnock`` method is employed, the :math:`a` constant may be specified with ``erf.most.charnock_constant`` (defaults to 0.0185). If the ``modified_charnock`` method is employed, the depth :math:`d` may be specified with ``erf.most.modified_charnock_depth`` (defaults to 30 m).
If the ``charnock`` method is employed, the :math:`a` constant may be specified with ``erf.most.charnock_constant`` (defaults to 0.0185). If the ``modified_charnock`` method is employed, the depth :math:`d` may be specified with ``erf.most.modified_charnock_depth`` (defaults to 30 m). If the ``wave_coupled`` method is employed, the user must provide wave height and mean wavelength data.

When computing an average :math:`\overline{\phi}` for the MOST boundary, where :math:`\phi` denotes a generic variable, ERF supports a variety of approaches. Specifically, ``planar averages`` and ``local region averages`` may be computed with or without ``time averaging``. With each averaging methodology, the query point :math:`z` may be determined from the following procedures: specified vertical distance :math:`z_{ref}` from the bottom surface, specified :math:`k_{index}`, or (when employing terrain-fit coordinates) specified normal vector length :math:`z_{ref}`. The available inputs to the MOST boundary and their associated data types are

Expand Down
25 changes: 21 additions & 4 deletions Source/BoundaryConditions/ABLMost.H
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public:
amrex::Vector<amrex::Vector<std::unique_ptr<amrex::iMultiFab>>>& lmask_lev,
amrex::Vector<amrex::Vector<amrex::MultiFab*>> lsm_data,
amrex::Vector<amrex::Vector<amrex::MultiFab*>> lsm_flux,
amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Hwave,
amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Lwave,
amrex::Vector<std::unique_ptr<amrex::MultiFab>>& eddyDiffs,
amrex::Real start_bdy_time = 0.0,
amrex::Real bdy_time_interval = 0.0)
: m_exp_most(use_exp_most),
Expand Down Expand Up @@ -117,6 +120,8 @@ public:
} else if (rough_string == "modified_charnock") {
rough_type = RoughCalcType::MODIFIED_CHARNOCK;
pp.query("most.modified_charnock_depth",depth);
} else if (rough_string == "wave_coupled") {
rough_type = RoughCalcType::WAVE_COUPLED;
} else {
amrex::Abort("Undefined MOST roughness type!");
}
Expand Down Expand Up @@ -156,6 +161,16 @@ public:
}
}

// Get pointers to wave data
m_Hwave_lev.resize(nlevs);
m_Lwave_lev.resize(nlevs);
m_eddyDiffs_lev.resize(nlevs);
for (int lev(0); lev<nlevs; ++lev) {
m_Hwave_lev[lev] = Hwave[lev].get();
m_Lwave_lev[lev] = Lwave[lev].get();
m_eddyDiffs_lev[lev] = eddyDiffs[lev].get();
}

for (int lev = 0; lev < nlevs; lev++) {
// Attributes for MFs and FABs
//--------------------------------------------------------
Expand Down Expand Up @@ -225,7 +240,6 @@ public:
amrex::MultiFab* xzmom_flux, amrex::MultiFab* zxmom_flux,
amrex::MultiFab* yzmom_flux, amrex::MultiFab* zymom_flux,
amrex::MultiFab* heat_flux,
amrex::MultiFab* eddyDiffs,
amrex::MultiFab* z_phys);

template<typename FluxCalc>
Expand All @@ -235,7 +249,6 @@ public:
amrex::MultiFab* xzmom_flux, amrex::MultiFab* zxmom_flux,
amrex::MultiFab* yzmom_flux, amrex::MultiFab* zymom_flux,
amrex::MultiFab* heat_flux,
amrex::MultiFab* eddyDiffs,
amrex::MultiFab* z_phys,
const amrex::Real& dz_no_terrain,
const FluxCalc& flux_comp);
Expand Down Expand Up @@ -306,7 +319,8 @@ public:
enum struct RoughCalcType {
CONSTANT = 0, ///< Constant z0
CHARNOCK,
MODIFIED_CHARNOCK
MODIFIED_CHARNOCK,
WAVE_COUPLED
};

FluxCalcType flux_type{FluxCalcType::MOENG};
Expand All @@ -316,7 +330,7 @@ public:
private:
bool use_moisture;
bool m_exp_most = false;
amrex::Real z0_const;
amrex::Real z0_const{0.1};
amrex::Real surf_temp;
amrex::Real surf_heating_rate{0};
amrex::Real surf_temp_flux{0};
Expand All @@ -341,6 +355,9 @@ private:
amrex::Vector<amrex::Vector<amrex::iMultiFab*>> m_lmask_lev;
amrex::Vector<amrex::Vector<amrex::MultiFab*>> m_lsm_data_lev;
amrex::Vector<amrex::Vector<amrex::MultiFab*>> m_lsm_flux_lev;
amrex::Vector<amrex::MultiFab*> m_Hwave_lev;
amrex::Vector<amrex::MultiFab*> m_Lwave_lev;
amrex::Vector<amrex::MultiFab*> m_eddyDiffs_lev;
};

#endif /* ABLMOST_H */
30 changes: 20 additions & 10 deletions Source/BoundaryConditions/ABLMost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ ABLMost::update_fluxes (const int& lev,
} else if (rough_type == RoughCalcType::CHARNOCK) {
surface_flux_charnock most_flux(m_ma.get_zref(), surf_temp_flux, cnk_a);
compute_fluxes(lev, max_iters, most_flux);
} else {
} else if (rough_type == RoughCalcType::MODIFIED_CHARNOCK) {
surface_flux_mod_charnock most_flux(m_ma.get_zref(), surf_temp_flux, depth);
compute_fluxes(lev, max_iters, most_flux);
} else {
surface_flux_wave_coupled most_flux(m_ma.get_zref(), surf_temp_flux);
compute_fluxes(lev, max_iters, most_flux);
}
} else if (theta_type == ThetaCalcType::SURFACE_TEMPERATURE) {
update_surf_temp(time);
Expand All @@ -48,9 +51,12 @@ ABLMost::update_fluxes (const int& lev,
} else if (rough_type == RoughCalcType::CHARNOCK) {
surface_temp_charnock most_flux(m_ma.get_zref(), surf_temp_flux, cnk_a);
compute_fluxes(lev, max_iters, most_flux);
} else {
} else if (rough_type == RoughCalcType::MODIFIED_CHARNOCK) {
surface_temp_mod_charnock most_flux(m_ma.get_zref(), surf_temp_flux, depth);
compute_fluxes(lev, max_iters, most_flux);
} else {
surface_temp_wave_coupled most_flux(m_ma.get_zref(), surf_temp_flux);
compute_fluxes(lev, max_iters, most_flux);
}
} else {
if (rough_type == RoughCalcType::CONSTANT) {
Expand All @@ -59,9 +65,12 @@ ABLMost::update_fluxes (const int& lev,
} else if (rough_type == RoughCalcType::CHARNOCK) {
adiabatic_charnock most_flux(m_ma.get_zref(), surf_temp_flux, cnk_a);
compute_fluxes(lev, max_iters, most_flux);
} else {
} else if (rough_type == RoughCalcType::MODIFIED_CHARNOCK) {
adiabatic_mod_charnock most_flux(m_ma.get_zref(), surf_temp_flux, depth);
compute_fluxes(lev, max_iters, most_flux);
} else {
adiabatic_wave_coupled most_flux(m_ma.get_zref(), surf_temp_flux);
compute_fluxes(lev, max_iters, most_flux);
}
} // theta flux
} else if (flux_type == FluxCalcType::CUSTOM) {
Expand Down Expand Up @@ -102,10 +111,16 @@ ABLMost::compute_fluxes (const int& lev,
const auto umm_arr = umm_ptr->array(mfi);
const auto z0_arr = z_0[lev].array();

// Wave properties if they exist
const auto Hwave_arr = (m_Hwave_lev[lev]) ? m_Hwave_lev[lev]->array(mfi) : Array4<Real> {};
const auto Lwave_arr = (m_Lwave_lev[lev]) ? m_Lwave_lev[lev]->array(mfi) : Array4<Real> {};
const auto eta_arr = m_eddyDiffs_lev[lev]->array(mfi);

ParallelFor(gtbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
{
most_flux.iterate_flux(i, j, k, max_iters, z0_arr, umm_arr, tm_arr,
u_star_arr, t_star_arr, t_surf_arr, olen_arr);
u_star_arr, t_star_arr, t_surf_arr, olen_arr,
Hwave_arr, Lwave_arr, eta_arr);
});
}
}
Expand All @@ -124,7 +139,6 @@ ABLMost::impose_most_bcs (const int& lev,
MultiFab* xzmom_flux, MultiFab* zxmom_flux,
MultiFab* yzmom_flux, MultiFab* zymom_flux,
MultiFab* heat_flux,
MultiFab* eddyDiffs,
MultiFab* z_phys)
{
const int klo = 0;
Expand All @@ -134,23 +148,20 @@ ABLMost::impose_most_bcs (const int& lev,
xzmom_flux, zxmom_flux,
yzmom_flux, zymom_flux,
heat_flux,
eddyDiffs,
z_phys, m_geom[lev].CellSize(2), flux_comp);
} else if (flux_type == FluxCalcType::DONELAN) {
donelan_flux flux_comp(klo);
compute_most_bcs(lev, mfs,
xzmom_flux, zxmom_flux,
yzmom_flux, zymom_flux,
heat_flux,
eddyDiffs,
z_phys, m_geom[lev].CellSize(2), flux_comp);
} else {
custom_flux flux_comp(klo);
compute_most_bcs(lev, mfs,
xzmom_flux, zxmom_flux,
yzmom_flux, zymom_flux,
heat_flux,
eddyDiffs,
z_phys, m_geom[lev].CellSize(2), flux_comp);
}
}
Expand All @@ -171,7 +182,6 @@ ABLMost::compute_most_bcs (const int& lev,
MultiFab* xzmom_flux, MultiFab* zxmom_flux,
MultiFab* yzmom_flux, MultiFab* zymom_flux,
MultiFab* heat_flux,
MultiFab* eddyDiffs,
MultiFab* z_phys,
const Real& dz_no_terrain,
const FluxCalc& flux_comp)
Expand Down Expand Up @@ -201,7 +211,7 @@ ABLMost::compute_most_bcs (const int& lev,
auto t32_arr = (zymom_flux && m_exp_most) ? zymom_flux->array(mfi) : Array4<Real>{};
auto hfx_arr = (m_exp_most) ? heat_flux->array(mfi) : Array4<Real>{};

const auto eta_arr = eddyDiffs->array(mfi);
const auto eta_arr = m_eddyDiffs_lev[lev]->array(mfi);

const auto zphys_arr = (z_phys) ? z_phys->const_array(mfi) : Array4<const Real>{};

Expand Down
1 change: 0 additions & 1 deletion Source/BoundaryConditions/ERF_FillPatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,6 @@ ERF::FillIntermediatePatch (int lev, Real time,
Tau13_lev[lev].get(), Tau31_lev[lev].get(),
Tau23_lev[lev].get(), Tau32_lev[lev].get(),
SFS_hfx3_lev[lev].get(),
eddyDiffs_lev[lev].get(),
z_phys_nd[lev].get());
}

Expand Down
Loading

0 comments on commit e0eaddd

Please sign in to comment.