FV3 Bundle
gsw_enthalpy_second_derivatives_ct_exact.f90
Go to the documentation of this file.
1 !==========================================================================
2 elemental subroutine gsw_enthalpy_second_derivatives_ct_exact (sa, ct, p, &
3  h_sa_sa, h_sa_ct, h_ct_ct)
4 !==========================================================================
5 !
6 ! Calculates three second-order derivatives of specific enthalpy (h).
7 ! Note that this function uses the full Gibbs function.
8 !
9 ! sa = Absolute Salinity [ g/kg ]
10 ! ct = Conservative Temperature (ITS-90) [ deg C ]
11 ! p = sea pressure [ dbar ]
12 ! ( i.e. absolute pressure - 10.1325 dbar )
13 !
14 ! h_sa_sa = The second derivative of specific enthalpy with respect to
15 ! Absolute Salinity at constant ct & p. [ J/(kg (g/kg)^2) ]
16 ! h_sa_ct = The second derivative of specific enthalpy with respect to
17 ! sa and ct at constant p. [ J/(kg K(g/kg)) ]
18 ! h_ct_ct = The second derivative of specific enthalpy with respect to
19 ! ct at constant sa and p. [ J/(kg K^2) ]
20 !--------------------------------------------------------------------------
21 
23 
25 
26 use gsw_mod_kinds
27 
28 implicit none
29 
30 real (r8), intent(in) :: sa, ct, p
31 real (r8), intent(out), optional :: h_sa_sa, h_sa_ct, h_ct_ct
32 
33 real (r8) :: factor, gsa_pt0, gsat_pt0, gsat, part_b, pt0, h_ct_ct_val
34 real (r8) :: rec_abs_pt0, rec_gtt_pt0, rec_gtt, t, temp_ratio
35 real (r8) :: gsasa, gsasa_pt0
36 
37 integer, parameter :: n0=0, n1=1, n2=2
38 real (r8), parameter :: pr0 = 0.0_r8, sa_small = 1e-100_r8
39 
40 pt0 = gsw_pt_from_ct(sa,ct)
41 rec_abs_pt0 = 1.0_r8/(gsw_t0 + pt0)
42 t = gsw_pt_from_t(sa,pt0,pr0,p)
43 temp_ratio = (gsw_t0 + t)*rec_abs_pt0
44 
45 rec_gtt_pt0 = 1.0_r8/gsw_gibbs(n0,n2,n0,sa,pt0,pr0)
46 rec_gtt = 1.0_r8/gsw_gibbs(n0,n2,n0,sa,t,p)
47 
48 ! h_ct_ct is naturally well-behaved as sa approaches zero.
49 h_ct_ct_val = gsw_cp0*gsw_cp0* &
50  (temp_ratio*rec_gtt_pt0 - rec_gtt)*(rec_abs_pt0*rec_abs_pt0)
51 
52 if (present(h_ct_ct)) h_ct_ct = h_ct_ct_val
53 
54 if (.not. present(h_sa_sa) .and. .not. present(h_sa_ct)) return
55 
56 gsat_pt0 = gsw_gibbs(n1,n1,n0,sa,pt0,pr0)
57 gsat = gsw_gibbs(n1,n1,n0,sa,t,p)
58 gsa_pt0 = gsw_gibbs(n1,n0,n0,sa,pt0,pr0)
59 
60 part_b = (temp_ratio*gsat_pt0*rec_gtt_pt0 - gsat*rec_gtt)*rec_abs_pt0
61 factor = gsa_pt0/gsw_cp0
62 
63 if (present(h_sa_sa)) then
64 
65  gsasa = gsw_gibbs(n2,n0,n0,sa,t,p)
66  gsasa_pt0 = gsw_gibbs(n2,n0,n0,sa,pt0,pr0)
67 
68  ! h_sa_sa has a singularity at sa = 0, and blows up as sa approaches zero.
69  h_sa_sa = gsasa - temp_ratio*gsasa_pt0 &
70  + temp_ratio*gsat_pt0*gsat_pt0*rec_gtt_pt0 &
71  - gsat*gsat*rec_gtt &
72  - 2.0_r8*gsa_pt0*part_b + (factor*factor)*h_ct_ct_val
73 
74 end if
75 if (.not. present(h_sa_ct)) return
76 
77 ! h_sa_ct should not blow up as sa approaches zero. The following lines
78 ! of code ensure that the h_sa_ct output of this function does not blow
79 ! up in this limit. That is, when sa < 1e-100 g/kg, we force the h_sa_ct
80 ! output to be the same as if sa = 1e-100 g/kg.
81 if (sa .lt. sa_small) then
82  rec_gtt_pt0 = 1.0_r8/gsw_gibbs(n0,n2,n0,sa_small,pt0,pr0)
83  rec_gtt = 1.0_r8/gsw_gibbs(n0,n2,n0,sa_small,t,p)
84  gsat_pt0 = gsw_gibbs(n1,n1,n0,sa_small,pt0,pr0)
85  gsat = gsw_gibbs(n1,n1,n0,sa_small,t,p)
86  gsa_pt0 = gsw_gibbs(n1,n0,n0,sa_small,pt0,pr0)
87  part_b = (temp_ratio*gsat_pt0*rec_gtt_pt0 - gsat*rec_gtt)*rec_abs_pt0
88  factor = gsa_pt0/gsw_cp0
89 end if
90 
91 h_sa_ct = gsw_cp0*part_b - factor*h_ct_ct_val
92 
93 return
94 end subroutine
95 
96 !--------------------------------------------------------------------------
elemental subroutine gsw_enthalpy_second_derivatives_ct_exact(sa, ct, p, h_sa_sa, h_sa_ct, h_ct_ct)