private void UpdateSoundSpeed() { if (meanWaterTemperatureC.IsInitialized) { pCore.SoundSpeed = PHX.Speed_of_sound_UNESCO_calc(meanWaterTemperatureC.Value, PHX.PHX_ATM_PRESSURE_MBAR, salinity_PSU); } }
private double getVByProfile(double z) { double t, p, s, v, rho0; if (z < tsp[tsp.Length - 1].Z) { int idx1 = 0, idx2 = tsp.Length - 1; while ((tsp[idx1].Z < z) && (idx1 < tsp.Length - 1)) { idx1++; } while ((z <= tsp[idx2].Z) && (idx2 > idx1 + 1)) { idx2--; } double z1 = tsp[idx1].Z; double t1 = tsp[idx1].T; double s1 = tsp[idx1].S; rho0 = PHX.Water_density_calc(t1, PHX.PHX_ATM_PRESSURE_MBAR, s1); double p1 = PHX.Pressure_by_depth_calc(z1, PHX.PHX_ATM_PRESSURE_MBAR, rho0, g); double z2 = tsp[idx2].Z; double t2 = tsp[idx2].T; double s2 = tsp[idx2].S; double p2 = PHX.Pressure_by_depth_calc(z2, PHX.PHX_ATM_PRESSURE_MBAR, rho0, g); t = PHX.Linterp(z1, t1, z2, t2, z); p = PHX.Linterp(z1, p1, z2, p2, z); s = PHX.Linterp(z1, s1, z2, s2, z); } else { t = tsp[tsp.Length - 1].T; s = tsp[tsp.Length - 1].S; rho0 = PHX.Water_density_calc(t, PHX.PHX_ATM_PRESSURE_MBAR, s); p = PHX.Pressure_by_depth_calc(z, PHX.PHX_ATM_PRESSURE_MBAR, rho0, g); } v = PHX.Speed_of_sound_UNESCO_calc(t, p, s); return(v); }
private void UpdateProfileDependant() { if (tsp.Length > 2) { v_surface = PHX.Speed_of_sound_UNESCO_calc(tsp[0].T, PHX.PHX_ATM_PRESSURE_MBAR, tsp[0].S); double t_mean = 0, s_mean = 0; for (int i = 0; i < tsp.Length; i++) { t_mean += tsp[i].T; s_mean += tsp[i].S; } t_mean /= tsp.Length; s_mean /= tsp.Length; v_mean = PHX.Speed_of_sound_UNESCO_calc(t_mean, PHX.PHX_ATM_PRESSURE_MBAR, s_mean); } }
public void Speed_of_sound_calc_test() { // Reference values according to // Algorithms for computation of fundamental properties of seawater. // Unesco technical papers in marine science vol. 44, 1983, pp. 28 // https://darchive.mblwhoilibrary.org/bitstream/handle/1912/2470/059832eb.pdf double[] ref_t = new double[] { 0.0, 10.0, 20.0, 30.0, 40.0 }; double[] ref_p = new double[] { 0.0, 1E5, 2E5, 3E5, 4E5, 5E5, 6E5, 7E5, 8E5, 9E5, 1E6 }; double[,] ref_v_s25 = new double[, ] { { 1435.8, 1477.7, 1510.3, 1535.2, 1553.4 }, { 1452.0, 1494.1, 1527.0, 1552.1, 1570.6 }, { 1468.6, 1510.7, 1543.6, 1569.0, 1587.6 }, { 1485.6, 1527.5, 1560.3, 1585.7, 1604.5 }, { 1502.8, 1544.3, 1576.9, 1602.4, 1621.3 }, { 1520.4, 1561.3, 1593.6, 1619.0, 1638.0 }, { 1538.1, 1578.4, 1610.3, 1635.5, 1654.6 }, { 1556.0, 1595.6, 1626.9, 1651.9, 1671.0 }, { 1574.1, 1612.8, 1643.5, 1668.2, 1687.2 }, { 1592.2, 1630.1, 1660.2, 1684.5, 1703.3 }, { 1610.4, 1647.4, 1676.8, 1700.6, 1719.2 }, }; double[,] ref_v_s30 = new double[, ] { { 1442.5, 1483.7, 1515.9, 1540.4, 1558.3 }, { 1458.8, 1500.2, 1532.5, 1557.3, 1575.4 }, { 1475.4, 1516.8, 1549.2, 1574.1, 1592.3 }, { 1492.4, 1533.6, 1565.8, 1590.8, 1609.2 }, { 1509.7, 1550.4, 1582.4, 1607.4, 1626.0 }, { 1527.2, 1567.4, 1599.1, 1624.0, 1642.7 }, { 1544.9, 1584.4, 1615.7, 1640.4, 1659.2 }, { 1562.7, 1601.5, 1632.3, 1656.8, 1675.6 }, { 1580.7, 1618.7, 1648.9, 1673.1, 1691.8 }, { 1598.8, 1636.0, 1665.5, 1689.3, 1707.8 }, { 1616.8, 1653.3, 1682.1, 1705.4, 1723.5 } }; double[,] ref_v_s35 = new double[, ] { { 1449.1, 1489.8, 1521.5, 1545.6, 1563.2 }, { 1465.5, 1506.3, 1538.1, 1562.4, 1580.2 }, { 1482.3, 1523.0, 1554.7, 1579.2, 1597.1 }, { 1499.3, 1539.7, 1571.3, 1595.9, 1613.9 }, { 1516.5, 1556.5, 1587.9, 1612.5, 1630.7 }, { 1534.0, 1573.4, 1604.5, 1629.0, 1647.3 }, { 1551.6, 1590.4, 1621.0, 1645.4, 1663.8 }, { 1569.4, 1607.5, 1637.6, 1661.7, 1680.1 }, { 1587.2, 1624.6, 1654.1, 1677.9, 1696.2 }, { 1605.2, 1641.8, 1670.6, 1694.0, 1712.2 }, { 1623.2, 1659.0, 1687.2, 1710.1, 1727.8 } }; for (int t_idx = 0; t_idx < ref_t.Length; t_idx++) { for (int p_idx = 0; p_idx < ref_p.Length; p_idx++) { Assert.AreEqual(PHX.Speed_of_sound_UNESCO_calc(ref_t[t_idx], ref_p[p_idx], 25.0), ref_v_s25[p_idx, t_idx], 0.1); Assert.AreEqual(PHX.Speed_of_sound_UNESCO_calc(ref_t[t_idx], ref_p[p_idx], 30.0), ref_v_s30[p_idx, t_idx], 0.1); Assert.AreEqual(PHX.Speed_of_sound_UNESCO_calc(ref_t[t_idx], ref_p[p_idx], 35.0), ref_v_s35[p_idx, t_idx], 0.1); } } Assert.AreEqual(PHX.Speed_of_sound_UNESCO_calc(40.0, 1000000.0, 40.0), 1731.995, 0.001); }
private void OnLBLA(object[] parameters) { // IC_D2H_LBLA $PRWLA,bID,baseLat,baseLon,[baseDpt],baseBat,pingerDataID,pingerData,TOAsecond,MSR_dB BaseIDs baseID = (parameters[0] == null) ? BaseIDs.BASE_INVALID : (BaseIDs)(int)parameters[0]; double baseLat = doubleNullChecker(parameters[1]); double baseLon = doubleNullChecker(parameters[2]); double baseDepth = (parameters[3] == null) ? RWLT.DEFAULT_BASE_DPT_M : (double)parameters[3]; double baseBat = doubleNullChecker(parameters[4]); PingerDataIDs pDataID = (parameters[5] == null) ? PingerDataIDs.DID_INVALID : (PingerDataIDs)(int)parameters[5]; double pData = doubleNullChecker(parameters[6]); double TOAs = doubleNullChecker(parameters[7]); double MSR = doubleNullChecker(parameters[8]); if ((baseID != BaseIDs.BASE_INVALID) && (!double.IsNaN(baseLat)) && (!double.IsNaN(baseLon)) && (!double.IsNaN(baseDepth))) { if ((baseID == auxGNSSBuoyID) && (!AUXGNSSUsed)) { GNSS_RMCSentenceReceived(this, new RMCMessageEventArgs(0xFF, TalkerIdentifiers.GN, GetTimeStamp(), baseLat, baseLon, double.NaN, double.NaN, double.NaN, true)); } LocationUpdatedEvent.Rise(this, new LocationUpdatedEventArgs(baseID.ToString().Replace('_', ' '), baseLat, baseLon, baseDepth, true, GetTimeStamp())); if (!double.IsNaN(MSR)) { BaseMSRs[baseID].Value = MSR; } if (!double.IsNaN(baseBat)) { BaseBatVoltages[baseID].Value = baseBat; } if (gravityAccNeedsUpdate) { gravityAcc = PHX.Gravity_constant_wgs84_calc(baseLat); gravityAccNeedsUpdate = false; } if (pDataID == PingerDataIDs.DID_BAT) { TargetBatVoltage.Value = pData; } else if (pDataID == PingerDataIDs.DID_TMP) { TargetTemperature.Value = pData; if (IsAutoSoundSpeed && TargetPressure.IsInitialized) { Soundspeed = PHX.Speed_of_sound_UNESCO_calc(TargetTemperature.Value, TargetPressure.Value / 2.0, salinity); } } else if (pDataID == PingerDataIDs.DID_PRS) { TargetPressure.Value = pData; if (TargetTemperature.IsInitialized) { if (IsAutoSoundSpeed) { Soundspeed = PHX.Speed_of_sound_UNESCO_calc(TargetTemperature.Value, TargetPressure.Value / 2.0, salinity); } double rho = PHX.Water_density_calc(TargetTemperature.Value, TargetPressure.Value / 2.0, salinity); // p0 is zero, because pinger calibrates surface pressure on start and transmits pressure relative to the surface TargetDepth.Value = PHX.Depth_by_pressure_calc(TargetPressure.Value, 0, rho, gravityAcc); } else if (TargetPressure.IsInitialized) { TargetDepth.Value = PHX.Depth_by_pressure_calc(TargetPressure.Value, 0, PHX.PHX_FWTR_DENSITY_KGM3, gravityAcc); } } else if (pDataID == PingerDataIDs.DID_CODE) { TargetAlarm.Value = (PingerCodeIDs)Enum.ToObject(typeof(PingerCodeIDs), Convert.ToInt32(pData)); } var bases = baseProcessor.ProcessBase(baseID, baseLat, baseLon, baseDepth, TOAs); if (bases != null) { TryLocate(bases); } } OnSystemUpdate(); }
private void waterSalinityEdit_ValueChanged(object sender, EventArgs e) { soundSpeedMps = PHX.Speed_of_sound_UNESCO_calc(waterTemperatureC, PHX.PHX_ATM_PRESSURE_MBAR, waterSalinityPSU); }