/* ** $Id: pss78.c,v 1.3 1998/01/16 23:56:41 frank Exp $ ** pss78.c 1.2 Solaris 2.5 Unix 960130 SIO/ODF fmd ** ** Various PSS-78 Salinity conversion functions: ** ** double PSS78Salinity(double press, double temp, double cond) ** calculate the PSS-78 salinity of sea water from p, t, g ** double PSS78Pressure(double temp, double cond, double salt) ** calculate the pressure of sea water from t, g, s ** double PSS78Temperature(double press, double cond, double salt) ** calculate the temperature of sea water from p, g, s ** double PSS78Conductivity(double press, double temp, double salt) ** calculate the conductivity of sea water from p, t, s ** ** Plus, soon-to-be obsolete Fortran interface functions. ** ** References: ** ========= ** ** Lewis, E. L., 1980. The Practical Salinity Scale 1978 and ** Its Antecedents. IEEE Journal of Oceanographic Engineering, ** OE-5, 3-8. ** ** Culkin, F. and Smith, N. D., 1980. Determination of the Concentration ** of Potassium Chloride Solution Having the Same Electrical ** Conductivity, at 15C and Infinite Frequency, As Standard Seawater ** of Salinity 35.0000ppt (Chlorinity 19.37394ppt), IEEE Journal ** of Oceanographic Engineering, Vol. OE-5, No. 1. ** ** UNESCO, 1981, Background Papers and Supporting Data on the ** Practical Salinity Scale 1978, Technical Papers in Marine Science, ** No. 37. */ #include #include #ifndef FORTRAN #define StandardConductivity 42.9140 /* ** Conductivity (millimhos/cm) of standard sea water ** @ pressure=0.0, temperature=15.0, salinity=35.0 ** Culkin & Smith, 1980. */ /* ** Calculate PSS-78 salinity from p, t, g */ double /* <- salinity (psu) */ PSS78Salinity(press, temp, cond) double press; /* -> pressure (decibars) */ double temp; /* -> temperature (degrees C) */ double cond; /* -> conductivity (milli-mhos/cm) */ { double salt, bars, risp0, dt, deltas, risstd, rstdis, rstrms; if (cond <= 5.0e-4) return (0.0); risstd = cond / StandardConductivity; /* ratio of in-situ conductivity to std conductivity */ bars = press * 0.1; /* pressure in bars */ risp0 = 1.0 + bars *( 2.070e-4 + bars *(-6.370e-8 + bars *( 3.989e-12)))/ (1.0 + temp*( 0.03426 + temp* 4.464e-4) + (temp* -0.003107 + 0.4215)*risstd); /* ratio of in-situ conductivity to cond at same temp, but pressure=0.0 */ rstdis = risstd / (risp0 * (0.6766097 + temp*( 0.0200564 + temp*( 1.104259e-4 + temp*(-6.9698e-7 + temp*( 1.0031e-9)))))); /* ratio of std conductivity to std sea water at t=in-situ */ rstrms = sqrt((fabs(rstdis))); dt = temp - 15.0; deltas = dt/(1.0+0.0162*dt) * (rstrms*(-0.0056 + rstrms*(-0.0066 + rstrms*(-0.0375 + rstrms*( 0.0636 + rstrms*(-0.0144))))) + 5.0e-4); /* conductivity ratio at 15 degrees */ salt = rstrms*(-0.1692 + rstrms*(25.3851 + rstrms*(14.0941 + rstrms*(-7.0261 + rstrms*( 2.7081))))) + deltas + .008; return (salt); } /* PSS78Salinity() */ /* ** Calculate pressure from t, g and PSS-78 salinity. */ double /* <- pressure (decibars) */ PSS78Pressure(temp, cond, salt) double temp; /* -> temperature (degrees C) */ double cond; /* -> conductivity (milli-mhos/cm) */ double salt; /* -> salinity (psu) */ { int iter; double s1, press; /* ** Newton-Raphson iterative method. */ press = 1000.0; /* first approximation to pressure */ for (iter = 1; iter <= 2000; iter++) { s1 = PSS78Salinity(press, temp, cond); if (fabs(s1 - salt) <= 1.0e-4) break; /* if close enough for government work */ press *= (1.0 - (salt-s1)/salt); } return (press); } /* PSS78Pressure() */ /* ** Calculate temperature from p, g and PSS-78 salinity. */ double /* <- temperature (degrees C) */ PSS78Temperature(press, cond, salt) double press; /* -> pressure (decibars) */ double cond; /* -> conductivity (milli-mhos/cm) */ double salt; /* -> salinity (psu) */ { int iter; double s1, temp; /* ** Newton-Raphson iterative method. */ temp = 10.0; /* first approximation to temperature */ for (iter = 1; iter <=200; iter++) { s1 = PSS78Salinity(press, temp, cond); if (fabs(s1 - salt) <= 1.0e-4) break; /* if close enough for government work */ temp *= (1.0 - (salt-s1)/salt); } return (temp); } /* PSS78Temperature() */ double /* <- conductivity (milli-mhos/cm) */ PSS78Conductivity(press, temp, salt) double press; /* press -> pressure (decibars) */ double temp; /* temp -> temperature (celsius degrees) */ double salt; /* salt -> salinity (psu) */ { double bars; int iter; double a, b, c, s1, t1, t2, dt, deltas, rstrms, rstdis, risstd, cond; if (salt <= 0.02) return (0.0); /* ** Newton-Raphson iterative method (no speed-up necessary, ** as usual number of iterations is less than 4) */ rstrms = sqrt(salt / 35.0); /* first approximation to the ratio of Standard Conductivity to standard sea water at t=in-situ */ dt = temp - 15.0; dt /= dt * 0.0162 + 1.0; for (iter = 1; iter <=10; iter++) { deltas = dt * (rstrms*(-0.0056 + rstrms*(-0.0066 + rstrms*(-0.0375 + rstrms*( 0.0636 + rstrms*(-0.0144))))) + 5.0e-4); /* ratio at 15 degrees */ s1 = rstrms*(-0.1692 + rstrms*(25.3851 + rstrms*(14.0941 + rstrms*(-7.0261 + rstrms*( 2.7081))))) + deltas + .008; if (fabs(s1 - salt) <= 1.0e-4) break; /* if close enough for government work */ rstrms += (salt-s1)/ ((-0.0056 + rstrms*(-0.0132 + rstrms*(-0.1125 + rstrms*( 0.2544 + rstrms*(-0.0720))))) * (dt/(1.0+0.0162*dt)) + (-0.1692 + rstrms*( 50.7702 + rstrms*( 42.2823 + rstrms*(-28.1044+ rstrms*( 13.5405)))))); } bars = press * 0.1; /* pressure in bars */ rstdis= rstrms*rstrms; /* ratio of Standard Conductivity to standard sea water at t=in-situ */ t1 = (0.6766097 + temp*( 0.0200564 + temp*( 1.104259e-4 + temp*(-6.9698e-7 + temp*( 1.0031e-9)))))*rstdis; t2 = 1.0 + temp*(0.03426 + temp* 4.464e-4); a = temp* -0.003107 + 0.4215; b = t2 - t1 * a; c = -t1 * (bars*( 2.07e-4 + bars*(-6.37e-8 + bars*( 3.989e-12))) + t2); /* ** Solve quadratic for ratio of in-situ to std conductivity. */ risstd= (-b+sqrt((fabs(b*b - 4.0*a*c))))/(a+a); cond = risstd * StandardConductivity; return (cond); } /* PSS78Conductivity() */ #else /* FORTRAN */ void salin_(p,t,c,s) float *p, *t, *c, *s; { *s = PSS78Salinity(*p,*t,*c); } void pss78press_(temp, cnd, salt, press) float *press, *temp, *salt, *cnd; { *press = PSS78Pressure(*temp, *cnd, *salt); } void pss78temp_(press, cnd, salt, temp) float *press, *temp, *salt, *cnd; { *temp = PSS78Temperature(*press, *cnd, *salt); } void cond_(press, temp, salt, cnd) float *press, *temp, *salt, *cnd; { *cnd = PSS78Conductivity(*press, *temp, *salt); } #endif /* FORTRAN */