1 #ifndef ERF_IBSEB_SOLAR_H
2 #define ERF_IBSEB_SOLAR_H
4 #include <AMReX_REAL.H>
5 #include <AMReX_GpuQualifiers.H>
6 #include <AMReX_Algorithm.H>
34 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
39 - 0.399912 * std::cos(
gamma) + 0.070257 * std::sin(
gamma)
40 - 0.006758 * std::cos(2.0 *
gamma) + 0.000907 * std::sin(2.0 *
gamma)
41 - 0.00248 * std::cos(3.0 *
gamma) + 0.00031 * std::sin(3.0 *
gamma);
45 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
49 return 229.18 * (0.000075 + 0.001868 * std::cos(
gamma) - 0.032077 * std::sin(
gamma)
50 - 0.014615 * std::cos(2.0 *
gamma) - 0.040849 * std::sin(2.0 *
gamma));
59 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
62 amrex::Real t_utc_h = std::fmod(time_utc_s / 3600.0, 24.0);
63 if (t_utc_h < 0.0) { t_utc_h += 24.0; }
65 return 15.0 * (t_solar_h - 12.0) *
PI / 180.0;
69 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
73 amrex::Real cz = std::sin(lat) * std::sin(decl) + std::cos(lat) * std::cos(decl) * std::cos(hour_angle);
74 if (cz < -1.0) { cz = -1.0; }
75 if (cz > 1.0) { cz = 1.0; }
84 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
91 if (sz < 1.0e-6) {
return 0.0; }
93 if (std::abs(cos_lat) < 1.0e-6) {
return 0.0; }
96 const amrex::Real sin_az = -std::sin(hour_angle) * std::cos(decl) / sz;
97 const amrex::Real cos_az = (std::sin(decl) - cz * std::sin(lat)) / (sz * cos_lat);
99 if (az < 0.0) { az += 2.0 *
PI; }
108 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
111 const amrex::Real G = 2.0 *
PI * (day_of_year - 1.0) / 365.0;
112 return 1.000110 + 0.034221 * std::cos(G) + 0.001280 * std::sin(G)
113 + 0.000719 * std::cos(2.0 * G) + 0.000077 * std::sin(2.0 * G);
117 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
122 sx = s * std::sin(azimuth);
123 sy = s * std::cos(azimuth);
124 sz = std::cos(zenith);
132 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
136 if (cos_zenith <= 1.0e-3)
return 0.0;
137 return S0 * distance_factor * std::pow(tau, 1.0 / cos_zenith);
145 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
149 if (cos_zenith <= 1.0e-3)
return 0.0;
150 const amrex::Real tr = std::pow(tau, 1.0 / cos_zenith);
151 return k_d * S0 * distance_factor * cos_zenith * (1.0 - tr);
162 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
164 int i0,
int j0,
int bw,
int bh,
168 if (ci < 0 || ci >= bw || cj < 0 || cj >= bh) {
return z_ground; }
169 const int kt = col_top[
ci * bh + cj];
170 return (kt < 0) ? z_ground : z_ground + (kt + 1) *
dz;
193 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
196 const int* col_top,
int nx,
int ny,
int i0,
int j0,
int bw,
int bh,
200 if (sz <= 0.0)
return true;
201 if (
z0 >= z_max)
return false;
205 int ci =
static_cast<int>(std::floor((
x - x_lo) /
dx));
206 int cj =
static_cast<int>(std::floor((
y - y_lo) /
dy));
207 const int stepx = (sx > 0.0) ? 1 : ((sx < 0.0) ? -1 : 0);
208 const int stepy = (sy > 0.0) ? 1 : ((sy < 0.0) ? -1 : 0);
210 const amrex::Real tdx = (stepx != 0) ?
dx / std::abs(sx) : big;
211 const amrex::Real tdy = (stepy != 0) ?
dy / std::abs(sy) : big;
214 if (stepx > 0) tmx = ((x_lo + (
ci + 1) *
dx) -
x) / sx;
215 else if (stepx < 0) tmx = ((x_lo +
ci *
dx) -
x) / sx;
216 if (stepy > 0) tmy = ((y_lo + (cj + 1) *
dy) -
y) / sy;
217 else if (stepy < 0) tmy = ((y_lo + cj *
dy) -
y) / sy;
219 const int max_iter = 4 * (
nx +
ny) + 8;
220 for (
int it = 0; it < max_iter; ++it) {
222 if (ci < 0 || ci >=
nx) {
223 if (!per_x)
return false;
226 if (cj < 0 || cj >=
ny) {
227 if (!per_y)
return false;
230 if (
z + eps <
column_top(col_top,
ci, cj, i0, j0, bw, bh, z_ground,
dz))
return true;
232 if (tmx < tmy) {
t = tmx; tmx += tdx;
ci += stepx; }
233 else {
t = tmy; tmy += tdy; cj += stepy; }
234 z =
z0 +
t0 * sz +
t * sz;
235 if (
z >= z_max)
return false;
236 if (
t > max_path)
return false;
260 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
263 const int* col_top,
int nx,
int ny,
int i0,
int j0,
int bw,
int bh,
269 if (sz > 0.0 &&
z0 >= z_max)
return RAY_SKY;
272 int ci =
static_cast<int>(std::floor((
x - x_lo) /
dx));
273 int cj =
static_cast<int>(std::floor((
y - y_lo) /
dy));
274 const int stepx = (sx > 0.0) ? 1 : ((sx < 0.0) ? -1 : 0);
275 const int stepy = (sy > 0.0) ? 1 : ((sy < 0.0) ? -1 : 0);
277 const amrex::Real tdx = (stepx != 0) ?
dx / std::abs(sx) : big;
278 const amrex::Real tdy = (stepy != 0) ?
dy / std::abs(sy) : big;
280 if (stepx > 0) tmx = ((x_lo + (
ci + 1) *
dx) -
x) / sx;
281 else if (stepx < 0) tmx = ((x_lo +
ci *
dx) -
x) / sx;
282 if (stepy > 0) tmy = ((y_lo + (cj + 1) *
dy) -
y) / sy;
283 else if (stepy < 0) tmy = ((y_lo + cj *
dy) -
y) / sy;
284 if (stepx == 0 && stepy == 0) {
291 const int max_iter = 4 * (
nx +
ny) + 8;
292 for (
int it = 0; it < max_iter; ++it) {
293 if (ci < 0 || ci >=
nx) {
297 if (cj < 0 || cj >=
ny) {
302 const bool solid = (top > z_ground + eps);
310 if (z_out <= z_ground + eps)
return RAY_GROUND;
312 if (tmx < tmy) {
t = tmx; tmx += tdx;
ci += stepx; }
313 else {
t = tmy; tmy += tdy; cj += stepy; }
315 if (sz > 0.0 &&
z >= z_max)
return RAY_SKY;
329 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
338 amrex::Real n[3] = {0.0, 0.0, 0.0}, t1[3] = {0.0, 0.0, 0.0}, t2[3] = {0.0, 0.0, 0.0};
340 if (dir == 0) { t1[1] = 1.0; t2[2] = 1.0; }
341 else if (dir == 1) { t1[0] = 1.0; t2[2] = 1.0; }
342 else { t1[0] = 1.0; t2[1] = 1.0; }
343 sx = cn * n[0] + ct * t1[0] + st * t2[0];
344 sy = cn * n[1] + ct * t1[1] + st * t2[1];
345 sz = cn * n[2] + ct * t1[2] + st * t2[2];
const int nx
Definition: ERF_InitCustomPertVels_CloudChamber.H:14
const int ny
Definition: ERF_InitCustomPertVels_CloudChamber.H:15
Real z0
Definition: ERF_InitCustomPertVels_ScalarAdvDiff.H:8
const Real dy
Definition: ERF_InitCustomPert_ABL.H:45
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
amrex::Real gamma
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:9
Dimensionless numeric literals and pure mathematical constants.
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:39
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ theta
Definition: ERF_SLM.H:19
@ dz
Definition: ERF_AdvanceWDM6.cpp:272
@ t
Definition: ERF_WSM6.H:272
Definition: ERF_IBSEBBalance.H:51
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void hemisphere_direction(int dir, int nsign, int ia, int ie, int n_az, int n_el, amrex::Real &sx, amrex::Real &sy, amrex::Real &sz)
Definition: ERF_IBSEBSolar.H:330
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real solar_zenith(amrex::Real latitude_deg, amrex::Real decl, amrex::Real hour_angle)
Definition: ERF_IBSEBSolar.H:70
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int ray_hit(amrex::Real x0, amrex::Real y0, amrex::Real z0, amrex::Real sx, amrex::Real sy, amrex::Real sz, const int *col_top, int nx, int ny, int i0, int j0, int bw, int bh, amrex::Real x_lo, amrex::Real y_lo, amrex::Real dx, amrex::Real dy, amrex::Real dz, bool per_x, bool per_y, amrex::Real z_ground, amrex::Real z_max, amrex::Real max_path)
Definition: ERF_IBSEBSolar.H:261
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real clear_sky_dni(amrex::Real cos_zenith, amrex::Real S0, amrex::Real tau, amrex::Real distance_factor)
Definition: ERF_IBSEBSolar.H:133
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real column_top(const int *col_top, int ci, int cj, int i0, int j0, int bw, int bh, amrex::Real z_ground, amrex::Real dz)
Definition: ERF_IBSEBSolar.H:163
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real equation_of_time(amrex::Real day_of_year)
Definition: ERF_IBSEBSolar.H:46
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real earth_sun_distance_factor(amrex::Real day_of_year)
Definition: ERF_IBSEBSolar.H:109
RayHit
What a ray from a face ends on.
Definition: ERF_IBSEBSolar.H:242
@ RAY_GROUND
Definition: ERF_IBSEBSolar.H:242
@ RAY_SKY
Definition: ERF_IBSEBSolar.H:242
@ RAY_BUILDING
Definition: ERF_IBSEBSolar.H:242
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void sun_vector(amrex::Real zenith, amrex::Real azimuth, amrex::Real &sx, amrex::Real &sy, amrex::Real &sz)
Definition: ERF_IBSEBSolar.H:118
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool ray_blocked(amrex::Real x0, amrex::Real y0, amrex::Real z0, amrex::Real sx, amrex::Real sy, amrex::Real sz, const int *col_top, int nx, int ny, int i0, int j0, int bw, int bh, amrex::Real x_lo, amrex::Real y_lo, amrex::Real dx, amrex::Real dy, amrex::Real dz, bool per_x, bool per_y, amrex::Real z_ground, amrex::Real z_max, amrex::Real max_path)
Definition: ERF_IBSEBSolar.H:194
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real solar_azimuth(amrex::Real latitude_deg, amrex::Real decl, amrex::Real hour_angle, amrex::Real zenith)
Definition: ERF_IBSEBSolar.H:85
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real solar_declination(amrex::Real day_of_year)
Definition: ERF_IBSEBSolar.H:35
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real solar_hour_angle(amrex::Real time_utc_s, amrex::Real longitude_deg, amrex::Real day_of_year)
Definition: ERF_IBSEBSolar.H:60
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real clear_sky_diffuse_h(amrex::Real cos_zenith, amrex::Real S0, amrex::Real tau, amrex::Real distance_factor, amrex::Real k_d)
Definition: ERF_IBSEBSolar.H:146
real(c_double), parameter t0
Definition: ERF_module_model_constants.F90:39
real(c_double), private ci
Definition: ERF_module_mp_morr_two_moment.F90:203