Skip to content

Add missing quantity-derivation relations #1654

@AdamCoulterOz

Description

@AdamCoulterOz

Is your feature request related to a problem? Please describe.
UnitsNet’s relation graph still has a number of gaps in otherwise natural quantity algebra.

In practice, this means formulas often have to drop down to raw scalar extraction and reconstruction even when the participating quantity types already exist and the algebra is semantically clear.

Examples include:

  • force over time producing impulse
  • irradiance over time producing irradiation
  • field/intensity over area or length producing total quantity
  • flow-per-area style reductions that are already implicit in existing relations

The result is an incomplete and sometimes asymmetric relation graph.

Describe the solution you'd like
I’d like the following straightforward derivation relations to be added to UnitRelations.json:

[
  "ElectricPotential.Volt = ElectricPotentialChangeRate.VoltPerSecond * Duration.Second",
  "Impulse.NewtonSecond = Force.Newton * Duration.Second",
  "RotationalSpeed.RadianPerSecond = RotationalAcceleration.RadianPerSecondSquared * Duration.Second",
  "Irradiation.JoulePerSquareMeter = Irradiance.WattPerSquareMeter * Duration.Second",
  "ElectricCurrent.Ampere = ElectricCurrentDensity.AmperePerSquareMeter * Area.SquareMeter",
  "ElectricCharge.Coulomb = ElectricSurfaceChargeDensity.CoulombPerSquareMeter * Area.SquareMeter",
  "ElectricCharge.Coulomb = ElectricChargeDensity.CoulombPerCubicMeter * Volume.CubicMeter",
  "HeatFlux.WattPerSquareMeter = HeatTransferCoefficient.WattPerSquareMeterKelvin * TemperatureDelta.Kelvin",
  "TemperatureDelta.Kelvin = ThermalResistance.KelvinPerWatt * Power.Watt",
  "TemperatureDelta.Kelvin = ThermalInsulance.SquareMeterKelvinPerWatt * HeatFlux.WattPerSquareMeter",
  "Power.Watt = LinearPowerDensity.WattPerMeter * Length.Meter",
  "Power.Watt = PowerDensity.WattPerCubicMeter * Volume.CubicMeter",
  "Volume.CubicMeter = VolumePerLength.CubicMeterPerMeter * Length.Meter",
  "VolumeFlow.CubicMeterPerSecond = VolumeFlowPerArea.CubicMeterPerSecondPerSquareMeter * Area.SquareMeter",
  "Ratio.DecimalFraction = RatioChangeRate.DecimalFractionPerSecond * Duration.Second",
  "Ratio.DecimalFraction = Compressibility.InversePascal * Pressure.Pascal",
  "EnergyDensity.JoulePerCubicMeter = VolumetricHeatCapacity.JoulePerCubicMeterKelvin * TemperatureDelta.Kelvin",
  "LuminousFlux.Lumen = LuminousIntensity.Candela * SolidAngle.Steradian",
  "MagneticFlux.Weber = MagneticField.Tesla * Area.SquareMeter",
  "ElectricCharge.Coulomb = ElectricCapacitance.Farad * ElectricPotential.Volt",
  "ElectricPotential.Volt = ElectricField.VoltPerMeter * Length.Meter",
  "ElectricCurrent.Ampere = ElectricPotential.Volt * ElectricConductance.Siemens",
  "Pressure.Pascal = FluidResistance.PascalSecondPerCubicMeter * VolumeFlow.CubicMeterPerSecond",
  "LeakRate.PascalCubicMeterPerSecond = Pressure.Pascal * VolumeFlow.CubicMeterPerSecond",
  "DoseAreaProduct.GraySquareMeter = AbsorbedDoseOfIonizingRadiation.Gray * Area.SquareMeter",
  "ElectricApparentEnergy.VoltampereHour = ElectricApparentPower.Voltampere * Duration.Hour",
  "ElectricReactiveEnergy.VoltampereReactiveHour = ElectricReactivePower.VoltampereReactive * Duration.Hour"
]

These all look like ordinary quantity derivations rather than semantic aliasing.

Describe alternatives you've considered
The main alternative is to keep writing these formulas manually with scalar extraction and reconstruction, for example:

Impulse impulse = Impulse.FromNewtonSeconds(force.Newtons * duration.Seconds);
RotationalAcceleration rotationalAcceleration = RotationalAcceleration.FromRadiansPerSecondSquared(
    rotationalSpeed.RadiansPerSecond / duration.Seconds);
ElectricCharge charge = ElectricCharge.FromCoulombs(capacitance.Farads * potential.Volts);
VolumeFlow volumeFlow = VolumeFlow.FromCubicMetersPerSecond(
    volumeFlowPerArea.CubicMetersPerSecondPerSquareMeter * area.SquareMeters);

With the proposed relations, these would instead become direct quantity expressions:

Impulse impulse = force * duration;
RotationalAcceleration rotationalAcceleration = rotationalSpeed / duration;
ElectricCharge charge = capacitance * potential;
VolumeFlow volumeFlow = volumeFlowPerArea * area;

The manual form works, but it weakens one of the main benefits of UnitsNet: keeping formulas in semantic quantity types instead of repeatedly dropping to primitive doubles and reconstructing the result manually.

Additional context
I think these should be evaluated simply as quantity algebra.

They are not proposals to merge semantically distinct quantity families or add context-sensitive aliases. They are straightforward derivations between quantity types that already exist in the library.

More generally, if a relation is physically meaningful and algebraically valid, it seems better for the relation graph to express it directly than to require callers to reconstruct it manually from scalar properties.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions