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;
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<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);

View File

@ -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,

View File

@ -9,8 +9,18 @@ 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 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 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 Double Apparent { get; internal init; }
public Double Active { get; internal init; }
public Double Reactive { get; internal init; }
public Double Phi { 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
};
}
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 Double Voltage { get; internal init; }
public Double Current { get; internal init; }
public Voltage Voltage { 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 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,

View File

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

View File

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

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

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);
// 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);
}