Coverage for src / CSET / operators / pressure.py: 100%

41 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-28 09:58 +0000

1# © Crown copyright, Met Office (2022-2026) and CSET contributors. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""Operators for pressure conversions.""" 

16 

17import iris.cube 

18import numpy as np 

19 

20from CSET._common import iter_maybe 

21from CSET.operators._atmospheric_constants import E0, KAPPA, P0 

22from CSET.operators.misc import convert_units 

23 

24 

25def vapour_pressure( 

26 temperature: iris.cube.Cube | iris.cube.CubeList, 

27) -> iris.cube.Cube | iris.cube.CubeList: 

28 r"""Calculate the vapour pressure of the atmosphere. 

29 

30 Arguments 

31 --------- 

32 temperature: iris.cube.Cube | iris.cube.CubeList 

33 Cubes of temperature to be converted into vapour pressure. 

34 Temperature must be provided in Kelvin. 

35 

36 Returns 

37 ------- 

38 iris.cube.Cube | iris.cube.CubeList 

39 Vapour pressure in hPa. 

40 

41 Notes 

42 ----- 

43 The vapour pressure represents the pressure exerted by water vapour on the 

44 atmosphere. It is related to atmospheric temperature through the 

45 Clausius-Clapeyron equation. There are several different formulations based 

46 on empirical relations that are used to calculate the vapour pressure. Here, 

47 we calculate the vapour pressure based on [Buck81]_ equation: 

48 

49 .. math:: e = e_0 * exp\left(\frac{17.508 T}{240.97 + T}\right) 

50 

51 for e the vapour pressure, :math:`e_0` the saturation vapour pressure at 

52 a reference temperature of 273.15 K with a value of 6.1121 hPa, and T the 

53 temperature in degrees Celsius. 

54 

55 The temperature is provided in Kelvin and converted to degrees Celsius; 

56 the vapour pressure is returned in hPa. 

57 

58 If the (dry-bulb) temperature is used the value given by the vapour pressure 

59 will be the saturation vapour pressure. On the other hand, if the dewpoint 

60 temperature is used the vapour pressure will be calculated. 

61 

62 References 

63 ---------- 

64 .. [Buck81] Buck, A.L. (1981) "New Equations for Computing Vapor Pressure 

65 and Enhancement Factor". J. App. Meteor. Clim. 20: 1527-1532. 

66 

67 Examples 

68 -------- 

69 >>> vapour_pressure = pressure.vapour_pressure(temperature) 

70 """ 

71 v_pressure = iris.cube.CubeList([]) 

72 for T in iter_maybe(temperature): 

73 es = T.copy() 

74 T_units = convert_units(T, "Celsius") 

75 exponent = (17.502 * T_units) / (240.97 + T_units) 

76 es.data = E0 * np.exp(exponent.core_data()) 

77 es.units = "hPa" 

78 es.rename("vapour_pressure") 

79 v_pressure.append(es) 

80 if len(v_pressure) == 1: 

81 return v_pressure[0] 

82 else: 

83 return v_pressure 

84 

85 

86def vapour_pressure_from_relative_humidity( 

87 temperature: iris.cube.Cube | iris.cube.CubeList, 

88 relative_humidity: iris.cube.Cube | iris.cube.CubeList, 

89) -> iris.cube.Cube | iris.cube.CubeList: 

90 r"""Calculate the vapour pressure using relative humidity RH. 

91 

92 Arguments 

93 --------- 

94 temperature: iris.cube.Cube | iris.cube.CubeList 

95 Cubes of temperature to be converted into saturation vapour pressure. 

96 Temperature must be provided in Kelvin. 

97 relative_humidity: iris.cube.Cube | iris.cube.CubeList 

98 Cubes of relative humidity to be converted into vapour pressure. 

99 Relative humidity must be provided in percentage and 

100 will be converted to a decimal by the operator. 

101 

102 Returns 

103 ------- 

104 iris.cube.Cube | iris.cube.CubeList 

105 Vapour pressure in hPa. 

106 

107 Notes 

108 ----- 

109 The vapour pressure can be derived from the relative humidity and 

110 temperature based on the following relation 

111 

112 .. math:: e = RH * e_s 

113 

114 for e the vapour pressure, :math:`e_s` the saturation vapour pressure, 

115 and RH the relative humidity. 

116 

117 The relative humidity is converted to a decimal. The saturation vapour 

118 pressure is calculated using `pressure.vapour_pressure`. 

119 

120 Examples 

121 -------- 

122 >>> vapour_pressure = pressure.vapour_pressure_from_relative_humidity(temperature, relative_humidity) 

123 """ 

124 v_pressure = iris.cube.CubeList([]) 

125 for T, RH in zip( 

126 iter_maybe(temperature), iter_maybe(relative_humidity), strict=True 

127 ): 

128 RH = convert_units(RH, "1") 

129 vp = vapour_pressure(T) * RH 

130 vp.units = "hPa" 

131 vp.rename("vapour_pressure") 

132 v_pressure.append(vp) 

133 if len(v_pressure) == 1: 

134 return v_pressure[0] 

135 else: 

136 return v_pressure 

137 

138 

139def exner_pressure( 

140 pressure: iris.cube.Cube | iris.cube.CubeList, 

141) -> iris.cube.Cube | iris.cube.CubeList: 

142 r"""Calculate the exner pressure. 

143 

144 Arguments 

145 --------- 

146 pressure: iris.cube.Cube | iris.cube.CubeList 

147 Cubes of pressure to be converted. 

148 

149 Returns 

150 ------- 

151 iris.cube.Cube | iris.cube.CubeList 

152 Exner pressure. 

153 

154 Notes 

155 ----- 

156 The Exner pressure is also referred to as the Exner function. It is a 

157 dimensionless parameter that can be used either as a vertical coordinate or 

158 more frequently as a means to simplifying conversions between different 

159 parameters (e.g. Temperature and Potential Temperature; [Holton13]_). 

160 It is calculated as 

161 

162 .. math:: \Pi = \left(\frac{P}{P_0}\right)^{\kappa} 

163 

164 for :math:`\Pi` the Exner Pressure, P the pressure in hPa, :math:`P_0` a reference pressure 

165 of 1000 hPa, :math:`\kappa` the ratio between the specific gas constant of dry air 

166 (287.05 :math:`J kg^{-1} K^{-1}`) and the specific heat capacity at constant pressure 

167 (1005.0 :math:`J kg^{-1} K^{-1}`) equating to 0.28562. 

168 

169 A value below one implies the pressure is higher than the reference pressure; 

170 values above one implies the pressure is lower than the reference pressure; a 

171 value of one implies the pressure is equal to the reference pressure. 

172 

173 References 

174 ---------- 

175 .. [Holton13] Holton, J.R. and Hakim G.J. (2013) "An Introduction to Dynamic 

176 Meteorology." 5th Edition, Burlington, MA, Elsevier Academic Press, 532 pp. 

177 

178 Examples 

179 -------- 

180 >>> Exner_pressure = pressure.exner_pressure(pressure) 

181 """ 

182 pi = iris.cube.CubeList([]) 

183 for P in iter_maybe(pressure): 

184 PI = P.copy() 

185 P = convert_units(P, "hPa") 

186 PI.data = (P.core_data() / P0) ** KAPPA 

187 PI.rename("exner_pressure") 

188 PI.units = "1" 

189 pi.append(PI) 

190 if len(pi) == 1: 

191 return pi[0] 

192 else: 

193 return pi