1 #ifndef ERF_TWO_STREAM_SW_H_
2 #define ERF_TWO_STREAM_SW_H_
4 #include <AMReX_GpuControl.H>
5 #include <AMReX_Math.H>
6 #include <AMReX_REAL.H>
70 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
75 if (cos_zenith <= 0.0) {
78 return S0 * cos_zenith * std::exp(-tau_cumulative / cos_zenith);
99 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
104 if (
dz <= 0.0 ||
rho <= 0.0 ||
cp <= 0.0) {
111 if (!amrex::Math::isfinite(heating)) {
174 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
181 if (!(tau > 0.0) || !amrex::Math::isfinite(tau)) {
184 if (!(cos_zenith > 0.0)) {
191 if (!(w0 > 0.0) || !amrex::Math::isfinite(w0)) w0 = 0.0;
192 if (w0 > 1.0) w0 = 1.0;
194 if (!amrex::Math::isfinite(asym)) asym = 0.0;
195 if (asym > 1.0) asym = 1.0;
196 if (asym < -1.0) asym = -1.0;
197 amrex::Real mu0 = (cos_zenith > 0.0) ? cos_zenith : 1.0;
198 if (mu0 > 1.0) mu0 = 1.0;
200 const amrex::Real gamma1 = (8.0 - w0 * (5.0 + 3.0 * asym)) / 4.0;
201 const amrex::Real gamma2 = 3.0 * w0 * (1.0 - asym) / 4.0;
202 const amrex::Real gamma3 = (2.0 - 3.0 * asym * mu0) / 4.0;
205 const amrex::Real alpha1 = gamma1 * gamma4 + gamma2 * gamma3;
206 const amrex::Real alpha2 = gamma1 * gamma3 + gamma2 * gamma4;
209 amrex::Real k_sq = (gamma1 - gamma2) * (gamma1 + gamma2);
210 if (k_sq < 1.0e-12) k_sq = 1.0e-12;
215 const amrex::Real D = k * (1.0 + E2) + gamma1 * (1.0 - E2);
218 L.R_dif = RT * gamma2 * (1.0 - E2);
219 L.T_dif = RT * 2.0 * k * E;
220 if (L.R_dif < 0.0) L.R_dif = 0.0;
221 if (L.T_dif < 0.0) L.T_dif = 0.0;
222 if (L.R_dif + L.T_dif > 1.0) {
228 if (!(cos_zenith > 0.0)) {
234 if (std::abs(1.0 - k_mu * k_mu) < 1.0e-4) {
235 k_mu = (k_mu < 1.0) ? (1.0 - 1.0e-2) : (1.0 + 1.0e-2);
238 L.T_noscat = T_noscat;
240 const amrex::Real RT2 = w0 * RT / (1.0 - k_mu * k_mu);
244 amrex::Real R_dir = RT2 * ((1.0 - k_mu) * (alpha2 + k_g3)
245 - (1.0 + k_mu) * (alpha2 - k_g3) * E2
246 - 2.0 * (k_g3 - alpha2 * k_mu) * E * T_noscat);
247 amrex::Real T_dir = -RT2 * ((1.0 + k_mu) * (alpha1 + k_g4) * T_noscat
248 - (1.0 - k_mu) * (alpha1 - k_g4) * E2 * T_noscat
249 - 2.0 * (k_g4 + alpha1 * k_mu) * E);
251 if (!amrex::Math::isfinite(R_dir) || R_dir < 0.0) R_dir = 0.0;
252 if (!amrex::Math::isfinite(T_dir) || T_dir < 0.0) T_dir = 0.0;
254 if (R_dir + T_dir > budget) {
255 const amrex::Real s = (R_dir + T_dir > 0.0) ? budget / (R_dir + T_dir) : 0.0;
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_sw_direct_flux(amrex::Real tau_cumulative, amrex::Real S0, amrex::Real cos_zenith)
Compute Beer-Lambert direct-beam flux at a given optical depth.
Definition: ERF_TwoStreamSW.H:72
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_sw_heating_rate(amrex::Real flux_top, amrex::Real flux_bot, amrex::Real dz, amrex::Real rho, amrex::Real cp)
Compute the shortwave heating rate of a layer from the net (downward positive) flux at its top and bo...
Definition: ERF_TwoStreamSW.H:101
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE TwoStreamLayerSW compute_sw_layer_two_stream(amrex::Real tau, amrex::Real omega, amrex::Real g, amrex::Real cos_zenith)
Compute the two-stream layer solution for shortwave radiation.
Definition: ERF_TwoStreamSW.H:176
@ rho
Definition: ERF_Kessler.H:25
@ omega
Definition: ERF_Morrison.H:55
@ dz
Definition: ERF_AdvanceWDM6.cpp:272
real(c_double), parameter g
Definition: ERF_module_model_constants.F90:19
real(c_double), parameter cp
Definition: ERF_module_model_constants.F90:22
Two-stream reflectance and transmittance of one homogeneous layer.
Definition: ERF_TwoStreamSW.H:132
amrex::Real T_dir
Definition: ERF_TwoStreamSW.H:136
amrex::Real T_dif
Definition: ERF_TwoStreamSW.H:134
amrex::Real R_dif
Definition: ERF_TwoStreamSW.H:133
amrex::Real R_dir
Definition: ERF_TwoStreamSW.H:135
amrex::Real T_noscat
Definition: ERF_TwoStreamSW.H:137