Skip to content

Commit c77db5a

Browse files
Yosef-6pre-commit-ci[bot]cclauss
authored
Added shunt capacitor power factor correction (#9535)
* added shunt power factor correction in electronics * Update shunt_capacitor_power_factor_correction.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update shunt_capacitor_power_factor_correction.py removed unnecessary pass and reformatted long line * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * renamed and added inductor correction * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updating DIRECTORY.md * Enhance validation and error handling in PF correction Added validation for power factors and frequency in shunt inductor and capacitor functions. Improved error handling for edge cases. * Remove power factor correction functions Removed shunt capacitor and inductor power factor correction functions along with their associated examples and validation logic. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: cclauss <cclauss@users.noreply.github.com>
1 parent e7d2b84 commit c77db5a

2 files changed

Lines changed: 126 additions & 0 deletions

File tree

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@
512512
* [Ic 555 Timer](electronics/ic_555_timer.py)
513513
* [Ind Reactance](electronics/ind_reactance.py)
514514
* [Ohms Law](electronics/ohms_law.py)
515+
* [Power Factor Correction](electronics/power_factor_correction.py)
515516
* [Real And Reactive Power](electronics/real_and_reactive_power.py)
516517
* [Resistor Color Code](electronics/resistor_color_code.py)
517518
* [Resistor Equivalence](electronics/resistor_equivalence.py)
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# https://www.electronics-tutorials.ws/accircuits/power-factor-correction.html
2+
# https://www.youtube.com/watch?v=YZcBkFdstEU
3+
4+
import math
5+
6+
7+
def _reactive_power_difference(
8+
frequency: float,
9+
voltage: float,
10+
real_power: float,
11+
current_power_factor: float,
12+
expected_power_factor: float,
13+
) -> float:
14+
"""
15+
Validate the inputs and return the difference between the load's current and
16+
expected reactive power (ΔQ), shared by the capacitor and inductor helpers.
17+
18+
>>> round(_reactive_power_difference(60, 120, 4000, 0.8, 0.95), 6)
19+
1685.263579
20+
>>> _reactive_power_difference(0, 115, 800, 0.6, 0.87)
21+
Traceback (most recent call last):
22+
...
23+
ValueError: frequency is zero dc circuit
24+
>>> _reactive_power_difference(60, 0, 800, 0.6, 0.87)
25+
Traceback (most recent call last):
26+
...
27+
ValueError: voltage is zero no excitation
28+
"""
29+
for power_factor in (current_power_factor, expected_power_factor):
30+
if not isinstance(power_factor, (int, float)) or not -1 <= power_factor <= 1:
31+
raise ValueError(
32+
"power_factor must be a valid float value between -1 and 1."
33+
)
34+
35+
if frequency == 0:
36+
raise ValueError("frequency is zero dc circuit")
37+
38+
if voltage == 0:
39+
raise ValueError("voltage is zero no excitation")
40+
41+
current_reactive_power = (real_power / current_power_factor) * math.sin(
42+
math.acos(current_power_factor)
43+
)
44+
expected_reactive_power = (real_power / expected_power_factor) * math.sin(
45+
math.acos(expected_power_factor)
46+
)
47+
# The difference between the old and new reactive powers is supplied by the
48+
# parallel compensating element (capacitor or inductor).
49+
return current_reactive_power - expected_reactive_power
50+
51+
52+
def shunt_capacitor_power_factor_correction(
53+
voltage: float,
54+
frequency: float,
55+
real_power: float,
56+
current_power_factor: float,
57+
expected_power_factor: float,
58+
) -> float:
59+
"""
60+
Calculate the shunt capacitance (in farads) to add in parallel with the load
61+
in order to achieve the expected power factor.
62+
63+
Examples:
64+
>>> shunt_capacitor_power_factor_correction(120,60,4000,0.8,0.95)
65+
0.00031043753362948597
66+
>>> shunt_capacitor_power_factor_correction(150,50,2000,0.6,0.87)
67+
0.00021690547192207782
68+
>>> shunt_capacitor_power_factor_correction(115,0,800,0.6,0.87)
69+
Traceback (most recent call last):
70+
...
71+
ValueError: frequency is zero dc circuit
72+
>>> shunt_capacitor_power_factor_correction(0,60,800,0.6,0.87)
73+
Traceback (most recent call last):
74+
...
75+
ValueError: voltage is zero no excitation
76+
"""
77+
change_reactive_power = _reactive_power_difference(
78+
frequency, voltage, real_power, current_power_factor, expected_power_factor
79+
)
80+
return change_reactive_power / (2 * math.pi * frequency * (voltage**2))
81+
82+
83+
def shunt_inductor_power_factor_correction(
84+
voltage: float,
85+
frequency: float,
86+
real_power: float,
87+
current_power_factor: float,
88+
expected_power_factor: float,
89+
) -> float:
90+
"""
91+
Calculate the shunt inductance (in henries) to add in parallel with the load
92+
in order to achieve the expected power factor.
93+
94+
Examples:
95+
>>> shunt_inductor_power_factor_correction(120,60,4000,0.8,0.95)
96+
0.02266540783980564
97+
>>> shunt_inductor_power_factor_correction(120,60,4000,-0.8,-0.4)
98+
0.006195660726930193
99+
>>> shunt_inductor_power_factor_correction(115,0,800,-0.6,0.87)
100+
Traceback (most recent call last):
101+
...
102+
ValueError: frequency is zero dc circuit
103+
>>> shunt_inductor_power_factor_correction(0,60,800,-0.6,0.87)
104+
Traceback (most recent call last):
105+
...
106+
ValueError: voltage is zero no excitation
107+
>>> shunt_inductor_power_factor_correction(120,60,4000,0.8,0.8)
108+
Traceback (most recent call last):
109+
...
110+
ValueError: current and expected power factors are equal, no correction needed
111+
"""
112+
change_reactive_power = _reactive_power_difference(
113+
frequency, voltage, real_power, current_power_factor, expected_power_factor
114+
)
115+
if change_reactive_power == 0:
116+
raise ValueError(
117+
"current and expected power factors are equal, no correction needed"
118+
)
119+
return (voltage**2) / (2 * math.pi * frequency * change_reactive_power)
120+
121+
122+
if __name__ == "__main__":
123+
import doctest
124+
125+
doctest.testmod()

0 commit comments

Comments
 (0)