ltbams 1.0.12__py3-none-any.whl → 1.0.13__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/core/matprocessor.py +170 -104
- ams/io/matpower.py +4 -0
- ams/io/psse.py +2 -0
- ams/opt/exprcalc.py +11 -0
- ams/routines/grbopt.py +2 -0
- ams/routines/pypower.py +8 -0
- ams/routines/routine.py +118 -1
- ams/shared.py +30 -2
- ams/system.py +10 -0
- docs/source/index.rst +4 -3
- docs/source/release-notes.rst +8 -0
- {ltbams-1.0.12.dist-info → ltbams-1.0.13.dist-info}/METADATA +4 -2
- {ltbams-1.0.12.dist-info → ltbams-1.0.13.dist-info}/RECORD +17 -45
- {ltbams-1.0.12.dist-info → ltbams-1.0.13.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.13.dist-info}/WHEEL +0 -0
- {ltbams-1.0.12.dist-info → ltbams-1.0.13.dist-info}/entry_points.txt +0 -0
ams/routines/routine.py
CHANGED
@@ -3,8 +3,9 @@ Module for routine data.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import logging
|
6
|
-
|
6
|
+
import json
|
7
7
|
from collections import OrderedDict
|
8
|
+
from typing import Optional, Union, Type, Iterable, Dict
|
8
9
|
|
9
10
|
import numpy as np
|
10
11
|
|
@@ -431,6 +432,90 @@ class RoutineBase:
|
|
431
432
|
logger.warning(msg)
|
432
433
|
return False
|
433
434
|
|
435
|
+
def load_json(self, path):
|
436
|
+
"""
|
437
|
+
Load scheduling results from a json file.
|
438
|
+
|
439
|
+
Parameters
|
440
|
+
----------
|
441
|
+
path : str
|
442
|
+
Path of the json file to load.
|
443
|
+
|
444
|
+
Returns
|
445
|
+
-------
|
446
|
+
bool
|
447
|
+
True if the loading is successful, False otherwise.
|
448
|
+
"""
|
449
|
+
try:
|
450
|
+
with open(path, 'r') as f:
|
451
|
+
data = json.load(f)
|
452
|
+
except Exception as e:
|
453
|
+
logger.error(f"Failed to load JSON file: {e}")
|
454
|
+
return False
|
455
|
+
|
456
|
+
if not self.initialized:
|
457
|
+
self.init()
|
458
|
+
|
459
|
+
# Unpack variables and expressions from JSON
|
460
|
+
for group, group_data in data.items():
|
461
|
+
if not isinstance(group_data, dict):
|
462
|
+
continue
|
463
|
+
for key, values in group_data.items():
|
464
|
+
if key == 'idx':
|
465
|
+
continue
|
466
|
+
# Find the corresponding variable or expression
|
467
|
+
if key in self.vars:
|
468
|
+
var = self.vars[key]
|
469
|
+
# Assign values to the variable
|
470
|
+
try:
|
471
|
+
var.v = np.array(values)
|
472
|
+
except Exception as e:
|
473
|
+
logger.warning(f"Failed to assign values to var '{key}': {e}")
|
474
|
+
elif key in self.exprs:
|
475
|
+
continue
|
476
|
+
elif key in self.exprcs:
|
477
|
+
exprc = self.exprcs[key]
|
478
|
+
# Assign values to the expression calculation
|
479
|
+
try:
|
480
|
+
exprc.v = np.array(values)
|
481
|
+
except Exception as e:
|
482
|
+
logger.warning(f"Failed to assign values to exprc '{key}': {e}")
|
483
|
+
logger.info(f"Loaded results from {path}")
|
484
|
+
return True
|
485
|
+
|
486
|
+
def export_json(self, path=None):
|
487
|
+
"""
|
488
|
+
Export scheduling results to a json file.
|
489
|
+
|
490
|
+
Parameters
|
491
|
+
----------
|
492
|
+
path : str, optional
|
493
|
+
Path of the json file to export.
|
494
|
+
|
495
|
+
Returns
|
496
|
+
-------
|
497
|
+
str
|
498
|
+
The exported json file name
|
499
|
+
"""
|
500
|
+
if not self.converged:
|
501
|
+
logger.warning("Routine did not converge, aborting export.")
|
502
|
+
return None
|
503
|
+
|
504
|
+
path, file_name = get_export_path(self.system, self.class_name,
|
505
|
+
path=path, fmt='json')
|
506
|
+
|
507
|
+
data_dict = dict()
|
508
|
+
|
509
|
+
group_data(self, data_dict, self.vars, 'v')
|
510
|
+
group_data(self, data_dict, self.exprs, 'v')
|
511
|
+
group_data(self, data_dict, self.exprcs, 'v')
|
512
|
+
|
513
|
+
with open(path, 'w') as f:
|
514
|
+
json.dump(data_dict, f, indent=4,
|
515
|
+
default=lambda x: x.tolist() if isinstance(x, np.ndarray) else x)
|
516
|
+
|
517
|
+
return file_name
|
518
|
+
|
434
519
|
def export_csv(self, path=None):
|
435
520
|
"""
|
436
521
|
Export scheduling results to a csv file.
|
@@ -1022,3 +1107,35 @@ def collect_data(rtn: RoutineBase, data_dict: Dict, items: Dict, attr: str):
|
|
1022
1107
|
logger.debug(f"Error with collecting data for '{key}': {e}")
|
1023
1108
|
data_v = [np.nan] * len(idx_v)
|
1024
1109
|
data_dict.update(OrderedDict(zip([f'{key} {dev}' for dev in idx_v], data_v)))
|
1110
|
+
|
1111
|
+
|
1112
|
+
def group_data(rtn: RoutineBase, data_dict: Dict, items: Dict, attr: str):
|
1113
|
+
"""
|
1114
|
+
Collect data for export from grouped items.
|
1115
|
+
|
1116
|
+
Parameters
|
1117
|
+
----------
|
1118
|
+
rtn : ams.routines.routine.RoutineBase
|
1119
|
+
The routine to collect data from.
|
1120
|
+
data_dict : Dict
|
1121
|
+
The data dictionary to populate.
|
1122
|
+
items : dict
|
1123
|
+
Dictionary of items to collect data from.
|
1124
|
+
attr : str
|
1125
|
+
Attribute to collect data for.
|
1126
|
+
"""
|
1127
|
+
for key, item in items.items():
|
1128
|
+
if item.owner is None:
|
1129
|
+
continue
|
1130
|
+
if item.owner.class_name not in data_dict.keys():
|
1131
|
+
idx_v = item.get_all_idxes()
|
1132
|
+
data_dict[item.owner.class_name] = dict(idx=idx_v)
|
1133
|
+
else:
|
1134
|
+
idx_v = data_dict[item.owner.class_name]['idx']
|
1135
|
+
try:
|
1136
|
+
data_v = rtn.get(src=key, attr=attr, idx=idx_v,
|
1137
|
+
horizon=rtn.timeslot.v if hasattr(rtn, 'timeslot') else None)
|
1138
|
+
except Exception as e:
|
1139
|
+
logger.warning(f"Error with collecting data for '{key}': {e}")
|
1140
|
+
data_v = [np.nan] * item.owner.n
|
1141
|
+
data_dict[item.owner.class_name][key] = data_v
|
ams/shared.py
CHANGED
@@ -4,6 +4,7 @@ Shared constants and delayed imports.
|
|
4
4
|
This module is supplementary to the ``andes.shared`` module.
|
5
5
|
"""
|
6
6
|
import logging
|
7
|
+
import sys
|
7
8
|
import unittest
|
8
9
|
from functools import wraps
|
9
10
|
from time import strftime
|
@@ -24,6 +25,7 @@ ppoption = LazyImport('from pypower.ppoption import ppoption')
|
|
24
25
|
runpf = LazyImport('from pypower.runpf import runpf')
|
25
26
|
runopf = LazyImport('from pypower.runopf import runopf')
|
26
27
|
opf = LazyImport('from gurobi_optimods import opf')
|
28
|
+
tqdm = LazyImport('from tqdm.auto import tqdm')
|
27
29
|
|
28
30
|
# --- an empty ANDES system ---
|
29
31
|
empty_adsys = adSystem(autogen_stale=False)
|
@@ -118,7 +120,7 @@ def skip_unittest_without_PYPOWER(f):
|
|
118
120
|
try:
|
119
121
|
import pypower # NOQA
|
120
122
|
except ImportError:
|
121
|
-
raise unittest.SkipTest("PYPOWER is not
|
123
|
+
raise unittest.SkipTest("PYPOWER is not available.")
|
122
124
|
return f(*args, **kwargs)
|
123
125
|
return wrapper
|
124
126
|
|
@@ -131,6 +133,32 @@ def skip_unittest_without_gurobi_optimods(f):
|
|
131
133
|
try:
|
132
134
|
import gurobi_optimods # NOQA
|
133
135
|
except ImportError:
|
134
|
-
raise unittest.SkipTest("
|
136
|
+
raise unittest.SkipTest("gurobi_optimods is not available.")
|
135
137
|
return f(*args, **kwargs)
|
136
138
|
return wrapper
|
139
|
+
|
140
|
+
|
141
|
+
def _init_pbar(total, unit, no_tqdm):
|
142
|
+
"""Initializes and returns a tqdm progress bar."""
|
143
|
+
pbar = tqdm(total=total, unit=unit, ncols=80, ascii=True,
|
144
|
+
file=sys.stdout, disable=no_tqdm)
|
145
|
+
pbar.update(0)
|
146
|
+
return pbar
|
147
|
+
|
148
|
+
|
149
|
+
def _update_pbar(pbar, current, total):
|
150
|
+
"""Updates and closes the progress bar."""
|
151
|
+
perc = np.round(min((current / total) * 100, 100), 2)
|
152
|
+
if pbar.total is not None: # Check if pbar is still valid
|
153
|
+
last_pc = pbar.n / pbar.total * 100 # Get current percentage based on updated value
|
154
|
+
else:
|
155
|
+
last_pc = 0
|
156
|
+
|
157
|
+
perc_diff = perc - last_pc
|
158
|
+
if perc_diff >= 1:
|
159
|
+
pbar.update(perc_diff)
|
160
|
+
|
161
|
+
# Ensure pbar finishes at 100% and closes
|
162
|
+
if pbar.n < pbar.total: # Check if it's not already at total
|
163
|
+
pbar.update(pbar.total - pbar.n) # Update remaining
|
164
|
+
pbar.close()
|
ams/system.py
CHANGED
@@ -740,6 +740,8 @@ class System(adSystem):
|
|
740
740
|
- Unlike the XLSX and JSON converters, this implementation uses value providers
|
741
741
|
(`v`) instead of vin. As a result, any changes made through `model.set` will be
|
742
742
|
reflected in the generated MPC.
|
743
|
+
|
744
|
+
.. versionadded:: 1.0.10
|
743
745
|
"""
|
744
746
|
return system2mpc(self)
|
745
747
|
|
@@ -769,6 +771,8 @@ class System(adSystem):
|
|
769
771
|
- Unlike the XLSX and JSON converters, this implementation uses value providers
|
770
772
|
(`v`) instead of vin. As a result, any changes made through `model.set` will be
|
771
773
|
reflected in the generated MPC.
|
774
|
+
|
775
|
+
.. versionadded:: 1.0.10
|
772
776
|
"""
|
773
777
|
return write_m(self, outfile=outfile, overwrite=overwrite)
|
774
778
|
|
@@ -783,6 +787,8 @@ class System(adSystem):
|
|
783
787
|
The output file name.
|
784
788
|
overwrite : bool, optional
|
785
789
|
If True, overwrite the existing file. Default is None.
|
790
|
+
|
791
|
+
.. versionadded:: 1.0.10
|
786
792
|
"""
|
787
793
|
return write_xlsx(self, outfile=outfile, overwrite=overwrite)
|
788
794
|
|
@@ -797,6 +803,8 @@ class System(adSystem):
|
|
797
803
|
The output file name.
|
798
804
|
overwrite : bool, optional
|
799
805
|
If True, overwrite the existing file. Default is None.
|
806
|
+
|
807
|
+
.. versionadded:: 1.0.10
|
800
808
|
"""
|
801
809
|
return write_json(self, outfile=outfile, overwrite=overwrite)
|
802
810
|
|
@@ -813,6 +821,8 @@ class System(adSystem):
|
|
813
821
|
The output file name.
|
814
822
|
overwrite : bool, optional
|
815
823
|
If True, overwrite the existing file. Default is None.
|
824
|
+
|
825
|
+
.. versionadded:: 1.0.10
|
816
826
|
"""
|
817
827
|
return write_raw(self, outfile=outfile, overwrite=overwrite)
|
818
828
|
|
docs/source/index.rst
CHANGED
@@ -89,9 +89,10 @@ dynamic simulator ANDES.
|
|
89
89
|
publication.
|
90
90
|
|
91
91
|
|
92
|
-
.. [Wang2025] J. Wang et al., "Dynamics-
|
93
|
-
Constrained Scheduling Under High-
|
94
|
-
Transactions on Sustainable Energy,
|
92
|
+
.. [Wang2025] J. Wang et al., "Dynamics-Incorporated Modeling Framework for Stability
|
93
|
+
Constrained Scheduling Under High-Penetration of Renewable Energy," in IEEE
|
94
|
+
Transactions on Sustainable Energy, vol. 16, no. 3, pp. 1673-1685, July 2025,
|
95
|
+
doi: 10.1109/TSTE.2025.3528027.
|
95
96
|
|
96
97
|
|
97
98
|
.. toctree::
|
docs/source/release-notes.rst
CHANGED
@@ -9,6 +9,14 @@ The APIs before v3.0.0 are in beta and may change without prior notice.
|
|
9
9
|
v1.0
|
10
10
|
==========
|
11
11
|
|
12
|
+
v1.0.13 (2025-08-18)
|
13
|
+
----------------------
|
14
|
+
|
15
|
+
- Add methods ``export_npz``, ``load_npz``, ``load_csv`` in ``MatProcessor``
|
16
|
+
to save and load matrices from files
|
17
|
+
- Add methods ``export_json``, ``load_json`` in ``RoutineBase``
|
18
|
+
to save and load routine results from JSON files
|
19
|
+
|
12
20
|
v1.0.12 (2025-05-29)
|
13
21
|
----------------------
|
14
22
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ltbams
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.13
|
4
4
|
Summary: Python software for scheduling modeling and co-simulation with dynamics.
|
5
5
|
Home-page: https://github.com/CURENT/ams
|
6
6
|
Author: Jinning Wang
|
@@ -23,6 +23,7 @@ Requires-Dist: openpyxl
|
|
23
23
|
Requires-Dist: andes>=1.9.3
|
24
24
|
Requires-Dist: pybind11
|
25
25
|
Requires-Dist: cvxpy
|
26
|
+
Requires-Dist: cffi
|
26
27
|
Provides-Extra: dev
|
27
28
|
Requires-Dist: pytest; extra == "dev"
|
28
29
|
Requires-Dist: pytest-cov; extra == "dev"
|
@@ -60,6 +61,7 @@ Python Software for Power System Scheduling Modeling and Co-Simulation with Dyna
|
|
60
61
|
| Badges | | |
|
61
62
|
|---|---|---|
|
62
63
|
| Repo |  |  |
|
64
|
+
| Python | [](https://www.python.org/) |
|
63
65
|
| Version | [](https://pypi.org/project/ltbams/) | [](https://anaconda.org/conda-forge/ltbams) |
|
64
66
|
| Tag | [](https://github.com/CURENT/ams/tags) |  |
|
65
67
|
| Documentation | [](https://ltb.readthedocs.io/projects/ams/en/stable/?badge=stable) | [](https://ltb.readthedocs.io/projects/ams/en/develop/?badge=develop) |
|
@@ -217,7 +219,7 @@ sa
|
|
217
219
|
# Citing AMS
|
218
220
|
If you use AMS for research or consulting, please cite the following paper in your publication that uses AMS:
|
219
221
|
|
220
|
-
> J. Wang et al., "Dynamics-
|
222
|
+
> J. Wang et al., "Dynamics-Incorporated Modeling Framework for Stability Constrained Scheduling Under High-Penetration of Renewable Energy," in IEEE Transactions on Sustainable Energy, vol. 16, no. 3, pp. 1673-1685, July 2025, doi: 10.1109/TSTE.2025.3528027.
|
221
223
|
|
222
224
|
# Sponsors and Contributors
|
223
225
|
AMS is the scheduling simulation engine for the CURENT Largescale Testbed (LTB).
|
@@ -1,12 +1,12 @@
|
|
1
1
|
ams/__init__.py,sha256=q-9-f0YCg6aaTW19VCkY6VosfvRA2ObI9mF1f_3016Y,313
|
2
2
|
ams/__main__.py,sha256=EB4GfGiKgvnQ_psNr0QwPoziYvjmGvQ2yVsBwQtfrLw,170
|
3
|
-
ams/_version.py,sha256=
|
3
|
+
ams/_version.py,sha256=cx7xVAwESB33WAGN1aq_ze2Enb6iFPvXPOw8AEV7mrg,498
|
4
4
|
ams/cli.py,sha256=EyNFXn565gFCppTxpyTZviBdPgUuKtgAPZ4WE6xewRk,6164
|
5
5
|
ams/interface.py,sha256=-UN7-TiSt7mOS0W7526LuOk4KCIGDZSguRaVmh_KMRM,45240
|
6
6
|
ams/main.py,sha256=lIqC16TO0pye75Wv8l_6EemNtm15iyMdvu8YQFkdd_4,23599
|
7
7
|
ams/report.py,sha256=ewcffopOzT5o45eJNmcV8pxeQqPIjKbarGN33-yHGA8,10961
|
8
|
-
ams/shared.py,sha256=
|
9
|
-
ams/system.py,sha256=
|
8
|
+
ams/shared.py,sha256=HNkW-fa7l1PSubHPUvG5iaJTKeKXEt-IUCEv1MyrX3Q,4820
|
9
|
+
ams/system.py,sha256=rKd9xeb6NKTcb74iqMh5zHS4ZrvQXI88zx56ChIoKkc,32118
|
10
10
|
ams/cases/5bus/pjm5bus_demo.json,sha256=IpxO2vzB9-9Kg9xjOXREKeXEz9wjFE7cuQbcUu8VORA,23152
|
11
11
|
ams/cases/5bus/pjm5bus_demo.xlsx,sha256=OWIUprkg8_aQ_bTCaEFMl7Bhfa1R20zxAHXRQtXBix0,32607
|
12
12
|
ams/cases/5bus/pjm5bus_ev.xlsx,sha256=vR8dJv5jIxib1pgcMonhzvraoqZVJWhBSJdVXDL0qsI,19498
|
@@ -38,7 +38,7 @@ ams/cases/wecc/wecc_uced.xlsx,sha256=R3tZgxEqz_ctKcjA1wwFecxn-QZXutvf7NzgnCg_078
|
|
38
38
|
ams/core/__init__.py,sha256=lIvrAvYf2yrHWqYi0rVuJgJt8KNA8nTmN2iuZ125z9Q,123
|
39
39
|
ams/core/common.py,sha256=934J7xq5JvC14yKp2Z4hWKUFJFhxzAnxB_8_99CChY0,704
|
40
40
|
ams/core/documenter.py,sha256=3-jUYrtN8zDZXd8tQZlmZouJluJPH9_xIDbK9ZEEnRU,25762
|
41
|
-
ams/core/matprocessor.py,sha256=
|
41
|
+
ams/core/matprocessor.py,sha256=T_WcfTS2qoXa8IxiaYBgSjt56yQm_qUKSsh3Gfq-yIc,27923
|
42
42
|
ams/core/model.py,sha256=LNZtzyf2A7Tz3pn9IDs35JYaHSkQRqhqZicTpZGSqsc,10926
|
43
43
|
ams/core/param.py,sha256=LPH48xUHyqWqODD6IsiamUtkJDDSgGCEMAo6vroFoHE,11130
|
44
44
|
ams/core/service.py,sha256=Q4aeaYFWycIEH7I8DSO8Itah2CJxc3oAW46dtKCQEyA,28041
|
@@ -48,8 +48,8 @@ ams/extension/__init__.py,sha256=5IFTNirDL0uDaUsg05_oociVT9VCy2rhPx1ad4LGveM,65
|
|
48
48
|
ams/extension/eva.py,sha256=4_q4ME0WrQIcd205SBTjv0-rMRZZIdQ07QJuEHwLIC8,16340
|
49
49
|
ams/io/__init__.py,sha256=GIfF7X44olHaySL8EzOBU1eXUnunr1owzzdPfPvvHZU,3802
|
50
50
|
ams/io/json.py,sha256=IurwcZDuKczSbRTpcbQZiIi0ARCrMK6kJ0E3wS8ENy8,2585
|
51
|
-
ams/io/matpower.py,sha256=
|
52
|
-
ams/io/psse.py,sha256=
|
51
|
+
ams/io/matpower.py,sha256=qxZ6qqFDm1F9mWotLT6walWD-rZaFKyh0-DVtRcjhgY,27601
|
52
|
+
ams/io/psse.py,sha256=qLKM9pRsNuSVNRHrgy4i6beSLuxu4fcBEU_SIV8owRA,13714
|
53
53
|
ams/io/pypower.py,sha256=Fe0sxzC5DZegtYksTixadXk_LcfJ1GNetWu9EuHCkG8,2790
|
54
54
|
ams/io/xlsx.py,sha256=7ATW1seyxsGn7d5p5IuSRFHcoCHVVjMu3E7mP1Mc74U,2460
|
55
55
|
ams/models/__init__.py,sha256=EGkViLkVX_We9FAGuEkgfleMNmPw_vGp2Nq1OQimL7U,691
|
@@ -74,7 +74,7 @@ ams/models/static/gen.py,sha256=QXklOYlnU7QHWy-WFJwhxuNItUPqFsLJIjAO4sGMUbg,7087
|
|
74
74
|
ams/models/static/pq.py,sha256=SCwAqhqvKy_PFHp6VYO_zgv3v6gI5pK3KvT3RNX-nvA,2782
|
75
75
|
ams/opt/__init__.py,sha256=INsl8yxtOzTKqV9pzVxlL6RSGDRaUDwxpZMY1QROrF4,459
|
76
76
|
ams/opt/constraint.py,sha256=ERT9zwjQyGkvDo465Yd0wBexlIhjVmw0MyWq4BWnWoI,5534
|
77
|
-
ams/opt/exprcalc.py,sha256=
|
77
|
+
ams/opt/exprcalc.py,sha256=7io0vEZu5zqsEnetocasRT1tu7o7g0TXw7iJf2YFIxI,4317
|
78
78
|
ams/opt/expression.py,sha256=WrWnYliB61uHA_wQjtYgtAXdpgSN1pNqQmWvzHWSsdE,5569
|
79
79
|
ams/opt/objective.py,sha256=W0dQfW5dHNdWEc2DQtWYNGMuhMY6Pu-HTD0n7-izDZA,5519
|
80
80
|
ams/opt/omodel.py,sha256=hEtfKoSNssSxHgUDdep79pifNTsywytDTjgGgne7nKM,12750
|
@@ -88,10 +88,10 @@ ams/routines/dcopf2.py,sha256=sDCP8zqYHDh7s7p9SX6G8QhMfIxCg3VPYJn6r3pRKyo,3620
|
|
88
88
|
ams/routines/dcpf.py,sha256=lGZ9LmCL1DsFB-sNxI7NGrq0qd_iBRMDPJmU5022t20,8242
|
89
89
|
ams/routines/dopf.py,sha256=8D36-FkPORYGaMnwGTqwz8HxAXk5ywo3mk8NlGq327g,6289
|
90
90
|
ams/routines/ed.py,sha256=9Hf_ZqD6poIxCIBfsTMC0DGoPNEja1ZtVxqhb4ijhgE,11875
|
91
|
-
ams/routines/grbopt.py,sha256=
|
91
|
+
ams/routines/grbopt.py,sha256=hEDy7L-lSd7QxSN_GAyDLaLkhIpxl6csXz6ntdKT_fw,5510
|
92
92
|
ams/routines/pflow.py,sha256=5_9n10r_PfsVXIRkaBgKxVITumImZ8mvpHnwxX_ECdw,9432
|
93
|
-
ams/routines/pypower.py,sha256=
|
94
|
-
ams/routines/routine.py,sha256=
|
93
|
+
ams/routines/pypower.py,sha256=VnqMQZkBIvDe3tDbTJcxYz04idon5XvmGlf7OSs8kOI,27334
|
94
|
+
ams/routines/routine.py,sha256=PB-97CkdNAiAGMlagihvFTklt2w7ce4FG2NcjW1InoA,39445
|
95
95
|
ams/routines/rted.py,sha256=GOHRxo0-HS5HhwQg8lv7-2VcGr_M_TdUvvomgJ31fDQ,22070
|
96
96
|
ams/routines/type.py,sha256=lvTWSnCYIbRJXIm3HX6jA0Hv-WWYusTOUPfoW8DITlU,3877
|
97
97
|
ams/routines/uc.py,sha256=VcuNy2TnBjsewKEGIqeo2EFTyuhpx5QsEvgpAtscDIQ,15648
|
@@ -104,8 +104,8 @@ docs/source/api.rst,sha256=BRzdDFDzDwVL7Jr_Xj-O5Icgx0gt5hNNd1OjvPl7ap0,1490
|
|
104
104
|
docs/source/conf.py,sha256=UyoWogZTUNSJU7pQS_JaR28nKddW94zr01LYoIciZZw,6688
|
105
105
|
docs/source/genmodelref.py,sha256=IhmF7bDw8BXPvLD8V3WjQNrfc-H07r5iS-_4DHbbp-8,1420
|
106
106
|
docs/source/genroutineref.py,sha256=glHhbWUXfZzMDrkque9CBZu8QtdxlxPojInERzAAOwA,1063
|
107
|
-
docs/source/index.rst,sha256=
|
108
|
-
docs/source/release-notes.rst,sha256=
|
107
|
+
docs/source/index.rst,sha256=oAdRBWTLCX8nEMVatfDFkn0dtvinOK7vg4QUekT4jns,2738
|
108
|
+
docs/source/release-notes.rst,sha256=bzZC_X3PP392jjG0j3hSbBtPUFceMcea0FjTIPljyl8,14308
|
109
109
|
docs/source/_templates/autosummary/base.rst,sha256=zl3U4baR4a6YjsHyT-x9zCOrHwKZOVUdWn1NPX2u3bc,106
|
110
110
|
docs/source/_templates/autosummary/class.rst,sha256=Hv_igCsLsUpM62_zN0nqj6FSfKnS5xLyu8ZldMbfOAk,668
|
111
111
|
docs/source/_templates/autosummary/module.rst,sha256=YdbpCudOrEU-JbuSlzGvcOI2hn_KrCM6FW5HcGqkaEE,1113
|
@@ -135,36 +135,8 @@ docs/source/modeling/index.rst,sha256=TasRAJSglc5KAZaGAj9TLMktOO2TtzZsqG5WvvZXB_
|
|
135
135
|
docs/source/modeling/model.rst,sha256=j7OSvoXnDht6rGpgwPiJklsCWrebfx4DxIN-G8r6iFo,7086
|
136
136
|
docs/source/modeling/routine.rst,sha256=BkUE3y5L1lA7LP9Nyzc4zzY-tF3t4k7egBE188kybHY,4286
|
137
137
|
docs/source/modeling/system.rst,sha256=NMOPNMOKG1_dRyNPPx-MiCKbbpadxWJxGyU6geRUsvQ,1374
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
tests/test_export_csv.py,sha256=NTULXfTexgI1jf5koUMOYi3RLrSQouS7zxRjXo3ng50,2921
|
144
|
-
tests/test_group.py,sha256=Tq0s9gtenqrv4ws5YNzWxbiF4WgyhtMEAXZfJtew6M4,2699
|
145
|
-
tests/test_interface.py,sha256=8hOZ1caRfoyoEdy1lnh8Y4rIL97FLb2oUKfX_N1lEDo,8838
|
146
|
-
tests/test_io.py,sha256=OXt1C6F_RAt0RoRj3xLKdbA3raKEAjvVyWlKD7Ju7BA,6947
|
147
|
-
tests/test_jumper.py,sha256=bdOknplEGnO_tiJc7p3xQvgTe2b6Dz53bOgbFaXKMAI,537
|
148
|
-
tests/test_known_good.py,sha256=NBrlAxnVMxIHXR2cWps-Kwjh36fiU4Y-eupspZkM0ks,9670
|
149
|
-
tests/test_matp.py,sha256=LkjhqxSFr6oY_ENpduDQ77rhLLBl6RzIHZ2d0m_8i-8,17262
|
150
|
-
tests/test_model.py,sha256=ZgghNYmEeALf8_1sPjq9lIJwuYDQ2SelivJNEYpHxJU,1621
|
151
|
-
tests/test_omodel.py,sha256=niVdTZJEZNSVHz-ocA0nnVx84Dt3-8P5FUrwKkNiA0I,4305
|
152
|
-
tests/test_paths.py,sha256=j_D9-Cjg73mwhTS3sUHDfQ8mCebD8enCQxjyRaR2ZH4,3020
|
153
|
-
tests/test_report.py,sha256=RR23by4G-cyleaHTy9A7SEVet0eOVS-Tm0kk1GXY5dM,8134
|
154
|
-
tests/test_repr.py,sha256=g7MRdxLcZRI1PlREFdUG_npp0LkcQiJZfOPw1aq0EFM,570
|
155
|
-
tests/test_routine.py,sha256=DP5CwKtzliw2gNLW2W_3kp0Ihy4rCaxeBxMpgyN5AXA,6234
|
156
|
-
tests/test_rtn_acopf.py,sha256=Kg-RHflrrwyX2uHr16xSAze9XAdYcK7eg1LHMyr1uyA,2354
|
157
|
-
tests/test_rtn_dcopf.py,sha256=qFY9mKTAIG-qDlU9-loHZddKDDszdGQwRjL-ZDnESu8,4204
|
158
|
-
tests/test_rtn_dcopf2.py,sha256=57_62TnHW-cS6iK2zXT_eXChnh83YiYoPypJwub3VmQ,3747
|
159
|
-
tests/test_rtn_ed.py,sha256=SeSuzqpTZZnBph41PV2Piplo9yxR3qpbhQUa6UCYnSw,10267
|
160
|
-
tests/test_rtn_opf.py,sha256=MmMNwb9-G0KzHcrrP4uHTvs9DBU71_XPIJqNnkQQPHo,4846
|
161
|
-
tests/test_rtn_pflow.py,sha256=QLg0q89Tcb-rrncpiNw6phjMEnvzvExjGTrkqGliiak,4664
|
162
|
-
tests/test_rtn_pypower.py,sha256=KO5VOZxETxVH2mY1mgNvzj1gz1Gdak1sAWxYleDU4E8,10477
|
163
|
-
tests/test_rtn_rted.py,sha256=QHDUymorCqQAJKFlDgTy40JyLTGDvNVNU3tjbjDl3-0,9850
|
164
|
-
tests/test_rtn_uc.py,sha256=UbMeaam3dZwgq2LAJokGOl3LT5B3TWKMjCp4dRcLs40,8497
|
165
|
-
tests/test_service.py,sha256=6IP6CAH2xHxGHZM4-R8LjZxVJ2L10LcGaPDyRIqKLmc,2438
|
166
|
-
ltbams-1.0.12.dist-info/METADATA,sha256=ZKZlrfSVEg8RkdZ-YjEWGZfY4p7kdEGppQfhHV6hgpg,13808
|
167
|
-
ltbams-1.0.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
168
|
-
ltbams-1.0.12.dist-info/entry_points.txt,sha256=FA56FlhO_yVNeEf810SrorVQb7_Xsmo3_EW-W-ijUfA,37
|
169
|
-
ltbams-1.0.12.dist-info/top_level.txt,sha256=pyKDqG2kj13F9-BYd_wkruRdBSqLXw8Nwc-cmljqrxg,15
|
170
|
-
ltbams-1.0.12.dist-info/RECORD,,
|
138
|
+
ltbams-1.0.13.dist-info/METADATA,sha256=Zlsv1ahEhFMTEJDWhCLAaek_J_nwX7v0i6HTKmZEY0w,14014
|
139
|
+
ltbams-1.0.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
140
|
+
ltbams-1.0.13.dist-info/entry_points.txt,sha256=FA56FlhO_yVNeEf810SrorVQb7_Xsmo3_EW-W-ijUfA,37
|
141
|
+
ltbams-1.0.13.dist-info/top_level.txt,sha256=5QQ_oDY9sa52MVmqCjqjUq07BssHOKmDSaQ8EZi6DOw,9
|
142
|
+
ltbams-1.0.13.dist-info/RECORD,,
|
tests/__init__.py
DELETED
File without changes
|
tests/test_1st_system.py
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
|
3
|
-
import ams
|
4
|
-
|
5
|
-
|
6
|
-
class TestCodegen(unittest.TestCase):
|
7
|
-
"""
|
8
|
-
Test code generation.
|
9
|
-
"""
|
10
|
-
|
11
|
-
def test_1_docs(self) -> None:
|
12
|
-
sp = ams.system.System()
|
13
|
-
out = ''
|
14
|
-
for tp in sp.types.values():
|
15
|
-
out += tp.doc_all()
|
16
|
-
|
17
|
-
out = ''
|
18
|
-
for group in sp.groups.values():
|
19
|
-
out += group.doc_all()
|
20
|
-
|
21
|
-
def test_docum(self) -> None:
|
22
|
-
sp = ams.load(ams.get_case('5bus/pjm5bus_demo.json'),
|
23
|
-
setup=True, no_output=True)
|
24
|
-
sp.DCOPF.init()
|
25
|
-
docum = sp.DCOPF.docum
|
26
|
-
for export in ['plain', 'rest']:
|
27
|
-
docum._obj_doc(max_width=78, export=export)
|
28
|
-
docum._constr_doc(max_width=78, export=export)
|
29
|
-
docum._exprc_doc(max_width=78, export=export)
|
30
|
-
docum._var_doc(max_width=78, export=export)
|
31
|
-
docum._service_doc(max_width=78, export=export)
|
32
|
-
docum._param_doc(max_width=78, export=export)
|
33
|
-
docum.parent.config.doc(max_width=78, export=export)
|
34
|
-
|
35
|
-
|
36
|
-
class TestParamCorrection(unittest.TestCase):
|
37
|
-
"""
|
38
|
-
Test parameter correction.
|
39
|
-
"""
|
40
|
-
|
41
|
-
def setUp(self) -> None:
|
42
|
-
"""
|
43
|
-
Test setup.
|
44
|
-
"""
|
45
|
-
self.ss = ams.load(ams.get_case('matpower/case14.m'),
|
46
|
-
setup=False, no_output=True, default_config=True,)
|
47
|
-
|
48
|
-
def test_line_correction(self):
|
49
|
-
"""
|
50
|
-
Test line correction.
|
51
|
-
"""
|
52
|
-
self.ss.Line.rate_a.v[5] = 0.0
|
53
|
-
self.ss.Line.rate_b.v[6] = 0.0
|
54
|
-
self.ss.Line.rate_c.v[7] = 0.0
|
55
|
-
self.ss.Line.amax.v[8] = 0.0
|
56
|
-
self.ss.Line.amin.v[9] = 0.0
|
57
|
-
|
58
|
-
self.ss.setup()
|
59
|
-
|
60
|
-
self.assertIsNot(self.ss.Line.rate_a.v[5], 0.0)
|
61
|
-
self.assertIsNot(self.ss.Line.rate_b.v[6], 0.0)
|
62
|
-
self.assertIsNot(self.ss.Line.rate_c.v[7], 0.0)
|
63
|
-
self.assertIsNot(self.ss.Line.amax.v[8], 0.0)
|
64
|
-
self.assertIsNot(self.ss.Line.amin.v[9], 0.0)
|
tests/test_addressing.py
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
import numpy as np
|
3
|
-
|
4
|
-
import ams
|
5
|
-
|
6
|
-
ams.config_logger(stream_level=40)
|
7
|
-
|
8
|
-
|
9
|
-
class TestAddressing(unittest.TestCase):
|
10
|
-
"""
|
11
|
-
Tests for addressing.
|
12
|
-
"""
|
13
|
-
|
14
|
-
def test_ieee14_address(self):
|
15
|
-
"""
|
16
|
-
Test IEEE14 address.
|
17
|
-
"""
|
18
|
-
|
19
|
-
# FIXME: why there will be case parsing information using ams.system.example()?
|
20
|
-
ss = ams.system.example()
|
21
|
-
|
22
|
-
# bus variable indices (internal)
|
23
|
-
np.testing.assert_array_equal(ss.Bus.a.a,
|
24
|
-
np.arange(0, ss.Bus.n, 1))
|
25
|
-
np.testing.assert_array_equal(ss.Bus.v.a,
|
26
|
-
np.arange(ss.Bus.n, 2*ss.Bus.n, 1))
|
27
|
-
|
28
|
-
# external variable indices
|
29
|
-
np.testing.assert_array_equal(ss.PV.ud.a,
|
30
|
-
np.array([31, 32, 33, 34]))
|
31
|
-
np.testing.assert_array_equal(ss.PV.p.a,
|
32
|
-
np.array([35, 36, 37, 38]))
|
33
|
-
np.testing.assert_array_equal(ss.PV.q.a,
|
34
|
-
np.array([39, 40, 41, 42]))
|
35
|
-
np.testing.assert_array_equal(ss.Slack.ud.a,
|
36
|
-
np.array([28]))
|
37
|
-
np.testing.assert_array_equal(ss.Slack.p.a,
|
38
|
-
np.array([29]))
|
39
|
-
np.testing.assert_array_equal(ss.Slack.q.a,
|
40
|
-
np.array([30]))
|