1 #ifndef ERF_SURFACELAYER_H
2 #define ERF_SURFACELAYER_H
4 #include "AMReX_Geometry.H"
5 #include "AMReX_ParmParse.H"
6 #include "AMReX_FArrayBox.H"
7 #include "AMReX_MultiFab.H"
8 #include "AMReX_iMultiFab.H"
9 #include "AMReX_Interpolater.H"
35 bool& use_rot_surface_flux,
36 std::string a_pp_prefix,
37 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qv_prim,
38 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& z_phys_nd,
39 const TerrainType& a_terrain_type,
40 amrex::Real start_bdy_time = 0.0,
41 amrex::Real bdy_time_interval = 0.0)
46 m_ma(geom, (z_phys_nd[0] != nullptr), a_pp_prefix, a_terrain_type)
52 amrex::ParmParse
pp(
"erf");
56 if (use_rot_surface_flux) {
59 std::string flux_string_in;
60 std::string flux_string{
"moeng"};
61 auto read_flux =
pp.query(
"surface_layer.flux_type", flux_string_in);
63 flux_string = amrex::toLower(flux_string_in);
65 if (flux_string ==
"donelan") {
67 }
else if (flux_string ==
"moeng") {
69 }
else if (flux_string ==
"custom") {
72 amrex::Abort(
"Undefined MOST flux type!");
79 std::string pblh_string_in;
80 std::string pblh_string{
"none"};
81 auto read_pblh =
pp.query(
"most.pblh_calc", pblh_string_in);
83 pblh_string = amrex::toLower(pblh_string_in);
85 if (pblh_string ==
"none") {
87 }
else if (pblh_string ==
"mynn25") {
89 }
else if (pblh_string ==
"mynnedmf") {
91 }
else if (pblh_string ==
"ysu") {
93 }
else if (pblh_string ==
"mrf") {
96 amrex::Abort(
"Undefined PBLH calc type!");
100 auto erf_st =
pp.query(
"most.surf_temp",
surf_temp);
117 "Specified custom MOST qv flux without moisture model!");
119 amrex::Print() <<
"Using specified ustar, tstar, qstar for MOST = "
130 amrex::Abort(
"Can only specify one of surf_temp_flux or surf_heating_rate");
136 amrex::Abort(
"Can only specify one of surf_temp_flux or surf_heating_rate");
161 std::string bogus_input;
162 if (
pp.query(
"most.roughness_type", bogus_input) > 0) {
163 amrex::Abort(
"most.roughness_type is deprecated; use "
164 "most.roughness_type_land and/or most.roughness_type_sea");
168 std::string rough_land_string_in;
169 std::string rough_land_string{
"constant"};
170 auto read_rough_land =
171 pp.query(
"most.roughness_type_land", rough_land_string_in);
172 if (read_rough_land) {
173 rough_land_string = amrex::toLower(rough_land_string_in);
175 if (rough_land_string ==
"constant") {
178 amrex::Abort(
"Undefined MOST roughness type for land!");
182 std::string rough_sea_string_in;
183 std::string rough_sea_string{
"charnock"};
184 auto read_rough_sea =
pp.query(
"most.roughness_type_sea", rough_sea_string_in);
185 if (read_rough_sea) {
186 rough_sea_string = amrex::toLower(rough_sea_string_in);
188 if (rough_sea_string ==
"charnock") {
190 pp.query(
"most.charnock_constant",
cnk_a);
191 pp.query(
"most.charnock_viscosity",
cnk_visc);
193 amrex::Print() <<
"If there is water, Charnock relation with C_a="
195 <<
" will be used" << std::endl;
197 amrex::Print() <<
"If there is water, Charnock relation with variable "
198 "Charnock parameter (COARE3.0)"
199 << (
cnk_visc ?
" and viscosity" :
"") <<
" will be used"
202 }
else if (rough_sea_string ==
"coare3.0") {
204 amrex::Print() <<
"If there is water, Charnock relation with variable "
205 "Charnock parameter (COARE3.0)"
206 << (
cnk_visc ?
" and viscosity" :
"") <<
" will be used"
209 }
else if (rough_sea_string ==
"donelan") {
211 }
else if (rough_sea_string ==
"modified_charnock") {
213 pp.query(
"most.modified_charnock_depth",
depth);
214 }
else if (rough_sea_string ==
"wave_coupled") {
216 }
else if (rough_sea_string ==
"constant") {
219 amrex::Abort(
"Undefined MOST roughness type for sea!");
225 const amrex::Vector<amrex::MultiFab*>& mfv,
226 std::unique_ptr<amrex::MultiFab>& Theta_prim,
227 std::unique_ptr<amrex::MultiFab>& Qv_prim,
228 std::unique_ptr<amrex::MultiFab>& Qr_prim,
229 std::unique_ptr<amrex::MultiFab>& z_phys_nd,
230 amrex::MultiFab* Hwave,
231 amrex::MultiFab* Lwave,
232 amrex::MultiFab* eddyDiffs,
233 amrex::Vector<amrex::MultiFab*> lsm_data,
234 amrex::Vector<amrex::MultiFab*> lsm_flux,
235 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& sst_lev,
236 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& tsk_lev,
237 amrex::Vector<std::unique_ptr<amrex::iMultiFab>>& lmask_lev)
241 Theta_prim, Qv_prim, Qr_prim,
245 amrex::MultiFab& mf = *(mfv[0]);
247 amrex::ParmParse
pp(
"erf");
251 const int nghost = 0;
253 amrex::ParallelDescriptor::ReduceIntMin(lmask_min);
257 std::string rough_sea_string{
"charnock"};
258 pp.query(
"most.roughness_type_sea", rough_sea_string);
259 amrex::Print() <<
"Variable sea roughness (type " << rough_sea_string
264 if ((lev == 0) || (lev > nlevs - 1)) {
289 int nt_tot_sst = sst_lev.size();
291 for (
int nt(0); nt < nt_tot_sst; ++nt) {
294 int nt_tot_tsk = tsk_lev.size();
296 for (
int nt(0); nt < nt_tot_tsk; ++nt) {
299 int nt_tot_lmask = lmask_lev.size();
301 for (
int nt(0); nt < nt_tot_lmask; ++nt) {
311 int nvar = lsm_data.size();
314 for (
int n(0); n < nvar; ++n) {
321 bool read_z0 =
false;
324 read_z0 =
pp.query(
"most.roughness_file_name", fname);
330 amrex::BoxArray ba = mf.boxArray();
331 amrex::BoxList bl2d = ba.boxList();
332 for (
auto& b : bl2d) {
335 amrex::BoxArray ba2d(std::move(bl2d));
336 const amrex::DistributionMapping& dm = mf.DistributionMap();
338 amrex::IntVect
ng = mf.nGrowVect();
343 amrex::Arena* Arena_Used = amrex::The_Arena();
345 Arena_Used = amrex::The_Pinned_Arena();
347 amrex::Box bx = amrex::grow(
m_geom[lev].Domain(),
ng);
350 z_0[lev].resize(bx, 1, Arena_Used);
358 u_star[lev] = std::make_unique<amrex::MultiFab>(ba2d, dm, ncomp,
ng);
359 u_star[lev]->setVal(1.E34);
361 w_star[lev] = std::make_unique<amrex::MultiFab>(ba2d, dm, ncomp,
ng);
362 w_star[lev]->setVal(1.E34);
364 t_star[lev] = std::make_unique<amrex::MultiFab>(ba2d, dm, ncomp,
ng);
367 q_star[lev] = std::make_unique<amrex::MultiFab>(ba2d, dm, ncomp,
ng);
370 olen[lev] = std::make_unique<amrex::MultiFab>(ba2d, dm, ncomp,
ng);
371 olen[lev]->setVal(1.E34);
373 pblh[lev] = std::make_unique<amrex::MultiFab>(ba2d, dm, ncomp,
ng);
374 pblh[lev]->setVal(1.E34);
376 t_surf[lev] = std::make_unique<amrex::MultiFab>(ba2d, dm, ncomp,
ng);
379 q_surf[lev] = std::make_unique<amrex::MultiFab>(ba2d, dm, ncomp,
ng);
396 const amrex::Real& time,
397 int max_iters = 500);
399 template <
typename FluxIter>
401 const int& max_iters,
402 const FluxIter& most_flux,
406 amrex::Vector<const amrex::MultiFab*> mfs,
407 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Tau_lev,
408 amrex::MultiFab* xheat_flux,
409 amrex::MultiFab* yheat_flux,
410 amrex::MultiFab* zheat_flux,
411 amrex::MultiFab* xqv_flux,
412 amrex::MultiFab* yqv_flux,
413 amrex::MultiFab* zqv_flux,
414 const amrex::MultiFab* z_phys);
416 template <
typename FluxCalc>
418 amrex::Vector<const amrex::MultiFab*> mfs,
419 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Tau_lev,
420 amrex::MultiFab* xheat_flux,
421 amrex::MultiFab* yheat_flux,
422 amrex::MultiFab* zheat_flux,
423 amrex::MultiFab* xqv_flux,
424 amrex::MultiFab* yqv_flux,
425 amrex::MultiFab* zqv_flux,
426 const amrex::MultiFab* z_phys,
427 const FluxCalc& flux_comp);
430 const amrex::Real& time);
436 amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars,
437 amrex::MultiFab* z_phys_cc,
438 const int RhoQv_comp,
439 const int RhoQc_comp,
440 const int RhoQr_comp);
442 template <
typename PBLHeightEstimator>
444 amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars,
445 amrex::MultiFab* z_phys_cc,
446 const PBLHeightEstimator& est,
447 const int RhoQv_comp,
448 const int RhoQc_comp,
449 const int RhoQr_comp);
452 const std::string& fname);
457 int nlevs =
m_geom.size();
458 for (
int lev = 0; lev < nlevs; lev++) {
460 amrex::Print() <<
"Surface temp at t=" << time <<
": "
467 amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars_old,
468 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Theta_prim,
469 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qv_prim,
470 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qr_prim)
498 amrex::FArrayBox*
get_z0 (
const int& lev) {
return &
z_0[lev]; }
507 int lmask_min = amrex::ReduceMin(lmask, nghost, [=] AMREX_GPU_HOST_DEVICE(
508 amrex::Box
const& bx, amrex::Array4<int const>
const& lm_arr) ->
int
510 int locmin = std::numeric_limits<int>::max();
511 const auto lo = lbound(bx);
512 const auto hi = ubound(bx);
513 for (
int j = lo.y; j <= hi.y; ++j) {
514 for (
int i = lo.x; i <= hi.x; ++i) {
515 locmin = std::min(locmin, lm_arr(i, j, 0));
582 amrex::Vector<amrex::FArrayBox>
z_0;
588 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
u_star;
589 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
w_star;
590 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
t_star;
591 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
q_star;
592 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
olen;
593 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
pblh;
594 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
t_surf;
595 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
q_surf;
597 amrex::Vector<amrex::Vector<amrex::MultiFab*>>
m_sst_lev;
598 amrex::Vector<amrex::Vector<amrex::MultiFab*>>
m_tsk_lev;
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pp(amrex::Real y)
Definition: ERF_MicrophysicsUtils.H:230
Definition: ERF_MOSTAverage.H:14
amrex::Real get_zref() const
Definition: ERF_MOSTAverage.H:104
const amrex::MultiFab * get_average(const int &lev, const int &comp) const
Definition: ERF_MOSTAverage.H:101
void update_field_ptrs(const int &lev, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars_old, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Theta_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qv_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qr_prim)
Definition: ERF_MOSTAverage.cpp:246
void make_MOSTAverage_at_level(const int &lev, const amrex::Vector< amrex::MultiFab * > &vars_old, std::unique_ptr< amrex::MultiFab > &Theta_prim, std::unique_ptr< amrex::MultiFab > &Qv_prim, std::unique_ptr< amrex::MultiFab > &Qr_prim, std::unique_ptr< amrex::MultiFab > &z_phys_nd)
Definition: ERF_MOSTAverage.cpp:70
Definition: ERF_SurfaceLayer.H:30
ThetaCalcType theta_type
Definition: ERF_SurfaceLayer.H:554
int lmask_min_reduce(amrex::iMultiFab &lmask, const int &nghost)
Definition: ERF_SurfaceLayer.H:504
bool m_include_wstar
Definition: ERF_SurfaceLayer.H:567
bool m_rotate
Definition: ERF_SurfaceLayer.H:563
void compute_pblh(const int &lev, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars, amrex::MultiFab *z_phys_cc, const PBLHeightEstimator &est, const int RhoQv_comp, const int RhoQc_comp, const int RhoQr_comp)
PBLHeightCalcType pblh_type
Definition: ERF_SurfaceLayer.H:558
amrex::Vector< amrex::Vector< amrex::iMultiFab * > > m_lmask_lev
Definition: ERF_SurfaceLayer.H:599
amrex::iMultiFab * get_lmask(const int &lev)
Definition: ERF_SurfaceLayer.H:502
bool use_moisture
Definition: ERF_SurfaceLayer.H:585
amrex::MultiFab * get_q_surf(const int &lev)
Definition: ERF_SurfaceLayer.H:494
SurfaceLayer(const amrex::Vector< amrex::Geometry > &geom, bool &use_rot_surface_flux, std::string a_pp_prefix, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qv_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &z_phys_nd, const TerrainType &a_terrain_type, amrex::Real start_bdy_time=0.0, amrex::Real bdy_time_interval=0.0)
Definition: ERF_SurfaceLayer.H:34
amrex::MultiFab * get_w_star(const int &lev)
Definition: ERF_SurfaceLayer.H:477
void update_surf_temp(const amrex::Real &time)
Definition: ERF_SurfaceLayer.H:454
RoughCalcType rough_type_land
Definition: ERF_SurfaceLayer.H:556
amrex::Vector< std::unique_ptr< amrex::MultiFab > > t_surf
Definition: ERF_SurfaceLayer.H:594
amrex::Real z0_const
Definition: ERF_SurfaceLayer.H:568
amrex::Real cnk_a
Definition: ERF_SurfaceLayer.H:579
amrex::Vector< amrex::FArrayBox > z_0
Definition: ERF_SurfaceLayer.H:582
void update_pblh(const int &lev, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars, amrex::MultiFab *z_phys_cc, const int RhoQv_comp, const int RhoQc_comp, const int RhoQr_comp)
Definition: ERF_SurfaceLayer.cpp:551
amrex::Real surf_temp
Definition: ERF_SurfaceLayer.H:570
void update_mac_ptrs(const int &lev, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars_old, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Theta_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qv_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qr_prim)
Definition: ERF_SurfaceLayer.H:466
void make_SurfaceLayer_at_level(const int &lev, int nlevs, const amrex::Vector< amrex::MultiFab * > &mfv, std::unique_ptr< amrex::MultiFab > &Theta_prim, std::unique_ptr< amrex::MultiFab > &Qv_prim, std::unique_ptr< amrex::MultiFab > &Qr_prim, std::unique_ptr< amrex::MultiFab > &z_phys_nd, amrex::MultiFab *Hwave, amrex::MultiFab *Lwave, amrex::MultiFab *eddyDiffs, amrex::Vector< amrex::MultiFab * > lsm_data, amrex::Vector< amrex::MultiFab * > lsm_flux, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &sst_lev, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &tsk_lev, amrex::Vector< std::unique_ptr< amrex::iMultiFab >> &lmask_lev)
Definition: ERF_SurfaceLayer.H:223
amrex::Vector< std::unique_ptr< amrex::MultiFab > > q_star
Definition: ERF_SurfaceLayer.H:591
amrex::Real m_start_bdy_time
Definition: ERF_SurfaceLayer.H:564
amrex::Vector< amrex::MultiFab * > m_Lwave_lev
Definition: ERF_SurfaceLayer.H:603
void get_lsm_tsurf(const int &lev)
Definition: ERF_SurfaceLayer.cpp:518
amrex::MultiFab * get_olen(const int &lev)
Definition: ERF_SurfaceLayer.H:483
amrex::Real surf_moist_flux
Definition: ERF_SurfaceLayer.H:575
void compute_SurfaceLayer_bcs(const int &lev, amrex::Vector< const amrex::MultiFab * > mfs, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Tau_lev, amrex::MultiFab *xheat_flux, amrex::MultiFab *yheat_flux, amrex::MultiFab *zheat_flux, amrex::MultiFab *xqv_flux, amrex::MultiFab *yqv_flux, amrex::MultiFab *zqv_flux, const amrex::MultiFab *z_phys, const FluxCalc &flux_comp)
RoughCalcType rough_type_sea
Definition: ERF_SurfaceLayer.H:557
void update_fluxes(const int &lev, const amrex::Real &time, int max_iters=500)
Definition: ERF_SurfaceLayer.cpp:12
amrex::Real surf_moist
Definition: ERF_SurfaceLayer.H:574
amrex::Vector< std::unique_ptr< amrex::MultiFab > > w_star
Definition: ERF_SurfaceLayer.H:589
amrex::MultiFab * get_u_star(const int &lev)
Definition: ERF_SurfaceLayer.H:475
amrex::Real m_bdy_time_interval
Definition: ERF_SurfaceLayer.H:565
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_lsm_data_lev
Definition: ERF_SurfaceLayer.H:600
amrex::Real custom_qstar
Definition: ERF_SurfaceLayer.H:578
amrex::Vector< std::unique_ptr< amrex::MultiFab > > u_star
Definition: ERF_SurfaceLayer.H:588
amrex::Vector< std::unique_ptr< amrex::MultiFab > > q_surf
Definition: ERF_SurfaceLayer.H:595
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_sst_lev
Definition: ERF_SurfaceLayer.H:597
FluxCalcType
Definition: ERF_SurfaceLayer.H:524
@ MOENG
Moeng functional form.
@ CUSTOM
Custom constant flux functional form.
@ ROTATE
Terrain rotation flux functional form.
@ DONELAN
Donelan functional form.
MoistCalcType
Definition: ERF_SurfaceLayer.H:537
@ SURFACE_MOISTURE
Surface Qv specified.
@ MOISTURE_FLUX
Qv-flux specified.
amrex::Real depth
Definition: ERF_SurfaceLayer.H:581
amrex::Vector< amrex::MultiFab * > m_Hwave_lev
Definition: ERF_SurfaceLayer.H:602
amrex::Real default_land_surf_moist
Definition: ERF_SurfaceLayer.H:573
bool m_var_z0
Definition: ERF_SurfaceLayer.H:583
amrex::MultiFab * get_t_star(const int &lev)
Definition: ERF_SurfaceLayer.H:479
bool have_variable_sea_roughness()
Definition: ERF_SurfaceLayer.H:500
void compute_fluxes(const int &lev, const int &max_iters, const FluxIter &most_flux, bool is_land)
Definition: ERF_SurfaceLayer.cpp:171
amrex::MultiFab * get_q_star(const int &lev)
Definition: ERF_SurfaceLayer.H:481
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_lsm_flux_lev
Definition: ERF_SurfaceLayer.H:601
PBLHeightCalcType
Definition: ERF_SurfaceLayer.H:551
amrex::MultiFab * get_pblh(const int &lev)
Definition: ERF_SurfaceLayer.H:485
void fill_tsurf_with_sst_and_tsk(const int &lev, const amrex::Real &time)
Definition: ERF_SurfaceLayer.cpp:445
amrex::Real surf_temp_flux
Definition: ERF_SurfaceLayer.H:572
amrex::Vector< amrex::Geometry > m_geom
Definition: ERF_SurfaceLayer.H:562
amrex::Vector< std::unique_ptr< amrex::MultiFab > > t_star
Definition: ERF_SurfaceLayer.H:590
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_tsk_lev
Definition: ERF_SurfaceLayer.H:598
amrex::Real custom_tstar
Definition: ERF_SurfaceLayer.H:577
bool cnk_visc
Definition: ERF_SurfaceLayer.H:580
amrex::Real surf_heating_rate
Definition: ERF_SurfaceLayer.H:571
RoughCalcType
Definition: ERF_SurfaceLayer.H:543
FluxCalcType flux_type
Definition: ERF_SurfaceLayer.H:553
MoistCalcType moist_type
Definition: ERF_SurfaceLayer.H:555
void impose_SurfaceLayer_bcs(const int &lev, amrex::Vector< const amrex::MultiFab * > mfs, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Tau_lev, amrex::MultiFab *xheat_flux, amrex::MultiFab *yheat_flux, amrex::MultiFab *zheat_flux, amrex::MultiFab *xqv_flux, amrex::MultiFab *yqv_flux, amrex::MultiFab *zqv_flux, const amrex::MultiFab *z_phys)
Definition: ERF_SurfaceLayer.cpp:238
amrex::Vector< amrex::MultiFab * > m_eddyDiffs_lev
Definition: ERF_SurfaceLayer.H:604
const amrex::MultiFab * get_mac_avg(const int &lev, int comp)
Definition: ERF_SurfaceLayer.H:487
amrex::Real custom_ustar
Definition: ERF_SurfaceLayer.H:576
amrex::Vector< std::unique_ptr< amrex::MultiFab > > olen
Definition: ERF_SurfaceLayer.H:592
amrex::FArrayBox * get_z0(const int &lev)
Definition: ERF_SurfaceLayer.H:498
amrex::MultiFab * get_t_surf(const int &lev)
Definition: ERF_SurfaceLayer.H:492
amrex::Vector< std::unique_ptr< amrex::MultiFab > > pblh
Definition: ERF_SurfaceLayer.H:593
amrex::Real default_land_surf_temp
Definition: ERF_SurfaceLayer.H:569
amrex::Real get_zref()
Definition: ERF_SurfaceLayer.H:496
ThetaCalcType
Definition: ERF_SurfaceLayer.H:531
@ SURFACE_TEMPERATURE
Surface temperature specified.
@ HEAT_FLUX
Heat-flux specified.
void read_custom_roughness(const int &lev, const std::string &fname)
Definition: ERF_SurfaceLayer.cpp:582
MOSTAverage m_ma
Definition: ERF_SurfaceLayer.H:587
@ ng
Definition: ERF_Morrison.H:48
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12