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>
36 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
41 - 0.399912 * std::cos(
gamma) + 0.070257 * std::sin(
gamma)
42 - 0.006758 * std::cos(2.0 *
gamma) + 0.000907 * std::sin(2.0 *
gamma)
43 - 0.00248 * std::cos(3.0 *
gamma) + 0.00031 * std::sin(3.0 *
gamma);
47 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
51 return 229.18 * (0.000075 + 0.001868 * std::cos(
gamma) - 0.032077 * std::sin(
gamma)
52 - 0.014615 * std::cos(2.0 *
gamma) - 0.040849 * std::sin(2.0 *
gamma));
61 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
64 amrex::Real t_utc_h = std::fmod(time_utc_s / 3600.0, 24.0);
65 if (t_utc_h < 0.0) { t_utc_h += 24.0; }
67 return 15.0 * (t_solar_h - 12.0) *
PI / 180.0;
79 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
82 const double two_pi = 2.0 * double(
PI);
83 double h = two_pi * (calday - std::floor(calday)) +
double(longitude_rad) - double(
PI);
84 h = std::fmod(h +
double(
PI), two_pi);
85 if (h < 0.0) { h += two_pi; }
90 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
94 amrex::Real cz = std::sin(lat) * std::sin(decl) + std::cos(lat) * std::cos(decl) * std::cos(hour_angle);
95 if (cz < -1.0) { cz = -1.0; }
96 if (cz > 1.0) { cz = 1.0; }
105 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
112 if (sz < 1.0e-6) {
return 0.0; }
114 if (std::abs(cos_lat) < 1.0e-6) {
return 0.0; }
117 const amrex::Real sin_az = -std::sin(hour_angle) * std::cos(decl) / sz;
118 const amrex::Real cos_az = (std::sin(decl) - cz * std::sin(lat)) / (sz * cos_lat);
120 if (az < 0.0) { az += 2.0 *
PI; }
129 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
132 const amrex::Real G = 2.0 *
PI * (day_of_year - 1.0) / 365.0;
133 return 1.000110 + 0.034221 * std::cos(G) + 0.001280 * std::sin(G)
134 + 0.000719 * std::cos(2.0 * G) + 0.000077 * std::sin(2.0 * G);
138 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
143 sx = s * std::sin(azimuth);
144 sy = s * std::cos(azimuth);
145 sz = std::cos(zenith);
153 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
157 if (cos_zenith <= 1.0e-3)
return 0.0;
158 return S0 * distance_factor * std::pow(tau, 1.0 / cos_zenith);
166 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
170 if (cos_zenith <= 1.0e-3)
return 0.0;
171 const amrex::Real tr = std::pow(tau, 1.0 / cos_zenith);
172 return k_d * S0 * distance_factor * cos_zenith * (1.0 - tr);
183 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
185 int i0,
int j0,
int bw,
int bh,
189 if (ci < 0 || ci >= bw || cj < 0 || cj >= bh) {
return z_ground; }
190 const int kt = col_top[
ci * bh + cj];
191 return (kt < 0) ? z_ground : z_ground + (kt + 1) *
dz;
214 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
217 const int* col_top,
int nx,
int ny,
int i0,
int j0,
int bw,
int bh,
221 if (sz <= 0.0)
return true;
222 if (
z0 >= z_max)
return false;
226 int ci =
static_cast<int>(std::floor((
x - x_lo) /
dx));
227 int cj =
static_cast<int>(std::floor((
y - y_lo) /
dy));
228 const int stepx = (sx > 0.0) ? 1 : ((sx < 0.0) ? -1 : 0);
229 const int stepy = (sy > 0.0) ? 1 : ((sy < 0.0) ? -1 : 0);
231 const amrex::Real tdx = (stepx != 0) ?
dx / std::abs(sx) : big;
232 const amrex::Real tdy = (stepy != 0) ?
dy / std::abs(sy) : big;
235 if (stepx > 0) tmx = ((x_lo + (
ci + 1) *
dx) -
x) / sx;
236 else if (stepx < 0) tmx = ((x_lo +
ci *
dx) -
x) / sx;
237 if (stepy > 0) tmy = ((y_lo + (cj + 1) *
dy) -
y) / sy;
238 else if (stepy < 0) tmy = ((y_lo + cj *
dy) -
y) / sy;
240 const int max_iter = 4 * (
nx +
ny) + 8;
241 for (
int it = 0; it < max_iter; ++it) {
243 if (ci < 0 || ci >=
nx) {
244 if (!per_x)
return false;
247 if (cj < 0 || cj >=
ny) {
248 if (!per_y)
return false;
251 if (
z + eps <
column_top(col_top,
ci, cj, i0, j0, bw, bh, z_ground,
dz))
return true;
253 if (tmx < tmy) {
t = tmx; tmx += tdx;
ci += stepx; }
254 else {
t = tmy; tmy += tdy; cj += stepy; }
255 z =
z0 +
t0 * sz +
t * sz;
256 if (
z >= z_max)
return false;
257 if (
t > max_path)
return false;
281 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
284 const int* col_top,
int nx,
int ny,
int i0,
int j0,
int bw,
int bh,
290 if (sz > 0.0 &&
z0 >= z_max)
return RAY_SKY;
293 int ci =
static_cast<int>(std::floor((
x - x_lo) /
dx));
294 int cj =
static_cast<int>(std::floor((
y - y_lo) /
dy));
295 const int stepx = (sx > 0.0) ? 1 : ((sx < 0.0) ? -1 : 0);
296 const int stepy = (sy > 0.0) ? 1 : ((sy < 0.0) ? -1 : 0);
298 const amrex::Real tdx = (stepx != 0) ?
dx / std::abs(sx) : big;
299 const amrex::Real tdy = (stepy != 0) ?
dy / std::abs(sy) : big;
301 if (stepx > 0) tmx = ((x_lo + (
ci + 1) *
dx) -
x) / sx;
302 else if (stepx < 0) tmx = ((x_lo +
ci *
dx) -
x) / sx;
303 if (stepy > 0) tmy = ((y_lo + (cj + 1) *
dy) -
y) / sy;
304 else if (stepy < 0) tmy = ((y_lo + cj *
dy) -
y) / sy;
305 if (stepx == 0 && stepy == 0) {
312 const int max_iter = 4 * (
nx +
ny) + 8;
313 for (
int it = 0; it < max_iter; ++it) {
314 if (ci < 0 || ci >=
nx) {
318 if (cj < 0 || cj >=
ny) {
323 const bool solid = (top > z_ground + eps);
331 if (z_out <= z_ground + eps)
return RAY_GROUND;
333 if (tmx < tmy) {
t = tmx; tmx += tdx;
ci += stepx; }
334 else {
t = tmy; tmy += tdy; cj += stepy; }
336 if (sz > 0.0 &&
z >= z_max)
return RAY_SKY;
350 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
359 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};
361 if (dir == 0) { t1[1] = 1.0; t2[2] = 1.0; }
362 else if (dir == 1) { t1[0] = 1.0; t2[2] = 1.0; }
363 else { t1[0] = 1.0; t2[1] = 1.0; }
364 sx = cn * n[0] + ct * t1[0] + st * t2[0];
365 sy = cn * n[1] + ct * t1[1] + st * t2[1];
366 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:46
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ theta
Definition: ERF_Kessler.H:26
@ 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:351
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:91
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:282
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:154
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real orbital_hour_angle(double calday, amrex::Real longitude_rad)
Definition: ERF_IBSEBSolar.H:80
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:184
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real equation_of_time(amrex::Real day_of_year)
Definition: ERF_IBSEBSolar.H:48
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real earth_sun_distance_factor(amrex::Real day_of_year)
Definition: ERF_IBSEBSolar.H:130
RayHit
What a ray from a face ends on.
Definition: ERF_IBSEBSolar.H:263
@ RAY_GROUND
Definition: ERF_IBSEBSolar.H:263
@ RAY_SKY
Definition: ERF_IBSEBSolar.H:263
@ RAY_BUILDING
Definition: ERF_IBSEBSolar.H:263
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:139
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:215
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:106
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real solar_declination(amrex::Real day_of_year)
Definition: ERF_IBSEBSolar.H:37
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:62
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:167
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