FV3 Bundle
gsw_seaice_fraction_to_freeze_seawater.f90
Go to the documentation of this file.
1 !==========================================================================
2 elemental subroutine gsw_seaice_fraction_to_freeze_seawater (sa, ct, p, &
3  sa_seaice, t_seaice, sa_freeze, ct_freeze, w_seaice)
4 !==========================================================================
5 !
6 ! Calculates the mass fraction of sea ice (mass of sea ice divided by mass
7 ! of sea ice plus seawater), which, when melted into seawater having the
8 ! properties (SA,CT,p) causes the final seawater to be at the freezing
9 ! temperature. The other outputs are the Absolute Salinity and
10 ! Conservative Temperature of the final 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.1325 dbar )
16 ! SA_seaice = Absolute Salinity of sea ice, that is, the mass fraction of
17 ! salt in sea ice, expressed in g of salt per kg of sea ice.
18 ! [ g/kg ]
19 ! t_seaice = in-situ temperature of the sea ice at pressure p (ITS-90)
20 ! [ deg C ]
21 !
22 ! SA_freeze = Absolute Salinity of seawater after the mass fraction of
23 ! sea ice, w_seaice, at temperature t_seaice has melted into
24 ! the original seawater, and the final mixture is at the
25 ! freezing temperature of seawater. [ g/kg ]
26 !
27 ! CT_freeze = Conservative Temperature of seawater after the mass
28 ! fraction, w_seaice, of sea ice at temperature t_seaice has
29 ! melted into the original seawater, and the final mixture
30 ! is at the freezing temperature of seawater. [ deg C ]
31 !
32 ! w_seaice = mass fraction of sea ice, at SA_seaice and t_seaice,
33 ! which, when melted into seawater at (SA,CT,p) leads to the
34 ! final mixed seawater being at the freezing temperature.
35 ! This output is between 0 and 1. [unitless]
36 !--------------------------------------------------------------------------
37 
43 
45 
46 use gsw_mod_kinds
47 
48 implicit none
49 
50 real (r8), intent(in) :: sa, ct, p, sa_seaice, t_seaice
51 real (r8), intent(out) :: sa_freeze, ct_freeze, w_seaice
52 
53 integer :: number_of_iterations
54 real (r8) :: ctf, ctf_mean, ctf_old, ctf_plus1, ctf_zero
55 real (r8) :: dfunc_dsaf, func, func_plus1, func_zero, h, h_brine
56 real (r8) :: h_ih, sa_freezing, saf, saf_mean, saf_old
57 real (r8) :: salt_ratio, tf_sa_seaice, h_hat_sa, h_hat_ct, ctf_sa
58 
59 real (r8), parameter :: sa0 = 0.0_r8, saturation_fraction = 0.0_r8
60 
61 character (*), parameter :: func_name = "gsw_seaice_fraction_to_freeze_seawater"
62 
63 ctf = gsw_ct_freezing_exact(sa,p,saturation_fraction)
64 if (ct .lt. ctf) then
65  ! The seawater ct input is below the freezing temp
66  sa_freeze = gsw_error_code(1,func_name)
67  ct_freeze = sa_freeze
68  w_seaice = sa_freeze
69  return
70 end if
71 
72 tf_sa_seaice = gsw_t_freezing_exact(sa_seaice,p,saturation_fraction) - 1e-6_r8
73 if (t_seaice .gt. tf_sa_seaice) then
74  ! The 1e-6 C buffer in the allowable t_seaice is to ensure that there is
75  ! some ice Ih in the sea ice. Without this buffer, that is if t_seaice
76  ! is allowed to be exactly equal to tf_sa_seaice, the sea ice is
77  ! actually 100% brine at Absolute Salinity of SA_seaice.
78  sa_freeze = gsw_error_code(2,func_name)
79  ct_freeze = sa_freeze
80  w_seaice = sa_freeze
81  return
82 end if
83 
84 sa_freezing = gsw_sa_freezing_from_t(t_seaice,p,saturation_fraction)
85 if (sa_freezing .gt. gsw_error_limit) then
86  sa_freeze = gsw_error_code(3,func_name,sa_freezing)
87  ct_freeze = sa_freeze
88  w_seaice = sa_freeze
89  return
90 end if
91 h_brine = gsw_enthalpy_t_exact(sa_freezing,t_seaice,p)
92 salt_ratio = sa_seaice/sa_freezing
93 
94 h = gsw_enthalpy_ct_exact(sa,ct,p)
95 h_ih = gsw_enthalpy_ice(t_seaice,p)
96 
97 ctf_plus1 = gsw_ct_freezing_exact(sa+1.0_r8,p,saturation_fraction)
98 func_plus1 = (sa - sa_seaice)*(gsw_enthalpy_ct_exact(sa+1.0_r8,ctf_plus1,p) &
99  - h) - (h - h_ih) + salt_ratio*(h_brine - h_ih)
100 
101 ctf_zero = gsw_ct_freezing_exact(sa0,p,saturation_fraction)
102 func_zero = (sa - sa_seaice)*(gsw_enthalpy_ct_exact(sa0,ctf_zero,p) - h) &
103  + sa*((h - h_ih) - salt_ratio*(h_brine - h_ih))
104 
105 saf = -(sa+1.0_r8)*func_zero/(func_plus1 - func_zero) ! initial guess of saf
106 ctf = gsw_ct_freezing_exact(saf,p,saturation_fraction)
107 call gsw_enthalpy_first_derivatives_ct_exact(saf,ctf,p,h_hat_sa,h_hat_ct)
108 call gsw_ct_freezing_first_derivatives(saf,p,saturation_fraction, &
109  ctfreezing_sa=ctf_sa)
110 
111 dfunc_dsaf = (sa - sa_seaice)*(h_hat_sa + h_hat_ct*ctf_sa) &
112  - (h - h_ih) + salt_ratio*(h_brine - h_ih)
113 
114 do number_of_iterations = 1, 4
115  saf_old = saf
116  ctf_old = ctf
117  func = (sa - sa_seaice)*(gsw_enthalpy_ct_exact(saf_old,ctf_old,p) - h) &
118  - (saf_old - sa)*((h - h_ih) - salt_ratio*(h_brine - h_ih))
119  saf = saf_old - func/dfunc_dsaf
120  saf_mean = 0.5_r8*(saf + saf_old)
121  ctf_mean = gsw_ct_freezing_exact(saf_mean,p,saturation_fraction)
122  call gsw_enthalpy_first_derivatives_ct_exact(saf_mean,ctf_mean,p, &
123  h_hat_sa,h_hat_ct)
124  call gsw_ct_freezing_first_derivatives(saf_mean,p,saturation_fraction, &
125  ctfreezing_sa=ctf_sa)
126  dfunc_dsaf = (sa - sa_seaice)*(h_hat_sa + h_hat_ct*ctf_sa) &
127  - (h - h_ih) + salt_ratio*(h_brine - h_ih)
128  saf = saf_old - func/dfunc_dsaf
129  ctf = gsw_ct_freezing_exact(saf,p,saturation_fraction)
130 end do
131 
132 ! After these 4 iterations of this modified Newton-Raphson method, the
133 ! errors in SA_freeze is less than 1.5x10^-12 g/kg, in CT_freeze is less than
134 ! 2x10^-13 deg C and in w_seaice is less than 2.8x10^-13 which represent machine
135 ! precision for these calculations.
136 
137 sa_freeze = saf
138 ct_freeze = ctf
139 w_seaice = (h - gsw_enthalpy_ct_exact(sa_freeze,ct_freeze,p)) / &
140  (h - h_ih - salt_ratio*(h_brine - h_ih))
141 return
142 end subroutine
143 
144 !--------------------------------------------------------------------------
elemental subroutine gsw_seaice_fraction_to_freeze_seawater(sa, ct, p, sa_seaice, t_seaice, sa_freeze, ct_freeze, w_seaice)
real(r8), parameter, public gsw_error_limit
elemental real(r8) function, public gsw_error_code(err_num, func_name, error_code)