157 lines
4.9 KiB
C#
157 lines
4.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using FootwearTest.Models;
|
|
|
|
namespace FootwearTest.Services;
|
|
|
|
public sealed class TestFormulaService
|
|
{
|
|
private const double VaporizationHeatWhPerGram = 0.672;
|
|
|
|
public double CalculateSkinMoistureResistance(
|
|
double footAreaSquareMeters,
|
|
double skinSaturatedVaporPressurePa,
|
|
double skinRelativeHumidity,
|
|
double environmentSaturatedVaporPressurePa,
|
|
double environmentRelativeHumidity,
|
|
double nakedFootSweatGramsPerHour)
|
|
{
|
|
return footAreaSquareMeters *
|
|
(skinSaturatedVaporPressurePa * skinRelativeHumidity - environmentSaturatedVaporPressurePa * environmentRelativeHumidity) /
|
|
(VaporizationHeatWhPerGram * Math.Max(nakedFootSweatGramsPerHour, 0.001));
|
|
}
|
|
|
|
public MethodASampleRecord CalculateMethodASample(
|
|
int index,
|
|
DeviceSnapshot snapshot,
|
|
double footAreaSquareMeters,
|
|
double skinMoistureResistance,
|
|
double skinSaturatedVaporPressurePa = 5623.0,
|
|
double environmentSaturatedVaporPressurePa = 2809.0)
|
|
{
|
|
var he = VaporizationHeatWhPerGram * Math.Max(snapshot.WaterLossGramsPerHour, 0.001);
|
|
var re = footAreaSquareMeters *
|
|
(skinSaturatedVaporPressurePa - environmentSaturatedVaporPressurePa * snapshot.EnvironmentHumidityPercent / 100.0) /
|
|
he - skinMoistureResistance;
|
|
var hd = Math.Max(snapshot.PowerWatts - he, 0.001);
|
|
var rt = footAreaSquareMeters * (snapshot.FootTemperatureC - snapshot.EnvironmentTemperatureC) / hd;
|
|
|
|
return new MethodASampleRecord(
|
|
index,
|
|
snapshot.Timestamp,
|
|
snapshot.FootTemperatureC,
|
|
snapshot.EnvironmentTemperatureC,
|
|
snapshot.EnvironmentHumidityPercent,
|
|
snapshot.WaterLossGramsPerHour,
|
|
snapshot.PowerWatts,
|
|
Math.Round(he, 3),
|
|
Math.Round(hd, 3),
|
|
Math.Round(re, 3),
|
|
Math.Round(rt, 4));
|
|
}
|
|
|
|
public double Average(IEnumerable<double> values)
|
|
{
|
|
var list = values.ToArray();
|
|
return list.Length == 0 ? 0 : list.Average();
|
|
}
|
|
|
|
public double CoefficientOfVariationPercent(IEnumerable<double> values)
|
|
{
|
|
var list = values.ToArray();
|
|
if (list.Length < 2)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
var average = list.Average();
|
|
if (Math.Abs(average) < 0.000001)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
var variance = list.Sum(value => Math.Pow(value - average, 2)) / (list.Length - 1);
|
|
return Math.Sqrt(variance) / Math.Abs(average) * 100.0;
|
|
}
|
|
|
|
public bool PassesTenPercentDeviation(IEnumerable<double> values)
|
|
{
|
|
var list = values.ToArray();
|
|
if (list.Length == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var average = list.Average();
|
|
return list.All(value => Math.Abs(value - average) <= Math.Abs(average) * 0.10);
|
|
}
|
|
|
|
public MethodBMoistureResult CalculateMethodBMoisture(
|
|
double m11,
|
|
double m12,
|
|
double m21,
|
|
double m22,
|
|
double m31,
|
|
double m32,
|
|
double m41,
|
|
double m42,
|
|
double m51,
|
|
double m52,
|
|
double m61,
|
|
double m62,
|
|
double m71,
|
|
double m72)
|
|
{
|
|
var m5 = m51 - m52;
|
|
var m6 = m61 - m62;
|
|
var m7 = m71 - m72;
|
|
var m8 = (m6 + m7) / 2.0;
|
|
var m180 = m5 - m8;
|
|
var scale = 15.0 / Math.Max(m180, 0.001);
|
|
|
|
var m1 = m12 - m11;
|
|
var m2 = m22 - m21;
|
|
var m3 = m32 - m31;
|
|
var m4 = m42 - m41;
|
|
var t180 = m180 - m1 - m2 - m3 - m4;
|
|
|
|
return new MethodBMoistureResult(
|
|
Math.Round(m1, 3),
|
|
Math.Round(m2, 3),
|
|
Math.Round(m3, 3),
|
|
Math.Round(m4, 3),
|
|
Math.Round(m5, 3),
|
|
Math.Round(m6, 3),
|
|
Math.Round(m7, 3),
|
|
Math.Round(m8, 3),
|
|
Math.Round(m180, 3),
|
|
Math.Round(t180, 3),
|
|
Math.Round(m1 * scale, 3),
|
|
Math.Round(m2 * scale, 3),
|
|
Math.Round(m3 * scale, 3),
|
|
Math.Round(m4 * scale, 3),
|
|
Math.Round(t180 * scale, 3),
|
|
Math.Round((t180 + m3 + m4) * scale, 3),
|
|
m180 >= 14.1 && m180 <= 15.9);
|
|
}
|
|
|
|
public MethodBWarmthResult CalculateMethodBWarmth(
|
|
double energyKilojoules,
|
|
double seconds,
|
|
double footAreaSquareMeters,
|
|
double footTemperatureC,
|
|
double chamberTemperatureC)
|
|
{
|
|
var heatWatts = energyKilojoules / Math.Max(seconds, 1.0) * 1000.0;
|
|
var resistance = footAreaSquareMeters * (footTemperatureC - chamberTemperatureC) / Math.Max(heatWatts, 0.001);
|
|
return new MethodBWarmthResult(
|
|
Math.Round(energyKilojoules, 1),
|
|
seconds,
|
|
Math.Round(heatWatts, 3),
|
|
Math.Round(footTemperatureC, 2),
|
|
Math.Round(chamberTemperatureC, 2),
|
|
Math.Round(resistance, 3));
|
|
}
|
|
}
|