using static DecimalMath.DecimalEx; namespace InnovEnergy.Lib.Units.Composite; public record AcPhase : Phase { public AcPhase(Voltage voltage, Current current, Angle phi) : base(voltage, current) { if (voltage < 0) throw new ArgumentException("RMS value cannot be negative", nameof(voltage)); if (current < 0) throw new ArgumentException("RMS value cannot be negative", nameof(current)); Phi = phi; } public Angle Phi { get; } public ApparentPower ApparentPower => Voltage.Value * Current.Value ; public Power ActivePower => ApparentPower.Value * PowerFactor; public ReactivePower ReactivePower => ApparentPower.Value * Sin(Phi); public Decimal PowerFactor => Cos(Phi); public static AcPhase operator +(AcPhase left, AcPhase right) { // the Voltages of two phases are expected to be in phase and equal var v = (left.Voltage + right.Voltage) / 2m; // TODO: check that l & r approximately equal // currents (RMS) can be different and out of phase // https://www.johndcook.com/blog/2020/08/17/adding-phase-shifted-sine-waves/ // IF // left(t) = ILeft sin(ωt) // right(t) = IRight sin(ωt + φ). // sum(t) = left(t) + right(t) = ISum sin(ωt + ψ). // THEN // ψ = arctan( IRight * sin(φ) / (ILeft + IRight cos(φ)) ). // C = IRight * sin(φ) / sin(ψ). // in this calc left(t) has zero phase shift. // we can shift both waves by -left.Phi, so // φ := right.phi - left.phi var phi = right.Phi - left.Phi; var phiSum = ATan2(right.Current * Sin(phi), left.Current + right.Current * Cos(phi)); var iSum = right.Current * Sin(phi) / Sin(phiSum); return new AcPhase(v, iSum, phiSum); } }