FV3 Bundle
gsw_ice_fraction_to_freeze_seawater.f90
Go to the documentation of this file.
1 !==========================================================================
2 elemental subroutine gsw_ice_fraction_to_freeze_seawater (sa, ct, p, &
3  t_ih, sa_freeze, ct_freeze, w_ih)
4 !==========================================================================
5 !
6 ! Calculates the mass fraction of ice (mass of ice divided by mass of ice
7 ! plus seawater), which, when melted into seawater having (SA,CT,p) causes
8 ! the final dilute seawater to be at the freezing temperature. The other
9 ! outputs are the Absolute Salinity and Conservative Temperature of the
10 ! final diluted seawater.
11 !
12 ! SA = Absolute Salinity of seawater [ g/kg ]
13 ! CT = Conservative Temperature of seawater (ITS-90) [ deg C ]
14 ! p = sea pressure [ dbar ]
15 ! ( i.e. absolute pressure - 10.1325d0 dbar )
16 ! t_Ih = in-situ temperature of the ice at pressure p (ITS-90) [ deg C ]
17 !
18 ! SA_freeze = Absolute Salinity of seawater after the mass fraction of
19 ! ice, ice_fraction, at temperature t_Ih has melted into the
20 ! original seawater, and the final mixture is at the freezing
21 ! temperature of seawater. [ g/kg ]
22 !
23 ! CT_freeze = Conservative Temperature of seawater after the mass
24 ! fraction, w_Ih, of ice at temperature t_Ih has melted into
25 ! the original seawater, and the final mixture is at the
26 ! freezing temperature of seawater. [ deg C ]
27 !
28 ! w_Ih = mass fraction of ice, having in-situ temperature t_Ih,
29 ! which, when melted into seawater at (SA,CT,p) leads to the
30 ! final diluted seawater being at the freezing temperature.
31 ! This output must be between 0 and 1. [unitless]
32 !--------------------------------------------------------------------------
33 
38 
40 
41 use gsw_mod_kinds
42 
43 implicit none
44 
45 real (r8), intent(in) :: sa, ct, p, t_ih
46 real (r8), intent(out) :: sa_freeze, ct_freeze, w_ih
47 
48 integer :: no_iter
49 real (r8) :: ctf, ctf_mean, ctf_old, ctf_plus1, ctf_zero
50 real (r8) :: dfunc_dsaf, func, func_plus1, func_zero, h, h_ih
51 real (r8) :: saf, saf_mean, saf_old, tf, h_hat_sa, h_hat_ct, ctf_sa
52 
53 real (r8), parameter :: sa0 = 0.0_r8, saturation_fraction = 0.0_r8
54 
55 character (*), parameter :: func_name = "gsw_ice_fraction_to_freeze_seawater"
56 
57 ctf = gsw_ct_freezing_exact(sa,p,saturation_fraction)
58 if (ct .lt. ctf) then
59  ! The seawater ct input is below the freezing temp
60  sa_freeze = gsw_error_code(1,func_name)
61  ct_freeze = sa_freeze
62  w_ih = sa_freeze
63  return
64 end if
65 
66 tf = gsw_t_freezing_exact(sa0,p,saturation_fraction)
67 if (t_ih .gt. tf) then
68  ! The input, t_Ih, exceeds the freezing temperature at sa = 0
69  sa_freeze = gsw_error_code(2,func_name)
70  ct_freeze = sa_freeze
71  w_ih = sa_freeze
72  return
73 end if
74 
75 h = gsw_enthalpy_ct_exact(sa,ct,p)
76 h_ih = gsw_enthalpy_ice(t_ih,p)
77 
78 ctf_zero = gsw_ct_freezing_exact(sa0,p,saturation_fraction)
79 func_zero = sa*(gsw_enthalpy_ct_exact(sa0,ctf_zero,p) - h_ih)
80 
81 ctf_plus1 = gsw_ct_freezing_exact(sa+1.0_r8,p,saturation_fraction)
82 func_plus1 = sa*(gsw_enthalpy_ct_exact(sa+1.0_r8,ctf_plus1,p) - h) - (h - h_ih)
83 
84 saf = -(sa+1.0_r8)*func_zero/(func_plus1 - func_zero) ! initial guess
85 ctf = gsw_ct_freezing_exact(saf,p,saturation_fraction)
86 call gsw_enthalpy_first_derivatives_ct_exact(saf,ctf,p,h_hat_sa,h_hat_ct)
87 call gsw_ct_freezing_first_derivatives(saf,p,1.0_r8,ctfreezing_sa=ctf_sa)
88 
89 dfunc_dsaf = sa*(h_hat_sa + h_hat_ct*ctf_sa) - (h - h_ih)
90 
91 do no_iter = 1, 2
92  saf_old = saf
93  ctf_old = ctf
94  func = sa*(gsw_enthalpy_ct_exact(saf_old,ctf_old,p) - h) &
95  - (saf_old - sa)*(h - h_ih)
96  saf = saf_old - func/dfunc_dsaf
97  saf_mean = 0.5_r8*(saf + saf_old)
98  ctf_mean = gsw_ct_freezing_exact(saf_mean,p,saturation_fraction)
99  call gsw_enthalpy_first_derivatives_ct_exact(saf_mean,ctf_mean,p,h_hat_sa, &
100  h_hat_ct)
101  call gsw_ct_freezing_first_derivatives(saf_mean,p,saturation_fraction, &
102  ctfreezing_sa=ctf_sa)
103  dfunc_dsaf = sa*(h_hat_sa + h_hat_ct*ctf_sa) - (h - h_ih)
104  saf = saf_old - func/dfunc_dsaf
105  ctf = gsw_ct_freezing_exact(saf,p,saturation_fraction)
106 end do
107 
108 ! After these 2 iterations of this modified Newton-Raphson method, the
109 ! error in SA_freeze is less than 1.3d0x10^-13 g/kg, in CT_freeze is less than
110 ! 4x10^-13 deg C and in w_Ih is less than 3.8d0x10^-15 which represent machine
111 ! precision for these calculations.
112 
113 sa_freeze = saf
114 ct_freeze = ctf
115 w_ih = (h - gsw_enthalpy_ct_exact(sa_freeze,ct_freeze,p))/(h - h_ih)
116 
117 return
118 end subroutine
real(r8), parameter, public gsw_error_limit
elemental subroutine gsw_ice_fraction_to_freeze_seawater(sa, ct, p, t_ih, sa_freeze, ct_freeze, w_ih)
elemental real(r8) function, public gsw_error_code(err_num, func_name, error_code)