1
1
//! Types and constants for handling humidity.
2
2
3
3
use super :: measurement:: * ;
4
- #[ cfg( not( feature = "no_std" ) ) ]
5
4
use density:: Density ;
6
- #[ cfg( not( feature = "no_std" ) ) ]
7
5
use pressure:: Pressure ;
8
- #[ cfg( not( feature = "no_std" ) ) ]
9
6
use temperature:: Temperature ;
10
7
11
8
/// The `Humidity` struct can be used to deal with relative humidity
@@ -35,9 +32,7 @@ use temperature::Temperature;
35
32
///
36
33
/// let humidity = Humidity::from_percent(85.0);
37
34
/// let temp = Temperature::from_celsius(18.0);
38
- /// #[cfg(not(feature="no_std"))]
39
35
/// let dewpoint = humidity.as_dewpoint(temp);
40
- /// #[cfg(not(feature="no_std"))]
41
36
/// println!("At {} humidity, air at {} has a dewpoint of {}", humidity, temp, dewpoint);
42
37
///
43
38
/// ```
@@ -82,6 +77,20 @@ impl Humidity {
82
77
/ ( 17.625 - humidity. ln ( ) - ( ( 17.625 * celsius) / ( 243.04 + celsius) ) ) ;
83
78
Temperature :: from_celsius ( dewpoint)
84
79
}
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
+
85
94
/// Calculates the actual vapour pressure in the air, based on the air temperature and humidity
86
95
/// at standard atmospheric pressure (1013.25 mb), using the Buck formula (accurate to +/- 0.02%
87
96
/// between 0 deg C and 50 deg C)
@@ -93,9 +102,19 @@ impl Humidity {
93
102
Pressure :: from_kilopascals ( ( self . relative_humidity * saturation_vapor_pressure) / 100.0 )
94
103
}
95
104
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
+
96
116
/// Calculates the absolute humidity (i.e. the density of water vapor in the air (kg/m3)), using
97
117
/// the Ideal Gas Law equation.
98
- #[ cfg( not( feature = "no_std" ) ) ]
99
118
pub fn as_absolute_humidity ( & self , temp : Temperature ) -> Density {
100
119
// use the Ideal Gas Law equation (Density = Pressure / (Temperature * [gas constant
101
120
// for water vapor= 461.5 (J/kg*Kelvin)]))
@@ -115,6 +134,19 @@ impl Humidity {
115
134
/ ( ( 17.625 * temp) / ( 243.04 + temp) ) . exp ( ) ) ;
116
135
Humidity :: from_percent ( rh)
117
136
}
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
+ }
118
150
}
119
151
120
152
impl Measurement for Humidity {
@@ -167,47 +199,41 @@ mod test {
167
199
assert_almost_eq ( o, 0.1 ) ;
168
200
}
169
201
// Dewpoint calculation
170
- #[ cfg( not( feature = "no_std" ) ) ]
171
202
#[ test]
172
203
fn to_dewpoint1 ( ) {
173
204
let humidity = Humidity :: from_percent ( 85.0 ) ;
174
205
let temp = Temperature :: from_celsius ( 18.0 ) ;
175
206
let dewpoint = humidity. as_dewpoint ( temp) ;
176
207
assert_almost_eq ( dewpoint. as_celsius ( ) , 15.44 ) ;
177
208
}
178
- #[ cfg( not( feature = "no_std" ) ) ]
179
209
#[ test]
180
210
fn to_dewpoint2 ( ) {
181
211
let humidity = Humidity :: from_percent ( 40.0 ) ;
182
212
let temp = Temperature :: from_celsius ( 5.0 ) ;
183
213
let dewpoint = humidity. as_dewpoint ( temp) ;
184
214
assert_almost_eq ( dewpoint. as_celsius ( ) , -7.5 ) ;
185
215
}
186
- #[ cfg( not( feature = "no_std" ) ) ]
187
216
#[ test]
188
217
fn to_dewpoint3 ( ) {
189
218
let humidity = Humidity :: from_percent ( 95.0 ) ;
190
219
let temp = Temperature :: from_celsius ( 30.0 ) ;
191
220
let dewpoint = humidity. as_dewpoint ( temp) ;
192
221
assert_almost_eq ( dewpoint. as_celsius ( ) , 29.11 ) ;
193
222
}
194
- #[ cfg( not( feature = "no_std" ) ) ]
195
223
#[ test]
196
224
fn from_dewpoint1 ( ) {
197
225
let temp = Temperature :: from_celsius ( 18.0 ) ;
198
226
let dewpoint = Temperature :: from_celsius ( 15.44 ) ;
199
227
let rh = Humidity :: from_dewpoint ( dewpoint, temp) ;
200
228
assert_almost_eq ( rh. as_percent ( ) , 85.0 ) ;
201
229
}
202
- #[ cfg( not( feature = "no_std" ) ) ]
203
230
#[ test]
204
231
fn vapour_pressure ( ) {
205
232
let humidity = Humidity :: from_percent ( 60.0 ) ;
206
233
let temp = Temperature :: from_celsius ( 25.0 ) ;
207
234
let vp = humidity. as_vapor_pressure ( temp) ;
208
235
assert_almost_eq ( vp. as_hectopascals ( ) , 19.011 ) ;
209
236
}
210
- #[ cfg( not( feature = "no_std" ) ) ]
211
237
#[ test]
212
238
// also tests as_vapor_pressure() on the fly
213
239
fn absolute_humidity ( ) {
@@ -216,7 +242,6 @@ mod test {
216
242
let density = humidity. as_absolute_humidity ( temp) ;
217
243
assert_almost_eq ( density. as_kilograms_per_cubic_meter ( ) , 0.0138166 ) ;
218
244
}
219
- #[ cfg( not( feature = "no_std" ) ) ]
220
245
#[ test]
221
246
// round-trip test
222
247
fn from_dewpoint2 ( ) {
0 commit comments