Coverage for src / CSET / operators / pressure.py: 100%
40 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-01-28 11:16 +0000
« prev ^ index » next coverage.py v7.13.2, created at 2026-01-28 11:16 +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.
15"""Operators for pressure conversions."""
17import iris.cube
18import numpy as np
20from CSET._common import iter_maybe
21from CSET.operators._atmospheric_constants import E0, KAPPA, P0
22from CSET.operators.misc import convert_units
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.
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.
36 Returns
37 -------
38 iris.cube.Cube | iris.cube.CubeList
39 Vapour pressure in hPa.
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 [Tetens30]_ equation:
49 .. math:: e = e_0 * exp\left(17.27\frac{T - 273.16}{T - 35.86}\right)
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.1078 hPa, and T the
53 temperature.
55 The temperature is provided in Kelvin, and the vapour pressure is returned
56 in hPa.
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.
62 References
63 ----------
64 .. [Tetens30] Tetens, O. (1930) "Über einige meteorologische Begriffe".
65 Z. Geophys 6: 297-309.
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 exponent = 17.27 * (T - 273.16) / (T - 35.86)
75 es.data = E0 * np.exp(exponent.core_data())
76 es.units = "hPa"
77 es.rename("vapour_pressure")
78 v_pressure.append(es)
79 if len(v_pressure) == 1:
80 return v_pressure[0]
81 else:
82 return v_pressure
85def vapour_pressure_from_relative_humidity(
86 temperature: iris.cube.Cube | iris.cube.CubeList,
87 relative_humidity: iris.cube.Cube | iris.cube.CubeList,
88) -> iris.cube.Cube | iris.cube.CubeList:
89 r"""Calculate the vapour pressure using relative humidity RH.
91 Arguments
92 ---------
93 temperature: iris.cube.Cube | iris.cube.CubeList
94 Cubes of temperature to be converted into saturation vapour pressure.
95 Temperature must be provided in Kelvin.
96 relative_humidity: iris.cube.Cube | iris.cube.CubeList
97 Cubes of relative humidity to be converted into vapour pressure.
98 Relative humidity must be provided in percentage and
99 will be converted to a decimal by the operator.
101 Returns
102 -------
103 iris.cube.Cube | iris.cube.CubeList
104 Vapour pressure in hPa.
106 Notes
107 -----
108 The vapour pressure can be derived from the relative humidity and
109 temperature based on the following relation
111 .. math:: e = RH * e_s
113 for e the vapour pressure, :math:`e_s` the saturation vapour pressure,
114 and RH the relative humidity.
116 The relative humidity is converted to a decimal. The saturation vapour
117 pressure is calculated using `pressure.vapour_pressure`.
119 Examples
120 --------
121 >>> vapour_pressure = pressure.vapour_pressure_from_relative_humidity(temperature, relative_humidity)
122 """
123 v_pressure = iris.cube.CubeList([])
124 for T, RH in zip(
125 iter_maybe(temperature), iter_maybe(relative_humidity), strict=True
126 ):
127 RH = convert_units(RH, "1")
128 vp = vapour_pressure(T) * RH
129 vp.units = "hPa"
130 vp.rename("vapour_pressure")
131 v_pressure.append(vp)
132 if len(v_pressure) == 1:
133 return v_pressure[0]
134 else:
135 return v_pressure
138def exner_pressure(
139 pressure: iris.cube.Cube | iris.cube.CubeList,
140) -> iris.cube.Cube | iris.cube.CubeList:
141 r"""Calculate the exner pressure.
143 Arguments
144 ---------
145 pressure: iris.cube.Cube | iris.cube.CubeList
146 Cubes of pressure to be converted.
148 Returns
149 -------
150 iris.cube.Cube | iris.cube.CubeList
151 Exner pressure.
153 Notes
154 -----
155 The Exner pressure is also referred to as the Exner function. It is a
156 dimensionless parameter that can be used either as a vertical coordinate or
157 more frequently as a means to simplifying conversions between different
158 parameters (e.g. Temperature and Potential Temperature; [Holton13]_).
159 It is calculated as
161 .. math:: \Pi = \left(\frac{P}{P_0}\right)^{\frac{R_d}{c_p}}
163 for :math:`\Pi` the Exner Pressure, P the pressure in hPa, :math:`P_0` a reference pressure
164 of 1000 hPa, :math:`R_d` the specific gas constant of dry air taken as 297 :math:`J kg^{-1} K^{-1}`,
165 :math:`c_p` the specific heat capacity at constant pressure taken as 1005.7 :math:`J kg^{-1} K^{-1}`.
167 A value below one implies the pressure is higher than the reference pressure;
168 values above one implies the pressure is lower than the reference pressure; a
169 value of one implies the pressure is equal to the reference pressure.
171 References
172 ----------
173 .. [Holton13] Holton, J.R. and Hakim G.J. (2013) "An Introduction to Dynamic
174 Meteorology." 5th Edition, Burlington, MA, Elsevier Academic Press, 532 pp.
176 Examples
177 --------
178 >>> Exner_pressure = pressure.exner_pressure(pressure)
179 """
180 pi = iris.cube.CubeList([])
181 for P in iter_maybe(pressure):
182 PI = P.copy()
183 P = convert_units(P, "hPa")
184 PI.data = (P.core_data() / P0) ** KAPPA
185 PI.rename("exner_pressure")
186 PI.units = "1"
187 pi.append(PI)
188 if len(pi) == 1:
189 return pi[0]
190 else:
191 return pi