Open lipchev opened 5 months ago
I wasn't able validate the conversion expressions for Pressure head - from what I've read it seems like it involves an additional parameter (density / specific weight): https://www.mydatabook.org/fluid-mechanics/pumps/head-to-pressure-converter/
I haven't checked, but if I were to try to decompose the expression in Pressure.json
- I'd probably find the ~density of water
somewhere in there. No sure if this is correct or not- I'm just saying that I've skipped these two units (MeterOfHead
and FootOfHead
).
The same goes for the MetersOfElevation
- I'm pretty sure that's not a valid Unit.. I think we should make it into a method / property for v6.
For Luminosity 3.828x10^26 would be the correct one since it comes from NASA.
I also think that for v6 we should replace the PressureUnit.FeetOfElevation
and PressureUnit.MeterOfElevation
with properties that convert to/from Length:
Here's what I have in mind:
/// <summary>
/// Calculates the pressure at a given elevation.
/// </summary>
/// <param name="elevation">The elevation for which to calculate the pressure.</param>
/// <param name="significantDigits">The number of significant digits to use in the calculation. Default is 13.</param>
/// <returns>A Pressure struct representing the pressure at the given elevation.</returns>
/// <remarks>
/// The calculation is based on the formula for pressure altitude from Wikipedia:
/// https://en.wikipedia.org/wiki/Pressure_altitude
/// </remarks>
public static Pressure FromElevation(Length elevation, int significantDigits = 13)
/// <summary>
/// Converts the pressure to an equivalent elevation or altitude.
/// </summary>
/// <param name="significantDigits">The number of significant digits to round the result to. Default is 15.</param>
/// <returns>A <see cref="Length" /> object representing the equivalent elevation or altitude.</returns>
/// <remarks>
/// The conversion is based on the formula for pressure altitude as described on Wikipedia
/// (https://en.wikipedia.org/wiki/Pressure_altitude).
/// </remarks>
public Length ToElevation(int significantDigits = 15)
There is unfortunately no way to make the conversion exact:
[Fact]
public void PressureFromElevation_ConvertsWithRounding()
{
var pressureFromElevation = Pressure.FromElevation(new Length(129149.9769457631m, LengthUnit.Foot), 13);
Assert.Equal(1, pressureFromElevation.Pascals);
}
[Fact]
public void ElevationFromPressure_ConvertsWithRounding()
{
Length elevationFromPressure = Pressure.FromPascals(1).ToElevation(16);
Assert.Equal(39364.91297306859288m, elevationFromPressure.Meters);
}
I would also suggest that for the FuelEfficiency
we replace the BaseUnit
(LiterPer100Kilometers
) with KilometerPerLiter
as this way FuelEfficiency.Zero
would bring you exactly 0 km
closer to your destination.. 🚀
PS
Technically, I'd say that LiterPer100Kilometers
should be another quantity altogether (I'd call it FuelConsumption
) but that's not very important, as long as we support NaN
and Infinity
..
I also have an issue with the following two "units":
Frequency.BUnit
added in #904 is the only expression in the code-base that requires Math.Sqrt
, which makes it non-reversible (doesn't work with my plan for v6)Angle.Tilt
added in #918 is the only expression requiring the use of Math.Sin
and Math.Asin
, which again won't work in both directions..I was going to suggest replacement functions for constructing with / converting to a number (e.g. Frequency.FromBUnit(..)) but I fail to find any information online about either of these units, so I wonder if those methods are actually useful..
@bplett-wgtcorp Are you still relying on these units? Do you think there are still active applications that depend on them?
I wasn't able validate the conversion expressions for Pressure head - from what I've read it seems like it involves an additional parameter (density / specific weight): https://www.mydatabook.org/fluid-mechanics/pumps/head-to-pressure-converter/
I haven't checked, but if I were to try to decompose the expression in
Pressure.json
- I'd probably find the~density of water
somewhere in there. No sure if this is correct or not- I'm just saying that I've skipped these two units (MeterOfHead
andFootOfHead
).
I'm still not 100% that either of the values is correct but I am pretty confident that they can't both be right:
Assuming that MetersOfHead
-> Pascals
is {x} * 9804.139432
(which is what this calculator uses), then we would expect that FeetOfHead
would be {x} * 9804.139432 * 0.3048
or simply {x} * 2988.3016988736
but what we have is {x} * 2989.0669
(which is not what this calculator uses).
Fixing it would most certainly break a test...
Motivation
Many of the expressions used in the UnitDefnitions (json files) currently correspond to the result of the division of two numbers that do not produce a terminating decimal: see how in #1389 the conversion for
VolumeFlow
for UkGallonsPerHour) is given as791887.667
.There are of course many cases where the resulting decimal is simply rounded, or is the result of some online converter that is introducing similar rounding errors (I don't know any that operate using rational numbers).
What is worse is that the AI agents are also picking up on these incorrect results, sometimes referencing this library.
Working with the
double
type, up until now, these rounding errors were not very important- however as per my upcoming proposal for v6 (incorporating theFractions
as the underlying value type), there wouldn't be any rounding errors.Approach
I've taken the following approach when working through the list:
Mass
/Length
etc - look at every coefficient, and the corresponding Wikipedia page- find where it saysexactly equal to ...
and take that (putting the corresponding link in the xml-docs).1/16 of something-else
I useexpression-for-something-else / 16
, where theexpression-for-something-else
is either acoefficient
or anotherexpression
.Area
then toVolume
etc., working in the exact same way- takingcoefficients
orexpressions
that are eitherexactly equal to ...
or (more often) referencing one of the previously verified filesResult
This resulted in almost half of all quantities receiving some modification to their expressions. Most of these are related to conversions involving the US/British units but there is also some confusion regarding the Calorie - the value of
4.1868
was used (instead of4.184
) in a few places, which is a note-worthy difference.Here are all the tests that broke:
HeatFlux
: due to the change inCalorie
HeatTransferCoefficient
: due to the change inCalorie
Impulse
:PoundFootPerSecond
,SlugFootPerSecond
were represented by a single coefficient that is significantly different from what got: I've used the expression for thePoundal
:{x} * (0.45359237 * 0.3048)
(0.138254954376) instead of{x} / 7.230657989877
(0.13830000000000150747000000001643)- although seeing how close this is to 0.1383 there might be something I'm missing here...Luminosity
: there are two conflicting values for the coefficient online- the top result on google points to this page (where the original value was taken from), while the linked article on Wikipedia (as well as the article about the Sun) both have it listed as 3.828×1026 W[5]. This was added in #680 by @ebfortin - hopefully he could confirm which one is the correct value.Power
: MechanicalHorsepower changed from{x} * 745.69
to{x} * 76.0402249 * 9.80665
as given by this articlePressure
the TechnicalAtmosphere coefficient (no idea where the old one was taken from)SpecificFuelConsumption
: I'm not a domain expert, but{x} * 28.33
doesn't look right forPoundMassPerPoundForceHour
(lb/(lbf·h))- here's what I got:{x} * 453.59237 / (0.0044482216152605 * 3600)
ThermalResistance
: using different conversion coefficients forBTU
andCalorie
from the one defined inEnergy
(note: I wasn't able to confirm the "correct" conversion coefficient for BTU).VolumetricHeatCapacity
: using different conversion coefficient forCalorie