diff --git a/.vscode/settings.json b/.vscode/settings.json index 1f5a90f0..74e2a60f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { - // Jupyter + // Jupyter Notebook "jupyter.notebookFileRoot": "${workspaceFolder}", + "notebook.formatOnSave.enabled": true, + "notebook.codeActionsOnSave": { + "source.organizeImports.ruff": true, + }, // Python "python.analysis.diagnosticSeverityOverrides": { diff --git a/doc/Changelog.md b/doc/Changelog.md index c085fa53..989833d6 100644 --- a/doc/Changelog.md +++ b/doc/Changelog.md @@ -4,6 +4,10 @@ **In development** +* [GH99](https://github.com/RoseauTechnologies/Roseau_Load_Flow/issues/99) Add `Line.res_series_currents` + and `Line.res_shunt_currents` properties to get the currents in the series and shunt components + of lines. Also added `ElectricalNetwork.res_lines` that contains the series losses and currents + of all the lines in the network. The property `ElectricalNetwork.res_lines_losses` was removed. * [GH100](https://github.com/RoseauTechnologies/Roseau_Load_Flow/issues/100) Fix the `Yz` transformers * [PR97](https://github.com/RoseauTechnologies/Roseau_Load_Flow/pull/97) Add the model section to the documentation * [PR96](https://github.com/RoseauTechnologies/Roseau_Load_Flow/pull/96) diff --git a/doc/models/Line/ShuntLine.md b/doc/models/Line/ShuntLine.md index d2254c9e..2e1f1e42 100644 --- a/doc/models/Line/ShuntLine.md +++ b/doc/models/Line/ShuntLine.md @@ -150,12 +150,33 @@ en.res_branches[["current2"]].transform([np.abs, ft.partial(np.angle, deg=True)] # | ('line', 'c') | 5.68434e-14 | 0 | # | ('line', 'n') | 20.6273 | -12.625 | -# The losses of the line can also be accessed. One can remark that there are shunt losses -en.res_lines_losses -# | | 'series_losses' | 'shunt_losses' | 'total_losses' | -# |:--------------|-------------------------:|---------------------:|------------------:| -# | ('line', 'a') | 171.841+57.2802j | -1.59017-26.6385j | 170.251+ 30.6417j | -# | ('line', 'b') | 38.1291+12.7097j | 1.01834-28.5657j | 39.1474 -15.856j | -# | ('line', 'c') | 0.00107497+0.000358324j | 3.69511-27.4104j | 3.69618-27.41j | -# | ('line', 'n') | 127.574 +42.5246j | 0.0351686+0.0139828j | 127.609+42.5385j | +# The currents in the series components of the line +en.res_lines[["series_current"]].transform([np.abs, ft.partial(np.angle, deg=True)]) +# | | ('series_current', 'absolute') | ('series_current', 'angle') | +# |:--------------|---------------------------------:|------------------------------:| +# | ('line', 'a') | 23.9333 | 15.5496 | +# | ('line', 'b') | 11.2737 | -104.796 | +# | ('line', 'c') | 0.0598601 | -157.579 | +# | ('line', 'n') | 20.6215 | 167.376 | + +# The losses of the series components of line can also be accessed +en.res_lines[["series_losses"]].transform([np.real, np.imag]) +# | | ('series_losses', 'real') | ('series_losses', 'imag') | +# |:--------------|----------------------------:|----------------------------:| +# | ('line', 'a') | 171.841 | 57.2802 | +# | ('line', 'b') | 38.1291 | 12.7097 | +# | ('line', 'c') | 0.00107497 | 0.000358324 | +# | ('line', 'n') | 127.574 | 42.5246 | + +# The shunt losses can be computed. Notice that the shunt losses are not null for the shunt line. +res_lines = en.res_lines +total_losses = res_lines["power1"] + res_lines["power2"] # total = series + shunt +shunt_losses = total_losses - res_lines["series_losses"] +shunt_losses.to_frame("shunt_losses").transform([np.real, np.imag]) +# | | ('shunt_losses', 'real') | ('shunt_losses', 'imag') | +# |:--------------|---------------------------:|---------------------------:| +# | ('line', 'a') | -1.59017 | -26.6385 | +# | ('line', 'b') | 1.01834 | -28.5657 | +# | ('line', 'c') | 3.69511 | -27.4104 | +# | ('line', 'n') | 0.0351686 | 0.0139828 | ``` diff --git a/doc/models/Line/SimplifiedLine.md b/doc/models/Line/SimplifiedLine.md index 94337e7e..836a0640 100644 --- a/doc/models/Line/SimplifiedLine.md +++ b/doc/models/Line/SimplifiedLine.md @@ -96,14 +96,30 @@ en.res_branches[["current2"]].transform([np.abs, ft.partial(np.angle, deg=True)] # | ('line', 'c') | 0 | 0 | # | ('line', 'n') | 20.628 | -11.5242 | -# The two currents are equal in magnitude and opposite in phase, as expected +# The currents in the series components of the line +en.res_lines[["series_current"]].transform([np.abs, ft.partial(np.angle, deg=True)]) +# | | ('series_current', 'absolute') | ('series_current', 'angle') | +# |:--------------|---------------------------------:|------------------------------:| +# | ('line', 'a') | 24.1958 | 16.4456 | +# | ('line', 'b') | 11.3722 | -105.263 | +# | ('line', 'c') | 0 | 0 | +# | ('line', 'n') | 20.628 | 168.476 | + +# All currents are equal in magnitude for a simplified lines as no current escapes to the ground. +# The current from bus 2 has an opposite direction to the current from bus 1 as expected. # The losses of the line can also be accessed. One can remark that there are no shunt losses -en.res_lines_losses -# | | 'series_losses' | 'shunt_losses' | 'total_losses' | -# |:--------------|-----------------------:|---------------:|----------------------:| -# | ('line', 'a') | 204.904 -2.66329e-15 | 0j | 204.904 -2.66329e-15 | -# | ('line', 'b') | 45.2646 -8.96306e-16 | 0j | 45.2646 -8.96306e-16 | -# | ('line', 'c') | 0j | 0j | 0j | -# | ('line', 'n') | 148.93 + 6.11606e-15 | 0j | 148.93 + 6.11606e-15 | +en.res_lines[["series_losses"]].transform([np.real, np.imag]) +# | | ('series_losses', 'real') | ('series_losses', 'imag') | +# |:--------------|----------------------------:|----------------------------:| +# | ('line', 'a') | 204.904 | -2.66329e-15 | +# | ('line', 'b') | 45.2646 | -8.96306e-16 | +# | ('line', 'c') | 0 | 0 | +# | ('line', 'n') | 148.93 | 7.62657e-16 | + +# With a simplified model, all the losses are caused by the series impedance of the line +res_lines = en.res_lines +total_losses = res_lines["power1"] + res_lines["power2"] # total = series + shunt +np.allclose(total_losses, res_lines["series_losses"]) +# True ``` diff --git a/doc/notebooks/Getting_Started.ipynb b/doc/notebooks/Getting_Started.ipynb index 2ba76cc3..b20993f1 100644 --- a/doc/notebooks/Getting_Started.ipynb +++ b/doc/notebooks/Getting_Started.ipynb @@ -169,7 +169,9 @@ "outputs": [ { "data": { - "text/plain": "" + "text/plain": [ + "" + ] }, "execution_count": 3, "metadata": {}, @@ -251,7 +253,9 @@ "outputs": [ { "data": { - "text/plain": "2" + "text/plain": [ + "2" + ] }, "execution_count": 5, "metadata": {}, @@ -283,7 +287,16 @@ "outputs": [ { "data": { - "text/plain": "{'solver': 'newton_goldstein',\n 'solver_params': {'m1': 0.1, 'm2': 0.9},\n 'tolerance': 1e-06,\n 'max_iterations': 20,\n 'warm_start': True,\n 'status': 'success',\n 'iterations': 2,\n 'residual': 1.8595619621919468e-07}" + "text/plain": [ + "{'solver': 'newton_goldstein',\n", + " 'solver_params': {'m1': 0.1, 'm2': 0.9},\n", + " 'tolerance': 1e-06,\n", + " 'max_iterations': 20,\n", + " 'warm_start': True,\n", + " 'status': 'success',\n", + " 'iterations': 2,\n", + " 'residual': 1.8595619621919468e-07}" + ] }, "execution_count": 6, "metadata": {}, @@ -388,9 +401,16 @@ "outputs": [ { "data": { - "text/plain": "array([ 2.21928183e+02-2.23031066e-21j, -1.10964092e+02-1.92195445e+02j,\n -1.10964092e+02+1.92195445e+02j, 2.35402704e-15-5.99225499e-20j]) ", - "text/html": "
Magnitude
[ 2.21928183e+02-2.23031066e-21j -1.10964092e+02-1.92195445e+02j
-1.10964092e+02+1.92195445e+02j 2.35402704e-15-5.99225499e-20j]
Unitsvolt
", - "text/latex": "$\\begin{pmatrix} & & & \\end{pmatrix}\\ \\mathrm{volt}$" + "text/html": [ + "
Magnitude
[ 2.21928183e+02-2.59992221e-18j -1.10964092e+02-1.92195445e+02j
-1.10964092e+02+1.92195445e+02j 2.65787708e-15-6.66257154e-17j]
Unitsvolt
" + ], + "text/latex": [ + "$\\begin{pmatrix} & & & \\end{pmatrix}\\ \\mathrm{volt}$" + ], + "text/plain": [ + "array([ 2.21928183e+02-2.59992221e-18j, -1.10964092e+02-1.92195445e+02j,\n", + " -1.10964092e+02+1.92195445e+02j, 2.65787708e-15-6.66257154e-17j]) " + ] }, "execution_count": 7, "metadata": {}, @@ -422,9 +442,15 @@ "outputs": [ { "data": { - "text/plain": "array([0.22192818, 0.22192818, 0.22192818]) ", - "text/html": "
Magnitude
[0.221928183361166 0.22192818336116596 0.22192818336116596]
Unitskilovolt
", - "text/latex": "$\\begin{pmatrix} & & \\end{pmatrix}\\ \\mathrm{kilovolt}$" + "text/html": [ + "
Magnitude
[0.221928183361166 0.22192818336116596 0.22192818336116596]
Unitskilovolt
" + ], + "text/latex": [ + "$\\begin{pmatrix} & & \\end{pmatrix}\\ \\mathrm{kilovolt}$" + ], + "text/plain": [ + "array([0.22192818, 0.22192818, 0.22192818]) " + ] }, "execution_count": 8, "metadata": {}, @@ -477,7 +503,12 @@ "outputs": [ { "data": { - "text/plain": "(array([ 4.50596216e+01+1.11515533e-20j, -2.25298108e+01-3.90227770e+01j,\n -2.25298108e+01+3.90227770e+01j, -1.17701352e-14+2.99612750e-19j]) ,\n array([-4.50596216e+01-1.11515533e-20j, 2.25298108e+01+3.90227770e+01j,\n 2.25298108e+01-3.90227770e+01j, 1.17701352e-14-2.99612750e-19j]) )" + "text/plain": [ + "(array([ 4.50596216e+01+1.29996111e-17j, -2.25298108e+01-3.90227770e+01j,\n", + " -2.25298108e+01+3.90227770e+01j, -1.32893854e-14+3.33128577e-16j]) ,\n", + " array([-4.50596216e+01-1.29996111e-17j, 2.25298108e+01+3.90227770e+01j,\n", + " 2.25298108e+01-3.90227770e+01j, 1.32893854e-14-3.33128577e-16j]) )" + ] }, "execution_count": 9, "metadata": {}, @@ -503,7 +534,7 @@ "* `res_buses`: Buses potentials indexed by *(bus id, phase)*\n", "* `res_buses_voltages`: Buses voltages indexed by *(bus id, voltage phase)*\n", "* `res_branches`: Branches currents, powers, and potentials indexed by *(branch id, phase)*\n", - "* `res_lines_losses`: Lines series, shunt, and total losses indexed by *(line id, phase)*\n", + "* `res_lines`: Lines currents, powers, potentials, series losses, series currents indexed by *(line id, phase)*\n", "* `res_loads`: Loads currents, powers, and potentials indexed by *(load id, phase)*\n", "* `res_loads_voltages`: Loads voltages indexed by *(load id, voltage phase)*\n", "* `res_loads_flexible_powers`: Loads flexible powers (only for flexible loads) indexed by\n", @@ -532,8 +563,85 @@ "outputs": [ { "data": { - "text/plain": " potential\nbus_id phase \nsb a 2.309401e+02+1.540744e-34j\n b -1.154701e+02-2.000000e+02j\n c -1.154701e+02+2.000000e+02j\n n 0.000000e+00+0.000000e+00j\nlb a 2.219282e+02-2.230311e-21j\n b -1.109641e+02-1.921954e+02j\n c -1.109641e+02+1.921954e+02j\n n 2.354027e-15-5.992255e-20j", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
potential
bus_idphase
sba2.309401e+02+1.540744e-34j
b-1.154701e+02-2.000000e+02j
c-1.154701e+02+2.000000e+02j
n0.000000e+00+0.000000e+00j
lba2.219282e+02-2.230311e-21j
b-1.109641e+02-1.921954e+02j
c-1.109641e+02+1.921954e+02j
n2.354027e-15-5.992255e-20j
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
potential
bus_idphase
sba2.309401e+02+0.000000e+00j
b-1.154701e+02-2.000000e+02j
c-1.154701e+02+2.000000e+02j
n0.000000e+00+0.000000e+00j
lba2.219282e+02-2.599922e-18j
b-1.109641e+02-1.921954e+02j
c-1.109641e+02+1.921954e+02j
n2.657877e-15-6.662572e-17j
\n", + "
" + ], + "text/plain": [ + " potential\n", + "bus_id phase \n", + "sb a 2.309401e+02+0.000000e+00j\n", + " b -1.154701e+02-2.000000e+02j\n", + " c -1.154701e+02+2.000000e+02j\n", + " n 0.000000e+00+0.000000e+00j\n", + "lb a 2.219282e+02-2.599922e-18j\n", + " b -1.109641e+02-1.921954e+02j\n", + " c -1.109641e+02+1.921954e+02j\n", + " n 2.657877e-15-6.662572e-17j" + ] }, "execution_count": 10, "metadata": {}, @@ -556,8 +664,75 @@ "outputs": [ { "data": { - "text/plain": " voltage\nbus_id phase \nsb an 230.9401008+0.0000000j\n bn -115.470054-200.000000j\n cn -115.470054+200.000000j\nlb an 221.9281803+0.0000000j\n bn -110.964092-192.195445j\n cn -110.964092+192.195445j", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
voltage
bus_idphase
sban230.9401008+0.0000000j
bn-115.470054-200.000000j
cn-115.470054+200.000000j
lban221.9281803+0.0000000j
bn-110.964092-192.195445j
cn-110.964092+192.195445j
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
voltage
bus_idphase
sban230.9401008+0.0000000j
bn-115.470054-200.000000j
cn-115.470054+200.000000j
lban221.9281803+0.0000000j
bn-110.964092-192.195445j
cn-110.964092+192.195445j
\n", + "
" + ], + "text/plain": [ + " voltage\n", + "bus_id phase \n", + "sb an 230.9401008+0.0000000j\n", + " bn -115.470054-200.000000j\n", + " cn -115.470054+200.000000j\n", + "lb an 221.9281803+0.0000000j\n", + " bn -110.964092-192.195445j\n", + " cn -110.964092+192.195445j" + ] }, "execution_count": 11, "metadata": {}, @@ -580,8 +755,108 @@ "outputs": [ { "data": { - "text/plain": " current1 current2 \\\nbranch_id phase \nline a 4.505962e+01+1.115155e-20j -4.505962e+01-1.115155e-20j \n b -2.252981e+01-3.902278e+01j 2.252981e+01+3.902278e+01j \n c -2.252981e+01+3.902278e+01j 2.252981e+01-3.902278e+01j \n n -1.177014e-14+2.996127e-19j 1.177014e-14-2.996127e-19j \n\n power1 power2 \\\nbranch_id phase \nline a 10406.073858-0.000000j -1.000000e+04+2.575341e-18j \n b 10406.073858+0.000000j -1.000000e+04-4.547474e-12j \n c 10406.073858-0.000000j -1.000000e+04+4.547474e-12j \n n 0.00000000+0.00000000j 2.770722e-29+8.552847e-50j \n\n potential1 potential2 \nbranch_id phase \nline a 230.9401008+0.0000000j 2.219282e+02-2.230311e-21j \n b -115.470054-200.000000j -1.109641e+02-1.921954e+02j \n c -115.470054+200.000000j -1.109641e+02+1.921954e+02j \n n 0.00000000+0.00000000j 2.354027e-15-5.992255e-20j ", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
current1current2power1power2potential1potential2
branch_idphase
linea4.505962e+01+1.115155e-20j-4.505962e+01-1.115155e-20j10406.073858-0.000000j-1.000000e+04+2.575341e-18j230.9401008+0.0000000j2.219282e+02-2.230311e-21j
b-2.252981e+01-3.902278e+01j2.252981e+01+3.902278e+01j10406.073858+0.000000j-1.000000e+04-4.547474e-12j-115.470054-200.000000j-1.109641e+02-1.921954e+02j
c-2.252981e+01+3.902278e+01j2.252981e+01-3.902278e+01j10406.073858-0.000000j-1.000000e+04+4.547474e-12j-115.470054+200.000000j-1.109641e+02+1.921954e+02j
n-1.177014e-14+2.996127e-19j1.177014e-14-2.996127e-19j0.00000000+0.00000000j2.770722e-29+8.552847e-50j0.00000000+0.00000000j2.354027e-15-5.992255e-20j
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
current1current2power1power2potential1potential2
branch_idphase
linea4.505962e+01+1.299961e-17j-4.505962e+01-1.299961e-17j10406.073858-0.000000j-1.000000e+04+3.002132e-15j230.9401008+0.0000000j2.219282e+02-2.599922e-18j
b-2.252981e+01-3.902278e+01j2.252981e+01+3.902278e+01j10406.073858+0.000000j-1.000000e+04-4.118724e-12j-115.470054-200.000000j-1.109641e+02-1.921954e+02j
c-2.252981e+01+3.902278e+01j2.252981e+01-3.902278e+01j10406.073858-0.000000j-1.000000e+04+4.118724e-12j-115.470054+200.000000j-1.109641e+02+1.921954e+02j
n-1.328939e-14+3.331286e-16j1.328939e-14-3.331286e-16j0.00000000+0.00000000j3.534375e-29+8.199138e-47j0.00000000+0.00000000j2.657877e-15-6.662572e-17j
\n", + "
" + ], + "text/plain": [ + " current1 current2 \\\n", + "branch_id phase \n", + "line a 4.505962e+01+1.299961e-17j -4.505962e+01-1.299961e-17j \n", + " b -2.252981e+01-3.902278e+01j 2.252981e+01+3.902278e+01j \n", + " c -2.252981e+01+3.902278e+01j 2.252981e+01-3.902278e+01j \n", + " n -1.328939e-14+3.331286e-16j 1.328939e-14-3.331286e-16j \n", + "\n", + " power1 power2 \\\n", + "branch_id phase \n", + "line a 10406.073858-0.000000j -1.000000e+04+3.002132e-15j \n", + " b 10406.073858+0.000000j -1.000000e+04-4.118724e-12j \n", + " c 10406.073858-0.000000j -1.000000e+04+4.118724e-12j \n", + " n 0.00000000+0.00000000j 3.534375e-29+8.199138e-47j \n", + "\n", + " potential1 potential2 \n", + "branch_id phase \n", + "line a 230.9401008+0.0000000j 2.219282e+02-2.599922e-18j \n", + " b -115.470054-200.000000j -1.109641e+02-1.921954e+02j \n", + " c -115.470054+200.000000j -1.109641e+02+1.921954e+02j \n", + " n 0.00000000+0.00000000j 2.657877e-15-6.662572e-17j " + ] }, "execution_count": 12, "metadata": {}, @@ -604,8 +879,127 @@ "outputs": [ { "data": { - "text/plain": " series_losses shunt_losses \\\nline_id phase \nline a 4.060739e+02+0.000000e+00j 0.0+0.0j \n b 4.060739e+02+0.000000e+00j 0.0+0.0j \n c 4.060739e+02+0.000000e+00j 0.0+0.0j \n n 2.770722e-29+8.552847e-50j 0.0+0.0j \n\n total_losses \nline_id phase \nline a 4.060739e+02+0.000000e+00j \n b 4.060739e+02+0.000000e+00j \n c 4.060739e+02+0.000000e+00j \n n 2.770722e-29+8.552847e-50j ", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
series_lossesshunt_lossestotal_losses
line_idphase
linea4.060739e+02+0.000000e+00j0.0+0.0j4.060739e+02+0.000000e+00j
b4.060739e+02+0.000000e+00j0.0+0.0j4.060739e+02+0.000000e+00j
c4.060739e+02+0.000000e+00j0.0+0.0j4.060739e+02+0.000000e+00j
n2.770722e-29+8.552847e-50j0.0+0.0j2.770722e-29+8.552847e-50j
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
current1current2power1power2potential1potential2series_lossesseries_current
line_idphase
linea4.505962e+01+1.299961e-17j-4.505962e+01-1.299961e-17j10406.073858-0.000000j-1.000000e+04+3.002132e-15j230.9401008+0.0000000j2.219282e+02-2.599922e-18j4.060739e+02-3.046946e-33j4.505962e+01+1.299961e-17j
b-2.252981e+01-3.902278e+01j2.252981e+01+3.902278e+01j10406.073858+0.000000j-1.000000e+04-4.118724e-12j-115.470054-200.000000j-1.109641e+02-1.921954e+02j4.060739e+02-8.298221e-15j-2.252981e+01-3.902278e+01j
c-2.252981e+01+3.902278e+01j2.252981e+01-3.902278e+01j10406.073858-0.000000j-1.000000e+04+4.118724e-12j-115.470054+200.000000j-1.109641e+02+1.921954e+02j4.060739e+02+8.298221e-15j-2.252981e+01+3.902278e+01j
n-1.328939e-14+3.331286e-16j1.328939e-14-3.331286e-16j0.00000000-0.00000000j3.534375e-29+8.199138e-47j0.00000000+0.00000000j2.657877e-15-6.662572e-17j3.534375e-29+8.199138e-47j-1.328939e-14+3.331286e-16j
\n", + "
" + ], + "text/plain": [ + " current1 current2 \\\n", + "line_id phase \n", + "line a 4.505962e+01+1.299961e-17j -4.505962e+01-1.299961e-17j \n", + " b -2.252981e+01-3.902278e+01j 2.252981e+01+3.902278e+01j \n", + " c -2.252981e+01+3.902278e+01j 2.252981e+01-3.902278e+01j \n", + " n -1.328939e-14+3.331286e-16j 1.328939e-14-3.331286e-16j \n", + "\n", + " power1 power2 \\\n", + "line_id phase \n", + "line a 10406.073858-0.000000j -1.000000e+04+3.002132e-15j \n", + " b 10406.073858+0.000000j -1.000000e+04-4.118724e-12j \n", + " c 10406.073858-0.000000j -1.000000e+04+4.118724e-12j \n", + " n 0.00000000-0.00000000j 3.534375e-29+8.199138e-47j \n", + "\n", + " potential1 potential2 \\\n", + "line_id phase \n", + "line a 230.9401008+0.0000000j 2.219282e+02-2.599922e-18j \n", + " b -115.470054-200.000000j -1.109641e+02-1.921954e+02j \n", + " c -115.470054+200.000000j -1.109641e+02+1.921954e+02j \n", + " n 0.00000000+0.00000000j 2.657877e-15-6.662572e-17j \n", + "\n", + " series_losses series_current \n", + "line_id phase \n", + "line a 4.060739e+02-3.046946e-33j 4.505962e+01+1.299961e-17j \n", + " b 4.060739e+02-8.298221e-15j -2.252981e+01-3.902278e+01j \n", + " c 4.060739e+02+8.298221e-15j -2.252981e+01+3.902278e+01j \n", + " n 3.534375e-29+8.199138e-47j -1.328939e-14+3.331286e-16j " + ] }, "execution_count": 13, "metadata": {}, @@ -613,7 +1007,7 @@ } ], "source": [ - "en.res_lines_losses" + "en.res_lines" ] }, { @@ -628,8 +1022,83 @@ "outputs": [ { "data": { - "text/plain": " current power \\\nload_id phase \nload a 4.505962e+01+1.171366e-20j 1.000000e+04-2.700087e-18j \n b -2.252981e+01-3.902278e+01j 1.000000e+04-9.094947e-13j \n c -2.252981e+01+3.902278e+01j 1.000000e+04+9.094947e-13j \n n -2.131628e-14+0.000000e+00j -5.017910e-29+1.277326e-33j \n\n potential \nload_id phase \nload a 2.219282e+02-2.230311e-21j \n b -1.109641e+02-1.921954e+02j \n c -1.109641e+02+1.921954e+02j \n n 2.354027e-15-5.992255e-20j ", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
currentpowerpotential
load_idphase
loada4.505962e+01+1.171366e-20j1.000000e+04-2.700087e-18j2.219282e+02-2.230311e-21j
b-2.252981e+01-3.902278e+01j1.000000e+04-9.094947e-13j-1.109641e+02-1.921954e+02j
c-2.252981e+01+3.902278e+01j1.000000e+04+9.094947e-13j-1.109641e+02+1.921954e+02j
n-2.131628e-14+0.000000e+00j-5.017910e-29+1.277326e-33j2.354027e-15-5.992255e-20j
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
currentpowerpotential
load_idphase
loada4.505962e+01+1.299960e-17j1.000000e+04-3.002130e-15j2.219282e+02-2.599922e-18j
b-2.252981e+01-3.902278e+01j1.000000e+04-4.890505e-13j-1.109641e+02-1.921954e+02j
c-2.252981e+01+3.902278e+01j1.000000e+04+4.890505e-13j-1.109641e+02+1.921954e+02j
n-2.131628e-14+0.000000e+00j-5.665606e-29+1.420213e-30j2.657877e-15-6.662572e-17j
\n", + "
" + ], + "text/plain": [ + " current power \\\n", + "load_id phase \n", + "load a 4.505962e+01+1.299960e-17j 1.000000e+04-3.002130e-15j \n", + " b -2.252981e+01-3.902278e+01j 1.000000e+04-4.890505e-13j \n", + " c -2.252981e+01+3.902278e+01j 1.000000e+04+4.890505e-13j \n", + " n -2.131628e-14+0.000000e+00j -5.665606e-29+1.420213e-30j \n", + "\n", + " potential \n", + "load_id phase \n", + "load a 2.219282e+02-2.599922e-18j \n", + " b -1.109641e+02-1.921954e+02j \n", + " c -1.109641e+02+1.921954e+02j \n", + " n 2.657877e-15-6.662572e-17j " + ] }, "execution_count": 14, "metadata": {}, @@ -652,8 +1121,59 @@ "outputs": [ { "data": { - "text/plain": " voltage\nload_id phase \nload an 221.9281803+0.0000000j\n bn -110.964092-192.195445j\n cn -110.964092+192.195445j", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
voltage
load_idphase
loadan221.9281803+0.0000000j
bn-110.964092-192.195445j
cn-110.964092+192.195445j
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
voltage
load_idphase
loadan221.9281803+0.0000000j
bn-110.964092-192.195445j
cn-110.964092+192.195445j
\n", + "
" + ], + "text/plain": [ + " voltage\n", + "load_id phase \n", + "load an 221.9281803+0.0000000j\n", + " bn -110.964092-192.195445j\n", + " cn -110.964092+192.195445j" + ] }, "execution_count": 15, "metadata": {}, @@ -676,8 +1196,83 @@ "outputs": [ { "data": { - "text/plain": " current power \\\nsource_id phase \nvs a -4.505962e+01+0.000000e+00j -10406.073858-0.000000j \n b 2.252981e+01+3.902278e+01j -10406.073858+0.000000j \n c 2.252981e+01-3.902278e+01j -10406.073858+0.000000j \n n 1.177357e-14-3.097125e-18j 0.00000000+0.00000000j \n\n potential \nsource_id phase \nvs a 230.9401008+0.0000000j \n b -115.470054-200.000000j \n c -115.470054+200.000000j \n n 0.00000000+0.00000000j ", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
currentpowerpotential
source_idphase
vsa-4.505962e+01+0.000000e+00j-10406.073858-0.000000j230.9401008+0.0000000j
b2.252981e+01+3.902278e+01j-10406.073858+0.000000j-115.470054-200.000000j
c2.252981e+01-3.902278e+01j-10406.073858+0.000000j-115.470054+200.000000j
n1.177357e-14-3.097125e-18j0.00000000+0.00000000j0.00000000+0.00000000j
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
currentpowerpotential
source_idphase
vsa-4.505962e+01-1.387779e-17j-10406.073858+0.000000j230.9401008+0.0000000j
b2.252981e+01+3.902278e+01j-10406.073858-0.000000j-115.470054-200.000000j
c2.252981e+01-3.902278e+01j-10406.073858+0.000000j-115.470054+200.000000j
n1.179612e-14+1.993850e-17j0.00000000+0.00000000j0.00000000+0.00000000j
\n", + "
" + ], + "text/plain": [ + " current power \\\n", + "source_id phase \n", + "vs a -4.505962e+01-1.387779e-17j -10406.073858+0.000000j \n", + " b 2.252981e+01+3.902278e+01j -10406.073858-0.000000j \n", + " c 2.252981e+01-3.902278e+01j -10406.073858+0.000000j \n", + " n 1.179612e-14+1.993850e-17j 0.00000000+0.00000000j \n", + "\n", + " potential \n", + "source_id phase \n", + "vs a 230.9401008+0.0000000j \n", + " b -115.470054-200.000000j \n", + " c -115.470054+200.000000j \n", + " n 0.00000000+0.00000000j " + ] }, "execution_count": 16, "metadata": {}, @@ -700,8 +1295,46 @@ "outputs": [ { "data": { - "text/plain": " potential\nground_id \ngnd 0.0+0.0j", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
potential
ground_id
gnd0.0+0.0j
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
potential
ground_id
gnd0.0+0.0j
\n", + "
" + ], + "text/plain": [ + " potential\n", + "ground_id \n", + "gnd 0.0+0.0j" + ] }, "execution_count": 17, "metadata": {}, @@ -724,8 +1357,46 @@ "outputs": [ { "data": { - "text/plain": " current\npotential_ref_id \npref 3.433019e-18-2.797513e-18j", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
current
potential_ref_id
pref3.433019e-18-2.797513e-18j
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
current
potential_ref_id
pref-1.493266e-15+3.530671e-16j
\n", + "
" + ], + "text/plain": [ + " current\n", + "potential_ref_id \n", + "pref -1.493266e-15+3.530671e-16j" + ] }, "execution_count": 18, "metadata": {}, @@ -757,8 +1428,93 @@ "outputs": [ { "data": { - "text/plain": " voltage \n absolute angle\nbus_id phase \nsb an 230.940108 6.671617e-37\n bn 230.940108 -2.094395e+00\n cn 230.940108 2.094395e+00\nlb an 221.928183 2.599590e-22\n bn 221.928183 -2.094395e+00\n cn 221.928183 2.094395e+00", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
voltage
absoluteangle
bus_idphase
sban230.9401086.671617e-37
bn230.940108-2.094395e+00
cn230.9401082.094395e+00
lban221.9281832.599590e-22
bn221.928183-2.094395e+00
cn221.9281832.094395e+00
\n
" + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
voltage
absoluteangle
bus_idphase
sban230.9401080.000000e+00
bn230.940108-2.094395e+00
cn230.9401082.094395e+00
lban221.9281832.884978e-19
bn221.928183-2.094395e+00
cn221.9281832.094395e+00
\n", + "
" + ], + "text/plain": [ + " voltage \n", + " absolute angle\n", + "bus_id phase \n", + "sb an 230.940108 0.000000e+00\n", + " bn 230.940108 -2.094395e+00\n", + " cn 230.940108 2.094395e+00\n", + "lb an 221.928183 2.884978e-19\n", + " bn 221.928183 -2.094395e+00\n", + " cn 221.928183 2.094395e+00" + ] }, "execution_count": 19, "metadata": {}, @@ -792,9 +1548,16 @@ "outputs": [ { "data": { - "text/plain": "array([ 216.02252269 +0.j, -115.47005384-200.j, -115.47005384+200.j,\n 14.91758499 +0.j]) ", - "text/html": "
Magnitude
[ 216.02252269  +0.j -115.47005384-200.j -115.47005384+200.j
14.91758499 +0.j]
Unitsvolt
", - "text/latex": "$\\begin{pmatrix} & & & \\end{pmatrix}\\ \\mathrm{volt}$" + "text/html": [ + "
Magnitude
[ 216.02252269-2.44097855e-29j -115.47005384-2.00000000e+02j
-115.47005384+2.00000000e+02j 14.91758499+2.44097855e-29j]
Unitsvolt
" + ], + "text/latex": [ + "$\\begin{pmatrix} & & & \\end{pmatrix}\\ \\mathrm{volt}$" + ], + "text/plain": [ + "array([ 216.02252269-2.44097855e-29j, -115.47005384-2.00000000e+02j,\n", + " -115.47005384+2.00000000e+02j, 14.91758499+2.44097855e-29j]) " + ] }, "execution_count": 20, "metadata": {}, @@ -862,7 +1625,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.11.4" }, "vscode": { "interpreter": { diff --git a/pyproject.toml b/pyproject.toml index e7e85147..62205e28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,6 +83,7 @@ line-length = 120 target-version = "py39" show-fixes = true namespace-packages = ["roseau"] +include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"] select = ["E", "F", "C90", "W", "B", "UP", "I", "RUF100", "TID", "SIM", "PT", "PIE", "N", "C4", "NPY"] unfixable = ["B"] ignore = ["E501", "B024", "N818"] diff --git a/roseau/load_flow/models/lines/lines.py b/roseau/load_flow/models/lines/lines.py index e9303ee5..178278f3 100644 --- a/roseau/load_flow/models/lines/lines.py +++ b/roseau/load_flow/models/lines/lines.py @@ -281,11 +281,25 @@ def parameters(self, value: LineParameters) -> None: self._parameters = value self._invalidate_network_results() - def _res_series_power_losses_getter(self, warning: bool) -> np.ndarray: + def _res_series_values_getter(self, warning: bool) -> tuple[np.ndarray, np.ndarray]: pot1, pot2 = self._res_potentials_getter(warning) # V du_line = pot1 - pot2 z_line = self.parameters.z_line * self.length i_line = np.linalg.inv(z_line.m_as("ohm")) @ du_line # Zₗ x Iₗ = ΔU -> I = Zₗ⁻¹ x ΔU + return du_line, i_line + + def _res_series_currents_getter(self, warning: bool) -> np.ndarray: + _, i_line = self._res_series_values_getter(warning) + return i_line + + @property + @ureg_wraps("A", (None,), strict=False) + def res_series_currents(self) -> Q_[np.ndarray]: + """Get the current in the series elements of the line (A).""" + return self._res_series_currents_getter(warning=True) + + def _res_series_power_losses_getter(self, warning: bool) -> np.ndarray: + du_line, i_line = self._res_series_values_getter(warning) return du_line * i_line.conj() # Sₗ = ΔU.Iₗ* @property @@ -294,9 +308,8 @@ def res_series_power_losses(self) -> Q_[np.ndarray]: """Get the power losses in the series elements of the line (VA).""" return self._res_series_power_losses_getter(warning=True) - def _res_shunt_power_losses_getter(self, warning: bool) -> np.ndarray: - if not self.parameters.with_shunt: - return np.zeros(len(self.phases), dtype=complex) + def _res_shunt_values_getter(self, warning: bool) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: + assert self.parameters.with_shunt, "this method only works when there is a shunt" y_shunt = self.parameters.y_shunt assert self.ground is not None pot1, pot2 = self._res_potentials_getter(warning) @@ -305,7 +318,26 @@ def _res_shunt_power_losses_getter(self, warning: bool) -> np.ndarray: yg = y_shunt.sum(axis=1) # y_ig = Y_ia + Y_ib + Y_ic + Y_in for i in {a, b, c, n} i1_shunt = (y_shunt @ pot1 - yg * vg) / 2 i2_shunt = (y_shunt @ pot2 - yg * vg) / 2 - return pot1 * i1_shunt.conj() + pot2 * i2_shunt.conj() + return pot1, pot2, i1_shunt, i2_shunt + + def _res_shunt_currents_getter(self, warning: bool) -> tuple[np.ndarray, np.ndarray]: + if not self.parameters.with_shunt: + zeros = np.zeros(len(self.phases), dtype=complex) + return zeros[:], zeros[:] + _, _, cur1, cur2 = self._res_shunt_values_getter(warning) + return cur1, cur2 + + @property + @ureg_wraps(("A", "A"), (None,), strict=False) + def res_shunt_currents(self) -> tuple[Q_[np.ndarray], Q_[np.ndarray]]: + """Get the currents in the shunt elements of the line (A).""" + return self._res_shunt_currents_getter(warning=True) + + def _res_shunt_power_losses_getter(self, warning: bool) -> np.ndarray: + if not self.parameters.with_shunt: + return np.zeros(len(self.phases), dtype=complex) + pot1, pot2, cur1, cur2 = self._res_shunt_values_getter(warning) + return pot1 * cur1.conj() + pot2 * cur2.conj() @property @ureg_wraps("VA", (None,), strict=False) diff --git a/roseau/load_flow/models/tests/test_branches.py b/roseau/load_flow/models/tests/test_branches.py index ead9a97d..1b0bebf6 100644 --- a/roseau/load_flow/models/tests/test_branches.py +++ b/roseau/load_flow/models/tests/test_branches.py @@ -222,7 +222,7 @@ def test_powers_equal(network_with_results): ), ), ) -def test_lines_res_powers(phases, z_line, y_shunt, len_line, bus_pot, line_cur, ground_pot, expected_pow): +def test_lines_results(phases, z_line, y_shunt, len_line, bus_pot, line_cur, ground_pot, expected_pow): bus1 = Bus("bus1", phases=phases["bus1"]) bus2 = Bus("bus2", phases=phases["bus2"]) y_shunt = np.asarray(y_shunt, dtype=complex) if y_shunt is not None else None @@ -257,3 +257,10 @@ def test_lines_res_powers(phases, z_line, y_shunt, len_line, bus_pot, line_cur, # Sanity check: the total power lost is equal to the sum of the powers flowing through assert np.allclose(res_powers1 + res_powers2, line_losses) + + # Check currents (Kirchhoff's law at each end of the line) + i1_line, i2_line = line.res_currents + i_series = line.res_series_currents + i1_shunt, i2_shunt = line.res_shunt_currents + assert np.allclose(i1_line, i_series + i1_shunt) + assert np.allclose(i2_line + i_series, i2_shunt, atol=1.0e-4) diff --git a/roseau/load_flow/network.py b/roseau/load_flow/network.py index 171f330d..d94652a7 100644 --- a/roseau/load_flow/network.py +++ b/roseau/load_flow/network.py @@ -680,52 +680,88 @@ def res_branches(self) -> pd.DataFrame: return res_df @property - def res_lines_losses(self) -> pd.DataFrame: - """The load flow results of the complex power losses of the network lines. + def res_lines(self) -> pd.DataFrame: + """The load flow results of the the network lines. - To get the active power losses, use the real part of the complex power losses. + This is similar to the :attr:`res_branches` property but provides more information that + only apply to lines. This includes currents and complex power losses in the series + components of the lines. The results are returned as a dataframe with the following index: - `line_id`: The id of the line. - `phase`: The phase of the line (in ``{'a', 'b', 'c', 'n'}``). + and the following columns: + - `current1`: The complex current of the line (in Amps) for the given phase at the + first bus. + - `current2`: The complex current of the line (in Amps) for the given phase at the + second bus. + - `power1`: The complex power of the line (in VoltAmps) for the given phase at the + first bus. + - `power2`: The complex power of the line (in VoltAmps) for the given phase at the + second bus. + - `potential1`: The complex potential of the first bus (in Volts) for the given phase. + - `potential2`: The complex potential of the second bus (in Volts) for the given phase. - `series_losses`: The complex power losses of the line (in VoltAmps) for the given phase due to the series and mutual impedances. - - `shunt_losses`: The complex power losses of the line (in VoltAmps) for the given - phase due to the shunt admittances. - - `total_losses`: The complex power losses of the line (in VoltAmps) for the given - phase due to the series and mutual impedances and the shunt admittances. This is - the sum of the series and shunt losses. It is equal to the power flow through the - line; for any line, ``series_losses + shunt_losses == power1 + power2`` is always - true. + - `series_current`: The complex current in the series impedance of the line (in Amps) + for the given phase. + + Additional information can be easily computed from this dataframe. For example: + + * To get the active power losses, use the real part of the complex power losses + * To get the total power losses, add the columns ``powers1 + powers2`` + * To get the power losses in the shunt components of the line, subtract the series losses + from the total power losses computed in the previous step: + ``(powers1 + powers2) - series_losses`` + * To get the currents in the shunt components of the line: + - For the first bus, subtract the columns ``current1 - series_current`` + - For the second bus, add the columns ``series_current + current2`` """ self._warn_invalid_results() - res_dict = {"line_id": [], "phase": [], "series_losses": [], "shunt_losses": [], "total_losses": []} - for br_id, branch in self.branches.items(): + res_dict = { + "line_id": [], + "phase": [], + "current1": [], + "current2": [], + "power1": [], + "power2": [], + "potential1": [], + "potential2": [], + "series_losses": [], + "series_current": [], + } + for branch in self.branches.values(): if not isinstance(branch, Line): continue + potentials = branch._res_potentials_getter(warning=False) + currents = branch._res_currents_getter(warning=False) + powers = branch._res_powers_getter(warning=False) series_losses = branch._res_series_power_losses_getter(warning=False) - shunt_losses = branch._res_shunt_power_losses_getter(warning=False) - total_losses = series_losses + shunt_losses - for series, shunt, total, phase in zip(series_losses, shunt_losses, total_losses, branch.phases): - res_dict["line_id"].append(br_id) + series_currents = branch._res_series_currents_getter(warning=False) + for i1, i2, s1, s2, v1, v2, s_series, i_series, phase in zip( + *currents, *powers, *potentials, series_losses, series_currents, branch.phases + ): + res_dict["line_id"].append(branch.id) res_dict["phase"].append(phase) - res_dict["series_losses"].append(series) - res_dict["shunt_losses"].append(shunt) - res_dict["total_losses"].append(total) - res_df = ( - pd.DataFrame.from_dict(res_dict, orient="columns") + res_dict["current1"].append(i1) + res_dict["current2"].append(i2) + res_dict["power1"].append(s1) + res_dict["power2"].append(s2) + res_dict["potential1"].append(v1) + res_dict["potential2"].append(v2) + res_dict["series_losses"].append(s_series) + res_dict["series_current"].append(i_series) + return ( + pd.DataFrame(res_dict) .astype( { "phase": _PHASE_DTYPE, - "series_losses": complex, - "shunt_losses": complex, - "total_losses": complex, - } + **{k: complex for k in res_dict if k not in ("phase", "line_id")}, + }, ) .set_index(["line_id", "phase"]) ) - return res_df @property def res_loads(self) -> pd.DataFrame: diff --git a/roseau/load_flow/tests/test_electrical_network.py b/roseau/load_flow/tests/test_electrical_network.py index 4b277bd7..c5d01e7e 100644 --- a/roseau/load_flow/tests/test_electrical_network.py +++ b/roseau/load_flow/tests/test_electrical_network.py @@ -856,6 +856,58 @@ def test_single_phase_network(single_phase_network: ElectricalNetwork): ) .set_index(["branch_id", "phase"]), ) + # Lines results + expected_res_lines = ( + pd.DataFrame.from_records( + [ + { + "line_id": "line", + "phase": "b", + "current1": 0.005000025000117603 + 0j, + "current2": -0.005000025000117603 - 0j, + "power1": (19999.94999975 + 0j) * (0.005000025000117603 + 0j).conjugate(), + "power2": (19999.899999499998 + 0j) * (-0.005000025000117603 - 0j).conjugate(), + "potential1": 19999.94999975 + 0j, + "potential2": 19999.899999499998 + 0j, + "series_losses": ( + (19999.94999975 + 0j) * (0.005000025000117603 + 0j).conjugate() + + (19999.899999499998 + 0j) * (-0.005000025000117603 - 0j).conjugate() + ), + "series_current": 0.005000025000117603 + 0j, + }, + { + "line_id": "line", + "phase": "n", + "current1": -0.005000025000125 + 0j, + "current2": 0.005000025000125 - 0j, + "power1": (-0.050000250001249996 + 0j) * (-0.005000025000125 + 0j).conjugate(), + "power2": (0j) * (0.005000025000125 - 0j).conjugate(), + "potential1": -0.050000250001249996 + 0j, + "potential2": 0j, + "series_losses": ( + (-0.050000250001249996 + 0j) * (-0.005000025000125 + 0j).conjugate() + + (0j) * (0.005000025000125 - 0j).conjugate() + ), + "series_current": -0.005000025000125 + 0j, + }, + ] + ) + .astype( + { + "phase": _PHASE_DTYPE, + "current1": complex, + "current2": complex, + "power1": complex, + "power2": complex, + "potential1": complex, + "potential2": complex, + "series_losses": complex, + "series_current": complex, + } + ) + .set_index(["line_id", "phase"]) + ) + pd.testing.assert_frame_equal(single_phase_network.res_lines, expected_res_lines) # Loads results pd.testing.assert_frame_equal( single_phase_network.res_loads,