Goby v2
salinity.h
1 // Copyright 2009-2018 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Goby Underwater Autonomy Project Libraries
8 // ("The Goby Libraries").
9 //
10 // The Goby Libraries are free software: you can redistribute them and/or modify
11 // them under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // The Goby Libraries are distributed in the hope that they will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
22 
23 // modified for C++ by s. petillo spetillo@mit.edu
24 // ocean engineering graduate student - mit / whoi joint program
25 // massachusetts institute of technology (mit)
26 // laboratory for autonomous marine sensing systems (lamss)
27 
28 //Algorithm from S. Petillo salinity.m
29 // Function for calculation of salinity from conductivity.
30 //
31 // S.Petillo (spetillo@mit.edu) - 02 Aug. 2010
32 //
33 // Taken directly from:
34 // 'Algorithms for computation of fundamental properties of seawater'
35 // UNESCO 1983 equation
36 // conductivity ratio to practical salinity conversion (SAL78)
37 //
38 // Valid over the ranges:
39 // Temperaturature: -2<T<35 degC
40 // Salinity: 2<S<42 psu
41 // (from Prekin and Lewis, 1980)
42 //
43 // Units:
44 // conductivity Cond mS/cm
45 // salinity S (PSS-78)
46 // temperature T (IPTS-68) degC
47 // pressure P decibars
48 
49 // Cond(35,15,0) = 42.914 mS/cm
50 // the electrical conductivity of the standard seawater.
51 // Given by Jan Schultz (23 May, 2008) in
52 // 'Conversion between conductivity and PSS-78 salinity' at
53 // http://www.code10.info/index.php?option=com_content&view=category&id=54&Itemid=79
54 
55 #ifndef SALINITYH
56 #define SALINITYH
57 
58 #include <cmath>
59 
61 {
62  public:
63  enum
64  {
65  TO_SALINITY = false,
66  FROM_SALINITY = true
67  };
68  static double salinity(double cnd_milli_siemens_per_cm, double temp_deg_c, double pressure_dbar,
69  bool M = TO_SALINITY)
70  {
71  const double CONDUCTIVITY_AT_STANDARD = 42.914; // S = 35, T = 15 deg C, P = 0 dbar
72  double CND = cnd_milli_siemens_per_cm / CONDUCTIVITY_AT_STANDARD;
73  double T = temp_deg_c;
74  double P = pressure_dbar;
75 
76  double SAL78 = 0;
77 
78  // ZERO SALINITY/CONDUCTIVITY TRAP
79  if (((M == 0) && (CND <= 5e-4)) || ((M == 1) && (CND <= 0.2)))
80  return SAL78;
81 
82  double DT = T - 15;
83 
84  // SELECT BRANCH FOR SALINITY (M=0) OR CONDUCTIVITY (M=1)
85  if (M == 0)
86  {
87  // CONVERT CONDUCTIVITY TO SALINITY
88  double Res = CND;
89  double RT = Res / (RT35(T) * (1.0 + C(P) / (B(T) + A(T) * Res)));
90  RT = std::sqrt(std::abs(RT));
91  SAL78 = SAL(RT, DT);
92  return SAL78;
93  }
94  else
95  {
96  // INVERT SALINITY TO CONDUCTIVITY BY THE
97  // NEWTON-RAPHSON ITERATIVE METHOD
98  // FIRST APPROXIMATION
99 
100  double RT = std::sqrt(CND / 35);
101  double SI = SAL(RT, DT);
102  double N = 0;
103 
104  // TIERATION LOOP BEGINS HERE WITH A MAXIMUM OF 10 CYCLES
105  double DELS = 0;
106  do
107  {
108  RT = RT + (CND - SI) / DSAL(RT, DT);
109  SI = SAL(RT, DT);
110  N = N + 1;
111  DELS = std::abs(SI - CND);
112  }
113  //IF((DELS.GT.1.0E-4).AND.(N.LT.10)) GO TO 15
114  while ((DELS < 1e-4) || (N >= 10));
115  //Until not ((DELS > 1.0E-4) AND (N <10));
116 
117  //COMPUTE CONDUCTIVITY RATIO
118  double RTT = RT35(T) * RT * RT;
119  double AT = A(T);
120  double BT = B(T);
121  double CP = C(P);
122  CP = RTT * (CP + BT);
123  BT = BT - RTT * AT;
124 
125  // SOLVE QUADRATIC EQUATION FOR R: R=RT35*RT*(1+C/AR+B)
126  // R := SQRT (ABS (BT * BT + 4.0 * AT * CP)) - BT;
127  double Res = std::sqrt(std::abs(BT * BT + 4 * AT * CP)) - BT;
128  // CONDUCTIVITY RETURN
129  SAL78 = 0.5 * Res / AT;
130  return SAL78;
131  }
132  }
133 
134  private:
135  static double SAL(double XR, double XT)
136  {
137  // PRACTICAL SALINITY SCALE 1978 DEFINITION WITH TEMPERATURE
138  // CORRECTION;XT :=T-15.0; XR:=SQRT(RT);
139  double sal =
140  ((((2.7081 * XR - 7.0261) * XR + 14.0941) * XR + 25.3851) * XR - 0.1692) * XR + 0.0080 +
141  (XT / (1.0 + 0.0162 * XT)) *
142  (((((-0.0144 * XR + 0.0636) * XR - 0.0375) * XR - 0.0066) * XR - 0.0056) * XR +
143  0.0005);
144  return sal;
145  }
146 
147  static double DSAL(double XR, double XT)
148  {
149  // FUNCTION FOR DERIVATIVE OF SAL(XR,XT) WITH XR
150  double dsal = ((((13.5405 * XR - 28.1044) * XR + 42.2823) * XR + 50.7702) * XR - 0.1692) +
151  (XT / (1.0 + 0.0162 * XT)) *
152  ((((-0.0720 * XR + 0.2544) * XR - 0.1125) * XR - 0.0132) * XR - 0.0056);
153  return dsal;
154  }
155 
156  static double RT35(double XT)
157  {
158  // FUNCTION RT35: C(35,T,0)/C(35,15,0) VARIATION WITH TEMPERATURE
159  double rt35 =
160  (((1.0031E-9 * XT - 6.9698E-7) * XT + 1.104259E-4) * XT + 2.00564E-2) * XT + 0.6766097;
161  return rt35;
162  }
163 
164  static double C(double XP)
165  {
166  // C(XP) POLYNOMIAL CORRESPONDS TO A1-A3 CONSTANTS: LEWIS 1980
167  double c = ((3.989E-15 * XP - 6.370E-10) * XP + 2.070E-5) * XP;
168  return c;
169  }
170 
171  static double B(double XT)
172  {
173  double b = (4.464E-4 * XT + 3.426E-2) * XT + 1.0;
174  return b;
175  }
176 
177  static double A(double XT)
178  {
179  //A(XT) POLYNOMIAL CORRESPONDS TO B3 AND B4 CONSTANTS: LEWIS 1980
180  double a = -3.107E-3 * XT + 0.4215;
181  return a;
182  }
183 
187  SalinityCalculator& operator=(const SalinityCalculator&);
188 };
189 
190 #endif
Definition: test2.pb.h:139
Definition: test_a.pb.h:42