units v2
This commit is contained in:
parent
bb51664a16
commit
249d4e7c31
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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; }
|
||||||
}
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue