26 MultiFab* mf_Tair, MultiFab* mf_qair, MultiFab* mf_Pair,
28 MultiFab* mf_longwave_down,
29 MultiFab* mf_evap, MultiFab* mf_sustr, MultiFab* mf_svstr,
30 MultiFab* mf_stflux, MultiFab* mf_lrflx, MultiFab* mf_lhflx,
34 BL_PROFILE(
"REMORA::bulk_fluxes()");
35 const int IterMax = 3;
36 const BoxArray& ba = mf_cons->boxArray();
37 const DistributionMapping& dm = mf_cons->DistributionMap();
38 MultiFab mf_Taux(ba, dm, 1, IntVect(
NGROW,
NGROW,0));
39 MultiFab mf_Tauy(ba, dm, 1, IntVect(
NGROW,
NGROW,0));
42 for ( MFIter mfi(*mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi) {
43 Array4<Real const>
const& uwind = mf_uwind->const_array(mfi);
44 Array4<Real const>
const& vwind = mf_vwind->const_array(mfi);
45 Array4<Real const>
const& Tair_arr = mf_Tair->const_array(mfi);
46 Array4<Real const>
const& qair_arr = mf_qair->const_array(mfi);
47 Array4<Real const>
const& Pair_arr = mf_Pair->const_array(mfi);
48 Array4<Real const>
const& srflx_arr = mf_srflx->const_array(mfi);
49 Array4<Real const> longwave_down_arr;
50 if (mf_longwave_down !=
nullptr) {
51 longwave_down_arr = mf_longwave_down->const_array(mfi);
53 Array4<Real const>
const& cons = mf_cons->const_array(mfi);
54 Array4<Real>
const& sustr = mf_sustr->array(mfi);
55 Array4<Real>
const& svstr = mf_svstr->array(mfi);
56 Array4<Real>
const& stflux = mf_stflux->array(mfi);
57 Array4<Real>
const& lrflx = mf_lrflx->array(mfi);
58 Array4<Real>
const& lhflx = mf_lhflx->array(mfi);
59 Array4<Real>
const& shflx = mf_shflx->array(mfi);
60 Array4<Real>
const& evap = mf_evap->array(mfi);
61 Array4<Real>
const& Taux = mf_Taux.array(mfi);
62 Array4<Real>
const& Tauy = mf_Tauy.array(mfi);
64 Array4<const Real>
const& mskr =
vec_mskr[lev]->const_array(mfi);
65 Array4<const Real>
const& msku =
vec_msku[lev]->const_array(mfi);
66 Array4<const Real>
const& mskv =
vec_mskv[lev]->const_array(mfi);
67 Array4<const Real>
const& rain =
vec_rain[lev]->const_array(mfi);
68 Array4<const Real>
const& EminusP =
vec_EminusP[lev]->const_array(mfi);
69 Array4<const Real>
const& cloud_arr =
vec_cloud[lev]->const_array(mfi);
79 bool have_longwave_from_file = (mf_longwave_down !=
nullptr);
84 Box bx = mfi.tilebox();
85 Box ubx = mfi.grownnodaltilebox(0,IntVect(
NGROW-1,
NGROW-1,0));
86 Box vbx = mfi.grownnodaltilebox(1,IntVect(
NGROW-1,
NGROW-1,0));
87 Box gbx1 = bx; gbx1.grow(IntVect(
NGROW,
NGROW,0));
89 ParallelFor(makeSlab(gbx1,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) {
91 Real PairM = Pair_arr(i,j,0);
92 Real TairC = Tair_arr(i,j,0);
93 Real TairK = TairC + 273.16_rt;
94 Real Hair = qair_arr(i,j,0);
96 Real srflux = srflx_arr(i,j,0);
97 Real cloud = cloud_arr(i,j,0);
100 Real wind_mag = std::sqrt(uwind(i,j,0)*uwind(i,j,0) + vwind(i,j,0) * vwind(i,j,0)) + eps;
101 Real TseaK = cons(i,j,N,
Temp_comp) + 273.16_rt;
108 Real LHeat = lhflx(i,j,0) * Hscale;
109 Real SHeat = shflx(i,j,0) * Hscale;
111 Taux(i,j,0) = 0.0_rt;
112 Tauy(i,j,0) = 0.0_rt;
127 if (have_longwave_from_file && longwave_netcdf_is_net) {
129 LRad = longwave_down_arr(i,j,0);
130 }
else if (use_longwave_down) {
131 Real Ldown = longwave_down_arr(i,j,0);
133 LRad = Ldown - Lemit;
136 cff=(0.7859_rt+0.03477_rt*TairC)/(1.0_rt+0.00412_rt*TairC);
137 Real e_sat=std::pow(10.0_rt,cff);
139 Real cff2=TairK*TairK*TairK;
140 Real cff1=cff2*TairK;
143 (cff1*(0.39_rt-0.05_rt*std::sqrt(vap_p))*
144 (1.0_rt-0.6823_rt*cloud*cloud)+
145 cff2*4.0_rt*(TseaK-TairK));
181 Real cff_saturation_air=(1.0007_rt+3.46E-6_rt*PairM)*6.1121_rt*
182 std::exp(17.502_rt*TairC/(240.97_rt+TairC));
186 Real Qair = 0.62197_rt*(cff_saturation_air/(PairM-0.378_rt*cff_saturation_air+eps));
191 Real cff_Q = cff_saturation_air*RH;
192 Q=0.62197_rt*(cff_Q/(PairM-0.378_rt*cff_Q+eps));
199 Real cff_saturation_water=(1.0007_rt+3.46E-6_rt*PairM)*6.1121_rt*
204 Real cff_vp=cff_saturation_water*0.98_rt;
210 Real Qsea=0.62197_rt*(cff_vp/(PairM-0.378_rt*cff_vp+eps));
219 Real rhoAir=PairM*100.0_rt/(
blk_Rgas*TairK*(1.0_rt+0.61_rt*Q));
223 Real VisAir=1.326E-5_rt*(1.0_rt+TairC*(6.542E-3_rt+TairC*
224 (8.301E-6_rt-4.84E-9_rt*TairC)));
228 Real Hlv = (2.501_rt-0.00237_rt*cons(i,j,N,
Temp_comp))*1.0e6_rt;
234 Real delW=std::sqrt(wind_mag*wind_mag+Wgus*Wgus);
240 Real u10=delW*std::log(10.0_rt/ZoW)/std::log(blk_ZW/ZoW);
241 Real Wstar=0.035_rt * u10;
242 Real Zo10=0.011_rt*Wstar*Wstar/
g+0.11_rt*VisAir/Wstar;
243 Real Cd10 =(
vonKar/std::log(10.0_rt/Zo10));
245 Real Ch10 =0.00115_rt;
246 Real Ct10 = Ch10/std::sqrt(Cd10);
247 Real ZoT10=10.0_rt/std::exp(
vonKar/Ct10);
248 Real Cd=(
vonKar/std::log(blk_ZW/Zo10));
252 Real Ct=
vonKar/std::log(blk_ZT/ZoT10);
256 Real Ri = -
g*blk_ZW*((delT-delTc)+0.61_rt*TairK*delQ)/
257 (TairK*delW*delW+eps);
260 Zetu=CC*Ri/(1.0_rt+Ri/Ribcu);
262 Zetu=CC*Ri/(1.0_rt+3.0_rt*Ri/CC);
264 Real L10 = blk_ZW/Zetu;
267 Wstar=delW*
vonKar/(std::log(blk_ZW/Zo10)-
269 Real Tstar=-(delT-delTc)*
vonKar/(std::log(blk_ZT/ZoT10)-
271 Real Qstar=-(delQ-delQc)*
vonKar/(std::log(blk_ZQ/ZoT10)-
278 if (delW > 18.0_rt) {
280 }
else if ((10.0_rt < delW) and (delW <= 18.0_rt)) {
281 charn=0.011_rt+0.125_rt*(0.018_rt-0.011_rt)*(delW-10.0_rt);
287 for (
int it=0; it<IterMax; it++) {
288 ZoW=charn*Wstar*Wstar/
g+0.11_rt*VisAir/(Wstar+eps);
289 Real Rr=ZoW*Wstar/VisAir;
291 Real ZoQ=std::min(1.15e-4_rt,5.5e-5_rt/std::pow(Rr,0.6_rt));
293 Real ZoL=
vonKar*
g*blk_ZW*(Tstar*(1.0_rt+0.61_rt*Q)+
294 0.61_rt*TairK*Qstar)/
295 (TairK*Wstar*Wstar*(1.0_rt+0.61_rt*Q)+eps);
296 Real L=blk_ZW/(ZoL+eps);
304 Wstar=std::max(eps,delW*
vonKar/(std::log(blk_ZW/ZoW)-Wpsi));
305 Tstar=-(delT-delTc)*
vonKar/(std::log(blk_ZT/ZoT)-Tpsi);
306 Qstar=-(delQ-delQc)*
vonKar/(std::log(blk_ZQ/ZoQ)-Qpsi);
309 Real Bf=-
g/TairK*Wstar*(Tstar+0.61_rt*TairK*Qstar);
315 delW=std::sqrt(wind_mag*wind_mag+Wgus*Wgus);
319 Real Wspeed=std::sqrt(wind_mag*wind_mag+Wgus*Wgus);
320 Cd=Wstar*Wstar/(Wspeed*Wspeed+eps);
323 Real Hs=-
blk_Cpa*rhoAir*Wstar*Tstar;
326 Real diffw=2.11E-5_rt*std::pow(TairK/273.16_rt,1.94_rt);
327 Real diffh=0.02411_rt*(1.0_rt+TairC*
328 (3.309E-3_rt-1.44E-6_rt*TairC))/
330 cff=Qair*Hlv/(
blk_Rgas*TairK*TairK);
331 Real wet_bulb=1.0_rt/(1.0_rt+0.622_rt*(cff*Hlv*diffw)/
333 Real Hsr=rain(i,j,0)*wet_bulb*
blk_Cpw*
335 SHeat=(Hs+Hsr) * mskr(i,j,0);
339 Real Hl=-Hlv*rhoAir*Wstar*Qstar;
342 Real upvel=-1.61_rt*Wstar*Qstar-
343 (1.0_rt+1.61_rt*Q)*Wstar*Tstar/TairK;
344 Real Hlw=rhoAir*Hlv*upvel*Q;
345 LHeat=(Hl+Hlw) * mskr(i,j,0);
348 Taur=0.85_rt*rain(i,j,0)*wind_mag;
351 cff=rhoAir*Cd*Wspeed;
353 Real sign_u = (uwind(i,j,0) >= 0.0_rt) ? 1 : -1;
354 Real sign_v = (vwind(i,j,0) >= 0.0_rt) ? 1 : -1;
355 Taux(i,j,0)=(cff*uwind(i,j,0)+Taur*sign_u) * mskr(i,j,0);
356 Tauy(i,j,0)=(cff*vwind(i,j,0)+Taur*sign_v) * mskr(i,j,0);
388 lrflx(i,j,0) = LRad*Hscale2;
389 lhflx(i,j,0) = -LHeat*Hscale2;
390 shflx(i,j,0) = -SHeat*Hscale2;
392 stflux(i,j,0,
Temp_comp)=(srflux*Hscale2 + lrflx(i,j,0) + lhflx(i,j,0) + shflx(i,j,0)) * mskr(i,j,0);
393 evap(i,j,0) = (LHeat / Hlv+eps) * mskr(i,j,0);
394 if (use_EminusP_from_file) {
396 stflux(i,j,0,
Salt_comp) = mskr(i,j,0) * EminusP(i,j,0);
398 stflux(i,j,0,
Salt_comp) = mskr(i,j,0) * (evap(i,j,0)-rain(i,j,0)) /
rhow;
403 ParallelFor(makeSlab(ubx,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) {
404 sustr(i,j,0) = cff_rho*(Taux(i-1,j,0) + Taux(i,j,0)) * msku(i,j,0);
406 ParallelFor(makeSlab(vbx,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) {
407 svstr(i,j,0) = cff_rho*(Tauy(i,j-1,0) + Tauy(i,j,0)) * mskv(i,j,0);