ltbams 1.0.12__py3-none-any.whl → 1.0.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ams/_version.py +3 -3
- ams/cli.py +2 -7
- ams/core/common.py +7 -3
- ams/core/documenter.py +2 -1
- ams/core/matprocessor.py +174 -108
- ams/core/model.py +14 -6
- ams/core/param.py +5 -3
- ams/core/symprocessor.py +8 -2
- ams/core/var.py +1 -1
- ams/extension/eva.py +11 -7
- ams/interface.py +7 -7
- ams/io/json.py +20 -16
- ams/io/matpower.py +10 -6
- ams/io/psse.py +4 -1
- ams/io/xlsx.py +21 -16
- ams/main.py +53 -45
- ams/models/distributed/esd1.py +4 -7
- ams/models/distributed/ev.py +10 -6
- ams/models/distributed/pvd1.py +4 -7
- ams/models/group.py +17 -18
- ams/models/renewable/regc.py +14 -22
- ams/models/timeslot.py +30 -0
- ams/models/zone.py +2 -4
- ams/opt/exprcalc.py +11 -0
- ams/opt/optzbase.py +4 -3
- ams/report.py +2 -7
- ams/routines/dcopf.py +7 -4
- ams/routines/dcopf2.py +14 -4
- ams/routines/dopf.py +2 -2
- ams/routines/ed.py +5 -5
- ams/routines/grbopt.py +2 -0
- ams/routines/pflow.py +1 -1
- ams/routines/pypower.py +8 -0
- ams/routines/routine.py +125 -1
- ams/routines/rted.py +5 -5
- ams/routines/uc.py +2 -2
- ams/shared.py +99 -2
- ams/system.py +103 -18
- ams/utils/paths.py +6 -10
- docs/source/genroutineref.py +12 -0
- docs/source/index.rst +4 -3
- docs/source/release-notes.rst +14 -0
- {ltbams-1.0.12.dist-info → ltbams-1.0.14.dist-info}/METADATA +21 -23
- {ltbams-1.0.12.dist-info → ltbams-1.0.14.dist-info}/RECORD +47 -75
- {ltbams-1.0.12.dist-info → ltbams-1.0.14.dist-info}/top_level.txt +0 -1
- tests/__init__.py +0 -0
- tests/test_1st_system.py +0 -64
- tests/test_addressing.py +0 -40
- tests/test_case.py +0 -301
- tests/test_cli.py +0 -34
- tests/test_export_csv.py +0 -89
- tests/test_group.py +0 -83
- tests/test_interface.py +0 -238
- tests/test_io.py +0 -190
- tests/test_jumper.py +0 -27
- tests/test_known_good.py +0 -267
- tests/test_matp.py +0 -437
- tests/test_model.py +0 -54
- tests/test_omodel.py +0 -119
- tests/test_paths.py +0 -89
- tests/test_report.py +0 -251
- tests/test_repr.py +0 -21
- tests/test_routine.py +0 -178
- tests/test_rtn_acopf.py +0 -75
- tests/test_rtn_dcopf.py +0 -121
- tests/test_rtn_dcopf2.py +0 -103
- tests/test_rtn_ed.py +0 -279
- tests/test_rtn_opf.py +0 -142
- tests/test_rtn_pflow.py +0 -147
- tests/test_rtn_pypower.py +0 -315
- tests/test_rtn_rted.py +0 -273
- tests/test_rtn_uc.py +0 -248
- tests/test_service.py +0 -73
- {ltbams-1.0.12.dist-info → ltbams-1.0.14.dist-info}/WHEEL +0 -0
- {ltbams-1.0.12.dist-info → ltbams-1.0.14.dist-info}/entry_points.txt +0 -0
ams/interface.py
CHANGED
@@ -177,9 +177,9 @@ def to_andes(system, addfile=None,
|
|
177
177
|
|
178
178
|
Notes
|
179
179
|
-----
|
180
|
-
|
181
|
-
|
182
|
-
|
180
|
+
- Power flow models in the addfile will be skipped and only dynamic models will be used.
|
181
|
+
- The addfile format is guessed based on the file extension. Currently only ``xlsx`` is supported.
|
182
|
+
- Index in the addfile is automatically adjusted when necessary.
|
183
183
|
"""
|
184
184
|
t0, _ = elapsed()
|
185
185
|
|
@@ -446,9 +446,9 @@ class Dynamic:
|
|
446
446
|
|
447
447
|
Notes
|
448
448
|
-----
|
449
|
-
|
450
|
-
|
451
|
-
|
449
|
+
- Using the file conversion ``to_andes()`` will automatically
|
450
|
+
link the AMS system to the converted ANDES system in the
|
451
|
+
attribute ``dyn``.
|
452
452
|
|
453
453
|
Examples
|
454
454
|
--------
|
@@ -503,7 +503,7 @@ class Dynamic:
|
|
503
503
|
|
504
504
|
Notes
|
505
505
|
-----
|
506
|
-
|
506
|
+
- AGC power reference ``paux`` is not included in this function.
|
507
507
|
"""
|
508
508
|
# 1) TurbineGov
|
509
509
|
syg_idx = sp.dyn.link['syg_idx'].dropna().tolist() # SynGen idx
|
ams/io/json.py
CHANGED
@@ -11,7 +11,9 @@ from collections import OrderedDict
|
|
11
11
|
from andes.io.json import (testlines, read) # NOQA
|
12
12
|
from andes.utils.paths import confirm_overwrite
|
13
13
|
|
14
|
-
from ams.shared import
|
14
|
+
from ams.shared import pd
|
15
|
+
from ams.shared import summary_row, summary_name, model2df
|
16
|
+
|
15
17
|
|
16
18
|
logger = logging.getLogger(__name__)
|
17
19
|
|
@@ -24,7 +26,8 @@ def write(system, outfile, skip_empty=True, overwrite=None,
|
|
24
26
|
If to_andes is True, only write models that are in ANDES,
|
25
27
|
but the outfile might not be able to be read back into AMS.
|
26
28
|
|
27
|
-
|
29
|
+
Revised from `andes.io.json.write`, where non-andes models
|
30
|
+
are skipped if `to_andes` is True.
|
28
31
|
|
29
32
|
Parameters
|
30
33
|
----------
|
@@ -63,20 +66,21 @@ def _dump_system(system, skip_empty, orient='records', to_andes=False):
|
|
63
66
|
them all in an OrderedDict.
|
64
67
|
"""
|
65
68
|
out = OrderedDict()
|
69
|
+
summary_found = False
|
66
70
|
for name, instance in system.models.items():
|
67
|
-
|
71
|
+
df = model2df(instance, skip_empty, to_andes=to_andes)
|
72
|
+
if df is None:
|
68
73
|
continue
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
out[name] = df.to_dict(orient=orient)
|
74
|
+
|
75
|
+
if name == summary_name:
|
76
|
+
df = pd.concat([pd.DataFrame([summary_row]), df], ignore_index=True)
|
77
|
+
df.index.name = "uid"
|
78
|
+
summary_found = True
|
79
|
+
out[name] = df.to_dict(orient=orient)
|
80
|
+
|
81
|
+
if not summary_found:
|
82
|
+
df = pd.DataFrame([summary_row])
|
83
|
+
df.index.name = "uid"
|
84
|
+
out[summary_name] = df.to_dict(orient=orient)
|
85
|
+
|
82
86
|
return json.dumps(out, indent=2)
|
ams/io/matpower.py
CHANGED
@@ -36,10 +36,11 @@ def read(system, file):
|
|
36
36
|
|
37
37
|
def m2mpc(infile: str) -> dict:
|
38
38
|
"""
|
39
|
-
Parse a MATPOWER file and return a dictionary containing the parsed data
|
39
|
+
Parse a MATPOWER file and return a dictionary containing the parsed data,
|
40
|
+
revised from `andes.io.matpower.m2mpc`.
|
40
41
|
|
41
42
|
This function processes MATPOWER case files and extracts relevant fields
|
42
|
-
into a structured dictionary.
|
43
|
+
into a structured dictionary.
|
43
44
|
|
44
45
|
Supported fields include:
|
45
46
|
- `baseMVA`: The system base power in MVA.
|
@@ -181,9 +182,8 @@ def m2mpc(infile: str) -> dict:
|
|
181
182
|
|
182
183
|
def mpc2system(mpc: dict, system) -> bool:
|
183
184
|
"""
|
184
|
-
Load an mpc dict into an empty AMS system
|
185
|
-
|
186
|
-
Revised from ``andes.io.matpower.mpc2system``.
|
185
|
+
Load an mpc dict into an empty AMS system, revised from
|
186
|
+
`andes.io.matpower.mpc2system`.
|
187
187
|
|
188
188
|
Note that `mbase` in mpc is converted to `Sn`, but it is not actually used in
|
189
189
|
MATPOWER nor AMS.
|
@@ -453,7 +453,7 @@ def system2mpc(system) -> dict:
|
|
453
453
|
"""
|
454
454
|
Convert a **setup** AMS system to a MATPOWER mpc dictionary.
|
455
455
|
|
456
|
-
|
456
|
+
Revised from `andes.io.matpower.system2mpc`.
|
457
457
|
|
458
458
|
Parameters
|
459
459
|
----------
|
@@ -646,6 +646,8 @@ def mpc2m(mpc: dict, outfile: str) -> str:
|
|
646
646
|
MATPOWER mpc dictionary.
|
647
647
|
outfile : str
|
648
648
|
Path to the output M-file.
|
649
|
+
|
650
|
+
.. versionadded:: 1.0.10
|
649
651
|
"""
|
650
652
|
with open(outfile, 'w') as f:
|
651
653
|
# Add version info
|
@@ -758,6 +760,8 @@ def write(system, outfile: str, overwrite: bool = None) -> bool:
|
|
758
760
|
- Unlike the XLSX and JSON converters, this implementation uses value providers
|
759
761
|
(`v`) instead of vin. As a result, any changes made through `model.set` will be
|
760
762
|
reflected in the generated MPC.
|
763
|
+
|
764
|
+
.. versionadded:: 1.0.10
|
761
765
|
"""
|
762
766
|
if not confirm_overwrite(outfile, overwrite=overwrite):
|
763
767
|
return False
|
ams/io/psse.py
CHANGED
@@ -16,7 +16,8 @@ def read(system, file):
|
|
16
16
|
"""
|
17
17
|
Read PSS/E RAW file v32/v33 formats.
|
18
18
|
|
19
|
-
Revised from
|
19
|
+
Revised from `andes.io.psse.read`, where model ``Zone`` is completed
|
20
|
+
when necessary.
|
20
21
|
"""
|
21
22
|
ret = ad_read(system, file)
|
22
23
|
# Extract zone data
|
@@ -56,6 +57,8 @@ def write_raw(system, outfile: str, overwrite: bool = None):
|
|
56
57
|
The output file path.
|
57
58
|
overwrite : bool, optional
|
58
59
|
If True, overwrite the file if it exists. If False, do not overwrite.
|
60
|
+
|
61
|
+
.. versionadded:: 1.0.10
|
59
62
|
"""
|
60
63
|
if not confirm_overwrite(outfile, overwrite=overwrite):
|
61
64
|
return False
|
ams/io/xlsx.py
CHANGED
@@ -7,7 +7,8 @@ import logging
|
|
7
7
|
|
8
8
|
from andes.io.xlsx import (read, testlines, confirm_overwrite, _add_book) # NOQA
|
9
9
|
|
10
|
-
from ams.shared import pd
|
10
|
+
from ams.shared import pd
|
11
|
+
from ams.shared import summary_row, summary_name, model2df
|
11
12
|
|
12
13
|
|
13
14
|
logger = logging.getLogger(__name__)
|
@@ -20,7 +21,8 @@ def write(system, outfile,
|
|
20
21
|
"""
|
21
22
|
Write loaded AMS system data into an xlsx file
|
22
23
|
|
23
|
-
Revised
|
24
|
+
Revised from `andes.io.xlsx.write`, where non-ANDES models
|
25
|
+
are skipped if `to_andes` is True.
|
24
26
|
|
25
27
|
Parameters
|
26
28
|
----------
|
@@ -59,22 +61,25 @@ def _write_system(system, writer, skip_empty, to_andes=False):
|
|
59
61
|
"""
|
60
62
|
Write the system to pandas ExcelWriter
|
61
63
|
|
62
|
-
|
64
|
+
Revised from `andes.io.xlsx._write_system`, where non-ANDES models
|
65
|
+
are skipped if `to_andes` is True.
|
63
66
|
"""
|
67
|
+
summary_found = False
|
64
68
|
for name, instance in system.models.items():
|
65
|
-
|
69
|
+
df = model2df(instance, skip_empty, to_andes=to_andes)
|
70
|
+
if df is None:
|
66
71
|
continue
|
67
|
-
|
68
|
-
if
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
ams_params = list(instance.params.keys())
|
74
|
-
andes_params = list(empty_adsys.models[name].params.keys())
|
75
|
-
skip_params = list(set(ams_params) - set(andes_params))
|
76
|
-
df = instance.cache.df_in.drop(skip_params, axis=1, errors='ignore')
|
77
|
-
else:
|
78
|
-
df = instance.cache.df_in
|
72
|
+
|
73
|
+
if name == summary_name:
|
74
|
+
df = pd.concat([pd.DataFrame([summary_row]), df], ignore_index=True)
|
75
|
+
df.index.name = "uid"
|
76
|
+
summary_found = True
|
77
|
+
|
79
78
|
df.to_excel(writer, sheet_name=name, freeze_panes=(1, 0))
|
79
|
+
|
80
|
+
if not summary_found:
|
81
|
+
df = pd.DataFrame([summary_row])
|
82
|
+
df.index.name = "uid"
|
83
|
+
df.to_excel(writer, sheet_name=summary_name, freeze_panes=(1, 0))
|
84
|
+
|
80
85
|
return writer
|
ams/main.py
CHANGED
@@ -48,7 +48,7 @@ def config_logger(stream_level=logging.INFO, *,
|
|
48
48
|
stream : bool, optional
|
49
49
|
Create a `StreamHandler` for `stdout` if ``True``.
|
50
50
|
If ``False``, the handler will not be created.
|
51
|
-
file : bool,
|
51
|
+
file : bool, optional
|
52
52
|
True if logging to ``log_file``.
|
53
53
|
log_file : str, optional
|
54
54
|
Logg file name for `FileHandler`, ``'ams.log'`` by default.
|
@@ -67,9 +67,12 @@ def config_logger(stream_level=logging.INFO, *,
|
|
67
67
|
|
68
68
|
Notes
|
69
69
|
-----
|
70
|
-
Copied from the ANDES project
|
70
|
+
Copied from the ANDES project:
|
71
|
+
https://github.com/CURENT/andes
|
72
|
+
|
71
73
|
Original author: Hantao Cui
|
72
|
-
|
74
|
+
|
75
|
+
License: GNU General Public License v3.0 (GPL-3.0)
|
73
76
|
"""
|
74
77
|
lg = logging.getLogger('ams')
|
75
78
|
lg.setLevel(logging.DEBUG)
|
@@ -118,6 +121,7 @@ def load(case, setup=True,
|
|
118
121
|
"""
|
119
122
|
Load a case and set up a system without running routine.
|
120
123
|
Return a system.
|
124
|
+
Revised from `andes.main.load`.
|
121
125
|
|
122
126
|
Takes other kwargs recognizable by ``System``,
|
123
127
|
such as ``addfile``, ``input_path``, and ``no_putput``.
|
@@ -137,12 +141,6 @@ def load(case, setup=True,
|
|
137
141
|
If one need to add devices in addition to these from the case
|
138
142
|
file, do ``setup=False`` and call ``System.add()`` to add devices.
|
139
143
|
When done, manually invoke ``setup()`` to set up the system.
|
140
|
-
|
141
|
-
Notes
|
142
|
-
-----
|
143
|
-
Revised from the ANDES project (https://github.com/CURENT/andes).
|
144
|
-
Original author: Hantao Cui
|
145
|
-
License: GPL3
|
146
144
|
"""
|
147
145
|
if use_input_path:
|
148
146
|
input_path = kwargs.get('input_path', '')
|
@@ -172,6 +170,8 @@ def run_case(case, *, routine='pflow', profile=False,
|
|
172
170
|
Run single simulation case for the given full path.
|
173
171
|
Use ``run`` instead of ``run_case`` whenever possible.
|
174
172
|
|
173
|
+
Revised from `andes.main.run_case`.
|
174
|
+
|
175
175
|
Argument ``input_path`` will not be prepended to ``case``.
|
176
176
|
|
177
177
|
Arguments recognizable by ``load`` can be passed to ``run_case``.
|
@@ -192,12 +192,6 @@ def run_case(case, *, routine='pflow', profile=False,
|
|
192
192
|
add_book : str, optional
|
193
193
|
Name of the device to be added to an excel case
|
194
194
|
as a new sheet.
|
195
|
-
|
196
|
-
Notes
|
197
|
-
-----
|
198
|
-
Revised from the ANDES project (https://github.com/CURENT/andes).
|
199
|
-
Original author: Hantao Cui
|
200
|
-
License: GPL3
|
201
195
|
"""
|
202
196
|
|
203
197
|
pr = cProfile.Profile()
|
@@ -270,9 +264,12 @@ def _run_mp_proc(cases, ncpu=NCPUS_PHYSICAL, **kwargs):
|
|
270
264
|
|
271
265
|
Notes
|
272
266
|
-----
|
273
|
-
Copied from the ANDES project
|
267
|
+
Copied from the ANDES project:
|
268
|
+
https://github.com/CURENT/andes
|
269
|
+
|
274
270
|
Original author: Hantao Cui
|
275
|
-
|
271
|
+
|
272
|
+
License: GNU General Public License v3.0 (GPL-3.0)
|
276
273
|
"""
|
277
274
|
|
278
275
|
# start processes
|
@@ -310,9 +307,12 @@ def _run_mp_pool(cases, ncpu=NCPUS_PHYSICAL, verbose=logging.INFO, **kwargs):
|
|
310
307
|
|
311
308
|
Notes
|
312
309
|
-----
|
313
|
-
Copied from the ANDES project
|
310
|
+
Copied from the ANDES project:
|
311
|
+
https://github.com/CURENT/andes
|
312
|
+
|
314
313
|
Original author: Hantao Cui
|
315
|
-
|
314
|
+
|
315
|
+
License: GNU General Public License v3.0 (GPL-3.0)
|
316
316
|
"""
|
317
317
|
|
318
318
|
pool = Pool(ncpu)
|
@@ -369,9 +369,12 @@ def run(filename, input_path='', verbose=20, mp_verbose=30,
|
|
369
369
|
|
370
370
|
Notes
|
371
371
|
-----
|
372
|
-
Copied from the ANDES project
|
372
|
+
Copied from the ANDES project:
|
373
|
+
https://github.com/CURENT/andes
|
374
|
+
|
373
375
|
Original author: Hantao Cui
|
374
|
-
|
376
|
+
|
377
|
+
License: GNU General Public License v3.0 (GPL-3.0)
|
375
378
|
"""
|
376
379
|
|
377
380
|
if is_interactive() and len(logger.handlers) == 0:
|
@@ -497,9 +500,12 @@ def misc(edit_config='', save_config='', show_license=False, clean=True, recursi
|
|
497
500
|
|
498
501
|
Notes
|
499
502
|
-----
|
500
|
-
Copied from the ANDES project
|
503
|
+
Copied from the ANDES project:
|
504
|
+
https://github.com/CURENT/andes
|
505
|
+
|
501
506
|
Original author: Hantao Cui
|
502
|
-
|
507
|
+
|
508
|
+
License: GNU General Public License v3.0 (GPL-3.0)
|
503
509
|
"""
|
504
510
|
|
505
511
|
if edit_conf(edit_config):
|
@@ -527,13 +533,8 @@ def misc(edit_config='', save_config='', show_license=False, clean=True, recursi
|
|
527
533
|
|
528
534
|
def doc(attribute=None, list_supported=False, config=False, **kwargs):
|
529
535
|
"""
|
530
|
-
Quick documentation from command-line
|
531
|
-
|
532
|
-
Notes
|
533
|
-
-----
|
534
|
-
Revised from the ANDES project (https://github.com/CURENT/andes).
|
535
|
-
Original author: Hantao Cui
|
536
|
-
License: GPL3
|
536
|
+
Quick documentation from command-line,
|
537
|
+
revised from `andes.main.doc`.
|
537
538
|
"""
|
538
539
|
system = System()
|
539
540
|
if attribute is not None:
|
@@ -558,13 +559,8 @@ def demo(**kwargs):
|
|
558
559
|
|
559
560
|
def versioninfo():
|
560
561
|
"""
|
561
|
-
Print version info for AMS and dependencies
|
562
|
-
|
563
|
-
Notes
|
564
|
-
-----
|
565
|
-
Revised from the ANDES project (https://github.com/CURENT/andes).
|
566
|
-
Original author: Hantao Cui
|
567
|
-
License: GPL3
|
562
|
+
Print version info for AMS and dependencies,
|
563
|
+
revised from `andes.main.versioninfo`.
|
568
564
|
"""
|
569
565
|
|
570
566
|
import numpy as np
|
@@ -630,9 +626,12 @@ def edit_conf(edit_config: Optional[Union[str, bool]] = ''):
|
|
630
626
|
|
631
627
|
Notes
|
632
628
|
-----
|
633
|
-
Copied from the ANDES project
|
629
|
+
Copied from the ANDES project:
|
630
|
+
https://github.com/CURENT/andes
|
631
|
+
|
634
632
|
Original author: Hantao Cui
|
635
|
-
|
633
|
+
|
634
|
+
License: GNU General Public License v3.0 (GPL-3.0)
|
636
635
|
"""
|
637
636
|
ret = False
|
638
637
|
|
@@ -689,9 +688,12 @@ def save_conf(config_path=None, overwrite=None, **kwargs):
|
|
689
688
|
|
690
689
|
Notes
|
691
690
|
-----
|
692
|
-
Copied from the ANDES project
|
691
|
+
Copied from the ANDES project:
|
692
|
+
https://github.com/CURENT/andes
|
693
|
+
|
693
694
|
Original author: Hantao Cui
|
694
|
-
|
695
|
+
|
696
|
+
License: GNU General Public License v3.0 (GPL-3.0)
|
695
697
|
"""
|
696
698
|
ret = False
|
697
699
|
|
@@ -729,9 +731,12 @@ def remove_output(recursive=False):
|
|
729
731
|
|
730
732
|
Notes
|
731
733
|
-----
|
732
|
-
Copied from the ANDES project
|
734
|
+
Copied from the ANDES project:
|
735
|
+
https://github.com/CURENT/andes
|
736
|
+
|
733
737
|
Original author: Hantao Cui
|
734
|
-
|
738
|
+
|
739
|
+
License: GNU General Public License v3.0 (GPL-3.0)
|
735
740
|
"""
|
736
741
|
found = False
|
737
742
|
cwd = os.getcwd()
|
@@ -764,9 +769,12 @@ def selftest(quick=False, extra=False, **kwargs):
|
|
764
769
|
|
765
770
|
Notes
|
766
771
|
-----
|
767
|
-
Copied from the ANDES project
|
772
|
+
Copied from the ANDES project:
|
773
|
+
https://github.com/CURENT/andes
|
774
|
+
|
768
775
|
Original author: Hantao Cui
|
769
|
-
|
776
|
+
|
777
|
+
License: GNU General Public License v3.0 (GPL-3.0)
|
770
778
|
"""
|
771
779
|
|
772
780
|
# map verbosity level from logging to unittest
|
ams/models/distributed/esd1.py
CHANGED
@@ -56,13 +56,10 @@ class ESD1(ESD1Data, Model):
|
|
56
56
|
``vt3``, ``vrflag``, ``ft0``, ``ft1``, ``ft2``, ``ft3``, ``frflag``,
|
57
57
|
``tip``, ``tiq``, ``recflag``.
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
Available:
|
64
|
-
|
65
|
-
https://docs.andes.app/en/latest/groupdoc/DG.html#esd1
|
59
|
+
References
|
60
|
+
----------
|
61
|
+
1. ANDES Documentation, ESD1,
|
62
|
+
https://andes.readthedocs.io/en/stable/groupdoc/DG.html#esd1
|
66
63
|
"""
|
67
64
|
|
68
65
|
def __init__(self, system, config):
|
ams/models/distributed/ev.py
CHANGED
@@ -12,13 +12,17 @@ class EV1(ModelData, Model):
|
|
12
12
|
"""
|
13
13
|
Aggregated EV model for scheduling at transmission level.
|
14
14
|
|
15
|
-
For co-simulation with
|
15
|
+
For co-simulation with ANDES, it is expected to be used in
|
16
16
|
conjunction with the dynamic models `EV1` or `EV2`.
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
References
|
19
|
+
----------
|
20
|
+
1. J. Wang et al., "Electric Vehicles Charging Time Constrained
|
21
|
+
Deliverable Provision of Secondary Frequency Regulation," in IEEE
|
22
|
+
Transactions on Smart Grid, vol. 15, no. 4, pp. 3892-3903, July
|
23
|
+
2024, doi: 10.1109/TSG.2024.3356948.
|
24
|
+
2. ANDES Documentation, EV1,
|
25
|
+
https://andes.readthedocs.io/en/stable/groupdoc/DG.html#ev1
|
22
26
|
"""
|
23
27
|
|
24
28
|
def __init__(self, system, config):
|
@@ -53,7 +57,7 @@ class EV1(ModelData, Model):
|
|
53
57
|
|
54
58
|
class EV2(EV1):
|
55
59
|
"""
|
56
|
-
|
60
|
+
Alias for EV1.
|
57
61
|
"""
|
58
62
|
|
59
63
|
def __init__(self, system=None, config=None) -> None:
|
ams/models/distributed/pvd1.py
CHANGED
@@ -52,13 +52,10 @@ class PVD1(PVD1Data, Model):
|
|
52
52
|
``vt3``, ``vrflag``, ``ft0``, ``ft1``, ``ft2``, ``ft3``, ``frflag``,
|
53
53
|
``tip``, ``tiq``, ``recflag``.
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
Available:
|
60
|
-
|
61
|
-
https://docs.andes.app/en/latest/groupdoc/DG.html#pvd1
|
55
|
+
References
|
56
|
+
----------
|
57
|
+
1. ANDES Documentation, PVD1,
|
58
|
+
https://andes.readthedocs.io/en/stable/groupdoc/DG.html#pvd1
|
62
59
|
"""
|
63
60
|
|
64
61
|
def __init__(self, system, config):
|
ams/models/group.py
CHANGED
@@ -3,22 +3,24 @@ import logging
|
|
3
3
|
from andes.models.group import GroupBase as adGroupBase
|
4
4
|
from andes.core.service import BackRef
|
5
5
|
|
6
|
+
from ams.utils.misc import deprec_get_idx
|
7
|
+
|
6
8
|
logger = logging.getLogger(__name__)
|
7
9
|
|
8
10
|
|
9
11
|
class GroupBase(adGroupBase):
|
10
12
|
"""
|
11
|
-
Base class for groups
|
13
|
+
Base class for groups, revised from
|
14
|
+
`andes.models.group.GroupBase`.
|
12
15
|
|
13
16
|
Add common_vars and common_params to the group class.
|
14
|
-
|
15
|
-
This class is revised from ``andes.models.group.GroupBase``.
|
16
17
|
"""
|
17
18
|
|
18
19
|
def __init__(self):
|
19
20
|
super().__init__()
|
20
21
|
self.common_params.extend(('idx',))
|
21
22
|
|
23
|
+
@deprec_get_idx
|
22
24
|
def get_idx(self):
|
23
25
|
"""
|
24
26
|
Return the value of group idx sorted in a human-readable style.
|
@@ -27,6 +29,9 @@ class GroupBase(adGroupBase):
|
|
27
29
|
-----
|
28
30
|
This function sorts the idx values using a custom sorting key,
|
29
31
|
which handles varying length strings with letters and numbers.
|
32
|
+
|
33
|
+
.. deprecated:: 1.0.0
|
34
|
+
Use ``get_all_idxes`` instead.
|
30
35
|
"""
|
31
36
|
all_idx = [mdl.idx.v for mdl in self.models.values()]
|
32
37
|
flat_list = [item for sublist in all_idx for item in sublist]
|
@@ -94,13 +99,10 @@ class RenGen(GroupBase):
|
|
94
99
|
See ANDES Documentation SynGen here for the notes on replacing StaticGen and setting the power
|
95
100
|
ratio parameters.
|
96
101
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
Available:
|
102
|
-
|
103
|
-
https://docs.andes.app/en/latest/groupdoc/RenGen.html#rengen
|
102
|
+
References
|
103
|
+
----------
|
104
|
+
1. ANDES Documentation, RenGen,
|
105
|
+
https://andes.readthedocs.io/en/stable/groupdoc/RenGen.html#rengen
|
104
106
|
"""
|
105
107
|
|
106
108
|
def __init__(self):
|
@@ -129,13 +131,10 @@ class DG(GroupBase):
|
|
129
131
|
See ANDES Documentation SynGen here for the notes on replacing StaticGen and setting the power
|
130
132
|
ratio parameters.
|
131
133
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
Available:
|
137
|
-
|
138
|
-
https://docs.andes.app/en/latest/groupdoc/SynGen.html#syngen
|
134
|
+
References
|
135
|
+
----------
|
136
|
+
1. ANDES Documentation, SynGen,
|
137
|
+
https://andes.readthedocs.io/en/stable/groupdoc/SynGen.html#syngen
|
139
138
|
"""
|
140
139
|
|
141
140
|
def __init__(self):
|
@@ -182,7 +181,7 @@ class StaticGen(GroupBase):
|
|
182
181
|
Notes
|
183
182
|
-----
|
184
183
|
For co-simulation with ANDES, refer to the `ANDES StaticGen Documentation
|
185
|
-
<https://
|
184
|
+
<https://andes.readthedocs.io/en/stable/groupdoc/StaticGen.html#staticgen>`_ for
|
186
185
|
replacing static generators with dynamic generators.
|
187
186
|
"""
|
188
187
|
|
ams/models/renewable/regc.py
CHANGED
@@ -39,12 +39,10 @@ class REGCA1(REGCData, Model):
|
|
39
39
|
"""
|
40
40
|
Renewable generator scheduling model.
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
Available:
|
47
|
-
https://docs.andes.app/en/latest/groupdoc/RenGen.html#regca1
|
42
|
+
References
|
43
|
+
----------
|
44
|
+
1. ANDES Documentation, REGCA1,
|
45
|
+
https://andes.readthedocs.io/en/stable/groupdoc/RenGen.html#regca1
|
48
46
|
"""
|
49
47
|
|
50
48
|
def __init__(self, system=None, config=None) -> None:
|
@@ -56,7 +54,7 @@ class REGCA1(REGCData, Model):
|
|
56
54
|
class REGCV1(REGCData, Model):
|
57
55
|
"""
|
58
56
|
Voltage-controlled converter model (virtual synchronous generator) with
|
59
|
-
inertia emulation.
|
57
|
+
inertia emulation, for scheduling purposes.
|
60
58
|
|
61
59
|
Here Mmax and Dmax are assumed to be constant, but they might subject to
|
62
60
|
the operating condition of the converter.
|
@@ -67,13 +65,10 @@ class REGCV1(REGCData, Model):
|
|
67
65
|
- Generation cost is defined by model :ref:`GCost`
|
68
66
|
- Inertia emulation cost is defined by model :ref:`VSGCost`
|
69
67
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Available:
|
75
|
-
|
76
|
-
https://docs.andes.app/en/latest/groupdoc/RenGen.html#regcv1
|
68
|
+
References
|
69
|
+
----------
|
70
|
+
1. ANDES Documentation, REGCV1,
|
71
|
+
https://andes.readthedocs.io/en/stable/groupdoc/RenGen.html#regcv1
|
77
72
|
"""
|
78
73
|
|
79
74
|
def __init__(self, system=None, config=None) -> None:
|
@@ -100,15 +95,12 @@ class REGCV1(REGCData, Model):
|
|
100
95
|
|
101
96
|
class REGCV2(REGCV1):
|
102
97
|
"""
|
103
|
-
|
104
|
-
|
105
|
-
Reference:
|
106
|
-
|
107
|
-
[1] ANDES Documentation, REGCV2
|
108
|
-
|
109
|
-
Available:
|
98
|
+
Alias for REGCV1, for scheduling purposes.
|
110
99
|
|
111
|
-
|
100
|
+
References
|
101
|
+
----------
|
102
|
+
1. ANDES Documentation, REGCV2,
|
103
|
+
https://andes.readthedocs.io/en/stable/groupdoc/RenGen.html#regcv2
|
112
104
|
"""
|
113
105
|
|
114
106
|
def __init__(self, system=None, config=None) -> None:
|