11//! Types and constants for handling humidity.
22
33use super :: measurement:: * ;
4- #[ cfg( not( feature = "no_std" ) ) ]
54use density:: Density ;
6- #[ cfg( not( feature = "no_std" ) ) ]
75use pressure:: Pressure ;
8- #[ cfg( not( feature = "no_std" ) ) ]
96use temperature:: Temperature ;
107
118/// The `Humidity` struct can be used to deal with relative humidity
@@ -35,9 +32,7 @@ use temperature::Temperature;
3532///
3633/// let humidity = Humidity::from_percent(85.0);
3734/// let temp = Temperature::from_celsius(18.0);
38- /// #[cfg(not(feature="no_std"))]
3935/// let dewpoint = humidity.as_dewpoint(temp);
40- /// #[cfg(not(feature="no_std"))]
4136/// println!("At {} humidity, air at {} has a dewpoint of {}", humidity, temp, dewpoint);
4237///
4338/// ```
@@ -82,6 +77,20 @@ impl Humidity {
8277 / ( 17.625 - humidity. ln ( ) - ( ( 17.625 * celsius) / ( 243.04 + celsius) ) ) ;
8378 Temperature :: from_celsius ( dewpoint)
8479 }
80+
81+ /// Calculates Dewpoint from humidity and air temperature using the Magnus-Tetens
82+ /// approximation, with coefficients derived by Alduchov and Eskridge (1996). The formulas assume
83+ // standard atmospheric pressure.
84+ #[ cfg( feature = "no_std" ) ]
85+ pub fn as_dewpoint ( & self , temp : Temperature ) -> Temperature {
86+ let humidity = self . relative_humidity / 100.0 ;
87+ let celsius = temp. as_celsius ( ) ;
88+ let humidity_ln = libm:: log ( humidity) ;
89+ let dewpoint: f64 = 243.04 * ( humidity_ln + ( ( 17.625 * celsius) / ( 243.04 + celsius) ) )
90+ / ( 17.625 - humidity_ln - ( ( 17.625 * celsius) / ( 243.04 + celsius) ) ) ;
91+ Temperature :: from_celsius ( dewpoint)
92+ }
93+
8594 /// Calculates the actual vapour pressure in the air, based on the air temperature and humidity
8695 /// at standard atmospheric pressure (1013.25 mb), using the Buck formula (accurate to +/- 0.02%
8796 /// between 0 deg C and 50 deg C)
@@ -93,9 +102,19 @@ impl Humidity {
93102 Pressure :: from_kilopascals ( ( self . relative_humidity * saturation_vapor_pressure) / 100.0 )
94103 }
95104
105+ /// Calculates the actual vapour pressure in the air, based on the air temperature and humidity
106+ /// at standard atmospheric pressure (1013.25 mb), using the Buck formula (accurate to +/- 0.02%
107+ /// between 0 deg C and 50 deg C)
108+ #[ cfg( feature = "no_std" ) ]
109+ pub fn as_vapor_pressure ( & self , temp : Temperature ) -> Pressure {
110+ let temp = temp. as_celsius ( ) ;
111+ let saturation_vapor_pressure =
112+ 0.61121 * libm:: exp ( ( 18.678 - ( temp / 234.5 ) ) * ( temp / ( 257.14 + temp) ) ) ;
113+ Pressure :: from_kilopascals ( ( self . relative_humidity * saturation_vapor_pressure) / 100.0 )
114+ }
115+
96116 /// Calculates the absolute humidity (i.e. the density of water vapor in the air (kg/m3)), using
97117 /// the Ideal Gas Law equation.
98- #[ cfg( not( feature = "no_std" ) ) ]
99118 pub fn as_absolute_humidity ( & self , temp : Temperature ) -> Density {
100119 // use the Ideal Gas Law equation (Density = Pressure / (Temperature * [gas constant
101120 // for water vapor= 461.5 (J/kg*Kelvin)]))
@@ -115,6 +134,19 @@ impl Humidity {
115134 / ( ( 17.625 * temp) / ( 243.04 + temp) ) . exp ( ) ) ;
116135 Humidity :: from_percent ( rh)
117136 }
137+
138+ /// Calculates humidity from dewpoint and air temperature using the Magnus-Tetens
139+ /// Approximation, with coefficients derived by Alduchov and Eskridge (1996). The formulas assume
140+ // standard atmospheric pressure.
141+ #[ cfg( feature = "no_std" ) ]
142+ pub fn from_dewpoint ( dewpoint : Temperature , temp : Temperature ) -> Humidity {
143+ let dewpoint = dewpoint. as_celsius ( ) ;
144+ let temp = temp. as_celsius ( ) ;
145+ let rh = 100.0
146+ * ( libm:: exp ( ( 17.625 * dewpoint) / ( 243.04 + dewpoint) )
147+ / libm:: exp ( ( 17.625 * temp) / ( 243.04 + temp) ) ) ;
148+ Humidity :: from_percent ( rh)
149+ }
118150}
119151
120152impl Measurement for Humidity {
@@ -167,47 +199,41 @@ mod test {
167199 assert_almost_eq ( o, 0.1 ) ;
168200 }
169201 // Dewpoint calculation
170- #[ cfg( not( feature = "no_std" ) ) ]
171202 #[ test]
172203 fn to_dewpoint1 ( ) {
173204 let humidity = Humidity :: from_percent ( 85.0 ) ;
174205 let temp = Temperature :: from_celsius ( 18.0 ) ;
175206 let dewpoint = humidity. as_dewpoint ( temp) ;
176207 assert_almost_eq ( dewpoint. as_celsius ( ) , 15.44 ) ;
177208 }
178- #[ cfg( not( feature = "no_std" ) ) ]
179209 #[ test]
180210 fn to_dewpoint2 ( ) {
181211 let humidity = Humidity :: from_percent ( 40.0 ) ;
182212 let temp = Temperature :: from_celsius ( 5.0 ) ;
183213 let dewpoint = humidity. as_dewpoint ( temp) ;
184214 assert_almost_eq ( dewpoint. as_celsius ( ) , -7.5 ) ;
185215 }
186- #[ cfg( not( feature = "no_std" ) ) ]
187216 #[ test]
188217 fn to_dewpoint3 ( ) {
189218 let humidity = Humidity :: from_percent ( 95.0 ) ;
190219 let temp = Temperature :: from_celsius ( 30.0 ) ;
191220 let dewpoint = humidity. as_dewpoint ( temp) ;
192221 assert_almost_eq ( dewpoint. as_celsius ( ) , 29.11 ) ;
193222 }
194- #[ cfg( not( feature = "no_std" ) ) ]
195223 #[ test]
196224 fn from_dewpoint1 ( ) {
197225 let temp = Temperature :: from_celsius ( 18.0 ) ;
198226 let dewpoint = Temperature :: from_celsius ( 15.44 ) ;
199227 let rh = Humidity :: from_dewpoint ( dewpoint, temp) ;
200228 assert_almost_eq ( rh. as_percent ( ) , 85.0 ) ;
201229 }
202- #[ cfg( not( feature = "no_std" ) ) ]
203230 #[ test]
204231 fn vapour_pressure ( ) {
205232 let humidity = Humidity :: from_percent ( 60.0 ) ;
206233 let temp = Temperature :: from_celsius ( 25.0 ) ;
207234 let vp = humidity. as_vapor_pressure ( temp) ;
208235 assert_almost_eq ( vp. as_hectopascals ( ) , 19.011 ) ;
209236 }
210- #[ cfg( not( feature = "no_std" ) ) ]
211237 #[ test]
212238 // also tests as_vapor_pressure() on the fly
213239 fn absolute_humidity ( ) {
@@ -216,7 +242,6 @@ mod test {
216242 let density = humidity. as_absolute_humidity ( temp) ;
217243 assert_almost_eq ( density. as_kilograms_per_cubic_meter ( ) , 0.0138166 ) ;
218244 }
219- #[ cfg( not( feature = "no_std" ) ) ]
220245 #[ test]
221246 // round-trip test
222247 fn from_dewpoint2 ( ) {
0 commit comments