FV3 Bundle
gsw_sa_freezing_from_t_poly.f90
Go to the documentation of this file.
1 !==========================================================================
2 elemental function gsw_sa_freezing_from_t_poly (t, p, saturation_fraction)
3 !==========================================================================
4 !
5 ! Calculates the Absolute Salinity of seawater at the freezing temperature.
6 ! That is, the output is the Absolute Salinity of seawater, with the
7 ! fraction saturation_fraction of dissolved air, that is in equilibrium
8 ! with ice at in-situ temperature t and pressure p. If the input values
9 ! are such that there is no positive value of Absolute Salinity for which
10 ! seawater is frozen, the output is put equal to Nan.
11 !
12 ! t = in-situ Temperature (ITS-90) [ deg C ]
13 ! p = sea pressure [ dbar ]
14 ! ( i.e. absolute pressure - 10.1325 dbar )
15 ! saturation_fraction = the saturation fraction of dissolved air in
16 ! seawater
17 !
18 ! sa_freezing_from_t_poly = Absolute Salinity of seawater when it freezes,
19 ! for given input values of in situ temperature, pressure and
20 ! air saturation fraction. [ g/kg ]
21 !--------------------------------------------------------------------------
22 
26 
28 
29 use gsw_mod_kinds
30 
31 implicit none
32 
33 real (r8), intent(in) :: t, p, saturation_fraction
34 
35 real (r8) :: gsw_sa_freezing_from_t_poly
36 
37 integer :: i_iter
38 real (r8) :: dt_dsa, sa, sa_old, sa_mean, t_freezing, t_freezing_zero_sa
39 
40 integer, parameter :: number_of_iterations = 5
41 
42 ! This is the band of sa within +- 2.5 g/kg of sa = 0, which we treat
43 ! differently in calculating the initial values of both SA and dCT_dSA.
44 real (r8), parameter :: sa_cut_off = 2.5_r8
45 
46 character (*), parameter :: func_name = "gsw_sa_freezing_from_t_poly"
47 
48 ! Find t > t_freezing_zero_SA. If this is the case, the input values
49 ! represent seawater that is not frozen (at any positive SA).
50 t_freezing_zero_sa = gsw_t_freezing_poly(0.0_r8,p,saturation_fraction)
51 if (t .gt. t_freezing_zero_sa) then
53  return
54 end if
55 
56 ! This is the inital guess of SA using a purpose-built polynomial in CT and p
57 sa = gsw_sa_freezing_estimate(p,saturation_fraction,t=t)
58 if (sa .lt. -sa_cut_off) then
60  return
61 end if
62 
63 ! Form the first estimate of dt_dSA, the derivative of t with respect
64 ! to SA at fixed p.
65 sa = max(sa,0.0_r8)
66 call gsw_t_freezing_first_derivatives_poly(sa,p,saturation_fraction, &
67  tfreezing_sa=dt_dsa)
68 
69 ! For -SA_cut_off < SA < SA_cut_off, replace the above estimate of SA
70 ! with one based on (t_freezing_zero_SA - t).
71 if (abs(sa) .lt. sa_cut_off) sa = (t - t_freezing_zero_sa)/dt_dsa
72 
73 !---------------------------------------------------------------------------
74 ! Begin the modified Newton-Raphson method to find the root of
75 ! t_freezing = t for SA.
76 !---------------------------------------------------------------------------
77 do i_iter = 1, number_of_iterations
78  sa_old = sa
79  t_freezing = gsw_t_freezing_poly(sa_old,p,saturation_fraction)
80  sa = sa_old - (t_freezing - t)/dt_dsa
81  sa_mean = 0.5_r8*(sa + sa_old)
82  call gsw_t_freezing_first_derivatives_poly(sa_mean,p,saturation_fraction, &
83  tfreezing_sa=dt_dsa)
84  sa = sa_old - (t_freezing - t)/dt_dsa
85 end do
86 
87 if (gsw_sa_p_inrange(sa,p)) then
89 else
91 end if
92 
93 return
94 end function
95 
96 !--------------------------------------------------------------------------
elemental real(r8) function gsw_sa_freezing_from_t_poly(t, p, saturation_fraction)
real(r8), parameter, public gsw_error_limit
#define max(a, b)
Definition: mosaic_util.h:33
elemental real(r8) function, public gsw_error_code(err_num, func_name, error_code)