FV3 Bundle
gsw_sa_freezing_from_ct_poly.f90
Go to the documentation of this file.
1 !==========================================================================
2 elemental function gsw_sa_freezing_from_ct_poly (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 the
7 ! fraction saturation_fraction of dissolved air, that is in equilibrium
8 ! with ice at Conservative Temperature CT and pressure p. If the input
9 ! values are such that there is no positive value of Absolute Salinity for
10 ! which seawater is frozen, the output is put equal to Nan.
11 !
12 ! CT = Conservative 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_ct = Absolute Salinity of seawater when it freezes,
19 ! for given input values of Conservative Temperature
20 ! pressure and air saturation fraction. [ g/kg ]
21 !--------------------------------------------------------------------------
22 
26 
28 
29 use gsw_mod_kinds
30 
31 implicit none
32 
33 real (r8), intent(in) :: ct, p, saturation_fraction
34 
36 
37 integer :: i_iter
38 real (r8) :: ct_freezing, ct_freezing_zero_sa, dct_dsa
39 real (r8) :: sa, sa_old, sa_mean
40 
41 integer, parameter :: number_of_iterations = 2
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_poly"
48 
49 ! Find CT > CT_freezing_zero_SA. If this is the case, the input values
50 ! represent seawater that is not frozen (at any positive SA).
51 ct_freezing_zero_sa = gsw_ct_freezing_poly(0.0_r8,p,saturation_fraction)
52 if (ct .gt. ct_freezing_zero_sa) then
54  return
55 endif
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 endif
63 
64 ! Form the first estimate of dCT_dSA, the derivative of CT with respect
65 ! to SA at fixed p.
66 sa = max(sa,0.0_r8)
67 call gsw_ct_freezing_first_derivatives_poly(sa,p,saturation_fraction, &
68  ctfreezing_sa=dct_dsa)
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)/dct_dsa
73 
74 !--------------------------------------------------------------------------
75 ! Begin the modified Newton-Raphson method to solve the root of
76 ! CT_freezing = CT for SA.
77 !--------------------------------------------------------------------------
78 do i_iter = 1, number_of_iterations
79  sa_old = sa
80  ct_freezing = gsw_ct_freezing_poly(sa_old,p,saturation_fraction)
81  sa = sa_old - (ct_freezing - ct)/dct_dsa
82  sa_mean = 0.5_r8*(sa + sa_old)
83  call gsw_ct_freezing_first_derivatives_poly(sa_mean,p,saturation_fraction, &
84  ctfreezing_sa=dct_dsa)
85  sa = sa_old - (ct_freezing - ct)/dct_dsa
86 enddo
87 
88 if (gsw_sa_p_inrange(sa,p)) then
90 else
92 endif
93 
94 return
95 end function
96 
97 !--------------------------------------------------------------------------
elemental real(r8) function gsw_sa_freezing_from_ct_poly(ct, 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)