1.3.64
 
Loading...
Searching...
No Matches
SolarPosition.h
Go to the documentation of this file.
1
16#ifndef SOLARPOSITION
17#define SOLARPOSITION
18
19#include "Context.h"
20#include <memory>
21
22// Forward declaration is in PragueSkyModelInterface.h
24
26public:
28
31 explicit SolarPosition(helios::Context *context_ptr);
32
34
40 SolarPosition(float UTC_hrs, float latitude_deg, float longitude_deg, helios::Context *context_ptr);
41
43 static int selfTest(int argc = 0, char **argv = nullptr);
44
46 [[nodiscard]] helios::Time getSunriseTime() const;
47
49 [[nodiscard]] helios::Time getSunsetTime() const;
50
52 [[nodiscard]] float getSunElevation() const;
53
55 [[nodiscard]] float getSunZenith() const;
56
58 [[nodiscard]] float getSunAzimuth() const;
59
61 [[nodiscard]] helios::vec3 getSunDirectionVector() const;
62
65
67
70 void setSunDirection(const helios::SphericalCoord &sundirection);
71
73
83 [[deprecated("Use setAtmosphericConditions() and parameter-free getSolarFlux() instead")]] [[nodiscard]] float getSolarFlux(float pressure_Pa, float temperature_K, float humidity_rel, float turbidity) const;
84
86
96 [[deprecated("Use setAtmosphericConditions() and parameter-free getSolarFluxPAR() instead")]] [[nodiscard]] float getSolarFluxPAR(float pressure_Pa, float temperature_K, float humidity_rel, float turbidity) const;
97
99
109 [[deprecated("Use setAtmosphericConditions() and parameter-free getSolarFluxNIR() instead")]] [[nodiscard]] float getSolarFluxNIR(float pressure_Pa, float temperature_K, float humidity_rel, float turbidity) const;
110
112
120 [[deprecated("Use setAtmosphericConditions() and parameter-free getDiffuseFraction() instead")]] [[nodiscard]] float getDiffuseFraction(float pressure_Pa, float temperature_K, float humidity_rel, float turbidity) const;
121
123
130 [[deprecated("Use setAtmosphericConditions() and parameter-free getAmbientLongwaveFlux() instead")]] [[nodiscard]] float getAmbientLongwaveFlux(float temperature_K, float humidity_rel) const;
131
133
138 [[nodiscard]] float calibrateTurbidityFromTimeseries(const std::string &timeseries_shortwave_flux_label_Wm2) const;
139
141
144 void enableCloudCalibration(const std::string &timeseries_shortwave_flux_label_Wm2);
145
148
150
159 void setAtmosphericConditions(float pressure_Pa, float temperature_K, float humidity_rel, float turbidity);
160
162
169 void getAtmosphericConditions(float &pressure_Pa, float &temperature_K, float &humidity_rel, float &turbidity) const;
170
172
178 [[nodiscard]] float getSolarFlux() const;
179
181
187 [[nodiscard]] float getSolarFluxPAR() const;
188
190
196 [[nodiscard]] float getSolarFluxNIR() const;
197
199
203 [[nodiscard]] float getDiffuseFraction() const;
204
206
211 [[nodiscard]] float getAmbientLongwaveFlux() const;
212
214
220 void calculateDirectSolarSpectrum(const std::string &label, float resolution_nm = 1.0f);
221
223
229 void calculateDiffuseSolarSpectrum(const std::string &label, float resolution_nm = 1.0f);
230
232
238 void calculateGlobalSolarSpectrum(const std::string &label, float resolution_nm = 1.0f);
239
240 // ===== Prague Sky Model =====
241
243
249
251
254 [[nodiscard]] bool isPragueSkyModelEnabled() const;
255
257
269 void updatePragueSkyModel(float ground_albedo = 0.33f);
270
272
281 [[nodiscard]] bool pragueSkyModelNeedsUpdate(float ground_albedo = 0.33f, float sun_tolerance = 0.01f, float turbidity_tolerance = 0.02f, float albedo_tolerance = 0.05f) const;
282
283private:
284 helios::Context *context;
285
286 float UTC;
287 float latitude;
288 float longitude;
289
290 bool issolarpositionoverridden = false;
291 helios::SphericalCoord sun_direction;
292
293 std::string cloudcalibrationlabel;
294
295 // Prague Sky Model members
296 std::unique_ptr<helios::PragueSkyModelInterface> prague_model;
297 bool prague_enabled = false;
298
299 // Cached values for Prague lazy evaluation
300 helios::vec3 cached_sun_direction;
301 float cached_turbidity = -1.0f;
302 float cached_albedo = -1.0f;
303
304 [[nodiscard]] helios::SphericalCoord calculateSunDirection(const helios::Time &time, const helios::Date &date) const;
305
306 // Prague Sky Model helper methods
307 void fitAngularParametersAtWavelength(float wavelength, float visibility_km, float albedo, const helios::vec3 &sun_dir, float &L_zenith, float &circ_str, float &circ_width, float &horiz_bright, float &normalization);
308
309 [[nodiscard]] float fitCircumsolarWidth(float L1, float L2, float h1, float h2, float gamma1, float gamma2) const;
310
311 [[nodiscard]] float computeAngularNormalization(float circ_str, float circ_width, float horiz_bright) const;
312
313 [[nodiscard]] helios::vec3 rotateDirectionTowardZenith(const helios::vec3 &dir, float angle_rad) const;
314
315 [[nodiscard]] helios::vec3 getDirectionAwayFromSun(const helios::vec3 &sun_dir, float zenith_angle_deg) const;
316
317 void GueymardSolarModel(float pressure, float temperature, float humidity, float turbidity, float &Eb_PAR, float &Eb_NIR, float &fdiff) const;
318
319 void applyCloudCalibration(float &R_calc_Wm2, float &fdiff_calc) const;
320
321 static float turbidityResidualFunction(float turbidity, std::vector<float> &parameters, const void *a_solarpositionmodel);
322
323 // ===== SSolar-GOA Spectral Solar Radiation Model =====
324
326 struct SpectralData {
327 std::vector<float> wavelengths_nm; // 300-2600 nm (2301 points)
328 std::vector<float> toa_irradiance; // Top-of-atmosphere irradiance in W/m²/nm
329 std::vector<float> h2o_coef; // Water vapor absorption coefficient
330 std::vector<float> h2o_exp; // Water vapor absorption exponent
331 std::vector<float> o3_xsec; // Ozone cross section in cm²/molecule
332 std::vector<float> o2_coef; // Oxygen absorption coefficient
333
335 void loadFromDirectory(const std::string &data_path);
336
338 [[nodiscard]] static float interpolate(const std::vector<float> &x, const std::vector<float> &y, float x_val);
339 };
340
342 [[nodiscard]] float calculateGeometricFactor(int julian_day) const;
343
345 void calculateRayleighTransmittance(const std::vector<float> &wavelengths_um, float mu0, float pressure_ratio, std::vector<float> &tdir, std::vector<float> &tglb, std::vector<float> &tdif, std::vector<float> &atm_albedo) const;
346
348 void calculateAerosolTransmittance(const std::vector<float> &wavelengths_um, float mu0, float alpha, float beta, float w0, float g, std::vector<float> &tdir, std::vector<float> &tglb, std::vector<float> &tdif,
349 std::vector<float> &atm_albedo) const;
350
352 void calculateMixtureTransmittance(const std::vector<float> &wavelengths_um, float mu0, float pressure_Pa, float turbidity_beta, float angstrom_alpha, float aerosol_ssa, float aerosol_g, bool coupling, std::vector<float> &tglb,
353 std::vector<float> &tdir, std::vector<float> &tdif, std::vector<float> &atm_albedo) const;
354
356 void calculateWaterVaporTransmittance(const SpectralData &data, float mu0, float water_vapor_cm, std::vector<float> &transmittance) const;
357
359 void calculateOzoneTransmittance(const SpectralData &data, float mu0, float ozone_DU, std::vector<float> &transmittance) const;
360
362 void calculateOxygenTransmittance(const SpectralData &data, float mu0, std::vector<float> &transmittance) const;
363
365 void calculateSpectralIrradianceComponents(std::vector<helios::vec2> &global_spectrum, std::vector<helios::vec2> &direct_spectrum, std::vector<helios::vec2> &diffuse_spectrum, float resolution_nm) const;
366};
367
368#endif