From 323c537066a71d96ecebedb41ba8cfee7bc3cf47 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 12 Jun 2026 09:31:03 +0000 Subject: [PATCH 1/3] feat(quantities): backfill missing dimensions and acoustic overloads from main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New generated dimensions: Permittivity (F/m), ElectricConductivity (S/m), ElectricFlux (V·m, with ElectricField x Area relationship), ElectricPowerDensity (W/m³, with x Volume => Power), Sensitivity (V/Pa, with x Pressure => Voltage), ThermalResistance (K/W), RateConstant (s⁻¹), Luminance (cd/m², Nit, FootLambert, with x Area => LuminousIntensity), and the psychoacoustic Loudness (sone) and Sharpness (acum). New semantic overloads: Impedance on Resistance (mirrors Admittance on Conductance), SoundPressure on Pressure, SoundPower on Power, SoundAbsorption / NoiseReductionCoefficient / SoundTransmissionClass on Ratio, and the signed ReflectionCoefficient on SignedRatio. Also fixes two latent metadata bugs: - Luminance was modelled as an overload of Illuminance; lux (light arriving) and cd/m² (light leaving) are different quantities, so the overload is replaced by the proper Luminance dimension. - The generator emits an identity factory for the first availableUnits entry, but Concentration listed Molar (x1000) and NuclearCrossSection listed Barn (x1e-28) first, so From{Base} and In(unit) disagreed about the storage unit. Both now lead with the true SI base unit (MolePerCubicMeter, SquareMeter); FromMolars and FromBarns now scale into SI storage as documented. RateConstant deliberately has no Time integral: Frequency already owns Ratio / Duration, and a second result type for the same operands cannot compile. https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW --- .../ConversionConstants.g.cs | 3 + .../PhysicalDimensions.g.cs | 112 ++++- .../Area.g.cs | 8 + .../Concentration.g.cs | 9 +- .../ElectricConductivity.g.cs | 43 ++ .../ElectricFieldMagnitude.g.cs | 4 + .../ElectricFlux.g.cs | 51 +++ .../ElectricPowerDensity.g.cs | 47 ++ .../Impedance.g.cs | 61 +++ .../Loudness.g.cs | 43 ++ .../Luminance.g.cs | 47 +- .../LuminousIntensity.g.cs | 8 + .../NoiseReductionCoefficient.g.cs | 103 +++++ .../NuclearCrossSection.g.cs | 9 +- .../Permittivity.g.cs | 43 ++ .../Power.g.cs | 8 + .../Pressure.g.cs | 4 + .../RateConstant.g.cs | 43 ++ .../ReflectionCoefficient.g.cs | 92 ++++ .../Sensitivity.g.cs | 47 ++ .../Sharpness.g.cs | 43 ++ .../SoundAbsorption.g.cs | 103 +++++ .../SoundPower.g.cs | 68 +++ .../SoundPressure.g.cs | 82 ++++ .../SoundTransmissionClass.g.cs | 103 +++++ .../ThermalResistance.g.cs | 43 ++ .../VoltageMagnitude.g.cs | 8 + .../Volume.g.cs | 4 + .../Units.g.cs | 405 +++++++++++++++++- .../Metadata/conversions.json | 5 + .../Metadata/dimensions.json | 191 ++++++++- .../Metadata/units.json | 92 ++++ 32 files changed, 1889 insertions(+), 43 deletions(-) create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricConductivity.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricFlux.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricPowerDensity.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Impedance.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Loudness.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/NoiseReductionCoefficient.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Permittivity.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/RateConstant.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ReflectionCoefficient.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Sensitivity.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Sharpness.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundAbsorption.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundPower.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundPressure.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundTransmissionClass.g.cs create mode 100644 Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ThermalResistance.g.cs diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.ConversionsGenerator/ConversionConstants.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.ConversionsGenerator/ConversionConstants.g.cs index accf11b..c2cb704 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.ConversionsGenerator/ConversionConstants.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.ConversionsGenerator/ConversionConstants.g.cs @@ -259,6 +259,9 @@ internal static class ConversionConstants{ /// Foot-candle to lux conversion: 1/0.09290304 ≈ 10.7639 lx/fc (exact) internal const double FootCandleToLux = 10.763910416709722; + /// Foot-lambert to candela per square meter: 1/(π·0.09290304) ≈ 3.4263 cd/m² per fL (exact) + internal const double FootLambertToCandelaPerSquareMeter = 3.4262590996353905; + /// Parts per million to ratio: 1e-6 (exact by definition) internal const double PartsPerMillionToRatio = 1e-6; diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.DimensionsGenerator/PhysicalDimensions.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.DimensionsGenerator/PhysicalDimensions.g.cs index daf532f..8208494 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.DimensionsGenerator/PhysicalDimensions.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.DimensionsGenerator/PhysicalDimensions.g.cs @@ -56,7 +56,7 @@ public static class PhysicalDimensions{ public static readonly DimensionInfo Density = new("Density", "M L⁻³", new Dictionary { ["mass"] = 1, ["length"] = -3 }, new List { "Density" }); /// Physical dimension: Dimensionless - public static readonly DimensionInfo Dimensionless = new("Dimensionless", "1", new Dictionary(), new List { "Ratio", "RefractiveIndex", "ReynoldsNumber", "SpecificGravity", "MachNumber", "SignedRatio" }); + public static readonly DimensionInfo Dimensionless = new("Dimensionless", "1", new Dictionary(), new List { "Ratio", "RefractiveIndex", "ReynoldsNumber", "SpecificGravity", "MachNumber", "SoundAbsorption", "NoiseReductionCoefficient", "SoundTransmissionClass", "SignedRatio", "ReflectionCoefficient" }); /// Physical dimension: DynamicViscosity public static readonly DimensionInfo DynamicViscosity = new("DynamicViscosity", "M L⁻¹ T⁻¹", new Dictionary { ["mass"] = 1, ["length"] = -1, ["time"] = -1 }, new List { "DynamicViscosity" }); @@ -70,17 +70,26 @@ public static class PhysicalDimensions{ /// Physical dimension: ElectricConductance public static readonly DimensionInfo ElectricConductance = new("ElectricConductance", "M⁻¹ L⁻² T³ I²", new Dictionary { ["mass"] = -1, ["length"] = -2, ["time"] = 3, ["electricCurrent"] = 2 }, new List { "Conductance", "Admittance" }); + /// Physical dimension: ElectricConductivity + public static readonly DimensionInfo ElectricConductivity = new("ElectricConductivity", "M⁻¹ L⁻³ T³ I²", new Dictionary { ["mass"] = -1, ["length"] = -3, ["time"] = 3, ["electricCurrent"] = 2 }, new List { "ElectricConductivity" }); + /// Physical dimension: ElectricCurrent public static readonly DimensionInfo ElectricCurrent = new("ElectricCurrent", "I", new Dictionary { ["electricCurrent"] = 1 }, new List { "CurrentMagnitude", "Current1D", "Current3D" }); /// Physical dimension: ElectricField public static readonly DimensionInfo ElectricField = new("ElectricField", "M L T⁻³ I⁻¹", new Dictionary { ["mass"] = 1, ["length"] = 1, ["time"] = -3, ["electricCurrent"] = -1 }, new List { "ElectricFieldMagnitude", "ElectricField1D", "ElectricField2D", "ElectricField3D" }); + /// Physical dimension: ElectricFlux + public static readonly DimensionInfo ElectricFlux = new("ElectricFlux", "M L³ T⁻³ I⁻¹", new Dictionary { ["mass"] = 1, ["length"] = 3, ["time"] = -3, ["electricCurrent"] = -1 }, new List { "ElectricFlux" }); + /// Physical dimension: ElectricPotential public static readonly DimensionInfo ElectricPotential = new("ElectricPotential", "M L² T⁻³ I⁻¹", new Dictionary { ["mass"] = 1, ["length"] = 2, ["time"] = -3, ["electricCurrent"] = -1 }, new List { "VoltageMagnitude", "EMF", "VoltageDrop", "Voltage" }); + /// Physical dimension: ElectricPowerDensity + public static readonly DimensionInfo ElectricPowerDensity = new("ElectricPowerDensity", "M L⁻¹ T⁻³", new Dictionary { ["mass"] = 1, ["length"] = -1, ["time"] = -3 }, new List { "ElectricPowerDensity" }); + /// Physical dimension: ElectricResistance - public static readonly DimensionInfo ElectricResistance = new("ElectricResistance", "M L² T⁻³ I⁻²", new Dictionary { ["mass"] = 1, ["length"] = 2, ["time"] = -3, ["electricCurrent"] = -2 }, new List { "Resistance" }); + public static readonly DimensionInfo ElectricResistance = new("ElectricResistance", "M L² T⁻³ I⁻²", new Dictionary { ["mass"] = 1, ["length"] = 2, ["time"] = -3, ["electricCurrent"] = -2 }, new List { "Resistance", "Impedance" }); /// Physical dimension: Energy public static readonly DimensionInfo Energy = new("Energy", "M L² T⁻²", new Dictionary { ["mass"] = 1, ["length"] = 2, ["time"] = -2 }, new List { "Energy", "Work", "Heat", "KineticEnergy", "PotentialEnergy", "ThermalEnergy" }); @@ -104,7 +113,7 @@ public static class PhysicalDimensions{ public static readonly DimensionInfo HeatTransferCoefficient = new("HeatTransferCoefficient", "M T⁻³ Θ⁻¹", new Dictionary { ["mass"] = 1, ["time"] = -3, ["temperature"] = -1 }, new List { "HeatTransferCoefficient" }); /// Physical dimension: Illuminance - public static readonly DimensionInfo Illuminance = new("Illuminance", "J L⁻²", new Dictionary { ["luminousIntensity"] = 1, ["length"] = -2 }, new List { "Illuminance", "Luminance" }); + public static readonly DimensionInfo Illuminance = new("Illuminance", "J L⁻²", new Dictionary { ["luminousIntensity"] = 1, ["length"] = -2 }, new List { "Illuminance" }); /// Physical dimension: Inductance public static readonly DimensionInfo Inductance = new("Inductance", "M L² T⁻² I⁻²", new Dictionary { ["mass"] = 1, ["length"] = 2, ["time"] = -2, ["electricCurrent"] = -2 }, new List { "Inductance" }); @@ -121,6 +130,12 @@ public static class PhysicalDimensions{ /// Physical dimension: Length public static readonly DimensionInfo Length = new("Length", "L", new Dictionary { ["length"] = 1 }, new List { "Length", "Width", "Height", "Depth", "Radius", "Diameter", "Distance", "Altitude", "Wavelength", "Thickness", "Perimeter", "Displacement1D", "Offset", "Displacement2D", "Displacement3D", "Position3D", "Translation3D", "Displacement4D" }); + /// Physical dimension: Loudness + public static readonly DimensionInfo Loudness = new("Loudness", "1", new Dictionary(), new List { "Loudness" }); + + /// Physical dimension: Luminance + public static readonly DimensionInfo Luminance = new("Luminance", "J L⁻²", new Dictionary { ["luminousIntensity"] = 1, ["length"] = -2 }, new List { "Luminance" }); + /// Physical dimension: LuminousFlux public static readonly DimensionInfo LuminousFlux = new("LuminousFlux", "J", new Dictionary { ["luminousIntensity"] = 1 }, new List { "LuminousFlux" }); @@ -157,18 +172,30 @@ public static class PhysicalDimensions{ /// Physical dimension: OpticalPower public static readonly DimensionInfo OpticalPower = new("OpticalPower", "L⁻¹", new Dictionary { ["length"] = -1 }, new List { "OpticalPower" }); + /// Physical dimension: Permittivity + public static readonly DimensionInfo Permittivity = new("Permittivity", "M⁻¹ L⁻³ T⁴ I²", new Dictionary { ["mass"] = -1, ["length"] = -3, ["time"] = 4, ["electricCurrent"] = 2 }, new List { "Permittivity" }); + /// Physical dimension: Power - public static readonly DimensionInfo Power = new("Power", "M L² T⁻³", new Dictionary { ["mass"] = 1, ["length"] = 2, ["time"] = -3 }, new List { "Power", "HeatFlowRate" }); + public static readonly DimensionInfo Power = new("Power", "M L² T⁻³", new Dictionary { ["mass"] = 1, ["length"] = 2, ["time"] = -3 }, new List { "Power", "HeatFlowRate", "SoundPower" }); /// Physical dimension: Pressure - public static readonly DimensionInfo Pressure = new("Pressure", "M L⁻¹ T⁻²", new Dictionary { ["mass"] = 1, ["length"] = -1, ["time"] = -2 }, new List { "Pressure", "Stress", "AtmosphericPressure", "GaugePressure", "BulkModulus", "YoungsModulus", "ShearModulus" }); + public static readonly DimensionInfo Pressure = new("Pressure", "M L⁻¹ T⁻²", new Dictionary { ["mass"] = 1, ["length"] = -1, ["time"] = -2 }, new List { "Pressure", "Stress", "AtmosphericPressure", "GaugePressure", "BulkModulus", "YoungsModulus", "ShearModulus", "SoundPressure" }); /// Physical dimension: RadioactiveActivity public static readonly DimensionInfo RadioactiveActivity = new("RadioactiveActivity", "T⁻¹", new Dictionary { ["time"] = -1 }, new List { "RadioactiveActivity" }); + /// Physical dimension: RateConstant + public static readonly DimensionInfo RateConstant = new("RateConstant", "T⁻¹", new Dictionary { ["time"] = -1 }, new List { "RateConstant" }); + /// Physical dimension: ReactionRate public static readonly DimensionInfo ReactionRate = new("ReactionRate", "N L⁻³ T⁻¹", new Dictionary { ["amountOfSubstance"] = 1, ["length"] = -3, ["time"] = -1 }, new List { "ReactionRate" }); + /// Physical dimension: Sensitivity + public static readonly DimensionInfo Sensitivity = new("Sensitivity", "M⁻¹ L⁻¹ T² I", new Dictionary { ["mass"] = -1, ["length"] = -1, ["time"] = 2, ["electricCurrent"] = 1 }, new List { "Sensitivity" }); + + /// Physical dimension: Sharpness + public static readonly DimensionInfo Sharpness = new("Sharpness", "1", new Dictionary(), new List { "Sharpness" }); + /// Physical dimension: Snap public static readonly DimensionInfo Snap = new("Snap", "L T⁻⁴", new Dictionary { ["length"] = 1, ["time"] = -4 }, new List { "SnapMagnitude", "Snap1D", "Snap2D", "Snap3D", "Snap4D" }); @@ -187,6 +214,9 @@ public static class PhysicalDimensions{ /// Physical dimension: ThermalExpansion public static readonly DimensionInfo ThermalExpansion = new("ThermalExpansion", "Θ⁻¹", new Dictionary { ["temperature"] = -1 }, new List { "ThermalExpansionCoefficient" }); + /// Physical dimension: ThermalResistance + public static readonly DimensionInfo ThermalResistance = new("ThermalResistance", "Θ M⁻¹ L⁻² T³", new Dictionary { ["temperature"] = 1, ["mass"] = -1, ["length"] = -2, ["time"] = 3 }, new List { "ThermalResistance" }); + /// Physical dimension: Time public static readonly DimensionInfo Time = new("Time", "T", new Dictionary { ["time"] = 1 }, new List { "Duration", "Period", "HalfLife", "TimeConstant", "Latency", "ReverberationTime", "DecayTime" }); @@ -203,7 +233,7 @@ public static class PhysicalDimensions{ public static readonly DimensionInfo VolumetricFlowRate = new("VolumetricFlowRate", "L³ T⁻¹", new Dictionary { ["length"] = 3, ["time"] = -1 }, new List { "VolumetricFlowRate" }); /// Gets a frozen collection of all standard physical dimensions. - public static IReadOnlySet All = new HashSet([ AbsorbedDose, Acceleration, AcousticImpedance, AmountOfSubstance, AngularAcceleration, AngularDisplacement, AngularJerk, AngularMomentum, AngularVelocity, Area, CatalyticActivity, Concentration, Density, Dimensionless, DynamicViscosity, ElectricCapacitance, ElectricCharge, ElectricConductance, ElectricCurrent, ElectricField, ElectricPotential, ElectricResistance, Energy, Entropy, EquivalentDose, Exposure, Force, Frequency, HeatTransferCoefficient, Illuminance, Inductance, Irradiance, Jerk, KinematicViscosity, Length, LuminousFlux, LuminousIntensity, MagneticFlux, MagneticFluxDensity, Mass, MassFlowRate, MolarEnergy, MolarMass, MomentOfInertia, Momentum, NuclearCrossSection, OpticalPower, Power, Pressure, RadioactiveActivity, ReactionRate, Snap, SpecificHeat, SurfaceTension, Temperature, ThermalConductivity, ThermalExpansion, Time, Torque, Velocity, Volume, VolumetricFlowRate ]); + public static IReadOnlySet All = new HashSet([ AbsorbedDose, Acceleration, AcousticImpedance, AmountOfSubstance, AngularAcceleration, AngularDisplacement, AngularJerk, AngularMomentum, AngularVelocity, Area, CatalyticActivity, Concentration, Density, Dimensionless, DynamicViscosity, ElectricCapacitance, ElectricCharge, ElectricConductance, ElectricConductivity, ElectricCurrent, ElectricField, ElectricFlux, ElectricPotential, ElectricPowerDensity, ElectricResistance, Energy, Entropy, EquivalentDose, Exposure, Force, Frequency, HeatTransferCoefficient, Illuminance, Inductance, Irradiance, Jerk, KinematicViscosity, Length, Loudness, Luminance, LuminousFlux, LuminousIntensity, MagneticFlux, MagneticFluxDensity, Mass, MassFlowRate, MolarEnergy, MolarMass, MomentOfInertia, Momentum, NuclearCrossSection, OpticalPower, Permittivity, Power, Pressure, RadioactiveActivity, RateConstant, ReactionRate, Sensitivity, Sharpness, Snap, SpecificHeat, SurfaceTension, Temperature, ThermalConductivity, ThermalExpansion, ThermalResistance, Time, Torque, Velocity, Volume, VolumetricFlowRate ]); }; @@ -333,6 +363,13 @@ public interface IElectricChargeUnit : IUnit public interface IElectricConductanceUnit : IUnit { } +/// +/// Marker interface implemented by every unit of the ElectricConductivity dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface IElectricConductivityUnit : IUnit +{ } + /// /// Marker interface implemented by every unit of the ElectricCurrent dimension. /// Generated quantities use this to make In(...) dimensionally type-safe at compile time. @@ -347,6 +384,13 @@ public interface IElectricCurrentUnit : IUnit public interface IElectricFieldUnit : IUnit { } +/// +/// Marker interface implemented by every unit of the ElectricFlux dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface IElectricFluxUnit : IUnit +{ } + /// /// Marker interface implemented by every unit of the ElectricPotential dimension. /// Generated quantities use this to make In(...) dimensionally type-safe at compile time. @@ -354,6 +398,13 @@ public interface IElectricFieldUnit : IUnit public interface IElectricPotentialUnit : IUnit { } +/// +/// Marker interface implemented by every unit of the ElectricPowerDensity dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface IElectricPowerDensityUnit : IUnit +{ } + /// /// Marker interface implemented by every unit of the ElectricResistance dimension. /// Generated quantities use this to make In(...) dimensionally type-safe at compile time. @@ -452,6 +503,20 @@ public interface IKinematicViscosityUnit : IUnit public interface ILengthUnit : IUnit { } +/// +/// Marker interface implemented by every unit of the Loudness dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface ILoudnessUnit : IUnit +{ } + +/// +/// Marker interface implemented by every unit of the Luminance dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface ILuminanceUnit : IUnit +{ } + /// /// Marker interface implemented by every unit of the LuminousFlux dimension. /// Generated quantities use this to make In(...) dimensionally type-safe at compile time. @@ -536,6 +601,13 @@ public interface INuclearCrossSectionUnit : IUnit public interface IOpticalPowerUnit : IUnit { } +/// +/// Marker interface implemented by every unit of the Permittivity dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface IPermittivityUnit : IUnit +{ } + /// /// Marker interface implemented by every unit of the Power dimension. /// Generated quantities use this to make In(...) dimensionally type-safe at compile time. @@ -557,6 +629,13 @@ public interface IPressureUnit : IUnit public interface IRadioactiveActivityUnit : IUnit { } +/// +/// Marker interface implemented by every unit of the RateConstant dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface IRateConstantUnit : IUnit +{ } + /// /// Marker interface implemented by every unit of the ReactionRate dimension. /// Generated quantities use this to make In(...) dimensionally type-safe at compile time. @@ -564,6 +643,20 @@ public interface IRadioactiveActivityUnit : IUnit public interface IReactionRateUnit : IUnit { } +/// +/// Marker interface implemented by every unit of the Sensitivity dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface ISensitivityUnit : IUnit +{ } + +/// +/// Marker interface implemented by every unit of the Sharpness dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface ISharpnessUnit : IUnit +{ } + /// /// Marker interface implemented by every unit of the Snap dimension. /// Generated quantities use this to make In(...) dimensionally type-safe at compile time. @@ -606,6 +699,13 @@ public interface IThermalConductivityUnit : IUnit public interface IThermalExpansionUnit : IUnit { } +/// +/// Marker interface implemented by every unit of the ThermalResistance dimension. +/// Generated quantities use this to make In(...) dimensionally type-safe at compile time. +/// +public interface IThermalResistanceUnit : IUnit +{ } + /// /// Marker interface implemented by every unit of the Time dimension. /// Generated quantities use this to make In(...) dimensionally type-safe at compile time. diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Area.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Area.g.cs index 26ffd39..dc001a6 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Area.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Area.g.cs @@ -100,6 +100,10 @@ public record Area : PhysicalQuantity, T>, IVector0, T> /// Multiplies Area by Pressure to produce ForceMagnitude. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static ForceMagnitude operator *(Area left, Pressure right) => Multiply>(left, right); +/// + /// Multiplies Area by ElectricFieldMagnitude to produce ElectricFlux. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static ElectricFlux operator *(Area left, ElectricFieldMagnitude right) => Multiply>(left, right); /// /// Multiplies Area by Illuminance to produce LuminousFlux. /// @@ -112,5 +116,9 @@ public record Area : PhysicalQuantity, T>, IVector0, T> /// Multiplies Area by Irradiance to produce Power. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Power operator *(Area left, Irradiance right) => Multiply>(left, right); +/// + /// Multiplies Area by Luminance to produce LuminousIntensity. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static LuminousIntensity operator *(Area left, Luminance right) => Multiply>(left, right); }; diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Concentration.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Concentration.g.cs index 5f62773..ecddd5c 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Concentration.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Concentration.g.cs @@ -21,12 +21,19 @@ public record Concentration : PhysicalQuantity, T>, IVector0 public override DimensionInfo Dimension => PhysicalDimensions.Concentration; /// + /// Creates a new from a value in MolePerCubicMeter. + /// + /// The value in MolePerCubicMeter. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static Concentration FromMolePerCubicMeter(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// /// Creates a new from a value in Molar. /// /// The value in Molar. /// A new instance. /// Thrown when the resulting magnitude would be negative. - public static Concentration FromMolars(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); + public static Concentration FromMolars(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.MolarToCubicMeter)), nameof(value))); /// /// Creates a new from a value in Millimolar. /// diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricConductivity.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricConductivity.g.cs new file mode 100644 index 0000000..b62c221 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricConductivity.g.cs @@ -0,0 +1,43 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude (Vector0) quantity for the ElectricConductivity dimension. +/// +/// The numeric storage type. +public record ElectricConductivity : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static ElectricConductivity Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.ElectricConductivity; + + /// + /// Creates a new from a value in SiemensPerMeter. + /// + /// The value in SiemensPerMeter. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static ElectricConductivity FromSiemensPerMeter(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-ElectricConductivity unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IElectricConductivityUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two ElectricConductivity values, returning the absolute difference as a non-negative ElectricConductivity. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static ElectricConductivity operator -(ElectricConductivity left, ElectricConductivity right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricFieldMagnitude.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricFieldMagnitude.g.cs index 5f5dc4c..b343741 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricFieldMagnitude.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricFieldMagnitude.g.cs @@ -43,5 +43,9 @@ public record ElectricFieldMagnitude : PhysicalQuantity [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static VoltageMagnitude operator *(ElectricFieldMagnitude left, Length right) => Multiply>(left, right); +/// + /// Multiplies ElectricFieldMagnitude by Area to produce ElectricFlux. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static ElectricFlux operator *(ElectricFieldMagnitude left, Area right) => Multiply>(left, right); }; diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricFlux.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricFlux.g.cs new file mode 100644 index 0000000..1292f8c --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricFlux.g.cs @@ -0,0 +1,51 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude (Vector0) quantity for the ElectricFlux dimension. +/// +/// The numeric storage type. +public record ElectricFlux : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static ElectricFlux Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.ElectricFlux; + + /// + /// Creates a new from a value in VoltMeter. + /// + /// The value in VoltMeter. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static ElectricFlux FromVoltMeters(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-ElectricFlux unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IElectricFluxUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two ElectricFlux values, returning the absolute difference as a non-negative ElectricFlux. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static ElectricFlux operator -(ElectricFlux left, ElectricFlux right) => Create(T.Abs(left.Quantity - right.Quantity)); +/// + /// Divides ElectricFlux by Area to produce ElectricFieldMagnitude. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static ElectricFieldMagnitude operator /(ElectricFlux left, Area right) => Divide>(left, right); +/// + /// Divides ElectricFlux by ElectricFieldMagnitude to produce Area. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Area operator /(ElectricFlux left, ElectricFieldMagnitude right) => Divide>(left, right); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricPowerDensity.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricPowerDensity.g.cs new file mode 100644 index 0000000..ac86fd4 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricPowerDensity.g.cs @@ -0,0 +1,47 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude (Vector0) quantity for the ElectricPowerDensity dimension. +/// +/// The numeric storage type. +public record ElectricPowerDensity : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static ElectricPowerDensity Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.ElectricPowerDensity; + + /// + /// Creates a new from a value in WattPerCubicMeter. + /// + /// The value in WattPerCubicMeter. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static ElectricPowerDensity FromWattPerCubicMeter(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-ElectricPowerDensity unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IElectricPowerDensityUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two ElectricPowerDensity values, returning the absolute difference as a non-negative ElectricPowerDensity. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static ElectricPowerDensity operator -(ElectricPowerDensity left, ElectricPowerDensity right) => Create(T.Abs(left.Quantity - right.Quantity)); +/// + /// Multiplies ElectricPowerDensity by Volume to produce Power. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Power operator *(ElectricPowerDensity left, Volume right) => Multiply>(left, right); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Impedance.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Impedance.g.cs new file mode 100644 index 0000000..2b80fd1 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Impedance.g.cs @@ -0,0 +1,61 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude of total opposition to alternating current. +/// Semantic overload of . +/// +/// The numeric storage type. +public record Impedance : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static Impedance Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.ElectricResistance; + + /// + /// Creates a new Impedance from a value in Ohm. + /// + /// The value in Ohm. + /// A new Impedance instance. + /// Thrown when the resulting magnitude would be negative. + public static Impedance FromOhms(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new Impedance from a value in Kilohm. + /// + /// The value in Kilohm. + /// A new Impedance instance. + /// Thrown when the resulting magnitude would be negative. + public static Impedance FromKilohms(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(MetricMagnitudes.Kilo)), nameof(value))); +/// + /// Creates a new Impedance from a value in Megohm. + /// + /// The value in Megohm. + /// A new Impedance instance. + /// Thrown when the resulting magnitude would be negative. + public static Impedance FromMegohms(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(MetricMagnitudes.Mega)), nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-ElectricResistance unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IElectricResistanceUnit unit) => unit.FromBase(Value); +/// Implicit conversion to Resistance. + public static implicit operator Resistance(Impedance value) => Resistance.Create(value.Value); +/// Explicit conversion from Resistance. + public static explicit operator Impedance(Resistance value) => Create(value.Value); +/// Creates a Impedance from a Resistance value. + public static Impedance From(Resistance value) => Create(value.Value); +/// Subtracts two Impedance values, returning the absolute difference as a non-negative Impedance. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Impedance operator -(Impedance left, Impedance right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Loudness.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Loudness.g.cs new file mode 100644 index 0000000..4b98a8e --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Loudness.g.cs @@ -0,0 +1,43 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude (Vector0) quantity for the Loudness dimension. +/// +/// The numeric storage type. +public record Loudness : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static Loudness Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Loudness; + + /// + /// Creates a new from a value in Sone. + /// + /// The value in Sone. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static Loudness FromSones(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Loudness unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.ILoudnessUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two Loudness values, returning the absolute difference as a non-negative Loudness. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Loudness operator -(Loudness left, Loudness right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Luminance.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Luminance.g.cs index 0d23b64..c1c022f 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Luminance.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Luminance.g.cs @@ -8,8 +8,7 @@ namespace ktsu.Semantics.Quantities; using System.Numerics; /// -/// Luminous intensity per unit area of a surface. -/// Semantic overload of . +/// Magnitude (Vector0) quantity for the Luminance dimension. /// /// The numeric storage type. public record Luminance : PhysicalQuantity, T>, IVector0, T> @@ -19,36 +18,44 @@ public record Luminance : PhysicalQuantity, T>, IVector0 Zero => Create(T.Zero); /// Gets the physical dimension this quantity belongs to. - public override DimensionInfo Dimension => PhysicalDimensions.Illuminance; + public override DimensionInfo Dimension => PhysicalDimensions.Luminance; /// - /// Creates a new Luminance from a value in Lux. + /// Creates a new from a value in CandelaPerSquareMeter. /// - /// The value in Lux. - /// A new Luminance instance. + /// The value in CandelaPerSquareMeter. + /// A new instance. /// Thrown when the resulting magnitude would be negative. - public static Luminance FromLux(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); + public static Luminance FromCandelaPerSquareMeter(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); /// - /// Creates a new Luminance from a value in FootCandle. + /// Creates a new from a value in Nit. /// - /// The value in FootCandle. - /// A new Luminance instance. + /// The value in Nit. + /// A new instance. /// Thrown when the resulting magnitude would be negative. - public static Luminance FromFootCandles(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.FootCandleToLux)), nameof(value))); + public static Luminance FromNits(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new from a value in FootLambert. + /// + /// The value in FootLambert. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static Luminance FromFootLamberts(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.FootLambertToCandelaPerSquareMeter)), nameof(value))); /// /// Converts this quantity's SI-base value to the value in . - /// Cross-dimension calls (e.g. passing a non-Illuminance unit) fail at compile time. + /// Cross-dimension calls (e.g. passing a non-Luminance unit) fail at compile time. /// /// The dimensionally-compatible target unit. /// The value expressed in . - public T In(global::ktsu.Semantics.Quantities.IIlluminanceUnit unit) => unit.FromBase(Value); -/// Implicit conversion to Illuminance. - public static implicit operator Illuminance(Luminance value) => Illuminance.Create(value.Value); -/// Explicit conversion from Illuminance. - public static explicit operator Luminance(Illuminance value) => Create(value.Value); -/// Creates a Luminance from a Illuminance value. - public static Luminance From(Illuminance value) => Create(value.Value); -/// Subtracts two Luminance values, returning the absolute difference as a non-negative Luminance. + public T In(global::ktsu.Semantics.Quantities.ILuminanceUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two Luminance values, returning the absolute difference as a non-negative Luminance. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Luminance operator -(Luminance left, Luminance right) => Create(T.Abs(left.Quantity - right.Quantity)); +/// + /// Multiplies Luminance by Area to produce LuminousIntensity. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static LuminousIntensity operator *(Luminance left, Area right) => Multiply>(left, right); }; diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/LuminousIntensity.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/LuminousIntensity.g.cs index e3819fc..a85a00a 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/LuminousIntensity.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/LuminousIntensity.g.cs @@ -46,5 +46,13 @@ public record LuminousIntensity : PhysicalQuantity, T>, /// Magnitude subtraction stays a magnitude (per the unified-vector model). /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static LuminousIntensity operator -(LuminousIntensity left, LuminousIntensity right) => Create(T.Abs(left.Quantity - right.Quantity)); +/// + /// Divides LuminousIntensity by Area to produce Luminance. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Luminance operator /(LuminousIntensity left, Area right) => Divide>(left, right); +/// + /// Divides LuminousIntensity by Luminance to produce Area. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Area operator /(LuminousIntensity left, Luminance right) => Divide>(left, right); }; diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/NoiseReductionCoefficient.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/NoiseReductionCoefficient.g.cs new file mode 100644 index 0000000..db4bf03 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/NoiseReductionCoefficient.g.cs @@ -0,0 +1,103 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Average sound absorption across standard frequencies. +/// Semantic overload of . +/// +/// The numeric storage type. +public record NoiseReductionCoefficient : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static NoiseReductionCoefficient Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Dimensionless; + + /// + /// Creates a new NoiseReductionCoefficient from a value in Dimensionless. + /// + /// The value in Dimensionless. + /// A new NoiseReductionCoefficient instance. + /// Thrown when the resulting magnitude would be negative. + public static NoiseReductionCoefficient FromDimensionless(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new NoiseReductionCoefficient from a value in Radian. + /// + /// The value in Radian. + /// A new NoiseReductionCoefficient instance. + /// Thrown when the resulting magnitude would be negative. + public static NoiseReductionCoefficient FromRadians(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new NoiseReductionCoefficient from a value in Degree. + /// + /// The value in Degree. + /// A new NoiseReductionCoefficient instance. + /// Thrown when the resulting magnitude would be negative. + public static NoiseReductionCoefficient FromDegrees(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.DegreeToRadians)), nameof(value))); +/// + /// Creates a new NoiseReductionCoefficient from a value in Gradian. + /// + /// The value in Gradian. + /// A new NoiseReductionCoefficient instance. + /// Thrown when the resulting magnitude would be negative. + public static NoiseReductionCoefficient FromGradians(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.GradianToRadians)), nameof(value))); +/// + /// Creates a new NoiseReductionCoefficient from a value in Revolution. + /// + /// The value in Revolution. + /// A new NoiseReductionCoefficient instance. + /// Thrown when the resulting magnitude would be negative. + public static NoiseReductionCoefficient FromRevolutions(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.RevolutionToRadians)), nameof(value))); +/// + /// Creates a new NoiseReductionCoefficient from a value in Milliradian. + /// + /// The value in Milliradian. + /// A new NoiseReductionCoefficient instance. + /// Thrown when the resulting magnitude would be negative. + public static NoiseReductionCoefficient FromMilliradians(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(MetricMagnitudes.Milli)), nameof(value))); +/// + /// Creates a new NoiseReductionCoefficient from a value in PartsPerMillion. + /// + /// The value in PartsPerMillion. + /// A new NoiseReductionCoefficient instance. + /// Thrown when the resulting magnitude would be negative. + public static NoiseReductionCoefficient FromPartsPerMillion(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PartsPerMillionToRatio)), nameof(value))); +/// + /// Creates a new NoiseReductionCoefficient from a value in PartsPerBillion. + /// + /// The value in PartsPerBillion. + /// A new NoiseReductionCoefficient instance. + /// Thrown when the resulting magnitude would be negative. + public static NoiseReductionCoefficient FromPartsPerBillion(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PartsPerBillionToRatio)), nameof(value))); +/// + /// Creates a new NoiseReductionCoefficient from a value in PercentByWeight. + /// + /// The value in PercentByWeight. + /// A new NoiseReductionCoefficient instance. + /// Thrown when the resulting magnitude would be negative. + public static NoiseReductionCoefficient FromPercentByWeight(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PercentByWeightToRatio)), nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Dimensionless unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IDimensionlessUnit unit) => unit.FromBase(Value); +/// Implicit conversion to Ratio. + public static implicit operator Ratio(NoiseReductionCoefficient value) => Ratio.Create(value.Value); +/// Explicit conversion from Ratio. + public static explicit operator NoiseReductionCoefficient(Ratio value) => Create(value.Value); +/// Creates a NoiseReductionCoefficient from a Ratio value. + public static NoiseReductionCoefficient From(Ratio value) => Create(value.Value); +/// Subtracts two NoiseReductionCoefficient values, returning the absolute difference as a non-negative NoiseReductionCoefficient. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static NoiseReductionCoefficient operator -(NoiseReductionCoefficient left, NoiseReductionCoefficient right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/NuclearCrossSection.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/NuclearCrossSection.g.cs index 4db3f1f..30fc38c 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/NuclearCrossSection.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/NuclearCrossSection.g.cs @@ -21,12 +21,19 @@ public record NuclearCrossSection : PhysicalQuantity, public override DimensionInfo Dimension => PhysicalDimensions.NuclearCrossSection; /// + /// Creates a new from a value in SquareMeter. + /// + /// The value in SquareMeter. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static NuclearCrossSection FromSquareMeters(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// /// Creates a new from a value in Barn. /// /// The value in Barn. /// A new instance. /// Thrown when the resulting magnitude would be negative. - public static NuclearCrossSection FromBarns(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); + public static NuclearCrossSection FromBarns(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.BarnToSquareMeters)), nameof(value))); /// /// Converts this quantity's SI-base value to the value in . /// Cross-dimension calls (e.g. passing a non-NuclearCrossSection unit) fail at compile time. diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Permittivity.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Permittivity.g.cs new file mode 100644 index 0000000..0c4014e --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Permittivity.g.cs @@ -0,0 +1,43 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude (Vector0) quantity for the Permittivity dimension. +/// +/// The numeric storage type. +public record Permittivity : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static Permittivity Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Permittivity; + + /// + /// Creates a new from a value in FaradPerMeter. + /// + /// The value in FaradPerMeter. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static Permittivity FromFaradPerMeter(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Permittivity unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IPermittivityUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two Permittivity values, returning the absolute difference as a non-negative Permittivity. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Permittivity operator -(Permittivity left, Permittivity right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Power.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Power.g.cs index 3529e5d..938ab92 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Power.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Power.g.cs @@ -88,5 +88,13 @@ public record Power : PhysicalQuantity, T>, IVector0, T> /// Divides Power by Irradiance to produce Area. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Area operator /(Power left, Irradiance right) => Divide>(left, right); +/// + /// Divides Power by Volume to produce ElectricPowerDensity. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static ElectricPowerDensity operator /(Power left, Volume right) => Divide>(left, right); +/// + /// Divides Power by ElectricPowerDensity to produce Volume. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Volume operator /(Power left, ElectricPowerDensity right) => Divide>(left, right); }; diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Pressure.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Pressure.g.cs index 817010c..7aacaf0 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Pressure.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Pressure.g.cs @@ -82,5 +82,9 @@ public record Pressure : PhysicalQuantity, T>, IVector0 [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Energy operator *(Pressure left, Volume right) => Multiply>(left, right); +/// + /// Multiplies Pressure by Sensitivity to produce VoltageMagnitude. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static VoltageMagnitude operator *(Pressure left, Sensitivity right) => Multiply>(left, right); }; diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/RateConstant.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/RateConstant.g.cs new file mode 100644 index 0000000..f0544a7 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/RateConstant.g.cs @@ -0,0 +1,43 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude (Vector0) quantity for the RateConstant dimension. +/// +/// The numeric storage type. +public record RateConstant : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static RateConstant Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.RateConstant; + + /// + /// Creates a new from a value in PerSecond. + /// + /// The value in PerSecond. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static RateConstant FromPerSecond(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-RateConstant unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IRateConstantUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two RateConstant values, returning the absolute difference as a non-negative RateConstant. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static RateConstant operator -(RateConstant left, RateConstant right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ReflectionCoefficient.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ReflectionCoefficient.g.cs new file mode 100644 index 0000000..5ca1028 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ReflectionCoefficient.g.cs @@ -0,0 +1,92 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Signed ratio of reflected to incident wave amplitude. +/// Semantic overload of . +/// +/// The numeric storage type. +public record ReflectionCoefficient : PhysicalQuantity, T>, IVector1, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static ReflectionCoefficient Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Dimensionless; + + /// + /// Creates a new ReflectionCoefficient from a value in Dimensionless. + /// + /// The value in Dimensionless. + /// A new ReflectionCoefficient instance. + public static ReflectionCoefficient FromDimensionless(T value) => Create(value); +/// + /// Creates a new ReflectionCoefficient from a value in Radian. + /// + /// The value in Radian. + /// A new ReflectionCoefficient instance. + public static ReflectionCoefficient FromRadians(T value) => Create(value); +/// + /// Creates a new ReflectionCoefficient from a value in Degree. + /// + /// The value in Degree. + /// A new ReflectionCoefficient instance. + public static ReflectionCoefficient FromDegrees(T value) => Create((value * T.CreateChecked(Units.ConversionConstants.DegreeToRadians))); +/// + /// Creates a new ReflectionCoefficient from a value in Gradian. + /// + /// The value in Gradian. + /// A new ReflectionCoefficient instance. + public static ReflectionCoefficient FromGradians(T value) => Create((value * T.CreateChecked(Units.ConversionConstants.GradianToRadians))); +/// + /// Creates a new ReflectionCoefficient from a value in Revolution. + /// + /// The value in Revolution. + /// A new ReflectionCoefficient instance. + public static ReflectionCoefficient FromRevolutions(T value) => Create((value * T.CreateChecked(Units.ConversionConstants.RevolutionToRadians))); +/// + /// Creates a new ReflectionCoefficient from a value in Milliradian. + /// + /// The value in Milliradian. + /// A new ReflectionCoefficient instance. + public static ReflectionCoefficient FromMilliradians(T value) => Create((value * T.CreateChecked(MetricMagnitudes.Milli))); +/// + /// Creates a new ReflectionCoefficient from a value in PartsPerMillion. + /// + /// The value in PartsPerMillion. + /// A new ReflectionCoefficient instance. + public static ReflectionCoefficient FromPartsPerMillion(T value) => Create((value * T.CreateChecked(Units.ConversionConstants.PartsPerMillionToRatio))); +/// + /// Creates a new ReflectionCoefficient from a value in PartsPerBillion. + /// + /// The value in PartsPerBillion. + /// A new ReflectionCoefficient instance. + public static ReflectionCoefficient FromPartsPerBillion(T value) => Create((value * T.CreateChecked(Units.ConversionConstants.PartsPerBillionToRatio))); +/// + /// Creates a new ReflectionCoefficient from a value in PercentByWeight. + /// + /// The value in PercentByWeight. + /// A new ReflectionCoefficient instance. + public static ReflectionCoefficient FromPercentByWeight(T value) => Create((value * T.CreateChecked(Units.ConversionConstants.PercentByWeightToRatio))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Dimensionless unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IDimensionlessUnit unit) => unit.FromBase(Value); +/// Implicit conversion to SignedRatio. + public static implicit operator SignedRatio(ReflectionCoefficient value) => SignedRatio.Create(value.Value); +/// Explicit conversion from SignedRatio. + public static explicit operator ReflectionCoefficient(SignedRatio value) => Create(value.Value); +/// Creates a ReflectionCoefficient from a SignedRatio value. + public static ReflectionCoefficient From(SignedRatio value) => Create(value.Value); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Sensitivity.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Sensitivity.g.cs new file mode 100644 index 0000000..cfa256a --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Sensitivity.g.cs @@ -0,0 +1,47 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude (Vector0) quantity for the Sensitivity dimension. +/// +/// The numeric storage type. +public record Sensitivity : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static Sensitivity Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Sensitivity; + + /// + /// Creates a new from a value in VoltPerPascal. + /// + /// The value in VoltPerPascal. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static Sensitivity FromVoltPerPascal(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Sensitivity unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.ISensitivityUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two Sensitivity values, returning the absolute difference as a non-negative Sensitivity. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Sensitivity operator -(Sensitivity left, Sensitivity right) => Create(T.Abs(left.Quantity - right.Quantity)); +/// + /// Multiplies Sensitivity by Pressure to produce VoltageMagnitude. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static VoltageMagnitude operator *(Sensitivity left, Pressure right) => Multiply>(left, right); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Sharpness.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Sharpness.g.cs new file mode 100644 index 0000000..ba4526b --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Sharpness.g.cs @@ -0,0 +1,43 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude (Vector0) quantity for the Sharpness dimension. +/// +/// The numeric storage type. +public record Sharpness : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static Sharpness Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Sharpness; + + /// + /// Creates a new from a value in Acum. + /// + /// The value in Acum. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static Sharpness FromAcum(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Sharpness unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.ISharpnessUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two Sharpness values, returning the absolute difference as a non-negative Sharpness. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Sharpness operator -(Sharpness left, Sharpness right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundAbsorption.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundAbsorption.g.cs new file mode 100644 index 0000000..79f7062 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundAbsorption.g.cs @@ -0,0 +1,103 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Fraction of incident sound energy absorbed by a surface. +/// Semantic overload of . +/// +/// The numeric storage type. +public record SoundAbsorption : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static SoundAbsorption Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Dimensionless; + + /// + /// Creates a new SoundAbsorption from a value in Dimensionless. + /// + /// The value in Dimensionless. + /// A new SoundAbsorption instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundAbsorption FromDimensionless(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new SoundAbsorption from a value in Radian. + /// + /// The value in Radian. + /// A new SoundAbsorption instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundAbsorption FromRadians(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new SoundAbsorption from a value in Degree. + /// + /// The value in Degree. + /// A new SoundAbsorption instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundAbsorption FromDegrees(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.DegreeToRadians)), nameof(value))); +/// + /// Creates a new SoundAbsorption from a value in Gradian. + /// + /// The value in Gradian. + /// A new SoundAbsorption instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundAbsorption FromGradians(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.GradianToRadians)), nameof(value))); +/// + /// Creates a new SoundAbsorption from a value in Revolution. + /// + /// The value in Revolution. + /// A new SoundAbsorption instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundAbsorption FromRevolutions(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.RevolutionToRadians)), nameof(value))); +/// + /// Creates a new SoundAbsorption from a value in Milliradian. + /// + /// The value in Milliradian. + /// A new SoundAbsorption instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundAbsorption FromMilliradians(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(MetricMagnitudes.Milli)), nameof(value))); +/// + /// Creates a new SoundAbsorption from a value in PartsPerMillion. + /// + /// The value in PartsPerMillion. + /// A new SoundAbsorption instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundAbsorption FromPartsPerMillion(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PartsPerMillionToRatio)), nameof(value))); +/// + /// Creates a new SoundAbsorption from a value in PartsPerBillion. + /// + /// The value in PartsPerBillion. + /// A new SoundAbsorption instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundAbsorption FromPartsPerBillion(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PartsPerBillionToRatio)), nameof(value))); +/// + /// Creates a new SoundAbsorption from a value in PercentByWeight. + /// + /// The value in PercentByWeight. + /// A new SoundAbsorption instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundAbsorption FromPercentByWeight(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PercentByWeightToRatio)), nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Dimensionless unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IDimensionlessUnit unit) => unit.FromBase(Value); +/// Implicit conversion to Ratio. + public static implicit operator Ratio(SoundAbsorption value) => Ratio.Create(value.Value); +/// Explicit conversion from Ratio. + public static explicit operator SoundAbsorption(Ratio value) => Create(value.Value); +/// Creates a SoundAbsorption from a Ratio value. + public static SoundAbsorption From(Ratio value) => Create(value.Value); +/// Subtracts two SoundAbsorption values, returning the absolute difference as a non-negative SoundAbsorption. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static SoundAbsorption operator -(SoundAbsorption left, SoundAbsorption right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundPower.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundPower.g.cs new file mode 100644 index 0000000..d7fc56b --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundPower.g.cs @@ -0,0 +1,68 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Acoustic energy emitted by a source per unit time. +/// Semantic overload of . +/// +/// The numeric storage type. +public record SoundPower : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static SoundPower Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Power; + + /// + /// Creates a new SoundPower from a value in Watt. + /// + /// The value in Watt. + /// A new SoundPower instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPower FromWatts(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new SoundPower from a value in Kilowatt. + /// + /// The value in Kilowatt. + /// A new SoundPower instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPower FromKilowatts(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(MetricMagnitudes.Kilo)), nameof(value))); +/// + /// Creates a new SoundPower from a value in Megawatt. + /// + /// The value in Megawatt. + /// A new SoundPower instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPower FromMegawatts(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(MetricMagnitudes.Mega)), nameof(value))); +/// + /// Creates a new SoundPower from a value in Horsepower. + /// + /// The value in Horsepower. + /// A new SoundPower instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPower FromHorsepower(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.HorsepowerToWatts)), nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Power unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IPowerUnit unit) => unit.FromBase(Value); +/// Implicit conversion to Power. + public static implicit operator Power(SoundPower value) => Power.Create(value.Value); +/// Explicit conversion from Power. + public static explicit operator SoundPower(Power value) => Create(value.Value); +/// Creates a SoundPower from a Power value. + public static SoundPower From(Power value) => Create(value.Value); +/// Subtracts two SoundPower values, returning the absolute difference as a non-negative SoundPower. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static SoundPower operator -(SoundPower left, SoundPower right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundPressure.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundPressure.g.cs new file mode 100644 index 0000000..a9c5af9 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundPressure.g.cs @@ -0,0 +1,82 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// RMS pressure deviation caused by a sound wave. +/// Semantic overload of . +/// +/// The numeric storage type. +public record SoundPressure : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static SoundPressure Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Pressure; + + /// + /// Creates a new SoundPressure from a value in Pascal. + /// + /// The value in Pascal. + /// A new SoundPressure instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPressure FromPascals(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new SoundPressure from a value in Kilopascal. + /// + /// The value in Kilopascal. + /// A new SoundPressure instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPressure FromKilopascals(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(MetricMagnitudes.Kilo)), nameof(value))); +/// + /// Creates a new SoundPressure from a value in Bar. + /// + /// The value in Bar. + /// A new SoundPressure instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPressure FromBars(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.BarToPascals)), nameof(value))); +/// + /// Creates a new SoundPressure from a value in Atmosphere. + /// + /// The value in Atmosphere. + /// A new SoundPressure instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPressure FromAtmospheres(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.AtmosphereToPascals)), nameof(value))); +/// + /// Creates a new SoundPressure from a value in Psi. + /// + /// The value in Psi. + /// A new SoundPressure instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPressure FromPsi(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PsiToPascals)), nameof(value))); +/// + /// Creates a new SoundPressure from a value in Torr. + /// + /// The value in Torr. + /// A new SoundPressure instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundPressure FromTorr(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.TorrToPascals)), nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Pressure unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IPressureUnit unit) => unit.FromBase(Value); +/// Implicit conversion to Pressure. + public static implicit operator Pressure(SoundPressure value) => Pressure.Create(value.Value); +/// Explicit conversion from Pressure. + public static explicit operator SoundPressure(Pressure value) => Create(value.Value); +/// Creates a SoundPressure from a Pressure value. + public static SoundPressure From(Pressure value) => Create(value.Value); +/// Subtracts two SoundPressure values, returning the absolute difference as a non-negative SoundPressure. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static SoundPressure operator -(SoundPressure left, SoundPressure right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundTransmissionClass.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundTransmissionClass.g.cs new file mode 100644 index 0000000..6fd2b42 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SoundTransmissionClass.g.cs @@ -0,0 +1,103 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Single-number rating of airborne sound insulation. +/// Semantic overload of . +/// +/// The numeric storage type. +public record SoundTransmissionClass : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static SoundTransmissionClass Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.Dimensionless; + + /// + /// Creates a new SoundTransmissionClass from a value in Dimensionless. + /// + /// The value in Dimensionless. + /// A new SoundTransmissionClass instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundTransmissionClass FromDimensionless(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new SoundTransmissionClass from a value in Radian. + /// + /// The value in Radian. + /// A new SoundTransmissionClass instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundTransmissionClass FromRadians(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Creates a new SoundTransmissionClass from a value in Degree. + /// + /// The value in Degree. + /// A new SoundTransmissionClass instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundTransmissionClass FromDegrees(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.DegreeToRadians)), nameof(value))); +/// + /// Creates a new SoundTransmissionClass from a value in Gradian. + /// + /// The value in Gradian. + /// A new SoundTransmissionClass instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundTransmissionClass FromGradians(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.GradianToRadians)), nameof(value))); +/// + /// Creates a new SoundTransmissionClass from a value in Revolution. + /// + /// The value in Revolution. + /// A new SoundTransmissionClass instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundTransmissionClass FromRevolutions(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.RevolutionToRadians)), nameof(value))); +/// + /// Creates a new SoundTransmissionClass from a value in Milliradian. + /// + /// The value in Milliradian. + /// A new SoundTransmissionClass instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundTransmissionClass FromMilliradians(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(MetricMagnitudes.Milli)), nameof(value))); +/// + /// Creates a new SoundTransmissionClass from a value in PartsPerMillion. + /// + /// The value in PartsPerMillion. + /// A new SoundTransmissionClass instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundTransmissionClass FromPartsPerMillion(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PartsPerMillionToRatio)), nameof(value))); +/// + /// Creates a new SoundTransmissionClass from a value in PartsPerBillion. + /// + /// The value in PartsPerBillion. + /// A new SoundTransmissionClass instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundTransmissionClass FromPartsPerBillion(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PartsPerBillionToRatio)), nameof(value))); +/// + /// Creates a new SoundTransmissionClass from a value in PercentByWeight. + /// + /// The value in PercentByWeight. + /// A new SoundTransmissionClass instance. + /// Thrown when the resulting magnitude would be negative. + public static SoundTransmissionClass FromPercentByWeight(T value) => Create(Vector0Guards.EnsureNonNegative((value * T.CreateChecked(Units.ConversionConstants.PercentByWeightToRatio)), nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-Dimensionless unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IDimensionlessUnit unit) => unit.FromBase(Value); +/// Implicit conversion to Ratio. + public static implicit operator Ratio(SoundTransmissionClass value) => Ratio.Create(value.Value); +/// Explicit conversion from Ratio. + public static explicit operator SoundTransmissionClass(Ratio value) => Create(value.Value); +/// Creates a SoundTransmissionClass from a Ratio value. + public static SoundTransmissionClass From(Ratio value) => Create(value.Value); +/// Subtracts two SoundTransmissionClass values, returning the absolute difference as a non-negative SoundTransmissionClass. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static SoundTransmissionClass operator -(SoundTransmissionClass left, SoundTransmissionClass right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ThermalResistance.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ThermalResistance.g.cs new file mode 100644 index 0000000..35e0753 --- /dev/null +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ThermalResistance.g.cs @@ -0,0 +1,43 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. +// + +namespace ktsu.Semantics.Quantities; + +using System.Numerics; + +/// +/// Magnitude (Vector0) quantity for the ThermalResistance dimension. +/// +/// The numeric storage type. +public record ThermalResistance : PhysicalQuantity, T>, IVector0, T> + where T : struct, INumber +{ + /// Gets a quantity with value zero. + public static ThermalResistance Zero => Create(T.Zero); + + /// Gets the physical dimension this quantity belongs to. + public override DimensionInfo Dimension => PhysicalDimensions.ThermalResistance; + + /// + /// Creates a new from a value in KelvinPerWatt. + /// + /// The value in KelvinPerWatt. + /// A new instance. + /// Thrown when the resulting magnitude would be negative. + public static ThermalResistance FromKelvinPerWatt(T value) => Create(Vector0Guards.EnsureNonNegative(value, nameof(value))); +/// + /// Converts this quantity's SI-base value to the value in . + /// Cross-dimension calls (e.g. passing a non-ThermalResistance unit) fail at compile time. + /// + /// The dimensionally-compatible target unit. + /// The value expressed in . + public T In(global::ktsu.Semantics.Quantities.IThermalResistanceUnit unit) => unit.FromBase(Value); +/// + /// Subtracts two ThermalResistance values, returning the absolute difference as a non-negative ThermalResistance. + /// Magnitude subtraction stays a magnitude (per the unified-vector model). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static ThermalResistance operator -(ThermalResistance left, ThermalResistance right) => Create(T.Abs(left.Quantity - right.Quantity)); +}; + diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/VoltageMagnitude.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/VoltageMagnitude.g.cs index 1d72803..f8bea7b 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/VoltageMagnitude.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/VoltageMagnitude.g.cs @@ -78,5 +78,13 @@ public record VoltageMagnitude : PhysicalQuantity, T>, IV /// Multiplies VoltageMagnitude by Duration to produce MagneticFlux. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static MagneticFlux operator *(VoltageMagnitude left, Duration right) => Multiply>(left, right); +/// + /// Divides VoltageMagnitude by Pressure to produce Sensitivity. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Sensitivity operator /(VoltageMagnitude left, Pressure right) => Divide>(left, right); +/// + /// Divides VoltageMagnitude by Sensitivity to produce Pressure. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Pressure operator /(VoltageMagnitude left, Sensitivity right) => Divide>(left, right); }; diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Volume.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Volume.g.cs index a24b676..68993ff 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Volume.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Volume.g.cs @@ -137,5 +137,9 @@ public record Volume : PhysicalQuantity, T>, IVector0, T> /// Divides Volume by VolumetricFlowRate to produce Duration. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Duration operator /(Volume left, VolumetricFlowRate right) => Divide>(left, right); +/// + /// Multiplies Volume by ElectricPowerDensity to produce Power. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Physics quantity operator")] public static Power operator *(Volume left, ElectricPowerDensity right) => Multiply>(left, right); }; diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.UnitsGenerator/Units.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.UnitsGenerator/Units.g.cs index 468f47c..0009632 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.UnitsGenerator/Units.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.UnitsGenerator/Units.g.cs @@ -655,7 +655,7 @@ public Microsecond() { } /// /// Square meter - SI derived unit of area. /// -public sealed record SquareMeter : IUnit, IAreaUnit +public sealed record SquareMeter : IUnit, IAreaUnit, INuclearCrossSectionUnit { /// Gets the full name of the unit. public string Name => "SquareMeter"; @@ -2640,6 +2640,34 @@ public Megawatt() { } }; +/// +/// Watt per cubic meter - SI unit of volumetric power density. +/// +public sealed record WattPerCubicMeter : IUnit, IElectricPowerDensityUnit +{ + /// Gets the full name of the unit. + public string Name => "WattPerCubicMeter"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "W/m³"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.ElectricPowerDensity; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public WattPerCubicMeter() { } + +}; + /// /// Kelvin - SI base unit of thermodynamic temperature. /// @@ -2892,6 +2920,34 @@ public Rankine() { } }; +/// +/// Kelvin per watt - SI unit of absolute thermal resistance. +/// +public sealed record KelvinPerWatt : IUnit, IThermalResistanceUnit +{ + /// Gets the full name of the unit. + public string Name => "KelvinPerWatt"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "K/W"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.ThermalResistance; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public KelvinPerWatt() { } + +}; + /// /// Ampere - SI base unit of electric current. /// @@ -3452,6 +3508,118 @@ public AmpereHour() { } }; +/// +/// Volt meter - SI unit of electric flux. +/// +public sealed record VoltMeter : IUnit, IElectricFluxUnit +{ + /// Gets the full name of the unit. + public string Name => "VoltMeter"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "V·m"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.ElectricFlux; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public VoltMeter() { } + +}; + +/// +/// Farad per meter - SI unit of permittivity. +/// +public sealed record FaradPerMeter : IUnit, IPermittivityUnit +{ + /// Gets the full name of the unit. + public string Name => "FaradPerMeter"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "F/m"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.Permittivity; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public FaradPerMeter() { } + +}; + +/// +/// Siemens per meter - SI unit of electrical conductivity. +/// +public sealed record SiemensPerMeter : IUnit, IElectricConductivityUnit +{ + /// Gets the full name of the unit. + public string Name => "SiemensPerMeter"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "S/m"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.ElectricConductivity; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public SiemensPerMeter() { } + +}; + +/// +/// Volt per pascal - SI unit of transducer sensitivity. +/// +public sealed record VoltPerPascal : IUnit, ISensitivityUnit +{ + /// Gets the full name of the unit. + public string Name => "VoltPerPascal"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "V/Pa"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.Sensitivity; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public VoltPerPascal() { } + +}; + /// /// Radians per second - SI derived unit of angular velocity. /// @@ -3648,6 +3816,62 @@ public Megahertz() { } }; +/// +/// Sone - psychoacoustic unit of perceived loudness. +/// +public sealed record Sone : IUnit, ILoudnessUnit +{ + /// Gets the full name of the unit. + public string Name => "Sone"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "sone"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.Other; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.Loudness; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public Sone() { } + +}; + +/// +/// Acum - psychoacoustic unit of perceived sharpness. +/// +public sealed record Acum : IUnit, ISharpnessUnit +{ + /// Gets the full name of the unit. + public string Name => "Acum"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "acum"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.Other; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.Sharpness; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public Acum() { } + +}; + /// /// Candela - SI base unit of luminous intensity. /// @@ -3816,6 +4040,90 @@ public FootCandle() { } }; +/// +/// Candela per square meter - SI unit of luminance. +/// +public sealed record CandelaPerSquareMeter : IUnit, ILuminanceUnit +{ + /// Gets the full name of the unit. + public string Name => "CandelaPerSquareMeter"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "cd/m²"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.Luminance; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public CandelaPerSquareMeter() { } + +}; + +/// +/// Nit - common name for one candela per square meter. +/// +public sealed record Nit : IUnit, ILuminanceUnit +{ + /// Gets the full name of the unit. + public string Name => "Nit"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "nt"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.Luminance; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public Nit() { } + +}; + +/// +/// Foot-lambert - Imperial unit of luminance (1/π candela per square foot). +/// +public sealed record FootLambert : IUnit, ILuminanceUnit +{ + /// Gets the full name of the unit. + public string Name => "FootLambert"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "fL"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.Imperial; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.Luminance; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => FootLambertToCandelaPerSquareMeter; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public FootLambert() { } + +}; + /// /// Becquerel - SI derived unit of radioactive activity. /// @@ -4180,6 +4488,34 @@ public Mole() { } }; +/// +/// Mole per cubic meter - SI base unit of concentration. +/// +public sealed record MolePerCubicMeter : IUnit, IConcentrationUnit +{ + /// Gets the full name of the unit. + public string Name => "MolePerCubicMeter"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "mol/m³"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.Concentration; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public MolePerCubicMeter() { } + +}; + /// /// Molar - Moles per liter concentration. /// @@ -4852,6 +5188,34 @@ public Dalton() { } }; +/// +/// Per second - SI unit of a first-order rate constant. +/// +public sealed record PerSecond : IUnit, IRateConstantUnit +{ + /// Gets the full name of the unit. + public string Name => "PerSecond"; + + /// Gets the symbol/abbreviation of the unit. + public string Symbol => "s⁻¹"; + + /// Gets the unit system this unit belongs to. + public UnitSystem System => UnitSystem.SIDerived; + + /// Gets the physical dimension this unit measures. + public DimensionInfo Dimension => PhysicalDimensions.RateConstant; + + /// Gets the multiplication factor used in the to-base affine conversion. + public double ToBaseFactor => 1d; + + /// Gets the additive offset used in the to-base affine conversion. + public double ToBaseOffset => 0d; + + /// Initializes a new instance of the unit. + public PerSecond() { } + +}; + /// /// Watt per square meter - SI derived unit of irradiance and sound intensity. /// @@ -4916,6 +5280,9 @@ public static class Units{ /// Singleton Acre instance. public static readonly Acre Acre = new Acre(); + /// Singleton Acum instance. + public static readonly Acum Acum = new Acum(); + /// Singleton Ampere instance. public static readonly Ampere Ampere = new Ampere(); @@ -4952,6 +5319,9 @@ public static class Units{ /// Singleton Candela instance. public static readonly Candela Candela = new Candela(); + /// Singleton CandelaPerSquareMeter instance. + public static readonly CandelaPerSquareMeter CandelaPerSquareMeter = new CandelaPerSquareMeter(); + /// Singleton Celsius instance. public static readonly Celsius Celsius = new Celsius(); @@ -5021,6 +5391,9 @@ public static class Units{ /// Singleton Farad instance. public static readonly Farad Farad = new Farad(); + /// Singleton FaradPerMeter instance. + public static readonly FaradPerMeter FaradPerMeter = new FaradPerMeter(); + /// Singleton FeetPerSecond instance. public static readonly FeetPerSecond FeetPerSecond = new FeetPerSecond(); @@ -5030,6 +5403,9 @@ public static class Units{ /// Singleton FootCandle instance. public static readonly FootCandle FootCandle = new FootCandle(); + /// Singleton FootLambert instance. + public static readonly FootLambert FootLambert = new FootLambert(); + /// Singleton Gallon instance. public static readonly Gallon Gallon = new Gallon(); @@ -5093,6 +5469,9 @@ public static class Units{ /// Singleton Kelvin instance. public static readonly Kelvin Kelvin = new Kelvin(); + /// Singleton KelvinPerWatt instance. + public static readonly KelvinPerWatt KelvinPerWatt = new KelvinPerWatt(); + /// Singleton Kiloampere instance. public static readonly Kiloampere Kiloampere = new Kiloampere(); @@ -5243,6 +5622,9 @@ public static class Units{ /// Singleton Mole instance. public static readonly Mole Mole = new Mole(); + /// Singleton MolePerCubicMeter instance. + public static readonly MolePerCubicMeter MolePerCubicMeter = new MolePerCubicMeter(); + /// Singleton MolePerCubicMeterSecond instance. public static readonly MolePerCubicMeterSecond MolePerCubicMeterSecond = new MolePerCubicMeterSecond(); @@ -5270,6 +5652,9 @@ public static class Units{ /// Singleton NewtonSecond instance. public static readonly NewtonSecond NewtonSecond = new NewtonSecond(); + /// Singleton Nit instance. + public static readonly Nit Nit = new Nit(); + /// Singleton Ohm instance. public static readonly Ohm Ohm = new Ohm(); @@ -5294,6 +5679,9 @@ public static class Units{ /// Singleton PerKelvin instance. public static readonly PerKelvin PerKelvin = new PerKelvin(); + /// Singleton PerSecond instance. + public static readonly PerSecond PerSecond = new PerSecond(); + /// Singleton PercentByWeight instance. public static readonly PercentByWeight PercentByWeight = new PercentByWeight(); @@ -5354,9 +5742,15 @@ public static class Units{ /// Singleton Siemens instance. public static readonly Siemens Siemens = new Siemens(); + /// Singleton SiemensPerMeter instance. + public static readonly SiemensPerMeter SiemensPerMeter = new SiemensPerMeter(); + /// Singleton Sievert instance. public static readonly Sievert Sievert = new Sievert(); + /// Singleton Sone instance. + public static readonly Sone Sone = new Sone(); + /// Singleton SquareCentimeter instance. public static readonly SquareCentimeter SquareCentimeter = new SquareCentimeter(); @@ -5408,15 +5802,24 @@ public static class Units{ /// Singleton Volt instance. public static readonly Volt Volt = new Volt(); + /// Singleton VoltMeter instance. + public static readonly VoltMeter VoltMeter = new VoltMeter(); + /// Singleton VoltPerMeter instance. public static readonly VoltPerMeter VoltPerMeter = new VoltPerMeter(); + /// Singleton VoltPerPascal instance. + public static readonly VoltPerPascal VoltPerPascal = new VoltPerPascal(); + /// Singleton Watt instance. public static readonly Watt Watt = new Watt(); /// Singleton WattHour instance. public static readonly WattHour WattHour = new WattHour(); + /// Singleton WattPerCubicMeter instance. + public static readonly WattPerCubicMeter WattPerCubicMeter = new WattPerCubicMeter(); + /// Singleton WattPerMeterKelvin instance. public static readonly WattPerMeterKelvin WattPerMeterKelvin = new WattPerMeterKelvin(); diff --git a/Semantics.SourceGenerators/Metadata/conversions.json b/Semantics.SourceGenerators/Metadata/conversions.json index d1b621f..6f44002 100644 --- a/Semantics.SourceGenerators/Metadata/conversions.json +++ b/Semantics.SourceGenerators/Metadata/conversions.json @@ -532,6 +532,11 @@ "name": "FootCandleToLux", "description": "Foot-candle to lux conversion: 1/0.09290304 ≈ 10.7639 lx/fc (exact)", "value": "10.763910416709722" + }, + { + "name": "FootLambertToCandelaPerSquareMeter", + "description": "Foot-lambert to candela per square meter: 1/(π·0.09290304) ≈ 3.4263 cd/m² per fL (exact)", + "value": "3.4262590996353905" } ] }, diff --git a/Semantics.SourceGenerators/Metadata/dimensions.json b/Semantics.SourceGenerators/Metadata/dimensions.json index da4f509..24ca0e9 100644 --- a/Semantics.SourceGenerators/Metadata/dimensions.json +++ b/Semantics.SourceGenerators/Metadata/dimensions.json @@ -12,10 +12,18 @@ { "name": "RefractiveIndex", "description": "Ratio of speed of light in vacuum to speed in a medium." }, { "name": "ReynoldsNumber", "description": "Ratio of inertial to viscous forces in fluid flow." }, { "name": "SpecificGravity", "description": "Ratio of a substance's density to a reference density." }, - { "name": "MachNumber", "description": "Ratio of flow velocity to local speed of sound." } + { "name": "MachNumber", "description": "Ratio of flow velocity to local speed of sound." }, + { "name": "SoundAbsorption", "description": "Fraction of incident sound energy absorbed by a surface." }, + { "name": "NoiseReductionCoefficient", "description": "Average sound absorption across standard frequencies." }, + { "name": "SoundTransmissionClass", "description": "Single-number rating of airborne sound insulation." } ] }, - "vector1": { "base": "SignedRatio" } + "vector1": { + "base": "SignedRatio", + "overloads": [ + { "name": "ReflectionCoefficient", "description": "Signed ratio of reflected to incident wave amplitude." } + ] + } }, "integrals": [], "derivatives": [], @@ -211,7 +219,7 @@ "name": "NuclearCrossSection", "symbol": "L²", "dimensionalFormula": { "length": 2 }, - "availableUnits": ["Barn"], + "availableUnits": ["SquareMeter", "Barn"], "quantities": { "vector0": { "base": "NuclearCrossSection" } }, @@ -600,7 +608,8 @@ { "name": "GaugePressure", "description": "Pressure relative to atmospheric pressure." }, { "name": "BulkModulus", "description": "Resistance of a substance to uniform compression." }, { "name": "YoungsModulus", "description": "Ratio of stress to strain in a material." }, - { "name": "ShearModulus", "description": "Ratio of shear stress to shear strain." } + { "name": "ShearModulus", "description": "Ratio of shear stress to shear strain." }, + { "name": "SoundPressure", "description": "RMS pressure deviation caused by a sound wave." } ] } }, @@ -645,7 +654,8 @@ "vector0": { "base": "Power", "overloads": [ - { "name": "HeatFlowRate", "description": "Rate of heat energy transfer." } + { "name": "HeatFlowRate", "description": "Rate of heat energy transfer." }, + { "name": "SoundPower", "description": "Acoustic energy emitted by a source per unit time." } ] } }, @@ -758,7 +768,8 @@ "vector3": { "base": "ElectricField3D" } }, "integrals": [ - { "other": "Length", "result": "ElectricPotential" } + { "other": "Length", "result": "ElectricPotential" }, + { "other": "Area", "result": "ElectricFlux" } ], "derivatives": [], "dotProducts": [], @@ -772,7 +783,12 @@ }, "availableUnits": ["Ohm", "Kilohm", "Megohm"], "quantities": { - "vector0": { "base": "Resistance" } + "vector0": { + "base": "Resistance", + "overloads": [ + { "name": "Impedance", "description": "Magnitude of total opposition to alternating current." } + ] + } }, "integrals": [ { "other": "ElectricCurrent", "result": "ElectricPotential" } @@ -819,12 +835,7 @@ "dimensionalFormula": { "luminousIntensity": 1, "length": -2 }, "availableUnits": ["Lux", "FootCandle"], "quantities": { - "vector0": { - "base": "Illuminance", - "overloads": [ - { "name": "Luminance", "description": "Luminous intensity per unit area of a surface." } - ] - } + "vector0": { "base": "Illuminance" } }, "integrals": [ { "other": "Area", "result": "LuminousFlux" } @@ -850,7 +861,7 @@ "name": "Concentration", "symbol": "N L⁻³", "dimensionalFormula": { "amountOfSubstance": 1, "length": -3 }, - "availableUnits": ["Molar", "Millimolar", "Micromolar"], + "availableUnits": ["MolePerCubicMeter", "Molar", "Millimolar", "Micromolar"], "quantities": { "vector0": { "base": "Concentration" } }, @@ -1206,6 +1217,158 @@ "derivatives": [], "dotProducts": [], "crossProducts": [] + }, + { + "name": "Permittivity", + "symbol": "M⁻¹ L⁻³ T⁴ I²", + "dimensionalFormula": { + "mass": -1, "length": -3, "time": 4, "electricCurrent": 2 + }, + "availableUnits": ["FaradPerMeter"], + "quantities": { + "vector0": { "base": "Permittivity" } + }, + "integrals": [], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] + }, + { + "name": "ElectricConductivity", + "symbol": "M⁻¹ L⁻³ T³ I²", + "dimensionalFormula": { + "mass": -1, "length": -3, "time": 3, "electricCurrent": 2 + }, + "availableUnits": ["SiemensPerMeter"], + "quantities": { + "vector0": { "base": "ElectricConductivity" } + }, + "integrals": [], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] + }, + { + "name": "ElectricFlux", + "symbol": "M L³ T⁻³ I⁻¹", + "dimensionalFormula": { + "mass": 1, "length": 3, "time": -3, "electricCurrent": -1 + }, + "availableUnits": ["VoltMeter"], + "quantities": { + "vector0": { "base": "ElectricFlux" } + }, + "integrals": [], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] + }, + { + "name": "ElectricPowerDensity", + "symbol": "M L⁻¹ T⁻³", + "dimensionalFormula": { + "mass": 1, "length": -1, "time": -3 + }, + "availableUnits": ["WattPerCubicMeter"], + "quantities": { + "vector0": { "base": "ElectricPowerDensity" } + }, + "integrals": [ + { "other": "Volume", "result": "Power" } + ], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] + }, + { + "name": "Sensitivity", + "symbol": "M⁻¹ L⁻¹ T² I", + "dimensionalFormula": { + "mass": -1, "length": -1, "time": 2, "electricCurrent": 1 + }, + "availableUnits": ["VoltPerPascal"], + "quantities": { + "vector0": { "base": "Sensitivity" } + }, + "integrals": [ + { "other": "Pressure", "result": "ElectricPotential" } + ], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] + }, + { + "name": "ThermalResistance", + "symbol": "Θ M⁻¹ L⁻² T³", + "dimensionalFormula": { + "temperature": 1, "mass": -1, "length": -2, "time": 3 + }, + "availableUnits": ["KelvinPerWatt"], + "quantities": { + "vector0": { "base": "ThermalResistance" } + }, + "integrals": [], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] + }, + { + "name": "RateConstant", + "symbol": "T⁻¹", + "dimensionalFormula": { + "time": -1 + }, + "availableUnits": ["PerSecond"], + "quantities": { + "vector0": { "base": "RateConstant" } + }, + "integrals": [], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] + }, + { + "name": "Luminance", + "symbol": "J L⁻²", + "dimensionalFormula": { + "luminousIntensity": 1, "length": -2 + }, + "availableUnits": ["CandelaPerSquareMeter", "Nit", "FootLambert"], + "quantities": { + "vector0": { "base": "Luminance" } + }, + "integrals": [ + { "other": "Area", "result": "LuminousIntensity" } + ], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] + }, + { + "name": "Loudness", + "symbol": "1", + "dimensionalFormula": {}, + "availableUnits": ["Sone"], + "quantities": { + "vector0": { "base": "Loudness" } + }, + "integrals": [], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] + }, + { + "name": "Sharpness", + "symbol": "1", + "dimensionalFormula": {}, + "availableUnits": ["Acum"], + "quantities": { + "vector0": { "base": "Sharpness" } + }, + "integrals": [], + "derivatives": [], + "dotProducts": [], + "crossProducts": [] } ] } diff --git a/Semantics.SourceGenerators/Metadata/units.json b/Semantics.SourceGenerators/Metadata/units.json index f07b672..a3a0277 100644 --- a/Semantics.SourceGenerators/Metadata/units.json +++ b/Semantics.SourceGenerators/Metadata/units.json @@ -742,6 +742,13 @@ "system": "SIDerived", "magnitude": "Mega", "factoryName": "Megawatts" + }, + { + "name": "WattPerCubicMeter", + "symbol": "W/m³", + "description": "Watt per cubic meter - SI unit of volumetric power density.", + "system": "SIDerived", + "factoryName": "WattPerCubicMeter" } ] }, @@ -815,6 +822,13 @@ "system": "Imperial", "conversionFactor": "FahrenheitScale", "factoryName": "Rankine" + }, + { + "name": "KelvinPerWatt", + "symbol": "K/W", + "description": "Kelvin per watt - SI unit of absolute thermal resistance.", + "system": "SIDerived", + "factoryName": "KelvinPerWatt" } ] }, @@ -971,6 +985,34 @@ "system": "SIDerived", "conversionFactor": "AmpereHourToCoulombs", "factoryName": "AmpereHours" + }, + { + "name": "VoltMeter", + "symbol": "V·m", + "description": "Volt meter - SI unit of electric flux.", + "system": "SIDerived", + "factoryName": "VoltMeters" + }, + { + "name": "FaradPerMeter", + "symbol": "F/m", + "description": "Farad per meter - SI unit of permittivity.", + "system": "SIDerived", + "factoryName": "FaradPerMeter" + }, + { + "name": "SiemensPerMeter", + "symbol": "S/m", + "description": "Siemens per meter - SI unit of electrical conductivity.", + "system": "SIDerived", + "factoryName": "SiemensPerMeter" + }, + { + "name": "VoltPerPascal", + "symbol": "V/Pa", + "description": "Volt per pascal - SI unit of transducer sensitivity.", + "system": "SIDerived", + "factoryName": "VoltPerPascal" } ] }, @@ -1035,6 +1077,20 @@ "system": "SIDerived", "magnitude": "Mega", "factoryName": "Megahertz" + }, + { + "name": "Sone", + "symbol": "sone", + "description": "Sone - psychoacoustic unit of perceived loudness.", + "system": "Other", + "factoryName": "Sones" + }, + { + "name": "Acum", + "symbol": "acum", + "description": "Acum - psychoacoustic unit of perceived sharpness.", + "system": "Other", + "factoryName": "Acum" } ] }, @@ -1085,6 +1141,28 @@ "system": "Imperial", "conversionFactor": "FootCandleToLux", "factoryName": "FootCandles" + }, + { + "name": "CandelaPerSquareMeter", + "symbol": "cd/m²", + "description": "Candela per square meter - SI unit of luminance.", + "system": "SIDerived", + "factoryName": "CandelaPerSquareMeter" + }, + { + "name": "Nit", + "symbol": "nt", + "description": "Nit - common name for one candela per square meter.", + "system": "SIDerived", + "factoryName": "Nits" + }, + { + "name": "FootLambert", + "symbol": "fL", + "description": "Foot-lambert - Imperial unit of luminance (1/π candela per square foot).", + "system": "Imperial", + "conversionFactor": "FootLambertToCandelaPerSquareMeter", + "factoryName": "FootLamberts" } ] }, @@ -1202,6 +1280,13 @@ "system": "SIBase", "factoryName": "Moles" }, + { + "name": "MolePerCubicMeter", + "symbol": "mol/m³", + "description": "Mole per cubic meter - SI base unit of concentration.", + "system": "SIDerived", + "factoryName": "MolePerCubicMeter" + }, { "name": "Molar", "symbol": "M", @@ -1396,6 +1481,13 @@ "system": "Atomic", "conversionFactor": "GramPerMoleToKilogramPerMole", "factoryName": "Daltons" + }, + { + "name": "PerSecond", + "symbol": "s⁻¹", + "description": "Per second - SI unit of a first-order rate constant.", + "system": "SIDerived", + "factoryName": "PerSecond" } ] }, From 6a725a72e59ee879afd862845938ee8897cac352 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 12 Jun 2026 09:31:03 +0000 Subject: [PATCH 2/3] feat(quantities): hand-written logarithmic-scale companions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Locks in the log-scale decision: decibel and pH scales don't obey linear arithmetic, so they are self-contained record structs (like the audio-engineering types) that convert to and from their linear generated counterparts, not dimensions.json entries. - SoundPressureLevel (dB re 20 µPa) <-> SoundPressure - SoundIntensityLevel (dB re 1e-12 W/m²) <-> SoundIntensity - SoundPowerLevel (dB re 1e-12 W) <-> SoundPower - DirectionalityIndex (dB) <-> intensity Ratio - PH <-> hydrogen-ion Concentration (plus pOH and acidity checks) Documented as resolved design decision #5 in CLAUDE.md. https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW --- CLAUDE.md | 1 + .../Acoustics/DirectionalityIndex.cs | 85 ++++++++++++++ .../Acoustics/SoundIntensityLevel.cs | 109 +++++++++++++++++ .../Acoustics/SoundPowerLevel.cs | 109 +++++++++++++++++ .../Acoustics/SoundPressureLevel.cs | 111 ++++++++++++++++++ Semantics.Quantities/Chemistry/PH.cs | 101 ++++++++++++++++ 6 files changed, 516 insertions(+) create mode 100644 Semantics.Quantities/Acoustics/DirectionalityIndex.cs create mode 100644 Semantics.Quantities/Acoustics/SoundIntensityLevel.cs create mode 100644 Semantics.Quantities/Acoustics/SoundPowerLevel.cs create mode 100644 Semantics.Quantities/Acoustics/SoundPressureLevel.cs create mode 100644 Semantics.Quantities/Chemistry/PH.cs diff --git a/CLAUDE.md b/CLAUDE.md index de37b4a..b7d4468 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -52,6 +52,7 @@ These are now baked into the generator and enforced by tests. **Do not reopen wi 2. **Dimensionless and angular quantities have both `Ratio` (V0) and `SignedRatio` (V1) bases.** Ratios that semantically must be non-negative (e.g. `RefractiveIndex`, `MachNumber`, `SpecificGravity`) are V0 overloads of `Ratio`. 3. **Semantic overloads widen implicitly to their base, narrow explicitly from it.** A `Weight` is implicitly a `ForceMagnitude`; the reverse requires `Weight.From(forceMagnitude)` or an explicit cast. 4. **Physical constraints are enforced structurally via the V0 (magnitude) form.** `Vector0` factories run `Vector0Guards.EnsureNonNegative` and throw `ArgumentException` on a negative value. That covers absolute zero (Temperature is V0, so Kelvin must be ≥ 0), non-negative frequency, non-negative absolute pressure, etc. A V0 *overload* can opt into a stricter rule by declaring `physicalConstraints: { "minExclusive": "0" }` in `dimensions.json` (#51); the generator then emits `Vector0Guards.EnsurePositive` and rejects zero too. Used today for `Wavelength`, `Period`, and `HalfLife` — quantities for which zero is unphysical. +5. **Logarithmic-scale quantities are hand-written companions, not generated dimensions.** Decibel scales (`SoundPressureLevel`, `SoundIntensityLevel`, `SoundPowerLevel`, `DirectionalityIndex`, the audio-engineering `Decibels`) and `PH` don't obey linear arithmetic, so they live as self-contained `readonly record struct`s that convert to and from their linear generated counterparts (`SoundPressure`, `SoundIntensity`, `SoundPower`, `Ratio`, `Concentration`). Adding a new log-scale quantity means writing such a companion, not a `dimensions.json` entry. ### Physical constants diff --git a/Semantics.Quantities/Acoustics/DirectionalityIndex.cs b/Semantics.Quantities/Acoustics/DirectionalityIndex.cs new file mode 100644 index 0000000..064ed2a --- /dev/null +++ b/Semantics.Quantities/Acoustics/DirectionalityIndex.cs @@ -0,0 +1,85 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. + +namespace ktsu.Semantics.Quantities; + +using System.Globalization; +using System.Numerics; + +/// +/// Represents a directivity index (DI) in decibels — how much more intense a +/// source or receiver is on-axis than its spherical average. +/// +/// +/// DI = 10·log10(I_axis / I_average). Like all decibel scales it is a +/// hand-written companion rather than a generated linear quantity. +/// +/// The floating-point storage type. +/// The index in decibels. +public readonly record struct DirectionalityIndex(T Value) : IComparable> + where T : struct, INumber +{ + /// Gets the index of an omnidirectional source (0 dB). + public static DirectionalityIndex Omnidirectional => new(T.Zero); + + /// + /// Creates an index from a raw decibel value. + /// + /// The index in decibels. + /// A new . + public static DirectionalityIndex FromDecibels(T decibels) => new(decibels); + + /// + /// Creates an index from the linear on-axis-to-average intensity ratio using DI = 10·log10(ratio). + /// + /// The intensity ratio. + /// A new . + public static DirectionalityIndex FromIntensityRatio(Ratio ratio) + { + ArgumentNullException.ThrowIfNull(ratio); + double linear = double.CreateChecked(ratio.Value); + return new(T.CreateChecked(10.0 * Math.Log10(linear))); + } + + /// + /// Converts this index to the linear intensity ratio using ratio = 10^(DI/10). + /// + /// The on-axis-to-average intensity . + public Ratio ToIntensityRatio() + { + double db = double.CreateChecked(Value); + return Ratio.Create(T.CreateChecked(Math.Pow(10.0, db / 10.0))); + } + + /// + public int CompareTo(DirectionalityIndex other) => Value.CompareTo(other.Value); + + /// Determines whether one index is less than another. + /// The left index. + /// The right index. + /// if is less than . + public static bool operator <(DirectionalityIndex left, DirectionalityIndex right) => left.CompareTo(right) < 0; + + /// Determines whether one index is greater than another. + /// The left index. + /// The right index. + /// if is greater than . + public static bool operator >(DirectionalityIndex left, DirectionalityIndex right) => left.CompareTo(right) > 0; + + /// Determines whether one index is less than or equal to another. + /// The left index. + /// The right index. + /// if is less than or equal to . + public static bool operator <=(DirectionalityIndex left, DirectionalityIndex right) => left.CompareTo(right) <= 0; + + /// Determines whether one index is greater than or equal to another. + /// The left index. + /// The right index. + /// if is greater than or equal to . + public static bool operator >=(DirectionalityIndex left, DirectionalityIndex right) => left.CompareTo(right) >= 0; + + /// Returns a culture-invariant string representation of this index. + /// The index formatted with a dB suffix. + public override string ToString() => string.Create(CultureInfo.InvariantCulture, $"{Value} dB"); +} diff --git a/Semantics.Quantities/Acoustics/SoundIntensityLevel.cs b/Semantics.Quantities/Acoustics/SoundIntensityLevel.cs new file mode 100644 index 0000000..ef56c2d --- /dev/null +++ b/Semantics.Quantities/Acoustics/SoundIntensityLevel.cs @@ -0,0 +1,109 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. + +namespace ktsu.Semantics.Quantities; + +using System.Globalization; +using System.Numerics; + +/// +/// Represents a sound intensity level (SIL) in decibels relative to the +/// 10⁻¹² W/m² threshold of hearing. +/// +/// +/// SIL is a logarithmic power quantity: SIL = 10·log10(I / I₀) with +/// I₀ = 10⁻¹² W/m². Logarithmic scales are hand-written companions to the +/// linear generated quantities — see . +/// +/// The floating-point storage type. +/// The level in decibels. +public readonly record struct SoundIntensityLevel(T Value) : IComparable> + where T : struct, INumber +{ + /// + /// Creates a level from a raw decibel value. + /// + /// The level in dB re 10⁻¹² W/m². + /// A new . + public static SoundIntensityLevel FromDecibels(T decibels) => new(decibels); + + /// + /// Creates a level from a linear sound intensity using SIL = 10·log10(I / I₀). + /// + /// The sound intensity. + /// A new . Zero intensity maps to negative infinity. + public static SoundIntensityLevel FromSoundIntensity(SoundIntensity intensity) + { + ArgumentNullException.ThrowIfNull(intensity); + double i = double.CreateChecked(intensity.Value); + double i0 = PhysicalConstants.Generic.ReferenceSoundIntensity(); + return new(T.CreateChecked(10.0 * Math.Log10(i / i0))); + } + + /// + /// Converts this level to the equivalent linear sound intensity using I = I₀·10^(SIL/10). + /// + /// The . + public SoundIntensity ToSoundIntensity() + { + double db = double.CreateChecked(Value); + double i0 = PhysicalConstants.Generic.ReferenceSoundIntensity(); + return SoundIntensity.Create(T.CreateChecked(i0 * Math.Pow(10.0, db / 10.0))); + } + + /// Adds two levels in decibel space. + /// The first level. + /// The second level. + /// The summed level. + public static SoundIntensityLevel operator +(SoundIntensityLevel left, SoundIntensityLevel right) => new(left.Value + right.Value); + + /// Subtracts one level from another in decibel space. + /// The level to subtract from. + /// The level to subtract. + /// The difference level. + public static SoundIntensityLevel operator -(SoundIntensityLevel left, SoundIntensityLevel right) => new(left.Value - right.Value); + + /// Adds two levels (friendly alternate for operator +). + /// The first level. + /// The second level. + /// The summed level. + public static SoundIntensityLevel Add(SoundIntensityLevel left, SoundIntensityLevel right) => left + right; + + /// Subtracts one level from another (friendly alternate for operator -). + /// The level to subtract from. + /// The level to subtract. + /// The difference level. + public static SoundIntensityLevel Subtract(SoundIntensityLevel left, SoundIntensityLevel right) => left - right; + + /// + public int CompareTo(SoundIntensityLevel other) => Value.CompareTo(other.Value); + + /// Determines whether one level is less than another. + /// The left level. + /// The right level. + /// if is less than . + public static bool operator <(SoundIntensityLevel left, SoundIntensityLevel right) => left.CompareTo(right) < 0; + + /// Determines whether one level is greater than another. + /// The left level. + /// The right level. + /// if is greater than . + public static bool operator >(SoundIntensityLevel left, SoundIntensityLevel right) => left.CompareTo(right) > 0; + + /// Determines whether one level is less than or equal to another. + /// The left level. + /// The right level. + /// if is less than or equal to . + public static bool operator <=(SoundIntensityLevel left, SoundIntensityLevel right) => left.CompareTo(right) <= 0; + + /// Determines whether one level is greater than or equal to another. + /// The left level. + /// The right level. + /// if is greater than or equal to . + public static bool operator >=(SoundIntensityLevel left, SoundIntensityLevel right) => left.CompareTo(right) >= 0; + + /// Returns a culture-invariant string representation of this level. + /// The level formatted with a dB SIL suffix. + public override string ToString() => string.Create(CultureInfo.InvariantCulture, $"{Value} dB SIL"); +} diff --git a/Semantics.Quantities/Acoustics/SoundPowerLevel.cs b/Semantics.Quantities/Acoustics/SoundPowerLevel.cs new file mode 100644 index 0000000..e91b81b --- /dev/null +++ b/Semantics.Quantities/Acoustics/SoundPowerLevel.cs @@ -0,0 +1,109 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. + +namespace ktsu.Semantics.Quantities; + +using System.Globalization; +using System.Numerics; + +/// +/// Represents a sound power level (SWL) in decibels relative to the 10⁻¹² W +/// reference sound power. +/// +/// +/// SWL is a logarithmic power quantity: SWL = 10·log10(P / P₀) with +/// P₀ = 10⁻¹² W. Logarithmic scales are hand-written companions to the +/// linear generated quantities — see . +/// +/// The floating-point storage type. +/// The level in decibels. +public readonly record struct SoundPowerLevel(T Value) : IComparable> + where T : struct, INumber +{ + /// + /// Creates a level from a raw decibel value. + /// + /// The level in dB re 10⁻¹² W. + /// A new . + public static SoundPowerLevel FromDecibels(T decibels) => new(decibels); + + /// + /// Creates a level from a linear sound power using SWL = 10·log10(P / P₀). + /// + /// The sound power. + /// A new . Zero power maps to negative infinity. + public static SoundPowerLevel FromSoundPower(SoundPower power) + { + ArgumentNullException.ThrowIfNull(power); + double p = double.CreateChecked(power.Value); + double p0 = PhysicalConstants.Generic.ReferenceSoundPower(); + return new(T.CreateChecked(10.0 * Math.Log10(p / p0))); + } + + /// + /// Converts this level to the equivalent linear sound power using P = P₀·10^(SWL/10). + /// + /// The . + public SoundPower ToSoundPower() + { + double db = double.CreateChecked(Value); + double p0 = PhysicalConstants.Generic.ReferenceSoundPower(); + return SoundPower.Create(T.CreateChecked(p0 * Math.Pow(10.0, db / 10.0))); + } + + /// Adds two levels in decibel space. + /// The first level. + /// The second level. + /// The summed level. + public static SoundPowerLevel operator +(SoundPowerLevel left, SoundPowerLevel right) => new(left.Value + right.Value); + + /// Subtracts one level from another in decibel space. + /// The level to subtract from. + /// The level to subtract. + /// The difference level. + public static SoundPowerLevel operator -(SoundPowerLevel left, SoundPowerLevel right) => new(left.Value - right.Value); + + /// Adds two levels (friendly alternate for operator +). + /// The first level. + /// The second level. + /// The summed level. + public static SoundPowerLevel Add(SoundPowerLevel left, SoundPowerLevel right) => left + right; + + /// Subtracts one level from another (friendly alternate for operator -). + /// The level to subtract from. + /// The level to subtract. + /// The difference level. + public static SoundPowerLevel Subtract(SoundPowerLevel left, SoundPowerLevel right) => left - right; + + /// + public int CompareTo(SoundPowerLevel other) => Value.CompareTo(other.Value); + + /// Determines whether one level is less than another. + /// The left level. + /// The right level. + /// if is less than . + public static bool operator <(SoundPowerLevel left, SoundPowerLevel right) => left.CompareTo(right) < 0; + + /// Determines whether one level is greater than another. + /// The left level. + /// The right level. + /// if is greater than . + public static bool operator >(SoundPowerLevel left, SoundPowerLevel right) => left.CompareTo(right) > 0; + + /// Determines whether one level is less than or equal to another. + /// The left level. + /// The right level. + /// if is less than or equal to . + public static bool operator <=(SoundPowerLevel left, SoundPowerLevel right) => left.CompareTo(right) <= 0; + + /// Determines whether one level is greater than or equal to another. + /// The left level. + /// The right level. + /// if is greater than or equal to . + public static bool operator >=(SoundPowerLevel left, SoundPowerLevel right) => left.CompareTo(right) >= 0; + + /// Returns a culture-invariant string representation of this level. + /// The level formatted with a dB SWL suffix. + public override string ToString() => string.Create(CultureInfo.InvariantCulture, $"{Value} dB SWL"); +} diff --git a/Semantics.Quantities/Acoustics/SoundPressureLevel.cs b/Semantics.Quantities/Acoustics/SoundPressureLevel.cs new file mode 100644 index 0000000..ab218cb --- /dev/null +++ b/Semantics.Quantities/Acoustics/SoundPressureLevel.cs @@ -0,0 +1,111 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. + +namespace ktsu.Semantics.Quantities; + +using System.Globalization; +using System.Numerics; + +/// +/// Represents a sound pressure level (SPL) in decibels relative to the 20 µPa +/// threshold of hearing. +/// +/// +/// SPL is a logarithmic field quantity: SPL = 20·log10(p / p₀) with +/// p₀ = 20 µPa. Logarithmic scales don't fit the linear +/// model (their addition is not linear +/// addition), so SPL is a hand-written companion that converts to and from the +/// linear quantity. +/// +/// The floating-point storage type. +/// The level in decibels. +public readonly record struct SoundPressureLevel(T Value) : IComparable> + where T : struct, INumber +{ + /// + /// Creates a level from a raw decibel value. + /// + /// The level in dB re 20 µPa. + /// A new . + public static SoundPressureLevel FromDecibels(T decibels) => new(decibels); + + /// + /// Creates a level from a linear sound pressure using SPL = 20·log10(p / p₀). + /// + /// The RMS sound pressure. + /// A new . Zero pressure maps to negative infinity. + public static SoundPressureLevel FromSoundPressure(SoundPressure pressure) + { + ArgumentNullException.ThrowIfNull(pressure); + double p = double.CreateChecked(pressure.Value); + double p0 = PhysicalConstants.Generic.ReferenceSoundPressure(); + return new(T.CreateChecked(20.0 * Math.Log10(p / p0))); + } + + /// + /// Converts this level to the equivalent linear sound pressure using p = p₀·10^(SPL/20). + /// + /// The RMS . + public SoundPressure ToSoundPressure() + { + double db = double.CreateChecked(Value); + double p0 = PhysicalConstants.Generic.ReferenceSoundPressure(); + return SoundPressure.Create(T.CreateChecked(p0 * Math.Pow(10.0, db / 20.0))); + } + + /// Adds two levels in decibel space (cascading gains). + /// The first level. + /// The second level. + /// The summed level. + public static SoundPressureLevel operator +(SoundPressureLevel left, SoundPressureLevel right) => new(left.Value + right.Value); + + /// Subtracts one level from another in decibel space. + /// The level to subtract from. + /// The level to subtract. + /// The difference level. + public static SoundPressureLevel operator -(SoundPressureLevel left, SoundPressureLevel right) => new(left.Value - right.Value); + + /// Adds two levels (friendly alternate for operator +). + /// The first level. + /// The second level. + /// The summed level. + public static SoundPressureLevel Add(SoundPressureLevel left, SoundPressureLevel right) => left + right; + + /// Subtracts one level from another (friendly alternate for operator -). + /// The level to subtract from. + /// The level to subtract. + /// The difference level. + public static SoundPressureLevel Subtract(SoundPressureLevel left, SoundPressureLevel right) => left - right; + + /// + public int CompareTo(SoundPressureLevel other) => Value.CompareTo(other.Value); + + /// Determines whether one level is less than another. + /// The left level. + /// The right level. + /// if is less than . + public static bool operator <(SoundPressureLevel left, SoundPressureLevel right) => left.CompareTo(right) < 0; + + /// Determines whether one level is greater than another. + /// The left level. + /// The right level. + /// if is greater than . + public static bool operator >(SoundPressureLevel left, SoundPressureLevel right) => left.CompareTo(right) > 0; + + /// Determines whether one level is less than or equal to another. + /// The left level. + /// The right level. + /// if is less than or equal to . + public static bool operator <=(SoundPressureLevel left, SoundPressureLevel right) => left.CompareTo(right) <= 0; + + /// Determines whether one level is greater than or equal to another. + /// The left level. + /// The right level. + /// if is greater than or equal to . + public static bool operator >=(SoundPressureLevel left, SoundPressureLevel right) => left.CompareTo(right) >= 0; + + /// Returns a culture-invariant string representation of this level. + /// The level formatted with a dB SPL suffix. + public override string ToString() => string.Create(CultureInfo.InvariantCulture, $"{Value} dB SPL"); +} diff --git a/Semantics.Quantities/Chemistry/PH.cs b/Semantics.Quantities/Chemistry/PH.cs new file mode 100644 index 0000000..3f62694 --- /dev/null +++ b/Semantics.Quantities/Chemistry/PH.cs @@ -0,0 +1,101 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. + +namespace ktsu.Semantics.Quantities; + +using System.Globalization; +using System.Numerics; + +/// +/// Represents acidity on the pH scale: pH = −log10([H⁺]) with the +/// hydrogen-ion activity in mol/L. +/// +/// +/// pH is a logarithmic scale, so — like the decibel quantities — it is a +/// hand-written companion that converts to and from the linear +/// quantity (stored in the SI base mol/m³). +/// +/// The floating-point storage type. +/// The pH value. +public readonly record struct PH(T Value) : IComparable> + where T : struct, INumber +{ + private const double MolesPerCubicMeterPerMolar = 1000.0; + + /// Gets the pH of pure water at 25 °C (7.0). + public static PH Neutral => new(PhysicalConstants.Generic.NeutralPH()); + + /// + /// Creates a pH from a raw scale value. + /// + /// The pH value. + /// A new . + public static PH Create(T value) => new(value); + + /// + /// Creates a pH from a hydrogen-ion concentration using pH = −log10([H⁺] in mol/L). + /// + /// The hydrogen-ion concentration. + /// A new . + public static PH FromHydrogenConcentration(Concentration hydrogenConcentration) + { + ArgumentNullException.ThrowIfNull(hydrogenConcentration); + double molesPerLiter = double.CreateChecked(hydrogenConcentration.Value) / MolesPerCubicMeterPerMolar; + return new(T.CreateChecked(-Math.Log10(molesPerLiter))); + } + + /// + /// Converts this pH to the equivalent hydrogen-ion concentration using [H⁺] = 10^(−pH) mol/L. + /// + /// The hydrogen-ion . + public Concentration ToHydrogenConcentration() + { + double ph = double.CreateChecked(Value); + double molesPerCubicMeter = Math.Pow(10.0, -ph) * MolesPerCubicMeterPerMolar; + return Concentration.Create(T.CreateChecked(molesPerCubicMeter)); + } + + /// + /// Gets the complementary pOH at 25 °C using pOH = 14 − pH. + /// + /// The pOH as a scale value. + public PH ToPOH() => new(T.CreateChecked(14) - Value); + + /// Gets whether this value describes an acid (pH below 7). + public bool IsAcidic => Value < PhysicalConstants.Generic.NeutralPH(); + + /// Gets whether this value describes a base (pH above 7). + public bool IsBasic => Value > PhysicalConstants.Generic.NeutralPH(); + + /// + public int CompareTo(PH other) => Value.CompareTo(other.Value); + + /// Determines whether one pH is less than another. + /// The left pH. + /// The right pH. + /// if is less than . + public static bool operator <(PH left, PH right) => left.CompareTo(right) < 0; + + /// Determines whether one pH is greater than another. + /// The left pH. + /// The right pH. + /// if is greater than . + public static bool operator >(PH left, PH right) => left.CompareTo(right) > 0; + + /// Determines whether one pH is less than or equal to another. + /// The left pH. + /// The right pH. + /// if is less than or equal to . + public static bool operator <=(PH left, PH right) => left.CompareTo(right) <= 0; + + /// Determines whether one pH is greater than or equal to another. + /// The left pH. + /// The right pH. + /// if is greater than or equal to . + public static bool operator >=(PH left, PH right) => left.CompareTo(right) >= 0; + + /// Returns a culture-invariant string representation of this pH. + /// The value formatted with a pH prefix. + public override string ToString() => string.Create(CultureInfo.InvariantCulture, $"pH {Value}"); +} From cdc48ee207a1ed2e7b1f4d0913489dc81def67b9 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 12 Jun 2026 09:31:03 +0000 Subject: [PATCH 3/3] test(quantities): cover backfilled dimensions and log-scale companions https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW --- .../Quantities/QuantityBackfillTests.cs | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 Semantics.Test/Quantities/QuantityBackfillTests.cs diff --git a/Semantics.Test/Quantities/QuantityBackfillTests.cs b/Semantics.Test/Quantities/QuantityBackfillTests.cs new file mode 100644 index 0000000..d00a051 --- /dev/null +++ b/Semantics.Test/Quantities/QuantityBackfillTests.cs @@ -0,0 +1,190 @@ +// Copyright (c) ktsu.dev +// All rights reserved. +// Licensed under the MIT license. + +namespace ktsu.Semantics.Test.Quantities; + +using ktsu.Semantics.Quantities; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +/// +/// Covers the quantities backfilled from main: new electrical/chemical/thermal/photometric +/// dimensions, acoustic overloads and coefficients, and the hand-written logarithmic-scale +/// companions (sound levels and pH). +/// +[TestClass] +public sealed class QuantityBackfillTests +{ + private const double Tolerance = 1e-9; + + // ---- New generated dimensions ---- + + [TestMethod] + public void Luminance_Factories_And_Intensity_Relationship() + { + Luminance nit = Luminance.FromNits(100.0); + Assert.AreEqual(100.0, nit.Value, Tolerance); + Assert.AreEqual(3.4262590996353905, Luminance.FromFootLamberts(1.0).Value, 1e-9); + + LuminousIntensity intensity = nit * Area.FromSquareMeters(2.0); + Assert.AreEqual(200.0, intensity.Value, Tolerance); + } + + [TestMethod] + public void Permittivity_And_Conductivity_Factories() + { + Assert.AreEqual(8.854e-12, Permittivity.FromFaradPerMeter(8.854e-12).Value, 1e-21); + Assert.AreEqual(5.96e7, ElectricConductivity.FromSiemensPerMeter(5.96e7).Value, 1.0); + } + + [TestMethod] + public void ElectricFlux_From_Field_Times_Area() + { + ElectricFieldMagnitude field = ElectricFieldMagnitude.FromVoltPerMeter(100.0); + ElectricFlux flux = field * Area.FromSquareMeters(0.5); + Assert.AreEqual(50.0, flux.Value, Tolerance); + } + + [TestMethod] + public void ElectricPowerDensity_Times_Volume_Is_Power() + { + ElectricPowerDensity density = ElectricPowerDensity.FromWattPerCubicMeter(250.0); + Power power = density * Volume.FromCubicMeters(4.0); + Assert.AreEqual(1000.0, power.Value, Tolerance); + } + + [TestMethod] + public void Sensitivity_Times_Pressure_Is_Voltage() + { + // A 50 mV/Pa microphone at 1 Pa (94 dB SPL) produces 50 mV. + Sensitivity mic = Sensitivity.FromVoltPerPascal(0.05); + VoltageMagnitude output = mic * Pressure.FromPascals(1.0); + Assert.AreEqual(0.05, output.Value, Tolerance); + } + + [TestMethod] + public void ThermalResistance_And_RateConstant_Factories() + { + Assert.AreEqual(2.5, ThermalResistance.FromKelvinPerWatt(2.5).Value, Tolerance); + Assert.AreEqual(0.693, RateConstant.FromPerSecond(0.693).Value, Tolerance); + } + + [TestMethod] + public void Loudness_And_Sharpness_Factories() + { + Assert.AreEqual(2.0, Loudness.FromSones(2.0).Value, Tolerance); + Assert.AreEqual(1.5, Sharpness.FromAcum(1.5).Value, Tolerance); + } + + // ---- New overloads ---- + + [TestMethod] + public void Impedance_Widens_To_Resistance() + { + Impedance z = Impedance.FromOhms(8.0); + Resistance r = z; + Assert.AreEqual(8.0, r.Value, Tolerance); + + // Ohm's law applies through the overload: V = I·Z. + VoltageMagnitude v = CurrentMagnitude.FromAmperes(2.0) * z; + Assert.AreEqual(16.0, v.Value, Tolerance); + } + + [TestMethod] + public void SoundPressure_And_SoundPower_Widen_To_Bases() + { + Pressure p = SoundPressure.FromPascals(0.2); + Assert.AreEqual(0.2, p.Value, Tolerance); + + Power w = SoundPower.FromWatts(0.01); + Assert.AreEqual(0.01, w.Value, Tolerance); + } + + [TestMethod] + public void Acoustic_Coefficients_Are_Ratio_Overloads() + { + SoundAbsorption alpha = SoundAbsorption.Create(0.85); + Ratio asRatio = alpha; + Assert.AreEqual(0.85, asRatio.Value, Tolerance); + + Assert.AreEqual(0.65, NoiseReductionCoefficient.Create(0.65).Value, Tolerance); + Assert.AreEqual(52.0, SoundTransmissionClass.Create(52.0).Value, Tolerance); + } + + [TestMethod] + public void ReflectionCoefficient_Is_Signed() + { + // A pressure-release boundary reflects with inverted phase. + ReflectionCoefficient r = ReflectionCoefficient.Create(-1.0); + Assert.AreEqual(-1.0, r.Value, Tolerance); + } + + // ---- Logarithmic-scale companions ---- + + [TestMethod] + public void SoundPressureLevel_From_Pressure_And_Back() + { + // 0.02 Pa is 1000× the 20 µPa reference: 20·log10(1000) = 60 dB. + SoundPressureLevel spl = SoundPressureLevel.FromSoundPressure(SoundPressure.FromPascals(0.02)); + Assert.AreEqual(60.0, spl.Value, 1e-9); + + SoundPressure back = spl.ToSoundPressure(); + Assert.AreEqual(0.02, back.Value, 1e-12); + } + + [TestMethod] + public void SoundIntensityLevel_From_Intensity_And_Back() + { + SoundIntensityLevel sil = SoundIntensityLevel.FromSoundIntensity(SoundIntensity.FromWattPerSquareMeter(1e-6)); + Assert.AreEqual(60.0, sil.Value, 1e-9); + Assert.AreEqual(1e-6, sil.ToSoundIntensity().Value, 1e-15); + } + + [TestMethod] + public void SoundPowerLevel_From_Power_And_Back() + { + SoundPowerLevel swl = SoundPowerLevel.FromSoundPower(SoundPower.FromWatts(1e-3)); + Assert.AreEqual(90.0, swl.Value, 1e-9); + Assert.AreEqual(1e-3, swl.ToSoundPower().Value, 1e-12); + } + + [TestMethod] + public void DirectionalityIndex_RoundTrips_Intensity_Ratio() + { + DirectionalityIndex di = DirectionalityIndex.FromIntensityRatio(Ratio.Create(10.0)); + Assert.AreEqual(10.0, di.Value, 1e-9); + Assert.AreEqual(10.0, di.ToIntensityRatio().Value, 1e-9); + Assert.AreEqual(0.0, DirectionalityIndex.Omnidirectional.Value, Tolerance); + } + + [TestMethod] + public void PH_From_Concentration_And_Back() + { + // Pure water: [H+] = 1e-7 mol/L. + PH ph = PH.FromHydrogenConcentration(Concentration.FromMolars(1e-7)); + Assert.AreEqual(7.0, ph.Value, 1e-9); + + Concentration back = ph.ToHydrogenConcentration(); + Assert.AreEqual(Concentration.FromMolars(1e-7).Value, back.Value, 1e-12); + } + + [TestMethod] + public void PH_Acidity_Classification_And_POH() + { + PH lemon = PH.Create(2.0); + Assert.IsTrue(lemon.IsAcidic); + Assert.IsFalse(lemon.IsBasic); + Assert.AreEqual(12.0, lemon.ToPOH().Value, Tolerance); + Assert.AreEqual(7.0, PH.Neutral.Value, Tolerance); + Assert.IsFalse(PH.Neutral.IsAcidic); + } + + [TestMethod] + public void Levels_Compare_And_Add_In_Decibel_Space() + { + SoundPressureLevel quiet = SoundPressureLevel.FromDecibels(40.0); + SoundPressureLevel loud = SoundPressureLevel.FromDecibels(90.0); + Assert.IsTrue(quiet < loud); + Assert.AreEqual(50.0, (loud - quiet).Value, Tolerance); + } +}