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