This commit is contained in:
ig 2023-05-04 09:36:30 +02:00
parent bb51664a16
commit 249d4e7c31
13 changed files with 156 additions and 58 deletions

View File

@ -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;
}

View File

@ -9,11 +9,11 @@ using System.CodeDom.Compiler;
namespace InnovEnergy.Lib.Units; namespace InnovEnergy.Lib.Units;
using T = Power; using T = ActivePower;
[GeneratedCode("generate.sh", "1")] [GeneratedCode("generate.sh", "1")]
[JsonConverter(typeof(PowerConverter))] [JsonConverter(typeof(ActivePowerConverter))]
public readonly partial struct Power public readonly partial struct ActivePower
{ {
public Double Value { get; } public Double Value { get; }
public override String ToString() => Value.RoundToSignificantDigits(Units.DisplaySignificantDigits) + Unit; public override String ToString() => Value.RoundToSignificantDigits(Units.DisplaySignificantDigits) + Unit;
@ -52,14 +52,14 @@ public readonly partial struct Power
} }
internal class PowerConverter : JsonConverter<Power> internal class ActivePowerConverter : JsonConverter<ActivePower>
{ {
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); var rounded = value.Value.RoundToSignificantDigits(Units.JsonSignificantDigits);

View File

@ -3,7 +3,7 @@ namespace InnovEnergy.Lib.Units.Composite;
public class Ac1Bus : AcPhase public class Ac1Bus : AcPhase
{ {
public Double Frequency { get; internal init; } public Frequency Frequency { get; internal init; }
public static Ac1Bus FromVoltageCurrentFrequencyPhi(Double voltageRms, public static Ac1Bus FromVoltageCurrentFrequencyPhi(Double voltageRms,

View File

@ -9,8 +9,18 @@ public class Ac3Bus
public AcPhase L1 { get; internal init; } public AcPhase L1 { get; internal init; }
public AcPhase L2 { get; internal init; } public AcPhase L2 { get; internal init; }
public AcPhase L3 { get; internal init; } public AcPhase L3 { get; internal init; }
public AcPower Power { get; internal init; } public AcPower Power { get; internal init; }
public Frequency Frequency { get; internal init; }
public Double 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,
};
} }

View File

@ -5,4 +5,36 @@ namespace InnovEnergy.Lib.Units.Composite;
public class AcPhase : Bus public class AcPhase : Bus
{ {
public AcPower Power { get; internal init; } 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)
};
} }

View File

@ -4,31 +4,85 @@ namespace InnovEnergy.Lib.Units.Composite;
public class AcPower public class AcPower
{ {
public Double Apparent { get; internal init; } public ApparentPower Apparent { get; internal init; }
public Double Active { get; internal init; } public ActivePower Active { get; internal init; }
public Double Reactive { get; internal init; } public ReactivePower Reactive { get; internal init; }
public Double Phi { get; internal init; } public Angle Phi { get; internal init; }
public Double CosPhi { 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 (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)); if (currentRms < 0) throw new ArgumentException("RMS value cannot be negative", nameof(currentRms));
phi = NormalizePhi(phi); var cosPhi = Cos(phi.Value);
var apparent = voltageRms.Value * currentRms.Value;
var cosPhi = Cos(phi);
var apparent = voltageRms * currentRms;
return new AcPower return new AcPower
{ {
Apparent = apparent, Apparent = apparent,
Active = apparent * cosPhi, Active = apparent * cosPhi,
Reactive = apparent * Sin(phi), Reactive = apparent * Sin(phi.Value),
Phi = phi, Phi = phi,
CosPhi = cosPhi CosPhi = cosPhi
}; };
} }
private static Double NormalizePhi(Double phi) => (phi + PI) % Tau - PI; // Tau is 2pi
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
} }

View File

@ -6,6 +6,6 @@ namespace InnovEnergy.Lib.Units.Composite;
public abstract class Bus public abstract class Bus
{ {
public Double Voltage { get; internal init; } public Voltage Voltage { get; internal init; }
public Double Current { get; internal init; } public Current Current { get; internal init; }
} }

View File

@ -2,9 +2,11 @@ namespace InnovEnergy.Lib.Units.Composite;
public class DcBus : Bus 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, Voltage = voltage,
Current = current, Current = current,

View File

@ -11,7 +11,7 @@ public readonly partial struct Current
public Current(Double value) => Value = value; public Current(Double value) => Value = value;
// P=UI // 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 // U=RI
public static Voltage operator *(Current current, Resistance resistance) => new Voltage(resistance.Value* current.Value); public static Voltage operator *(Current current, Resistance resistance) => new Voltage(resistance.Value* current.Value);

View File

@ -11,6 +11,6 @@ public readonly partial struct Energy
public Energy(Double value) => Value = value; public Energy(Double value) => Value = value;
public static Power operator /(Energy energy, TimeSpan timeSpan) => energy.Value * 1000 / timeSpan.TotalHours ; public static ActivePower 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, UnixTimeSpan timeSpan) => energy.Value * 3_600_000 / timeSpan.Ticks;
} }

View File

@ -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;
}

View File

@ -7,7 +7,7 @@ public static class Units
public static Current A (this Double value) => value; public static Current A (this Double value) => value;
public static Voltage V (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 ReactivePower Var (this Double value) => value;
public static ApparentPower Va (this Double value) => value; public static ApparentPower Va (this Double value) => value;
public static Resistance Ohm (this Double value) => value; public static Resistance Ohm (this Double value) => value;

View File

@ -16,6 +16,6 @@ public readonly partial struct Voltage
public static Current operator /(Voltage voltage, Resistance resistance) => new Current(voltage.Value / resistance.Value); public static Current operator /(Voltage voltage, Resistance resistance) => new Current(voltage.Value / resistance.Value);
// P=UI // 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);
} }