MOM6
MOM_TFreeze.F90
Go to the documentation of this file.
1 module mom_tfreeze
2 
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 determine the potential temperature *
25 !* at which sea-water freezes. *
26 !********+*********+*********+*********+*********+*********+*********+**
27 use gsw_mod_toolbox, only : gsw_ct_freezing_exact
28 
29 implicit none ; private
30 
32 
35 end interface calculate_tfreeze_linear
36 
39 end interface calculate_tfreeze_millero
40 
43 end interface calculate_tfreeze_teos10
44 
45 contains
46 
47 subroutine calculate_tfreeze_linear_scalar(S, pres, T_Fr, TFr_S0_P0, &
48  dTFr_dS, dTFr_dp)
49  real, intent(in) :: S, pres
50  real, intent(out) :: T_Fr
51  real, intent(in) :: TFr_S0_P0, dTFr_dS, dTFr_dp
52 ! This subroutine computes the freezing point potential temparature
53 ! (in deg C) from salinity (in psu), and pressure (in Pa) using a simple
54 ! linear expression, with coefficients passed in as arguments.
55 !
56 ! Arguments: S - salinity in PSU.
57 ! (in) pres - pressure in Pa.
58 ! (out) T_Fr - Freezing point potential temperature in deg C.
59 ! (in) TFr_S0_P0 - The freezing point at S=0, p=0, in deg C.
60 ! (in) dTFr_dS - The derivatives of freezing point with salinity, in
61 ! deg C PSU-1.
62 ! (in) dTFr_dp - The derivatives of freezing point with pressure, in
63 ! deg C Pa-1.
64 
65  t_fr = (tfr_s0_p0 + dtfr_ds*s) + dtfr_dp*pres
66 
68 
69 !> This subroutine computes the freezing point potential temparature
70 !! (in deg C) from salinity (in psu), and pressure (in Pa) using a simple
71 !! linear expression, with coefficients passed in as arguments.
72 subroutine calculate_tfreeze_linear_array(S, pres, T_Fr, start, npts, &
73  TFr_S0_P0, dTFr_dS, dTFr_dp)
74  real, dimension(:), intent(in) :: S !< salinity in PSU.
75  real, dimension(:), intent(in) :: pres !< pressure in Pa.
76  real, dimension(:), intent(out) :: T_Fr !< Freezing point potential temperature in deg C.
77  integer, intent(in) :: start !< the starting point in the arrays.
78  integer, intent(in) :: npts !< the number of values to calculate.
79  real, intent(in) :: TFr_S0_P0 !< The freezing point at S=0, p=0, in deg C.
80  real, intent(in) :: dTFr_dS !< The derivative of freezing point with salinity,
81  !! in deg C PSU-1.
82  real, intent(in) :: dTFr_dp !< The derivative of freezing point with pressure,
83  !! in deg C Pa-1.
84 
85 ! This subroutine computes the freezing point potential temparature
86 ! (in deg C) from salinity (in psu), and pressure (in Pa) using a simple
87 ! linear expression, with coefficients passed in as arguments.
88 !
89 ! Arguments: S - salinity in PSU.
90 ! (in) pres - pressure in Pa.
91 ! (out) T_Fr - Freezing point potential temperature in deg C.
92 ! (in) start - the starting point in the arrays.
93 ! (in) npts - the number of values to calculate.
94 ! (in) TFr_S0_P0 - The freezing point at S=0, p=0, in deg C.
95 ! (in) dTFr_dS - The derivative of freezing point with salinity, in
96 ! deg C PSU-1.
97 ! (in) dTFr_dp - The derivative of freezing point with pressure, in
98 ! deg C Pa-1.
99  integer :: j
100 
101  do j=start,start+npts-1
102  t_fr(j) = (tfr_s0_p0 + dtfr_ds*s(j)) + dtfr_dp*pres(j)
103  enddo
104 
105 end subroutine calculate_tfreeze_linear_array
106 
107 !> This subroutine computes the freezing point potential temparature
108 !! (in deg C) from salinity (in psu), and pressure (in Pa) using the expression
109 !! from Millero (1978) (and in appendix A of Gill 1982), but with the of the
110 !! pressure dependence changed from 7.53e-8 to 7.75e-8 to make this an
111 !! expression for potential temperature (not in situ temperature), using a
112 !! value that is correct at the freezing point at 35 PSU and 5e6 Pa (500 dbar).
113 subroutine calculate_tfreeze_millero_scalar(S, pres, T_Fr)
114  real, intent(in) :: S !< Salinity in PSU.
115  real, intent(in) :: pres !< Pressure in Pa.
116  real, intent(out) :: T_Fr !< Freezing point potential temperature in deg C.
117 
118 ! This subroutine computes the freezing point potential temparature
119 ! (in deg C) from salinity (in psu), and pressure (in Pa) using the expression
120 ! from Millero (1978) (and in appendix A of Gill 1982), but with the of the
121 ! pressure dependence changed from 7.53e-8 to 7.75e-8 to make this an
122 ! expression for potential temperature (not in situ temperature), using a
123 ! value that is correct at the freezing point at 35 PSU and 5e6 Pa (500 dbar).
124 !
125 ! Arguments: S - salinity in PSU.
126 ! (in) pres - pressure in Pa.
127 ! (out) T_Fr - Freezing point potential temperature in deg C.
128  real, parameter :: cS1 = -0.0575, cs3_2 = 1.710523e-3, cs2 = -2.154996e-4
129  real, parameter :: dTFr_dp = -7.75e-8
130 
131  t_fr = s*(cs1 + (cs3_2 * sqrt(max(s,0.0)) + cs2 * s)) + dtfr_dp*pres
132 
134 
135 !> This subroutine computes the freezing point potential temparature
136 !! (in deg C) from salinity (in psu), and pressure (in Pa) using the expression
137 !! from Millero (1978) (and in appendix A of Gill 1982), but with the of the
138 !! pressure dependence changed from 7.53e-8 to 7.75e-8 to make this an
139 !! expression for potential temperature (not in situ temperature), using a
140 !! value that is correct at the freezing point at 35 PSU and 5e6 Pa (500 dbar).
141 subroutine calculate_tfreeze_millero_array(S, pres, T_Fr, start, npts)
142  real, dimension(:), intent(in) :: S !< Salinity in PSU.
143  real, dimension(:), intent(in) :: pres !< Pressure in Pa.
144  real, dimension(:), intent(out) :: T_Fr !< Freezing point potential temperature in deg C.
145  integer, intent(in) :: start !< The starting point in the arrays.
146  integer, intent(in) :: npts !< The number of values to calculate.
147 ! This subroutine computes the freezing point potential temparature
148 ! (in deg C) from salinity (in psu), and pressure (in Pa) using the expression
149 ! from Millero (1978) (and in appendix A of Gill 1982), but with the of the
150 ! pressure dependence changed from 7.53e-8 to 7.75e-8 to make this an
151 ! expression for potential temperature (not in situ temperature), using a
152 ! value that is correct at the freezing point at 35 PSU and 5e6 Pa (500 dbar).
153 !
154 ! Arguments: S - salinity in PSU.
155 ! (in) pres - pressure in Pa.
156 ! (out) T_Fr - Freezing point potential temperature in deg C.
157 ! (in) start - the starting point in the arrays.
158 ! (in) npts - the number of values to calculate.
159  real, parameter :: cS1 = -0.0575, cs3_2 = 1.710523e-3, cs2 = -2.154996e-4
160  real, parameter :: dTFr_dp = -7.75e-8
161  integer :: j
162 
163  do j=start,start+npts-1
164  t_fr(j) = s(j)*(cs1 + (cs3_2 * sqrt(max(s(j),0.0)) + cs2 * s(j))) + &
165  dtfr_dp*pres(j)
166  enddo
167 
168 end subroutine calculate_tfreeze_millero_array
169 
170 !> This subroutine computes the freezing point conservative temparature
171 !! (in deg C) from absolute salinity (in g/kg), and pressure (in Pa) using the
172 !! TEOS10 package.
173 subroutine calculate_tfreeze_teos10_scalar(S, pres, T_Fr)
174  real, intent(in) :: S !< Absolute salinity in g/kg.
175  real, intent(in) :: pres !< Pressure in Pa.
176  real, intent(out) :: T_Fr !< Freezing point conservative temperature in deg C.
177 ! This subroutine computes the freezing point conservative temparature
178 ! (in deg C) from absolute salinity (in g/kg), and pressure (in Pa) using the
179 ! TEOS10 package.
180 !
181 ! Arguments: S - absolute salinity in g/kg.
182 ! (in) pres - pressure in Pa.
183 ! (out) T_Fr - Freezing point conservative temperature in deg C.
184  real, dimension(1) :: S0, pres0
185  real, dimension(1) :: tfr0
186 
187  s0(1) = s
188  pres0(1) = pres
189 
190  call calculate_tfreeze_teos10_array(s0, pres0, tfr0, 1, 1)
191  t_fr = tfr0(1)
192 
193 end subroutine calculate_tfreeze_teos10_scalar
194 
195 !> This subroutine computes the freezing point conservative temparature
196 !! (in deg C) from absolute salinity (in g/kg), and pressure (in Pa) using the
197 !! TEOS10 package.
198 subroutine calculate_tfreeze_teos10_array(S, pres, T_Fr, start, npts)
199  real, dimension(:), intent(in) :: S !< absolute salinity in g/kg.
200  real, dimension(:), intent(in) :: pres !< pressure in Pa.
201  real, dimension(:), intent(out) :: T_Fr !< Freezing point conservative temperature in deg C.
202  integer, intent(in) :: start !< the starting point in the arrays.
203  integer, intent(in) :: npts !< the number of values to calculate.
204 ! This subroutine computes the freezing point conservative temparature
205 ! (in deg C) from absolute salinity (in g/kg), and pressure (in Pa) using the
206 ! TEOS10 package.
207 !
208 ! Arguments: S - absolute salinity in g/kg.
209 ! (in) pres - pressure in Pa.
210 ! (out) T_Fr - Freezing point conservative temperature in deg C.
211 ! * (in) start - the starting point in the arrays. *
212 ! * (in) npts - the number of values to calculate. *
213 
214  real, parameter :: Pa2db = 1.e-4 ! The conversion factor from Pa to dbar.
215 
216  real :: zs,zp
217  integer :: j
218  ! Assume sea-water contains no dissolved air.
219  real, parameter :: saturation_fraction = 0.0
220 
221  do j=start,start+npts-1
222  !Conversions
223  zs = s(j)
224  zp = pres(j)* pa2db !Convert pressure from Pascal to decibar
225 
226  if(s(j).lt.-1.0e-10) cycle !Can we assume safely that this is a missing value?
227  t_fr(j) = gsw_ct_freezing_exact(zs,zp,saturation_fraction)
228  enddo
229 
230 
231 end subroutine calculate_tfreeze_teos10_array
232 
233 end module mom_tfreeze
subroutine calculate_tfreeze_linear_scalar(S, pres, T_Fr, TFr_S0_P0, dTFr_dS, dTFr_dp)
Definition: MOM_TFreeze.F90:49
subroutine calculate_tfreeze_teos10_scalar(S, pres, T_Fr)
This subroutine computes the freezing point conservative temparature (in deg C) from absolute salinit...
subroutine calculate_tfreeze_millero_scalar(S, pres, T_Fr)
This subroutine computes the freezing point potential temparature (in deg C) from salinity (in psu)...
subroutine calculate_tfreeze_teos10_array(S, pres, T_Fr, start, npts)
This subroutine computes the freezing point conservative temparature (in deg C) from absolute salinit...
subroutine calculate_tfreeze_linear_array(S, pres, T_Fr, start, npts, TFr_S0_P0, dTFr_dS, dTFr_dp)
This subroutine computes the freezing point potential temparature (in deg C) from salinity (in psu)...
Definition: MOM_TFreeze.F90:74
subroutine calculate_tfreeze_millero_array(S, pres, T_Fr, start, npts)
This subroutine computes the freezing point potential temparature (in deg C) from salinity (in psu)...