132 lines
4.2 KiB
C#
132 lines
4.2 KiB
C#
///
|
|
/// Copyright (c) 2013-2015 Sensus Metering Systems
|
|
///
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using log4net;
|
|
|
|
namespace TBF.BenchControl
|
|
{
|
|
public static class Formulas
|
|
{
|
|
private static readonly ILog log = LogManager.GetLogger(typeof(Formulas));
|
|
|
|
/// <summary>
|
|
/// Calculate density of distilled water from temperature
|
|
/// </summary>
|
|
/// <param name="t">Temperature in [degC]</param>
|
|
/// <returns>Density in [kg/m3]</returns>
|
|
public static double DistilledWaterDensityFromTemp(float t)
|
|
{
|
|
double tt = (double)t;
|
|
const double a0 = 999.842594;
|
|
const double a1 = 0.06793952;
|
|
const double a2 = -0.00909529;
|
|
const double a3 = 0.0001001685;
|
|
const double a4 = -0.000001120083;
|
|
const double a5 = 6.536332e-09;
|
|
|
|
return ((((a5 * tt + a4) * tt + a3) * tt + a2) * tt + a1) * tt + a0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculate corrected (real) water density from temperature
|
|
/// </summary>
|
|
/// <param name="t">Temperature in [degC]</param>
|
|
/// <returns>Density in [kg/m3]</returns>
|
|
public static double WaterDensityFromTemp(float t)
|
|
{
|
|
double realDensity = Program.LocalSettings.RealDensity;
|
|
float atTemperature = Program.LocalSettings.AtTemperature;
|
|
|
|
double c_rho = realDensity / DistilledWaterDensityFromTemp(atTemperature);
|
|
|
|
return c_rho * DistilledWaterDensityFromTemp(t);
|
|
}
|
|
|
|
|
|
public static float AirDensityFromAmbientVales(float tempC, float pressureBar, float humiPct)
|
|
{
|
|
double pressurePa = 100000.0 * (double)pressureBar; /// [Pa]
|
|
double tempKelvin = 273.15 + (double)tempC;
|
|
double coef1 = 1.2811805 / 10000.0 * tempKelvin * tempKelvin
|
|
- 1.950987 / 100.0 * tempKelvin
|
|
+ 34.04926034
|
|
- 6.353631 * 1000.0 / tempKelvin;
|
|
double coef3 = humiPct / 100.0 * System.Math.Exp(coef1) / pressurePa;
|
|
double airDensityKgm3 = 0.00348353 * pressurePa * (1.0 - 0.378 * coef3) / tempKelvin; /// kg/m3
|
|
return (float)airDensityKgm3;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert 'pulses' to 'volume', prevent division by zero
|
|
/// </summary>
|
|
public static double VolumeFromPulses(int pulses, double pulsesPerLiter)
|
|
{
|
|
if (pulsesPerLiter <= double.Epsilon) return 0;
|
|
return Convert.ToDouble(pulses) / pulsesPerLiter;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculate the error in % from 'measured' and 'true' volume, prevent division by zero
|
|
/// </summary>
|
|
public static double ErrorFromVolumes(double measuredVolume, double trueVolume)
|
|
{
|
|
if (trueVolume <= float.Epsilon)
|
|
{
|
|
if (measuredVolume <= float.Epsilon)
|
|
{
|
|
log.WarnFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, 99.0);
|
|
return 99.0;
|
|
}
|
|
|
|
log.WarnFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, 99.0);
|
|
return 99.0;
|
|
}
|
|
double error = 100.0 * (measuredVolume - trueVolume) / trueVolume;
|
|
log.InfoFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, error);
|
|
return error;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates corrected value form a list of corrections by interpolation.
|
|
/// It is assumed that values in the list 'corrections' are sorted.
|
|
/// </summary>
|
|
/// <param name="rawMeasurement">Raw uncorrected value</param>
|
|
/// <param name="corrections">Sorted (value, correction) pairs</param>
|
|
/// <returns>Corrected value</returns>
|
|
public static double CorrectedValue(double rawValue, IList<Config.Entities.MeasurementCorrection> corrections)
|
|
{
|
|
if (corrections == null || corrections.Count == 0) return rawValue;
|
|
|
|
if (rawValue < corrections[0].Measurement)
|
|
{
|
|
return rawValue + corrections[0].Correction;
|
|
}
|
|
|
|
int count = corrections.Count;
|
|
for (int i = 1; i < count; i++)
|
|
{
|
|
if (rawValue < corrections[i].Measurement)
|
|
{
|
|
double d1 = rawValue - corrections[i-1].Measurement;
|
|
double d2 = corrections[i].Measurement - rawValue;
|
|
|
|
double corr;
|
|
if (d1 + d2 <= float.Epsilon)
|
|
{
|
|
corr = (corrections[i - 1].Correction + corrections[i].Correction) / 2.0;
|
|
}
|
|
else
|
|
{
|
|
corr = (corrections[i - 1].Correction * d2 + corrections[i].Correction * d1) / (d1 + d2);
|
|
}
|
|
return rawValue + corr;
|
|
}
|
|
}
|
|
|
|
return rawValue + corrections[count - 1].Correction;
|
|
}
|
|
}
|
|
}
|