MOM6
MOM_EOS_TEOS10.F90
Go to the documentation of this file.
1 
3 !***********************************************************************
4 !* GNU General Public License *
5 !* This file is a part of MOM. *
6 !* *
7 !* MOM is free software; you can redistribute it and/or modify it and *
8 !* are expected to follow the terms of the GNU General Public License *
9 !* as published by the Free Software Foundation; either version 2 of *
10 !* the License, or (at your option) any later version. *
11 !* *
12 !* MOM is distributed in the hope that it will be useful, but WITHOUT *
13 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
14 !* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public *
15 !* License for more details. *
16 !* *
17 !* For the full text of the GNU General Public License, *
18 !* write to: Free Software Foundation, Inc., *
19 !* 675 Mass Ave, Cambridge, MA 02139, USA. *
20 !* or see: http://www.gnu.org/licenses/gpl.html *
21 !***********************************************************************
22 
23 !***********************************************************************
24 !* The subroutines in this file implement the equation of state for *
25 !* sea water using the TEOS10 functions *
26 !***********************************************************************
27 
28 use gsw_mod_toolbox, only : gsw_sp_from_sr, gsw_pt_from_ct
29 use gsw_mod_toolbox, only : gsw_rho, gsw_rho_first_derivatives, gsw_specvol_first_derivatives
30 !use gsw_mod_toolbox, only : gsw_sr_from_sp, gsw_ct_from_pt
31 
32 implicit none ; private
33 
37 public gsw_sp_from_sr, gsw_pt_from_ct
38 
41 end interface calculate_density_teos10
42 
43 real, parameter :: pa2db = 1.e-4 ! The conversion factor from Pa to dbar.
44 
45 contains
46 
47 !> This subroutine computes the in situ density of sea water (rho in
48 !! units of kg/m^3) from salinity (S in psu), potential temperature
49 !! (T in deg C), and pressure in Pa. It uses the expression from
50 !! TEOS10 website.
51 subroutine calculate_density_scalar_teos10(T, S, pressure, rho)
52 real, intent(in) :: T !< Conservative temperature in C.
53 real, intent(in) :: S !< Absolute salinity in g/kg.
54 real, intent(in) :: pressure !< Pressure in Pa.
55 real, intent(out) :: rho !< In situ density in kg m-3.
56 ! * Arguments: T - conservative temperature in C. *
57 ! * (in) S - absolute salinity in g/kg. *
58 ! * (in) pressure - pressure in Pa. *
59 ! * (out) rho - in situ density in kg m-3. *
60 ! * (in) start - the starting point in the arrays. *
61 ! * (in) npts - the number of values to calculate. *
62 
63 ! *====================================================================*
64 ! * This subroutine computes the in situ density of sea water (rho in *
65 ! * units of kg/m^3) from salinity (S in psu), potential temperature *
66 ! * (T in deg C), and pressure in Pa. It uses the expression from *
67 ! * TEOS10 website. *
68 ! *====================================================================*
69 
70  real, dimension(1) :: T0, S0, pressure0
71  real, dimension(1) :: rho0
72 
73  t0(1) = t
74  s0(1) = s
75  pressure0(1) = pressure
76 
77  call calculate_density_array_teos10(t0, s0, pressure0, rho0, 1, 1)
78  rho = rho0(1)
79 
81 
82 subroutine calculate_density_array_teos10(T, S, pressure, rho, start, npts)
83  real, intent(in), dimension(:) :: T, S, pressure
84  real, intent(out), dimension(:) :: rho
85  integer, intent(in) :: start, npts
86 ! * Arguments: T - conservative temperature in C. *
87 ! * (in) S - absolute salinity in g/kg. *
88 ! * (in) pressure - pressure in Pa. *
89 ! * (out) rho - in situ density in kg m-3. *
90 ! * (in) start - the starting point in the arrays. *
91 ! * (in) npts - the number of values to calculate. *
92 
93 ! *====================================================================*
94 ! * This subroutine computes the in situ density of sea water (rho in *
95 ! * units of kg/m^3) from absolute salinity (S in g/Kg), *
96 ! * conservative temperature (T in deg C), and pressure in Pa. *
97 ! * It uses the functions from TEOS10 website *
98 ! *====================================================================*
99  real :: zs,zt,zp
100  integer :: j
101 
102  do j=start,start+npts-1
103  !Conversions
104  zs = s(j) !gsw_sr_from_sp(S(j)) !Convert practical salinity to absolute salinity
105  zt = t(j) !gsw_ct_from_pt(S(j),T(j)) !Convert potantial temp to conservative temp
106  zp = pressure(j)* pa2db !Convert pressure from Pascal to decibar
107 
108  if(s(j).lt.-1.0e-10) cycle !Can we assume safely that this is a missing value?
109  rho(j) = gsw_rho(zs,zt,zp)
110  enddo
111 end subroutine calculate_density_array_teos10
112 
113 subroutine calculate_density_derivs_teos10(T, S, pressure, drho_dT, drho_dS, start, npts)
114  real, intent(in), dimension(:) :: T !< Conservative temperature in C.
115  real, intent(in), dimension(:) :: S !< Absolute salinity in g/kg.
116  real, intent(in), dimension(:) :: pressure !< Pressure in Pa.
117  real, intent(out), dimension(:) :: drho_dT !< The partial derivative of density with potential
118  !! temperature, in kg m-3 K-1.
119  real, intent(out), dimension(:) :: drho_dS !< The partial derivative of density with salinity,
120  !! in kg m-3 psu-1.
121  integer, intent(in) :: start !< The starting point in the arrays.
122  integer, intent(in) :: npts !< The number of values to calculate.
123 ! * Arguments: T - conservative temperature in C. *
124 ! * (in) S - absolute salinity in g/kg. *
125 ! * (in) pressure - pressure in Pa. *
126 ! * (out) drho_dT - the partial derivative of density with *
127 ! * potential temperature, in kg m-3 K-1. *
128 ! * (out) drho_dS - the partial derivative of density with *
129 ! * salinity, in kg m-3 psu-1. *
130 ! * (in) start - the starting point in the arrays. *
131 ! * (in) npts - the number of values to calculate. *
132  real :: zs,zt,zp
133  integer :: j
134 
135  do j=start,start+npts-1
136  !Conversions
137  zs = s(j) !gsw_sr_from_sp(S(j)) !Convert practical salinity to absolute salinity
138  zt = t(j) !gsw_ct_from_pt(S(j),T(j)) !Convert potantial temp to conservative temp
139  zp = pressure(j)* pa2db !Convert pressure from Pascal to decibar
140  if(s(j).lt.-1.0e-10) cycle !Can we assume safely that this is a missing value?
141  call gsw_rho_first_derivatives(zs, zt, zp, drho_dsa=drho_ds(j), drho_dct=drho_dt(j))
142  enddo
143 
144 end subroutine calculate_density_derivs_teos10
145 
146 subroutine calculate_specvol_derivs_teos10(T, S, pressure, dSV_dT, dSV_dS, start, npts)
147  real, intent(in), dimension(:) :: T !< Conservative temperature in C.
148  real, intent(in), dimension(:) :: S !< Absolute salinity in g/kg.
149  real, intent(in), dimension(:) :: pressure !< Pressure in Pa.
150  real, intent(out), dimension(:) :: dSV_dT !< The partial derivative of specific volume with
151  !! potential temperature, in m3 kg-1 K-1.
152  real, intent(out), dimension(:) :: dSV_dS !< The partial derivative of specific volume with
153  !! salinity, in m3 kg-1 / (g/kg).
154  integer, intent(in) :: start !< The starting point in the arrays.
155  integer, intent(in) :: npts !< The number of values to calculate.
156 ! * Arguments: T - conservative temperature in C. *
157 ! * (in) S - absolute salinity in g/kg. *
158 ! * (in) pressure - pressure in Pa. *
159 ! * (out) dSV_dT - the partial derivative of specific volume with *
160 ! * potential temperature, in m3 kg-1 K-1. *
161 ! * (out) dSV_dS - the partial derivative of specific volume with *
162 ! * salinity, in m3 kg-1 / (g/kg). *
163 ! * (in) start - the starting point in the arrays. *
164 ! * (in) npts - the number of values to calculate. *
165  real :: zs, zt, zp
166  integer :: j
167 
168  do j=start,start+npts-1
169  !Conversions
170  zs = s(j) !gsw_sr_from_sp(S(j)) !Convert practical salinity to absolute salinity
171  zt = t(j) !gsw_ct_from_pt(S(j),T(j)) !Convert potantial temp to conservative temp
172  zp = pressure(j)* pa2db !Convert pressure from Pascal to decibar
173  if(s(j).lt.-1.0e-10) cycle !Can we assume safely that this is a missing value?
174  call gsw_specvol_first_derivatives(zs,zt,zp, v_sa=dsv_ds(j), v_ct=dsv_dt(j))
175  enddo
176 
177 end subroutine calculate_specvol_derivs_teos10
178 
179 !> This subroutine computes the in situ density of sea water (rho in *
180 !! units of kg/m^3) and the compressibility (drho/dp = C_sound^-2) *
181 !! (drho_dp in units of s2 m-2) from salinity (sal in psu), potential*
182 !! temperature (T in deg C), and pressure in Pa. It uses the *
183 !! subroutines from TEOS10 website
184 subroutine calculate_compress_teos10(T, S, pressure, rho, drho_dp, start, npts)
185  real, intent(in), dimension(:) :: T !< Conservative temperature in C.
186  real, intent(in), dimension(:) :: S !< Absolute salinity in g/kg.
187  real, intent(in), dimension(:) :: pressure !< Pressure in Pa.
188  real, intent(out), dimension(:) :: rho !< In situ density in kg m-3.
189  real, intent(out), dimension(:) :: drho_dp !< The partial derivative of density with pressure
190  !! (also the inverse of the square of sound speed)
191  !! in s2 m-2.
192  integer, intent(in) :: start !< The starting point in the arrays.
193  integer, intent(in) :: npts !< The number of values to calculate.
194 ! * Arguments: T - conservative temperature in C. *
195 ! * (in) S - absolute salinity in g/kg. *
196 ! * (in) pressure - pressure in Pa. *
197 ! * (out) rho - in situ density in kg m-3. *
198 ! * (out) drho_dp - the partial derivative of density with *
199 ! * pressure (also the inverse of the square of *
200 ! * sound speed) in s2 m-2. *
201 ! * (in) start - the starting point in the arrays. *
202 ! * (in) npts - the number of values to calculate. *
203 ! *====================================================================*
204 ! * This subroutine computes the in situ density of sea water (rho in *
205 ! * units of kg/m^3) and the compressibility (drho/dp = C_sound^-2) *
206 ! * (drho_dp in units of s2 m-2) from salinity (sal in psu), potential*
207 ! * temperature (T in deg C), and pressure in Pa. It uses the *
208 ! * subroutines from TEOS10 website *
209 ! *====================================================================*
210  real :: zs,zt,zp
211  integer :: j
212 
213  do j=start,start+npts-1
214  !Conversions
215  zs = s(j) !gsw_sr_from_sp(S(j)) !Convert practical salinity to absolute salinity
216  zt = t(j) !gsw_ct_from_pt(S(j),T(j)) !Convert potantial temp to conservative temp
217  zp = pressure(j)* pa2db !Convert pressure from Pascal to decibar
218  if(s(j).lt.-1.0e-10) cycle !Can we assume safely that this is a missing value?
219  rho(j) = gsw_rho(zs,zt,zp)
220  call gsw_rho_first_derivatives(zs,zt,zp, drho_dp=drho_dp(j))
221  enddo
222 end subroutine calculate_compress_teos10
223 
224 end module mom_eos_teos10
subroutine, public calculate_compress_teos10(T, S, pressure, rho, drho_dp, start, npts)
This subroutine computes the in situ density of sea water (rho in * units of kg/m^3) and the compress...
subroutine, public calculate_specvol_derivs_teos10(T, S, pressure, dSV_dT, dSV_dS, start, npts)
subroutine, public calculate_density_derivs_teos10(T, S, pressure, drho_dT, drho_dS, start, npts)
real, parameter pa2db
subroutine, public calculate_density_scalar_teos10(T, S, pressure, rho)
This subroutine computes the in situ density of sea water (rho in units of kg/m^3) from salinity (S i...
subroutine, public calculate_density_array_teos10(T, S, pressure, rho, start, npts)