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 explicit ABLMost (
const amrex::Vector<amrex::Geometry>& geom,
38 amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars_old,
39 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Theta_prim,
40 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qv_prim,
41 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qr_prim,
42 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& z_phys_nd,
43 amrex::Vector<amrex::Vector<std::unique_ptr<amrex::MultiFab>>>& sst_lev,
44 amrex::Vector<amrex::Vector<std::unique_ptr<amrex::iMultiFab>>>& lmask_lev,
45 amrex::Vector<amrex::Vector<amrex::MultiFab*>> lsm_data,
46 amrex::Vector<amrex::Vector<amrex::MultiFab*>> lsm_flux,
47 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Hwave,
48 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Lwave,
49 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& eddyDiffs,
50 amrex::Real start_bdy_time = 0.0,
51 amrex::Real bdy_time_interval = 0.0)
57 m_ma(geom,vars_old,Theta_prim,Qv_prim,Qr_prim,z_phys_nd)
63 amrex::ParmParse
pp(
"erf");
70 std::string flux_string{
"moeng"};
71 pp.query(
"most.flux_type", flux_string);
72 if (flux_string ==
"donelan") {
74 }
else if (flux_string ==
"moeng") {
76 }
else if (flux_string ==
"custom") {
79 amrex::Abort(
"Undefined MOST flux type!");
86 std::string pblh_string{
"none"};
87 pp.query(
"most.pblh_calc", pblh_string);
88 if (pblh_string ==
"none") {
90 }
else if (pblh_string ==
"MYNN2.5") {
92 }
else if (pblh_string ==
"YSU") {
95 amrex::Abort(
"Undefined PBLH calc type!");
99 auto erf_st =
pp.query(
"most.surf_temp",
surf_temp);
108 AMREX_ASSERT_WITH_MESSAGE(
use_moisture,
"Specified custom MOST qv flux without moisture model!");
110 amrex::Print() <<
"Using specified ustar, tstar, qstar for MOST = "
122 amrex::Abort(
"Can only specify one of surf_temp_flux or surf_heating_rate");
127 amrex::Abort(
"Can only specify one of surf_temp_flux or surf_heating_rate");
129 if (std::abs(
surf_temp_flux) > std::numeric_limits<amrex::Real>::epsilon()) {
138 std::string rough_land_string{
"constant"};
139 pp.query(
"most.roughness_type_land", rough_land_string);
140 if (rough_land_string ==
"constant") {
143 amrex::Abort(
"Undefined MOST roughness type for land!");
147 std::string rough_sea_string{
"charnock"};
148 pp.query(
"most.roughness_type_sea", rough_sea_string);
149 if (rough_sea_string ==
"charnock") {
151 pp.query(
"most.charnock_constant",
cnk_a);
154 amrex::Print() <<
"If there is water, Charnock relation with C_a=" <<
cnk_a
155 << (
cnk_visc?
" and viscosity" :
"")
159 amrex::Print() <<
"If there is water, Charnock relation with variable Charnock parameter (COARE3.0)"
160 << (
cnk_visc?
" and viscosity" :
"")
164 }
else if (rough_sea_string ==
"coare3.0") {
166 amrex::Print() <<
"If there is water, Charnock relation with variable Charnock parameter (COARE3.0)"
167 << (
cnk_visc?
" and viscosity" :
"")
171 }
else if (rough_sea_string ==
"donelan") {
173 }
else if (rough_sea_string ==
"modified_charnock") {
175 pp.query(
"most.modified_charnock_depth",
depth);
176 }
else if (rough_sea_string ==
"wave_coupled") {
178 }
else if (rough_sea_string ==
"constant") {
181 amrex::Abort(
"Undefined MOST roughness type for sea!");
186 bool read_z0 =
false;
189 read_z0 =
pp.query(
"most.roughness_file_name", fname);
193 const int nghost = 0;
196 amrex::ParallelDescriptor::ReduceIntMin(lmask_min);
200 amrex::Print() <<
"Variable sea roughness (type " << rough_sea_string <<
")" << std::endl;
204 int nlevs =
m_geom.size();
218 for (
int lev(0); lev<nlevs; ++lev) {
219 int nt_tot_sst = sst_lev[lev].size();
221 for (
int nt(0); nt<nt_tot_sst; ++nt) {
222 m_sst_lev[lev][nt] = sst_lev[lev][nt].get();
224 int nt_tot_lmask = lmask_lev[lev].size();
226 for (
int nt(0); nt<nt_tot_lmask; ++nt) {
234 for (
int lev(0); lev<nlevs; ++lev) {
235 int nvar = lsm_data[lev].size();
238 for (
int n(0); n<nvar; ++n) {
248 for (
int lev(0); lev<nlevs; ++lev) {
254 for (
int lev = 0; lev < nlevs; lev++) {
259 amrex::BoxArray ba = mf.boxArray();
260 amrex::BoxList bl2d = ba.boxList();
261 for (
auto& b : bl2d) {
264 amrex::BoxArray ba2d(std::move(bl2d));
265 const amrex::DistributionMapping& dm = mf.DistributionMap();
267 amrex::IntVect ng = mf.nGrowVect(); ng[2]=0;
271 amrex::Arena* Arena_Used = amrex::The_Arena();
273 Arena_Used = amrex::The_Pinned_Arena();
275 amrex::Box bx = amrex::grow(
m_geom[lev].Domain(),ng);
278 z_0[lev].resize(bx,1,Arena_Used);
284 u_star[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
285 u_star[lev]->setVal(1.E34);
287 w_star[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
288 w_star[lev]->setVal(1.E34);
290 t_star[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
293 q_star[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
296 olen[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
297 olen[lev]->setVal(1.E34);
299 pblh[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
300 pblh[lev]->setVal(1.E34);
302 t_surf[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
319 const amrex::Real& time,
322 template <
typename FluxIter>
325 const int& max_iters,
326 const FluxIter& most_flux,
331 const amrex::Vector<amrex::MultiFab*>& mfs,
332 amrex::MultiFab* xxmom_flux,
333 amrex::MultiFab* yymom_flux,
334 amrex::MultiFab* zzmom_flux,
335 amrex::MultiFab* xymom_flux, amrex::MultiFab* yxmom_flux,
336 amrex::MultiFab* xzmom_flux, amrex::MultiFab* zxmom_flux,
337 amrex::MultiFab* yzmom_flux, amrex::MultiFab* zymom_flux,
338 amrex::MultiFab* xheat_flux,
339 amrex::MultiFab* yheat_flux,
340 amrex::MultiFab* zheat_flux,
341 amrex::MultiFab* xqv_flux,
342 amrex::MultiFab* yqv_flux,
343 amrex::MultiFab* zqv_flux,
344 amrex::MultiFab* z_phys);
346 template <
typename FluxCalc>
349 const amrex::Vector<amrex::MultiFab*>& mfs,
350 amrex::MultiFab* xxmom_flux,
351 amrex::MultiFab* yymom_flux,
352 amrex::MultiFab* zzmom_flux,
353 amrex::MultiFab* xymom_flux, amrex::MultiFab* yxmom_flux,
354 amrex::MultiFab* xzmom_flux, amrex::MultiFab* zxmom_flux,
355 amrex::MultiFab* yzmom_flux, amrex::MultiFab* zymom_flux,
356 amrex::MultiFab* xheat_flux,
357 amrex::MultiFab* yheat_flux,
358 amrex::MultiFab* zheat_flux,
359 amrex::MultiFab* xqv_flux,
360 amrex::MultiFab* yqv_flux,
361 amrex::MultiFab* zqv_flux,
362 amrex::MultiFab* z_phys,
363 const FluxCalc& flux_comp);
367 const amrex::Real& time);
375 amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars,
376 amrex::MultiFab* z_phys_cc,
377 const int RhoQv_comp,
378 const int RhoQc_comp,
379 const int RhoQr_comp);
381 template <
typename PBLHeightEstimator>
384 amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars,
385 amrex::MultiFab* z_phys_cc,
386 const PBLHeightEstimator& est,
387 const int RhoQv_comp,
388 const int RhoQc_comp,
389 const int RhoQr_comp);
393 const std::string& fname);
399 int nlevs =
m_geom.size();
400 for (
int lev = 0; lev < nlevs; lev++)
403 amrex::Print() <<
"Surface temp at t=" << time
413 amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars_old,
414 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Theta_prim,
415 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qv_prim,
416 amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qr_prim)
419 const amrex::MultiFab*
422 const amrex::MultiFab*
425 const amrex::MultiFab*
428 const amrex::MultiFab*
431 const amrex::MultiFab*
434 const amrex::MultiFab*
437 const amrex::MultiFab*
440 const amrex::MultiFab*
446 const amrex::FArrayBox*
451 const amrex::iMultiFab*
457 int lmask_min = amrex::ReduceMin(lmask, nghost,
458 [=] AMREX_GPU_HOST_DEVICE (amrex::Box
const& bx, amrex::Array4<int const>
const& lm_arr) ->
int
460 int locmin = std::numeric_limits<int>::max();
461 const auto lo = lbound(bx);
462 const auto hi = ubound(bx);
463 for (
int j = lo.y; j <= hi.y; ++j) {
464 for (
int i = lo.x; i <= hi.x; ++i) {
465 locmin = std::min(locmin, lm_arr(i,j,0));
523 amrex::Vector<amrex::FArrayBox>
z_0;
527 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
u_star;
528 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
w_star;
529 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
t_star;
530 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
q_star;
531 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
olen;
532 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
pblh;
533 amrex::Vector<std::unique_ptr<amrex::MultiFab>>
t_surf;
535 amrex::Vector<amrex::Vector<amrex::MultiFab*>>
m_sst_lev;
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pp(amrex::Real y)
Definition: ERF_MicrophysicsUtils.H:219
Definition: ERF_ABLMost.H:30
amrex::Real m_bdy_time_interval
Definition: ERF_ABLMost.H:521
amrex::Vector< amrex::MultiFab * > m_eddyDiffs_lev
Definition: ERF_ABLMost.H:541
amrex::Vector< std::unique_ptr< amrex::MultiFab > > q_star
Definition: ERF_ABLMost.H:530
const amrex::MultiFab * get_u_star(const int &lev)
Definition: ERF_ABLMost.H:420
amrex::Vector< std::unique_ptr< amrex::MultiFab > > olen
Definition: ERF_ABLMost.H:531
const amrex::MultiFab * get_t_star(const int &lev)
Definition: ERF_ABLMost.H:426
amrex::Vector< std::unique_ptr< amrex::MultiFab > > w_star
Definition: ERF_ABLMost.H:528
amrex::Vector< amrex::FArrayBox > z_0
Definition: ERF_ABLMost.H:523
amrex::Vector< amrex::Geometry > m_geom
Definition: ERF_ABLMost.H:522
amrex::Real custom_ustar
Definition: ERF_ABLMost.H:514
amrex::Vector< std::unique_ptr< amrex::MultiFab > > t_surf
Definition: ERF_ABLMost.H:533
amrex::Real custom_qstar
Definition: ERF_ABLMost.H:516
amrex::Real depth
Definition: ERF_ABLMost.H:519
amrex::Real surf_heating_rate
Definition: ERF_ABLMost.H:512
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)
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_lsm_flux_lev
Definition: ERF_ABLMost.H:538
MOSTAverage m_ma
Definition: ERF_ABLMost.H:526
ThetaCalcType
Definition: ERF_ABLMost.H:481
@ SURFACE_TEMPERATURE
Surface temperature specified.
@ HEAT_FLUX
Heat-flux specified.
const amrex::iMultiFab * get_lmask(const int &lev)
Definition: ERF_ABLMost.H:452
int lmask_min_reduce(amrex::iMultiFab &lmask, const int &nghost)
Definition: ERF_ABLMost.H:455
bool have_variable_sea_roughness()
Definition: ERF_ABLMost.H:449
bool cnk_visc
Definition: ERF_ABLMost.H:518
amrex::Real m_start_bdy_time
Definition: ERF_ABLMost.H:520
const amrex::MultiFab * get_q_star(const int &lev)
Definition: ERF_ABLMost.H:429
amrex::Vector< std::unique_ptr< amrex::MultiFab > > pblh
Definition: ERF_ABLMost.H:532
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_ABLMost.H:412
const amrex::FArrayBox * get_z0(const int &lev)
Definition: ERF_ABLMost.H:447
amrex::Vector< amrex::MultiFab * > m_Hwave_lev
Definition: ERF_ABLMost.H:539
void read_custom_roughness(const int &lev, const std::string &fname)
Definition: ERF_ABLMost.cpp:592
amrex::Real surf_temp
Definition: ERF_ABLMost.H:511
amrex::Real cnk_a
Definition: ERF_ABLMost.H:517
ThetaCalcType theta_type
Definition: ERF_ABLMost.H:500
void compute_fluxes(const int &lev, const int &max_iters, const FluxIter &most_flux, bool is_land)
Definition: ERF_ABLMost.cpp:145
PBLHeightCalcType pblh_type
Definition: ERF_ABLMost.H:503
FluxCalcType
Definition: ERF_ABLMost.H:474
@ MOENG
Moeng functional form.
@ CUSTOM
Custom constant flux functional form.
@ ROTATE
Terrain rotation flux functional form.
@ DONELAN
Donelan functional form.
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_lsm_data_lev
Definition: ERF_ABLMost.H:537
amrex::Real surf_temp_flux
Definition: ERF_ABLMost.H:513
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_ABLMost.cpp:561
const amrex::MultiFab * get_w_star(const int &lev)
Definition: ERF_ABLMost.H:423
void impose_most_bcs(const int &lev, const amrex::Vector< amrex::MultiFab * > &mfs, amrex::MultiFab *xxmom_flux, amrex::MultiFab *yymom_flux, amrex::MultiFab *zzmom_flux, amrex::MultiFab *xymom_flux, amrex::MultiFab *yxmom_flux, amrex::MultiFab *xzmom_flux, amrex::MultiFab *zxmom_flux, amrex::MultiFab *yzmom_flux, amrex::MultiFab *zymom_flux, amrex::MultiFab *xheat_flux, amrex::MultiFab *yheat_flux, amrex::MultiFab *zheat_flux, amrex::MultiFab *xqv_flux, amrex::MultiFab *yqv_flux, amrex::MultiFab *zqv_flux, amrex::MultiFab *z_phys)
Definition: ERF_ABLMost.cpp:211
amrex::Vector< amrex::Vector< amrex::iMultiFab * > > m_lmask_lev
Definition: ERF_ABLMost.H:536
const amrex::MultiFab * get_pblh(const int &lev)
Definition: ERF_ABLMost.H:435
void time_interp_sst(const int &lev, const amrex::Real &time)
Definition: ERF_ABLMost.cpp:493
RoughCalcType rough_type_land
Definition: ERF_ABLMost.H:501
bool m_rotate
Definition: ERF_ABLMost.H:508
amrex::Vector< amrex::MultiFab * > m_Lwave_lev
Definition: ERF_ABLMost.H:540
bool m_var_z0
Definition: ERF_ABLMost.H:524
RoughCalcType rough_type_sea
Definition: ERF_ABLMost.H:502
bool use_moisture
Definition: ERF_ABLMost.H:506
void compute_most_bcs(const int &lev, const amrex::Vector< amrex::MultiFab * > &mfs, amrex::MultiFab *xxmom_flux, amrex::MultiFab *yymom_flux, amrex::MultiFab *zzmom_flux, amrex::MultiFab *xymom_flux, amrex::MultiFab *yxmom_flux, amrex::MultiFab *xzmom_flux, amrex::MultiFab *zxmom_flux, amrex::MultiFab *yzmom_flux, amrex::MultiFab *zymom_flux, amrex::MultiFab *xheat_flux, amrex::MultiFab *yheat_flux, amrex::MultiFab *zheat_flux, amrex::MultiFab *xqv_flux, amrex::MultiFab *yqv_flux, amrex::MultiFab *zqv_flux, amrex::MultiFab *z_phys, const FluxCalc &flux_comp)
bool m_include_wstar
Definition: ERF_ABLMost.H:509
bool m_exp_most
Definition: ERF_ABLMost.H:507
ABLMost(const amrex::Vector< amrex::Geometry > &geom, bool &use_exp_most, bool &use_rot_most, 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, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &z_phys_nd, amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab >>> &sst_lev, 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)
Definition: ERF_ABLMost.H:35
amrex::Vector< std::unique_ptr< amrex::MultiFab > > t_star
Definition: ERF_ABLMost.H:529
const amrex::MultiFab * get_t_surf(const int &lev)
Definition: ERF_ABLMost.H:441
amrex::Vector< std::unique_ptr< amrex::MultiFab > > u_star
Definition: ERF_ABLMost.H:527
PBLHeightCalcType
Definition: ERF_ABLMost.H:495
amrex::Real z0_const
Definition: ERF_ABLMost.H:510
FluxCalcType flux_type
Definition: ERF_ABLMost.H:499
void update_surf_temp(const amrex::Real &time)
Definition: ERF_ABLMost.H:396
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_sst_lev
Definition: ERF_ABLMost.H:535
void get_lsm_tsurf(const int &lev)
Definition: ERF_ABLMost.cpp:528
amrex::Real get_zref()
Definition: ERF_ABLMost.H:444
RoughCalcType
Definition: ERF_ABLMost.H:487
const amrex::MultiFab * get_olen(const int &lev)
Definition: ERF_ABLMost.H:432
const amrex::MultiFab * get_mac_avg(const int &lev, int comp)
Definition: ERF_ABLMost.H:438
void update_fluxes(const int &lev, const amrex::Real &time, int max_iters=25)
Definition: ERF_ABLMost.cpp:12
amrex::Real custom_tstar
Definition: ERF_ABLMost.H:515
Definition: ERF_MOSTAverage.H:12
void update_field_ptrs(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:228
amrex::Real get_zref() const
Definition: ERF_MOSTAverage.H:95
const amrex::MultiFab * get_average(int lev, int comp) const
Definition: ERF_MOSTAverage.H:92
@ cons
Definition: ERF_IndexDefines.H:129