25 #ifndef GOBY_UTIL_SEAWATER_SOUNDSPEED_H
26 #define GOBY_UTIL_SEAWATER_SOUNDSPEED_H
30 #include <boost/units/quantity.hpp>
31 #include <boost/units/systems/si.hpp>
32 #include <boost/units/systems/temperature/celsius.hpp>
48 template <
typename TemperatureUnit = boost::units::celsius::temperature,
50 typename LengthUnit = boost::units::si::length>
51 boost::units::quantity<boost::units::si::velocity>
53 boost::units::quantity<DimensionlessUnit>
salinity,
54 boost::units::quantity<LengthUnit>
depth,
bool ignore_bounds =
false)
58 double T = quantity<absolute<celsius::temperature> >(temperature).value();
59 double S = quantity<si::dimensionless>(
salinity).value();
60 double D = quantity<si::length>(
depth).value();
73 if (T < min_T || T > max_T)
74 throw std::out_of_range(
"Temperature not in valid range [-2, 30] deg C");
75 if (S < min_S || S > max_S)
76 throw std::out_of_range(
"Salinity not in valid range [25, 40]");
77 if (D < min_D || D > max_D)
78 throw std::out_of_range(
"Depth not in valid range [0, 8000] meters");
81 return (1448.96 + 4.591 * T - 5.304
e-2 * T * T + 2.374
e-4 * T * T * T + 1.340 * (S - 35) +
82 1.630
e-2 * D + 1.675
e-7 * D * D - 1.025
e-2 * T * (S - 35) - 7.139
e-13 * T * D * D * D) *
83 si::meters_per_second;
94 template <
typename TemperatureUnit = boost::units::celsius::temperature,
95 typename LengthUnit = boost::units::si::length>
96 boost::units::quantity<boost::units::si::velocity>
99 bool ignore_bounds =
false)
102 boost::units::quantity<boost::units::si::dimensionless>(
salinity),
103 depth, ignore_bounds);