From 249d4e7c31f94677b9cc19b807695ce533c80b14 Mon Sep 17 00:00:00 2001 From: ig Date: Thu, 4 May 2023 09:36:30 +0200 Subject: [PATCH] units v2 --- csharp/Lib/Units/ActivePower.cs | 23 ++++++ ....generated.cs => ActivePower.generated.cs} | 14 ++-- csharp/Lib/Units/Composite/Ac1Bus.cs | 2 +- csharp/Lib/Units/Composite/Ac3Bus.cs | 24 ++++-- csharp/Lib/Units/Composite/AcPhase.cs | 32 ++++++++ csharp/Lib/Units/Composite/AcPower.cs | 76 ++++++++++++++++--- csharp/Lib/Units/Composite/Bus.cs | 4 +- csharp/Lib/Units/Composite/DcBus.cs | 6 +- csharp/Lib/Units/Current.cs | 2 +- csharp/Lib/Units/Energy.cs | 4 +- csharp/Lib/Units/Power.cs | 23 ------ csharp/Lib/Units/Units.cs | 2 +- csharp/Lib/Units/Voltage.cs | 2 +- 13 files changed, 156 insertions(+), 58 deletions(-) create mode 100644 csharp/Lib/Units/ActivePower.cs rename csharp/Lib/Units/{Power.generated.cs => ActivePower.generated.cs} (81%) delete mode 100644 csharp/Lib/Units/Power.cs diff --git a/csharp/Lib/Units/ActivePower.cs b/csharp/Lib/Units/ActivePower.cs new file mode 100644 index 000000000..85a5cd6de --- /dev/null +++ b/csharp/Lib/Units/ActivePower.cs @@ -0,0 +1,23 @@ +using InnovEnergy.Lib.Time.Unix; +using InnovEnergy.Lib.Units.Generator; + +namespace InnovEnergy.Lib.Units; + +[Generate] +public readonly partial struct ActivePower +{ + public static String Unit => "W"; + public static String Symbol => "P"; + + public ActivePower(Double value) => Value = value; + + // P=UI + public static Voltage operator /(ActivePower power, Current current) => new Voltage(power.Value / current.Value); + public static Current operator /(ActivePower power, Voltage voltage) => new Current(power.Value / voltage.Value); + + public static Energy operator *(ActivePower power, TimeSpan timeSpan) => power.Value / 1000 * timeSpan.TotalHours; + public static Energy operator *(TimeSpan timeSpan, ActivePower power) => power.Value / 1000 * timeSpan.TotalHours; + + public static Energy operator *(ActivePower power, UnixTimeSpan timeSpan) => power.Value * timeSpan.Ticks / 3_600_000; + public static Energy operator *(UnixTimeSpan timeSpan, ActivePower power) => power.Value * timeSpan.Ticks / 3_600_000; +} \ No newline at end of file diff --git a/csharp/Lib/Units/Power.generated.cs b/csharp/Lib/Units/ActivePower.generated.cs similarity index 81% rename from csharp/Lib/Units/Power.generated.cs rename to csharp/Lib/Units/ActivePower.generated.cs index b465161cf..65a5b9fa2 100644 --- a/csharp/Lib/Units/Power.generated.cs +++ b/csharp/Lib/Units/ActivePower.generated.cs @@ -9,11 +9,11 @@ using System.CodeDom.Compiler; namespace InnovEnergy.Lib.Units; -using T = Power; +using T = ActivePower; [GeneratedCode("generate.sh", "1")] -[JsonConverter(typeof(PowerConverter))] -public readonly partial struct Power +[JsonConverter(typeof(ActivePowerConverter))] +public readonly partial struct ActivePower { public Double Value { get; } public override String ToString() => Value.RoundToSignificantDigits(Units.DisplaySignificantDigits) + Unit; @@ -52,14 +52,14 @@ public readonly partial struct Power } -internal class PowerConverter : JsonConverter +internal class ActivePowerConverter : JsonConverter { - public override Power Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override ActivePower Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - return new Power(reader.GetDouble()); + return new ActivePower(reader.GetDouble()); } - public override void Write(Utf8JsonWriter writer, Power value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, ActivePower value, JsonSerializerOptions options) { var rounded = value.Value.RoundToSignificantDigits(Units.JsonSignificantDigits); diff --git a/csharp/Lib/Units/Composite/Ac1Bus.cs b/csharp/Lib/Units/Composite/Ac1Bus.cs index 23b81aec4..7a802e1e8 100644 --- a/csharp/Lib/Units/Composite/Ac1Bus.cs +++ b/csharp/Lib/Units/Composite/Ac1Bus.cs @@ -3,7 +3,7 @@ namespace InnovEnergy.Lib.Units.Composite; public class Ac1Bus : AcPhase { - public Double Frequency { get; internal init; } + public Frequency Frequency { get; internal init; } public static Ac1Bus FromVoltageCurrentFrequencyPhi(Double voltageRms, diff --git a/csharp/Lib/Units/Composite/Ac3Bus.cs b/csharp/Lib/Units/Composite/Ac3Bus.cs index 358cc2af8..d9a1e2b42 100644 --- a/csharp/Lib/Units/Composite/Ac3Bus.cs +++ b/csharp/Lib/Units/Composite/Ac3Bus.cs @@ -6,11 +6,21 @@ namespace InnovEnergy.Lib.Units.Composite; public class Ac3Bus { - public AcPhase L1 { get; internal init; } - public AcPhase L2 { get; internal init; } - public AcPhase L3 { get; internal init; } - - public AcPower Power { get; internal init; } - - public Double Frequency { get; internal init; } + public AcPhase L1 { get; internal init; } + public AcPhase L2 { get; internal init; } + public AcPhase L3 { get; internal init; } + public AcPower Power { get; internal init; } + public Frequency Frequency { get; internal init; } + + public static Ac3Bus FromPhasesAndFrequency(AcPhase l1, + AcPhase l2, + AcPhase l3, + Frequency frequency) => new() + { + L1 = l1, + L2 = l2, + L3 = l3, + Power = AcPower.SumOf(l1.Power, l2.Power, l3.Power), + Frequency = frequency, + }; } \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/AcPhase.cs b/csharp/Lib/Units/Composite/AcPhase.cs index da0023fcc..1f99214fe 100644 --- a/csharp/Lib/Units/Composite/AcPhase.cs +++ b/csharp/Lib/Units/Composite/AcPhase.cs @@ -5,4 +5,36 @@ namespace InnovEnergy.Lib.Units.Composite; public class AcPhase : Bus { public AcPower Power { get; internal init; } + + public static AcPhase FromVoltageCurrentPhi(Voltage voltageRms, + Current currentRms, + Angle phi) => new() + { + Current = currentRms, + Voltage = voltageRms, + Power = AcPower.FromVoltageCurrentPhi(voltageRms, currentRms, phi) + }; + + public static AcPhase FromVoltageCurrentActiveReactive(Voltage voltageRms, + Current currentRms, + ActivePower activePower, + ReactivePower reactivePower) => new() + { + Current = currentRms, + Voltage = voltageRms, + Power = AcPower.FromActiveReactive(activePower, reactivePower) + }; + + public static AcPhase FromVoltageCurrentActiveReactiveApparent(Voltage voltageRms, + Current currentRms, + ActivePower activePower, + ReactivePower reactivePower, + ApparentPower apparentPower) => new() + { + Current = currentRms, + Voltage = voltageRms, + Power = AcPower.FromActiveReactiveApparent(activePower, reactivePower, apparentPower) + }; + + } \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/AcPower.cs b/csharp/Lib/Units/Composite/AcPower.cs index e9302be3e..68e9a1727 100644 --- a/csharp/Lib/Units/Composite/AcPower.cs +++ b/csharp/Lib/Units/Composite/AcPower.cs @@ -4,31 +4,85 @@ namespace InnovEnergy.Lib.Units.Composite; public class AcPower { - public Double Apparent { get; internal init; } - public Double Active { get; internal init; } - public Double Reactive { get; internal init; } - public Double Phi { get; internal init; } - public Double CosPhi { get; internal init; } + public ApparentPower Apparent { get; internal init; } + public ActivePower Active { get; internal init; } + public ReactivePower Reactive { get; internal init; } + public Angle Phi { get; internal init; } + public Double CosPhi { get; internal init; } - public static AcPower FromVoltageCurrentPhi(Double voltageRms, Double currentRms, Double phi) + + public static AcPower FromActiveReactiveApparent(ActivePower activePower, ReactivePower reactivePower, ApparentPower apparentPower) + { + var q = reactivePower.Value; + var p = activePower.Value; + var s = apparentPower.Value; + var phi = Atan2(q, p); + + return new AcPower + { + Active = p, + Reactive = q, + Apparent = s, + Phi = phi, + CosPhi = p/s, + }; + } + + public static AcPower FromActiveReactive(ActivePower activePower, ReactivePower reactivePower) + { + var q = reactivePower.Value; + var p = activePower.Value; + var s = Sqrt(p * p + q * q); + var phi = Atan2(q, p); + + return new AcPower + { + Active = p, + Reactive = q, + Apparent = s, + Phi = phi, + CosPhi = p/s, + }; + } + + public static AcPower FromVoltageCurrentPhi(Voltage voltageRms, Current currentRms, Angle phi) { if (voltageRms < 0) throw new ArgumentException("RMS value cannot be negative", nameof(voltageRms)); if (currentRms < 0) throw new ArgumentException("RMS value cannot be negative", nameof(currentRms)); - phi = NormalizePhi(phi); - - var cosPhi = Cos(phi); - var apparent = voltageRms * currentRms; + var cosPhi = Cos(phi.Value); + var apparent = voltageRms.Value * currentRms.Value; return new AcPower { Apparent = apparent, Active = apparent * cosPhi, - Reactive = apparent * Sin(phi), + Reactive = apparent * Sin(phi.Value), Phi = phi, CosPhi = cosPhi }; } + + public static AcPower SumOf(params AcPower[] phases) + { + var p = phases.Sum(l => l.Active.Value); + var q = phases.Sum(l => l.Reactive.Value); + var s = Sqrt(p * p + q * q); + + Angle phi = Atan2(q, p); + + return new AcPower + { + Apparent = s, + Active = p, + Reactive = q, + Phi = phi, + CosPhi = Cos(phi.Value) + }; + } + private static Double NormalizePhi(Double phi) => (phi + PI) % Tau - PI; // Tau is 2pi + + } \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/Bus.cs b/csharp/Lib/Units/Composite/Bus.cs index 7562c1c3b..396723c69 100644 --- a/csharp/Lib/Units/Composite/Bus.cs +++ b/csharp/Lib/Units/Composite/Bus.cs @@ -6,6 +6,6 @@ namespace InnovEnergy.Lib.Units.Composite; public abstract class Bus { - public Double Voltage { get; internal init; } - public Double Current { get; internal init; } + public Voltage Voltage { get; internal init; } + public Current Current { get; internal init; } } \ No newline at end of file diff --git a/csharp/Lib/Units/Composite/DcBus.cs b/csharp/Lib/Units/Composite/DcBus.cs index efcf436b8..9e9f3d373 100644 --- a/csharp/Lib/Units/Composite/DcBus.cs +++ b/csharp/Lib/Units/Composite/DcBus.cs @@ -2,9 +2,11 @@ namespace InnovEnergy.Lib.Units.Composite; public class DcBus : Bus { - public Double Power { get; internal init; } + private DcBus() {} - public static DcBus FromVoltageCurrent(Double voltage, Double current) => new() + public ActivePower Power { get; internal init; } + + public static DcBus FromVoltageCurrent(Voltage voltage, Current current) => new() { Voltage = voltage, Current = current, diff --git a/csharp/Lib/Units/Current.cs b/csharp/Lib/Units/Current.cs index 997fb5428..15df03a03 100644 --- a/csharp/Lib/Units/Current.cs +++ b/csharp/Lib/Units/Current.cs @@ -11,7 +11,7 @@ public readonly partial struct Current public Current(Double value) => Value = value; // P=UI - public static Power operator *(Current current, Voltage voltage) => new Power(current.Value * voltage.Value); + public static ActivePower operator *(Current current, Voltage voltage) => new ActivePower(current.Value * voltage.Value); // U=RI public static Voltage operator *(Current current, Resistance resistance) => new Voltage(resistance.Value* current.Value); diff --git a/csharp/Lib/Units/Energy.cs b/csharp/Lib/Units/Energy.cs index f949f9975..474b8449b 100644 --- a/csharp/Lib/Units/Energy.cs +++ b/csharp/Lib/Units/Energy.cs @@ -11,6 +11,6 @@ public readonly partial struct Energy public Energy(Double value) => Value = value; - public static Power operator /(Energy energy, TimeSpan timeSpan) => energy.Value * 1000 / timeSpan.TotalHours ; - public static Power operator /(Energy energy, UnixTimeSpan timeSpan) => energy.Value * 3_600_000 / timeSpan.Ticks; + public static ActivePower operator /(Energy energy, TimeSpan timeSpan) => energy.Value * 1000 / timeSpan.TotalHours ; + public static ActivePower operator /(Energy energy, UnixTimeSpan timeSpan) => energy.Value * 3_600_000 / timeSpan.Ticks; } \ No newline at end of file diff --git a/csharp/Lib/Units/Power.cs b/csharp/Lib/Units/Power.cs deleted file mode 100644 index 8a5e54b4e..000000000 --- a/csharp/Lib/Units/Power.cs +++ /dev/null @@ -1,23 +0,0 @@ -using InnovEnergy.Lib.Time.Unix; -using InnovEnergy.Lib.Units.Generator; - -namespace InnovEnergy.Lib.Units; - -[Generate] -public readonly partial struct Power -{ - public static String Unit => "W"; - public static String Symbol => "P"; - - public Power(Double value) => Value = value; - - // P=UI - public static Voltage operator /(Power power, Current current) => new Voltage(power.Value / current.Value); - public static Current operator /(Power power, Voltage voltage) => new Current(power.Value / voltage.Value); - - public static Energy operator *(Power power, TimeSpan timeSpan) => power.Value / 1000 * timeSpan.TotalHours; - public static Energy operator *(TimeSpan timeSpan, Power power) => power.Value / 1000 * timeSpan.TotalHours; - - public static Energy operator *(Power power, UnixTimeSpan timeSpan) => power.Value * timeSpan.Ticks / 3_600_000; - public static Energy operator *(UnixTimeSpan timeSpan, Power power) => power.Value * timeSpan.Ticks / 3_600_000; -} \ No newline at end of file diff --git a/csharp/Lib/Units/Units.cs b/csharp/Lib/Units/Units.cs index 71495bd3d..271a8f256 100644 --- a/csharp/Lib/Units/Units.cs +++ b/csharp/Lib/Units/Units.cs @@ -7,7 +7,7 @@ public static class Units public static Current A (this Double value) => value; public static Voltage V (this Double value) => value; - public static Power W (this Double value) => value; + public static ActivePower W (this Double value) => value; public static ReactivePower Var (this Double value) => value; public static ApparentPower Va (this Double value) => value; public static Resistance Ohm (this Double value) => value; diff --git a/csharp/Lib/Units/Voltage.cs b/csharp/Lib/Units/Voltage.cs index f4a430c60..119dc17a8 100644 --- a/csharp/Lib/Units/Voltage.cs +++ b/csharp/Lib/Units/Voltage.cs @@ -16,6 +16,6 @@ public readonly partial struct Voltage public static Current operator /(Voltage voltage, Resistance resistance) => new Current(voltage.Value / resistance.Value); // P=UI - public static Power operator *(Voltage voltage, Current current) => new Power(current.Value * voltage.Value); + public static ActivePower operator *(Voltage voltage, Current current) => new ActivePower(current.Value * voltage.Value); }