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& cloud_arr =
vec_cloud[lev]->const_array(mfi);
78 bool have_longwave_from_file = (mf_longwave_down !=
nullptr);
82 Box bx = mfi.tilebox();
83 Box ubx = mfi.grownnodaltilebox(0,IntVect(
NGROW-1,
NGROW-1,0));
84 Box vbx = mfi.grownnodaltilebox(1,IntVect(
NGROW-1,
NGROW-1,0));
85 Box gbx1 = bx; gbx1.grow(IntVect(
NGROW,
NGROW,0));
87 ParallelFor(makeSlab(gbx1,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) {
89 Real PairM = Pair_arr(i,j,0);
90 Real TairC = Tair_arr(i,j,0);
91 Real TairK = TairC + 273.16_rt;
92 Real Hair = qair_arr(i,j,0);
94 Real srflux = srflx_arr(i,j,0);
95 Real cloud = cloud_arr(i,j,0);
98 Real wind_mag = std::sqrt(uwind(i,j,0)*uwind(i,j,0) + vwind(i,j,0) * vwind(i,j,0)) + eps;
99 Real TseaK = cons(i,j,N,
Temp_comp) + 273.16_rt;
106 Real LHeat = lhflx(i,j,0) * Hscale;
107 Real SHeat = shflx(i,j,0) * Hscale;
109 Taux(i,j,0) = 0.0_rt;
110 Tauy(i,j,0) = 0.0_rt;
125 if (have_longwave_from_file && longwave_netcdf_is_net) {
127 LRad = longwave_down_arr(i,j,0);
128 }
else if (use_longwave_down) {
129 Real Ldown = longwave_down_arr(i,j,0);
131 LRad = Ldown - Lemit;
134 cff=(0.7859_rt+0.03477_rt*TairC)/(1.0_rt+0.00412_rt*TairC);
135 Real e_sat=std::pow(10.0_rt,cff);
137 Real cff2=TairK*TairK*TairK;
138 Real cff1=cff2*TairK;
141 (cff1*(0.39_rt-0.05_rt*std::sqrt(vap_p))*
142 (1.0_rt-0.6823_rt*cloud*cloud)+
143 cff2*4.0_rt*(TseaK-TairK));
179 Real cff_saturation_air=(1.0007_rt+3.46E-6_rt*PairM)*6.1121_rt*
180 std::exp(17.502_rt*TairC/(240.97_rt+TairC));
184 Real Qair = 0.62197_rt*(cff_saturation_air/(PairM-0.378_rt*cff_saturation_air+eps));
189 Real cff_Q = cff_saturation_air*RH;
190 Q=0.62197_rt*(cff_Q/(PairM-0.378_rt*cff_Q+eps));
197 Real cff_saturation_water=(1.0007_rt+3.46E-6_rt*PairM)*6.1121_rt*
202 Real cff_vp=cff_saturation_water*0.98_rt;
208 Real Qsea=0.62197_rt*(cff_vp/(PairM-0.378_rt*cff_vp+eps));
217 Real rhoAir=PairM*100.0_rt/(
blk_Rgas*TairK*(1.0_rt+0.61_rt*Q));
221 Real VisAir=1.326E-5_rt*(1.0_rt+TairC*(6.542E-3_rt+TairC*
222 (8.301E-6_rt-4.84E-9_rt*TairC)));
226 Real Hlv = (2.501_rt-0.00237_rt*cons(i,j,N,
Temp_comp))*1.0e6_rt;
232 Real delW=std::sqrt(wind_mag*wind_mag+Wgus*Wgus);
238 Real u10=delW*std::log(10.0_rt/ZoW)/std::log(blk_ZW/ZoW);
239 Real Wstar=0.035_rt * u10;
240 Real Zo10=0.011_rt*Wstar*Wstar/
g+0.11_rt*VisAir/Wstar;
241 Real Cd10 =(
vonKar/std::log(10.0_rt/Zo10));
243 Real Ch10 =0.00115_rt;
244 Real Ct10 = Ch10/std::sqrt(Cd10);
245 Real ZoT10=10.0_rt/std::exp(
vonKar/Ct10);
246 Real Cd=(
vonKar/std::log(blk_ZW/Zo10));
250 Real Ct=
vonKar/std::log(blk_ZT/ZoT10);
254 Real Ri = -
g*blk_ZW*((delT-delTc)+0.61_rt*TairK*delQ)/
255 (TairK*delW*delW+eps);
258 Zetu=CC*Ri/(1.0_rt+Ri/Ribcu);
260 Zetu=CC*Ri/(1.0_rt+3.0_rt*Ri/CC);
262 Real L10 = blk_ZW/Zetu;
265 Wstar=delW*
vonKar/(std::log(blk_ZW/Zo10)-
267 Real Tstar=-(delT-delTc)*
vonKar/(std::log(blk_ZT/ZoT10)-
269 Real Qstar=-(delQ-delQc)*
vonKar/(std::log(blk_ZQ/ZoT10)-
276 if (delW > 18.0_rt) {
278 }
else if ((10.0_rt < delW) and (delW <= 18.0_rt)) {
279 charn=0.011_rt+0.125_rt*(0.018_rt-0.011_rt)*(delW-10.0_rt);
285 for (
int it=0; it<IterMax; it++) {
286 ZoW=charn*Wstar*Wstar/
g+0.11_rt*VisAir/(Wstar+eps);
287 Real Rr=ZoW*Wstar/VisAir;
289 Real ZoQ=std::min(1.15e-4_rt,5.5e-5_rt/std::pow(Rr,0.6_rt));
291 Real ZoL=
vonKar*
g*blk_ZW*(Tstar*(1.0_rt+0.61_rt*Q)+
292 0.61_rt*TairK*Qstar)/
293 (TairK*Wstar*Wstar*(1.0_rt+0.61_rt*Q)+eps);
294 Real L=blk_ZW/(ZoL+eps);
302 Wstar=std::max(eps,delW*
vonKar/(std::log(blk_ZW/ZoW)-Wpsi));
303 Tstar=-(delT-delTc)*
vonKar/(std::log(blk_ZT/ZoT)-Tpsi);
304 Qstar=-(delQ-delQc)*
vonKar/(std::log(blk_ZQ/ZoQ)-Qpsi);
307 Real Bf=-
g/TairK*Wstar*(Tstar+0.61_rt*TairK*Qstar);
313 delW=std::sqrt(wind_mag*wind_mag+Wgus*Wgus);
317 Real Wspeed=std::sqrt(wind_mag*wind_mag+Wgus*Wgus);
318 Cd=Wstar*Wstar/(Wspeed*Wspeed+eps);
321 Real Hs=-
blk_Cpa*rhoAir*Wstar*Tstar;
324 Real diffw=2.11E-5_rt*std::pow(TairK/273.16_rt,1.94_rt);
325 Real diffh=0.02411_rt*(1.0_rt+TairC*
326 (3.309E-3_rt-1.44E-6_rt*TairC))/
328 cff=Qair*Hlv/(
blk_Rgas*TairK*TairK);
329 Real wet_bulb=1.0_rt/(1.0_rt+0.622_rt*(cff*Hlv*diffw)/
331 Real Hsr=rain(i,j,0)*wet_bulb*
blk_Cpw*
333 SHeat=(Hs+Hsr) * mskr(i,j,0);
337 Real Hl=-Hlv*rhoAir*Wstar*Qstar;
340 Real upvel=-1.61_rt*Wstar*Qstar-
341 (1.0_rt+1.61_rt*Q)*Wstar*Tstar/TairK;
342 Real Hlw=rhoAir*Hlv*upvel*Q;
343 LHeat=(Hl+Hlw) * mskr(i,j,0);
346 Taur=0.85_rt*rain(i,j,0)*wind_mag;
349 cff=rhoAir*Cd*Wspeed;
351 Real sign_u = (uwind(i,j,0) >= 0.0_rt) ? 1 : -1;
352 Real sign_v = (vwind(i,j,0) >= 0.0_rt) ? 1 : -1;
353 Taux(i,j,0)=(cff*uwind(i,j,0)+Taur*sign_u) * mskr(i,j,0);
354 Tauy(i,j,0)=(cff*vwind(i,j,0)+Taur*sign_v) * mskr(i,j,0);
386 lrflx(i,j,0) = LRad*Hscale2;
387 lhflx(i,j,0) = -LHeat*Hscale2;
388 shflx(i,j,0) = -SHeat*Hscale2;
390 stflux(i,j,0,
Temp_comp)=(srflux*Hscale2 + lrflx(i,j,0) + lhflx(i,j,0) + shflx(i,j,0)) * mskr(i,j,0);
391 evap(i,j,0) = (LHeat / Hlv+eps) * mskr(i,j,0);
392 stflux(i,j,0,
Salt_comp) = mskr(i,j,0) * (evap(i,j,0)-rain(i,j,0)) /
rhow;
396 ParallelFor(makeSlab(ubx,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) {
397 sustr(i,j,0) = cff_rho*(Taux(i-1,j,0) + Taux(i,j,0)) * msku(i,j,0);
399 ParallelFor(makeSlab(vbx,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int ) {
400 svstr(i,j,0) = cff_rho*(Tauy(i,j-1,0) + Tauy(i,j,0)) * mskv(i,j,0);