use sciforge::hub::domain::common::constants::SIGMA_SB;
use sciforge::hub::domain::meteorology::radiation::{
planck_function, solar_zenith_angle, stefan_boltzmann_flux,
};
pub struct MercuryThermalState {
pub distance_au: f64,
pub albedo: f64,
}
impl MercuryThermalState {
pub fn mean() -> Self {
Self {
distance_au: 0.387,
albedo: crate::BOND_ALBEDO,
}
}
pub fn at_perihelion() -> Self {
Self {
distance_au: 0.307,
albedo: crate::BOND_ALBEDO,
}
}
pub fn at_aphelion() -> Self {
Self {
distance_au: 0.467,
albedo: crate::BOND_ALBEDO,
}
}
pub fn at_distance(distance_au: f64) -> Self {
Self {
distance_au,
albedo: crate::BOND_ALBEDO,
}
}
pub fn solar_flux(&self) -> f64 {
sciforge::hub::domain::meteorology::radiation::solar_constant()
/ (self.distance_au * self.distance_au)
}
pub fn subsolar_temperature_k(&self) -> f64 {
let flux = self.solar_flux() * (1.0 - self.albedo);
(flux / SIGMA_SB).powf(0.25)
}
pub fn temperature_at_zenith_k(&self, zenith_deg: f64) -> f64 {
if zenith_deg >= 90.0 {
return crate::NIGHTSIDE_TEMP_K;
}
let cos_z = zenith_deg.to_radians().cos();
let flux = self.solar_flux() * (1.0 - self.albedo) * cos_z;
(flux / SIGMA_SB).powf(0.25)
}
pub fn outgoing_radiation(&self, temperature_k: f64) -> f64 {
crate::SURFACE_EMISSIVITY * stefan_boltzmann_flux(temperature_k)
}
pub fn effective_temperature_k(&self) -> f64 {
let s = self.solar_flux();
((s * (1.0 - self.albedo)) / (4.0 * SIGMA_SB)).powf(0.25)
}
pub fn greenhouse_effect_k(&self) -> f64 {
0.0
}
pub fn energy_imbalance(&self, surface_temp_k: f64) -> f64 {
let absorbed = self.solar_flux() * (1.0 - self.albedo) / 4.0;
let emitted = crate::SURFACE_EMISSIVITY * stefan_boltzmann_flux(surface_temp_k);
absorbed - emitted
}
}
pub fn solar_zenith(latitude_deg: f64, declination_deg: f64, hour_angle_deg: f64) -> f64 {
solar_zenith_angle(latitude_deg, declination_deg, hour_angle_deg)
}
pub fn planck_spectral_radiance(wavelength_m: f64, temperature_k: f64) -> f64 {
planck_function(wavelength_m, temperature_k)
}
pub fn wien_peak_wavelength(temperature_k: f64) -> f64 {
2.898e-3 / temperature_k
}
pub fn equatorial_temp_range() -> (f64, f64) {
(crate::NIGHTSIDE_TEMP_K, crate::SUBSOLAR_TEMP_K)
}
pub fn polar_cold_trap_temp() -> f64 {
crate::POLAR_COLD_TRAP_TEMP_K
}