1#ifndef SOLAR_POSITION_MICHALSKY_H
2#define SOLAR_POSITION_MICHALSKY_H
5#include "../framework/degree_trigonometry.h"
6#include "../framework/module.h"
7#include "../framework/state_map.h"
100 state_map
const& input_quantities,
101 state_map* output_quantities)
105 lat{get_input(input_quantities,
"lat")},
106 longitude{get_input(input_quantities,
"longitude")},
107 fractional_doy{get_input(input_quantities,
"fractional_doy")},
108 time_zone_offset{get_input(input_quantities,
"time_zone_offset")},
109 year{get_input(input_quantities,
"year")},
112 cosine_zenith_angle_op{get_op(output_quantities,
"cosine_zenith_angle")},
113 julian_date_op{get_op(output_quantities,
"julian_date")},
114 solar_L_op{get_op(output_quantities,
"solar_L")},
115 solar_g_op{get_op(output_quantities,
"solar_g")},
116 solar_ell_op{get_op(output_quantities,
"solar_ell")},
117 solar_ep_op{get_op(output_quantities,
"solar_ep")},
118 solar_ra_op{get_op(output_quantities,
"solar_ra")},
119 solar_dec_op{get_op(output_quantities,
"solar_dec")},
120 gmst_op{get_op(output_quantities,
"gmst")},
121 lmst_op{get_op(output_quantities,
"lmst")},
122 lha_op{get_op(output_quantities,
"lha")},
123 solar_zenith_angle_op{get_op(output_quantities,
"solar_zenith_angle")},
124 solar_azimuth_angle_op{get_op(output_quantities,
"solar_azimuth_angle")}
129 static std::string
get_name() {
return "solar_position_michalsky"; }
134 double const& longitude;
135 double const& fractional_doy;
136 double const& time_zone_offset;
140 double* cosine_zenith_angle_op;
141 double* julian_date_op;
144 double* solar_ell_op;
147 double* solar_dec_op;
151 double* solar_zenith_angle_op;
152 double* solar_azimuth_angle_op;
155 void do_operation()
const;
172 "cosine_zenith_angle",
183 "solar_zenith_angle",
184 "solar_azimuth_angle"
188void solar_position_michalsky::do_operation()
const
191 double constexpr deg_to_hr = 1.0 / 15.0;
192 double constexpr hr_to_deg = 15.0;
193 double constexpr hr_per_day = 24.0;
194 double constexpr deg_per_rev = 360.0;
196 double constexpr jd_ref_1948 = 2432916.5;
197 double constexpr jd_ref_2000 = 2451545.0;
200 double const fractional_doy_utc = fractional_doy - time_zone_offset / hr_per_day;
201 double const doy_utc = std::floor(fractional_doy_utc / hr_per_day);
202 double const hour_utc = hr_per_day * (fractional_doy_utc - doy_utc);
205 double const delta = year - 1949.0;
206 double const leap = floor(0.25 * delta);
207 double const jd = jd_ref_1948 + delta * 365.0 + leap + doy_utc + hour_utc / hr_per_day;
210 double const n = jd - jd_ref_2000;
213 double const L = fmod(280.460 + 0.9856474 * n, deg_per_rev);
214 double const g = fmod(357.528 + 0.9856003 * n, deg_per_rev);
215 double const ell = fmod(L + 1.915 * sin_deg(g) + 0.020 * sin_deg(2 * g), deg_per_rev);
216 double const ep = 23.439 - 0.0000004 * n;
219 double const ra = atan2_deg(cos_deg(ep) * sin_deg(ell), cos_deg(ell));
220 double const dec = asin_deg(sin_deg(ep) * sin_deg(ell));
223 double const gmst = fmod(6.697375 + 0.0657098242 * n + hour_utc, hr_per_day);
224 double const lmst = fmod(gmst + longitude * deg_to_hr, hr_per_day);
227 double const lha = fmod(lmst * hr_to_deg - ra, deg_per_rev);
229 double const zen = acos_deg(sin_deg(dec) * sin_deg(lat) +
230 cos_deg(dec) * cos_deg(lat) * cos_deg(lha));
232 double az = asin_deg(-cos_deg(dec) * sin_deg(lha) / cos_deg(90.0 - zen));
235 double const el = 90.0 - zen;
236 double const el_critical = asin_deg(sin_deg(dec) / sin_deg(lat));
238 if (el >= el_critical) {
240 }
else if (lha > 0) {
245 double const cos_zen = cos_deg(zen);
248 update(cosine_zenith_angle_op, cos_zen);
249 update(julian_date_op, jd);
250 update(solar_L_op, L);
251 update(solar_g_op, g);
252 update(solar_ell_op, ell);
253 update(solar_ep_op, ep);
254 update(solar_ra_op, ra);
255 update(solar_dec_op, dec);
256 update(gmst_op, gmst);
257 update(lmst_op, lmst);
259 update(solar_zenith_angle_op, zen);
260 update(solar_azimuth_angle_op, az);
Calculates the solar position using the model described in Michalsky, J. J. "The Astronomical Almanac...
solar_position_michalsky(state_map const &input_quantities, state_map *output_quantities)
static string_vector get_outputs()
static string_vector get_inputs()
static std::string get_name()
This is the standard BioCro module library; it includes the essential modules used in typical BioCro ...