FV3 Bundle
gsw_saar.f90
Go to the documentation of this file.
1 !==========================================================================
2 elemental function gsw_saar (p, long, lat)
3 !==========================================================================
4 !
5 ! Calculates the Absolute Salinity Anomaly Ratio, SAAR at a geographic point.
6 !
7 ! p : sea pressure [dbar]
8 ! long : longitude [deg E]
9 ! lat : latitude [deg N]
10 !
11 ! gsw_saar : Absolute Salinity Anomaly Ratio [unitless]
12 !--------------------------------------------------------------------------
13 
15 
17 
19 
20 use gsw_mod_kinds
21 
22 implicit none
23 
24 real (r8), intent(in) :: p, long, lat
25 
26 real (r8) :: gsw_saar
27 
28 integer :: indx0, indy0, indz0, k, ndepth_max
29 
30 real (r8), dimension(4) :: saar, saar_old
31 real (r8) :: p0_original, sa_upper, sa_lower, dlong, dlat
32 real (r8) :: r1, s1, t1, p_tmp, long360
33 
34 character (*), parameter :: func_name = "gsw_saar"
35 
36 long360 = long
37 if (long360.lt.0.0_r8) long360 = long360 + 360.0_r8
38 
39 indx0 = floor(1.0_r8 + (nx-1)*(long360-longs_ref(1)) / &
40  (longs_ref(nx)-longs_ref(1)))
41 
42 indy0 = floor(1.0_r8 + (ny-1)*(lat-lats_ref(1)) / (lats_ref(ny)-lats_ref(1)))
43 
44 if ((indx0.ge.1 .and. indx0.le.nx) .and. (indy0.ge.1 .and. indy0.le.ny)) then
45  if (indx0.eq.nx) indx0 = nx-1
46  if (indy0.eq.ny) indy0 = ny-1
47 else
48  ! This is to catch any out-of-range or nonsense lat/long input (including
49  ! NaN, +Inf, -Inf etc). Note: NaNs will not satisfy any "if" conditional
50  ! so will be trapped by the "else".
51  gsw_saar = gsw_error_code(2,func_name)
52  return
53 end if
54 
55 ! Look for the maximum valid "ndepth_ref" value around our point.
56 ! Note: invalid "ndepth_ref" values are NaNs (a hangover from the codes
57 ! Matlab origins), but we have replaced the NaNs with a value of 999,
58 ! hence we need an additional upper-limit check in the code below so they
59 ! will not be recognised as valid values.
60 ndepth_max = -1
61 do k = 1,4
62  if ((ndepth_ref(indy0+delj(k),indx0+deli(k)).gt.0) .and. &
63  (ndepth_ref(indy0+delj(k),indx0+deli(k)).lt.99)) &
64  ndepth_max = max(ndepth_max,ndepth_ref(indy0+delj(k),indx0+deli(k)))
65 end do
66 
67 ! If we are a long way from the ocean then there will be no valid "ndepth_ref"
68 ! values near the point (ie. surrounded by NaNs) - so just return SAAR = 0.0
69 if (ndepth_max.eq.-1) then
70  gsw_saar = 0.0_r8
71  return
72 end if
73 
74 p0_original = p
75 p_tmp = p
76 if (p_tmp.gt.p_ref(ndepth_max)) p_tmp = p_ref(ndepth_max)
77 indz0 = gsw_util_indx(p_ref,p_tmp)
78 
79 dlong = longs_ref(indx0+1) - longs_ref(indx0)
80 dlat = lats_ref(indy0+1) - lats_ref(indy0)
81 
82 r1 = (long360-longs_ref(indx0)) / dlong
83 s1 = (lat-lats_ref(indy0)) / dlat
84 t1 = (p_tmp-p_ref(indz0))/(p_ref(indz0+1)-p_ref(indz0))
85 
86 do k = 1,4
87  saar(k) = saar_ref(indz0,indy0+delj(k),indx0+deli(k))
88 end do
89 
90 if ( longs_pan(1).le.long360 .and. long360.le.longs_pan(npan)-0.001_r8 .and. &
91  lats_pan(npan).le.lat .and. lat.le.lats_pan(1)) then
92  saar_old = saar
93  call gsw_add_barrier(saar_old,long360,lat,longs_ref(indx0), &
94  lats_ref(indy0),dlong,dlat,saar)
95 else if (abs(sum(saar)).ge.1e10_r8) then
96  saar_old = saar
97  call gsw_add_mean(saar_old,saar)
98 end if
99 
100 sa_upper = (1.0_r8-s1)*(saar(1) + r1*(saar(2)-saar(1))) + s1*(saar(4) + &
101  r1*(saar(3)-saar(4)))
102 
103 do k = 1,4
104  saar(k) = saar_ref(indz0+1,indy0+delj(k),indx0+deli(k))
105 end do
106 
107 if ( longs_pan(1).le.long360 .and. long360.le.longs_pan(npan)-0.001_r8 .and. &
108  lats_pan(npan).le.lat .and. lat.le.lats_pan(1)) then
109  saar_old = saar
110  call gsw_add_barrier(saar_old,long360,lat,longs_ref(indx0), &
111  lats_ref(indy0),dlong,dlat,saar)
112 else if (abs(sum(saar)).ge.1e10_r8) then
113  saar_old = saar
114  call gsw_add_mean(saar_old,saar)
115 end if
116 
117 sa_lower = (1.0_r8-s1)*(saar(1) + r1*(saar(2)-saar(1))) + s1*(saar(4) + &
118  r1*(saar(3)-saar(4)))
119 if (abs(sa_lower).ge.1e10_r8) sa_lower = sa_upper
120 gsw_saar = sa_upper + t1*(sa_lower-sa_upper)
121 
122 if (abs(gsw_saar).ge.1e10_r8) gsw_saar = gsw_error_code(3,func_name)
123 
124 return
125 end function
126 
127 !--------------------------------------------------------------------------
integer, parameter, public long
Definition: Type_Kinds.f90:76
real(r8), dimension(npan) longs_pan
integer, parameter nx
real(r8), dimension(npan) lats_pan
integer, parameter ny
elemental real(r8) function gsw_saar(p, long, lat)
Definition: gsw_saar.f90:3
integer, dimension(4) delj
real(r8), dimension(nz) p_ref
real(r8), dimension(nx) longs_ref
integer, parameter npan
integer, dimension(4) deli
#define max(a, b)
Definition: mosaic_util.h:33
integer, dimension(ny, nx) ndepth_ref
real(r8), dimension(nz, ny, nx) saar_ref
real(r8), dimension(ny) lats_ref
elemental real(r8) function, public gsw_error_code(err_num, func_name, error_code)