libSUFR
a LIBrary of Some Useful Fortran Routines
All Classes Namespaces Files Functions Variables Pages
weather.f90
Go to the documentation of this file.
1!> \file weather.f90 Procedures to deal with weather
2
3
4! Copyright (c) 2002-2025 Marc van der Sluys - Nikhef/Utrecht University - marc.vandersluys.nl
5!
6! This file is part of the libSUFR package,
7! see: https://libsufr.sourceforge.net/
8!
9! This is free software: you can redistribute it and/or modify it under the terms of the European Union
10! Public Licence 1.2 (EUPL 1.2). This software is distributed in the hope that it will be useful, but
11! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12! PURPOSE. See the EU Public Licence for more details. You should have received a copy of the European
13! Union Public Licence along with this code. If not, see <https://www.eupl.eu/1.2/en/>.
14
15
16
17
18!***********************************************************************************************************************************
19!> \brief Procedures to deal with weather
20
22 implicit none
23 save
24
25contains
26
27
28 !*********************************************************************************************************************************
29 !> \brief Compute the air pressure for a given elevation and pressure at sea level
30 !!
31 !! \param elev Elevation w.r.t. sea level (m)
32 !! \param press0 Air pressure at sea level (e.g. mbar)
33 !! \retval air_pressure Air pressure at the given elevation (same as press0, default: mbar)
34 !!
35 !! \see https://en.wikipedia.org/wiki/Scale_height
36
37 elemental function air_pressure(elev, press0)
38 use sufr_kinds, only: double
39 implicit none
40 real(double), intent(in) :: elev
41 real(double), intent(in), optional :: press0
42 real(double) :: air_pressure, press00
43
44 press00 = 1010 ! 1010 mbar by default
45 if(present(press0)) press00 = press0
46
47 air_pressure = press0*exp(-elev/8500.d0) ! 8500m: typical pressure scale height for Earth's atmosphere
48
49 end function air_pressure
50 !*********************************************************************************************************************************
51
52
53
54 !*********************************************************************************************************************************
55 !> \brief Compute the air density for the given temperature and pressure
56 !!
57 !! \param press Pressure (Pa)
58 !! \param temp Temperature (K)
59 !! \retval air_density Air density (kg/m^3)
60 !!
61 !! \see https://en.wikipedia.org/wiki/Density_of_air
62
63 elemental function air_density(press, temp)
64 use sufr_kinds, only: double
65 implicit none
66 real(double), intent(in) :: press, temp
67 real(double) :: air_density, rspec
68
69 ! air_density = 1.225d0 ! Density of air, at std pressure and 15 deg C - https://en.wikipedia.org/wiki/Density_of_air
70
71 rspec = 287.058d0 ! Specific gas constant for dry air, J/(kg K) - https://en.wikipedia.org/wiki/Density_of_air
72
73 air_density = press / (rspec * temp) ! rho = P/RT
74
75 end function air_density
76 !*********************************************************************************************************************************
77
78
79 !*********************************************************************************************************************************
80 !> \brief Compute the air density for the given temperature and pressure, single-precision wrapper for air_density()
81 !!
82 !! \param press Pressure (Pa)
83 !! \param temp Temperature (K)
84 !! \retval air_density_sp Air density (kg/m^3)
85 !!
86 !! \see https://en.wikipedia.org/wiki/Density_of_air
87
88 elemental function air_density_sp(press, temp)
89 implicit none
90 real, intent(in) :: press, temp
91 real :: air_density_sp
92
93 air_density_sp = real( air_density( dble(press), dble(temp) ) )
94
95 end function air_density_sp
96 !*********************************************************************************************************************************
97
98
99 !*********************************************************************************************************************************
100 !> \brief Derive wind "force" on Beaufort scale from wind speed in m/s
101 !!
102 !! \param speed Wind speed (m/s)
103 !! \retval wind_speed_2_bft Wind "force" on the Beaufort scale
104 !!
105 !! \see https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale
106
107 elemental function beaufort(speed)
108 use sufr_kinds, only: double
109 implicit none
110 real(double), intent(in) :: speed
111 integer :: beaufort, speed_kmh
112
113 speed_kmh = ceiling(abs(speed)*3.6d0) ! Speed in km/h
114 select case(speed_kmh)
115 case(1) ! v <= 1 km/h
116 beaufort = 0
117 case(2:11) ! 1 km/h < v <= 11 km/h
118 if(abs(speed)*3.6d0.le.5.5d0) then ! 1 km/h < v <= 5.5 km/h
119 beaufort = 1
120 else ! 5.5 km/h < v <= 11 km/h
121 beaufort = 2
122 end if
123 case(12:19) ! 11 km/h < v <= 19 km/h
124 beaufort = 3
125 case(20:28) ! 19 km/h < v <= 28 km/h
126 beaufort = 4
127 case(29:38) ! 28 km/h < v <= 38 km/h
128 beaufort = 5
129 case(39:49) ! 38 km/h < v <= 49 km/h
130 beaufort = 6
131 case(50:61) ! 49 km/h < v <= 61 km/h
132 beaufort = 7
133 case(62:74) ! 61 km/h < v <= 74 km/h
134 beaufort = 8
135 case(75:88) ! 74 km/h < v <= 88 km/h
136 beaufort = 9
137 case(89:102) ! 88 km/h < v <= 102 km/h
138 beaufort = 10
139 case(103:117) ! 102 km/h < v <= 117 km/h
140 beaufort = 11
141 case default ! v > 117 km/h
142 beaufort = 12
143 end select
144
145 end function beaufort
146 !*********************************************************************************************************************************
147
148
149
150 !*********************************************************************************************************************************
151 !> \brief Compute the dew point from the temperature and relative humidity
152 !!
153 !! \param tempc Air temperature (degrees Celsius)
154 !! \param RH Relative humidity (fraction)
155 !! \retval dew_point Dew point (degrees Celsius)
156 !!
157 !! \see https://en.wikipedia.org/wiki/Dew_point
158
159 elemental function dew_point(tempc, RH)
160 use sufr_kinds, only: double
161 implicit none
162 real(double), intent(in) :: tempc, rh
163 real(double) :: dew_point, temp0, tempfac, gam
164
165 temp0 = 273.7d0
166 tempfac = 17.27d0
167 gam = tempfac * tempc/(temp0+tempc) + log(rh)
168
169 dew_point = temp0 * gam/(tempfac-gam)
170
171 end function dew_point
172 !*********************************************************************************************************************************
173
174
175
176 !*********************************************************************************************************************************
177 !> \brief Compute the saturated water-vapor density in air for a given temperature
178 !!
179 !! \param tempc Air temperature (degrees Celsius)
180 !! \retval water_vapor_saturated_density Saturated water-vapor density (g/m^3)
181 !!
182 !! \note
183 !! - uses data from https://hyperphysics.phy-astr.gsu.edu/hbase/kinetic/relhum.html#c3:
184 !! - for T= -10 - +60°C.
185 !! - drops to 0 below T~-25°C;
186 !! - significantly better results than original fit (3rd order polynomial):
187 !! - for T<~-15°C and T>~45°C: by eye;
188 !! - for -10°C < T < 60°C (range original fit -0°C < T < 40°C):
189 !! - typical sigma 0.116 (T=0-40°C) -> 0.030 g/m^3 (T=-10-60°C);
190 !! - max. abs. deviation: 0.168 g/m^3 (T=0-40°C; \@T=0°C) -> 0.0445 g/m^3 (T=-10-60°C; \@T=25°C)
191 !! - max. rel. deviation: 3.46 % (T=0-40°C; \@T=0°C) -> 0.194 % (T=-10-60°C; \@T=25°C)
192
193 elemental function water_vapor_saturated_density(tempc)
194 use sufr_kinds, only: double
195 implicit none
196 real(double), intent(in) :: tempc
198
199 water_vapor_saturated_density = 4.85684d0 + 3.32664d-1 * tempc + 1.00885d-2 * tempc**2 + &
200 1.89345d-4 * tempc**3 + 1.09606d-6 * tempc**4 + 1.83396d-8 * tempc**5
201
203 !*********************************************************************************************************************************
204
205
206
207end module sufr_weather
208!***********************************************************************************************************************************
209
Provides kinds and related constants/routines.
Definition kinds.f90:26
integer, parameter double
Double-precision float. Precision = 15, range = 307.
Definition kinds.f90:35
Procedures to deal with weather.
Definition weather.f90:21
elemental real(double) function water_vapor_saturated_density(tempc)
Compute the saturated water-vapor density in air for a given temperature.
Definition weather.f90:194
elemental real(double) function dew_point(tempc, rh)
Compute the dew point from the temperature and relative humidity.
Definition weather.f90:160
elemental real(double) function air_pressure(elev, press0)
Compute the air pressure for a given elevation and pressure at sea level.
Definition weather.f90:38
elemental real function air_density_sp(press, temp)
Compute the air density for the given temperature and pressure, single-precision wrapper for air_dens...
Definition weather.f90:89
elemental real(double) function air_density(press, temp)
Compute the air density for the given temperature and pressure.
Definition weather.f90:64
elemental integer function beaufort(speed)
Derive wind "force" on Beaufort scale from wind speed in m/s.
Definition weather.f90:108