Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement #572

Merged
merged 12 commits into from
Oct 5, 2024
63 changes: 63 additions & 0 deletions andes/cases/wscc9/wscc9_3wxfr.raw
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
0, 100.00, 33, 0, 0, 60.00 /
This case has a extra three-winding transformer for file parser testing only. October 04, 2024 15:43:21
0 / END OF SYSTEM-WIDE DATA, BEGIN BUS DATA
1,'Bus1 ', 16.5000,3, 1, 1, 1,1.04000, 0.0000
2,'Bus 2 ', 18.0000,2, 1, 1, 1,1.02500, 9.3507
3,'Bus 3 ', 13.8000,2, 1, 1, 1,1.02500, 5.1420
4,'Bus 4 ', 230.0000,1, 2, 2, 2,1.02531, -2.2174
5,'Bus 5 ', 230.0000,1, 1, 1, 1,0.99972, -3.6802
6,'Bus 6 ', 230.0000,1, 1, 1, 1,1.01225, -3.5666
7,'Bus 7 ', 230.0000,1, 1, 1, 1,1.02683, 3.7961
8,'Bus 8 ', 230.0000,1, 1, 1, 1,1.01727, 1.3373
9,'Bus 9 ', 230.0000,1, 1, 1, 1,1.03269, 2.4448
0 / END OF BUS DATA, BEGIN LOAD DATA
5,'1 ',1, 1, 1, 125.000, 50.000, 0.000, 0.000, 0.000, -0.000, 1,1
6,'1 ',1, 1, 1, 90.000, 30.000, 0.000, 0.000, 0.000, -0.000, 1,1
8,'1 ',1, 1, 1, 100.000, 35.000, 0.000, 0.000, 0.000, -0.000, 1,1
0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA
0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA
1,'1 ', 71.627, 27.915, 9900.000, -9900.000,1.04000, 0, 500.000, 0.00000, 1.00000, 0.00000, 0.00000,1.00000,1, 100.0, 450.000, 0.000, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000,0, 1.0000
2,'1 ', 163.000, 4.903, 9900.000, -9900.000,1.02500, 0, 250.000, 0.00000, 1.00000, 0.00000, 0.00000,1.00000,1, 100.0, 240.000, 0.000, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000,0, 1.0000
3,'1 ', 85.000, -11.449, 9900.000, -9900.000,1.02500, 0, 100.000, 0.00000, 1.00000, 0.00000, 0.00000,1.00000,1, 100.0, 90.000, 0.000, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000,0, 1.0000
0 / END OF GENERATOR DATA, BEGIN BRANCH DATA
5, 4,'1 ', 0.01000, 0.06800,0.17600, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
6, 4,'1 ', 0.01700, 0.09200,0.15800, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
7, 5,'1 ', 0.03200, 0.16100,0.30600, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
9, 6,'1 ', 0.03900, 0.17380,0.35800, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
7, 8,'1 ', 0.00850, 0.05760,0.14900, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
8, 9,'1 ', 0.01190, 0.10080,0.20900, 0.00, 0.00, 0.00, 0.00000, 0.00000, 0.00000, 0.00000,1,1, 0.0, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
0 / END OF BRANCH DATA, BEGIN TRANSFORMER DATA
4, 1, 0,'1 ',1,1,1, 0.00000, 0.00000,2,' ',1, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
0.00000, 0.05760, 100.00
1.00000, 0.000, 0.000, 0.00, 0.00, 0.00,0, 0, 1.50000, 0.51000, 1.50000, 0.51000,159, 0, 0.00000, 0.00000
1.00000, 0.000
2, 7, 0,'1 ',1,1,1, 0.00000, 0.00000,2,' ',1, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
0.00000, 0.06250, 100.00
1.00000, 0.000, 0.000, 0.00, 0.00, 0.00,0, 2, 1.10000, 0.90000, 1.00000, 0.99000, 33, 0, 0.00000, 0.00000
1.00000, 0.000
9, 3, 0,'1 ',1,1,1, 0.00000, 0.00000,2,' ',1, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
0.00000, 0.05860, 100.00
1.00000, 0.000, 0.000, 0.00, 0.00, 0.00,0, 9, 1.10000, 0.90000, 1.00000, 0.99000, 33, 0, 0.00000, 0.00000
1.00000, 0.000
4, 5, 6,'1 ',1,1,1, 0.00000, 0.00000,2,'3WINDXFR',1, 1,1.0000, 0,1.0000, 0,1.0000, 0,1.0000
0.01000, 0.10000, 100.00, 0.02000, 0.20000, 100.00, 0.03000, 0.30000, 100.00, 1.00000, 0.00000
1.00000, 230.00, 0.000, 100.00, 100.00, 100.00, 0, 4, 1.10000, 0.90000, 1.10000, 0.90000, 33, 0, 0.00000, 0.00000
1.00000, 230.00, 0.000, 100.00, 100.00, 100.00, 0, 5, 1.10000, 0.90000, 1.10000, 0.90000, 33, 0, 0.00000, 0.00000
1.00000, 230.00, 0.000, 100.00, 100.00, 100.00, 0, 6, 1.10000, 0.90000, 1.10000, 0.90000, 33, 0, 0.00000, 0.00000
0 / END OF TRANSFORMER DATA, BEGIN AREA DATA
1, 0, 0.000, 1.000,'1 '
0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA
0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA
0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA
0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA
0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA
0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA
1,'1 '
0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA
0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA
1,'1'
0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA
0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA
0 /END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA
0 /END OF GNE DEVICE DATA
Q
11 changes: 10 additions & 1 deletion andes/io/psse.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,11 +555,20 @@ def _parse_transf_v33(raw, system, max_bus):
logger.warning('Added bus <%s> for 3-winding transformer <%s-%s-%s>',
new_bus, data[0][0], data[0][1], data[0][2])

# Assign `area`, `owner`, and `zone` using the high-voltage side bus values
high_voltage_bus = data[0][0]
area = system.Bus.get(src='area', attr='v', idx=high_voltage_bus)
zone = system.Bus.get(src='zone', attr='v', idx=high_voltage_bus)
owner = system.Bus.get(src='owner', attr='v', idx=high_voltage_bus)

param = {'idx': new_bus,
'name': '_'.join([str(i) for i in data[0][:3]]),
'Vn': 1.0,
'v0': data[1][-2],
'a0': data[1][-1] * deg2rad
'a0': data[1][-1] * deg2rad,
'area': area,
'owner': owner,
'zone': zone,
}

out['Bus'].append(param)
Expand Down
25 changes: 25 additions & 0 deletions andes/models/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,31 @@ def get_next_idx(self, idx=None, model_name=None):

return idx

def get_all_idxes(self):
"""
Return all the devices idx in this group.

Returns
-------
list
List of indices.

Notes
-----
The default models sequence depends on the order of the models in the group,
which comes from OrderedDict `file_classes` in `models.__init__.py`.

Examples
--------
>>> ss = andes.load(andes.get_case('ieee14/ieee14_pvd1.xlsx'))
>>> ss.DG.get_all_idxes()
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

>>> ss.StaticGen.get_all_idxes()
[2, 3, 4, 5, 6, 1]
"""
return list(self._idx2model.keys())

def doc(self, export='plain'):
"""
Return the documentation of the group in a string.
Expand Down
3 changes: 3 additions & 0 deletions andes/routines/pflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
class PFlow(BaseRoutine):
"""
Power flow calculation routine.

Power flow analysis currently supports limiting reactive power (needs to to be
turned on via `config.pv2pq`) but does not enforce voltage limits.
"""

def __init__(self, system=None, config=None):
Expand Down
4 changes: 3 additions & 1 deletion docs/source/release-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ v1.9 Notes

v1.9.3 (2024-04-XX)
-------------------
- In the `dae`` module, change `self.t.itemset` to array assignment to ensure compatibility with NumPy 2.0.
- In the ``dae`` module, change `self.t.itemset` to array assignment to ensure compatibility with NumPy 2.0.
- Follow RTD's deprecation of Sphinx context injection at build time
- In symbolic processor, most variables are assumed to be real, except some
services that are specified as complex. This will allow generating simplified
Expand All @@ -20,6 +20,8 @@ v1.9.3 (2024-04-XX)
- Add parameter from_csv=None in TDS.run() to allow loading data from CSV files at TDS begining.
- Fix `TDS.init()` and `TDS._csv_step()` to fit loading from CSV when `Output` exists.
- Add parameter `allow_all=False` to `ModelData.find_idx()` `GroupBase.find_idx()` to allow searching all matches.
- Add method `GroupBase.get_all_idxes()` to get all indices of a group.
- Enhanced three-winding transformer parsing in PSS/E raw files by assigning the equivalent star bus `area`, `owner`, and `zone` using the high-voltage bus values.

v1.9.2 (2024-03-25)
-------------------
Expand Down
29 changes: 18 additions & 11 deletions examples/ex1.ipynb

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions tests/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,9 @@ def test_group_access(self):
# --- get_field ---
ff = ss.DG.get_field('f', list(ss.DG._idx2model.keys()), 'v_code')
self.assertTrue(any([item == 'y' for item in ff]))

# --- get group idx ---
self.assertSetEqual(set(ss.DG.get_all_idxes()),
set(ss.PVD1.idx.v))
self.assertSetEqual(set(ss.StaticGen.get_all_idxes()),
set(ss.PV.idx.v + ss.Slack.idx.v))
24 changes: 24 additions & 0 deletions tests/test_psse_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from andes.system import System
from andes.io import psse

import andes


class TestPSSEParser(unittest.TestCase):
"""
Expand All @@ -26,3 +28,25 @@ def test_sort_models(self):
with open(f'{dirname}/../andes/io/psse-dyr.yaml', 'r') as f:
dyr_yaml = yaml.full_load(f)
psse.sort_psse_models(dyr_yaml, system)

def test_3wxfr(self):
"""
Test three winding transformer parsing.
"""

ss = andes.load(andes.get_case('wscc9/wscc9_3wxfr.raw'),
setup=True)

hv_bus = 4 # high voltage bus
area_hv = ss.Bus.get(src='area', attr='v', idx=hv_bus)
zone_hv = ss.Bus.get(src='zone', attr='v', idx=hv_bus)
owner_hv = ss.Bus.get(src='owner', attr='v', idx=hv_bus)

star_bus = 10 # created star bus
area_star = ss.Bus.get(src='area', attr='v', idx=star_bus)
zone_hv = ss.Bus.get(src='zone', attr='v', idx=star_bus)
owner_hv = ss.Bus.get(src='owner', attr='v', idx=star_bus)

self.assertEqual(area_hv, area_star)
self.assertEqual(zone_hv, zone_hv)
self.assertEqual(owner_hv, owner_hv)
Loading