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.
Files changed (45) hide show
  1. ams/_version.py +3 -3
  2. ams/core/matprocessor.py +170 -104
  3. ams/io/matpower.py +4 -0
  4. ams/io/psse.py +2 -0
  5. ams/opt/exprcalc.py +11 -0
  6. ams/routines/grbopt.py +2 -0
  7. ams/routines/pypower.py +8 -0
  8. ams/routines/routine.py +118 -1
  9. ams/shared.py +30 -2
  10. ams/system.py +10 -0
  11. docs/source/index.rst +4 -3
  12. docs/source/release-notes.rst +8 -0
  13. {ltbams-1.0.12.dist-info → ltbams-1.0.13.dist-info}/METADATA +4 -2
  14. {ltbams-1.0.12.dist-info → ltbams-1.0.13.dist-info}/RECORD +17 -45
  15. {ltbams-1.0.12.dist-info → ltbams-1.0.13.dist-info}/top_level.txt +0 -1
  16. tests/__init__.py +0 -0
  17. tests/test_1st_system.py +0 -64
  18. tests/test_addressing.py +0 -40
  19. tests/test_case.py +0 -301
  20. tests/test_cli.py +0 -34
  21. tests/test_export_csv.py +0 -89
  22. tests/test_group.py +0 -83
  23. tests/test_interface.py +0 -238
  24. tests/test_io.py +0 -190
  25. tests/test_jumper.py +0 -27
  26. tests/test_known_good.py +0 -267
  27. tests/test_matp.py +0 -437
  28. tests/test_model.py +0 -54
  29. tests/test_omodel.py +0 -119
  30. tests/test_paths.py +0 -89
  31. tests/test_report.py +0 -251
  32. tests/test_repr.py +0 -21
  33. tests/test_routine.py +0 -178
  34. tests/test_rtn_acopf.py +0 -75
  35. tests/test_rtn_dcopf.py +0 -121
  36. tests/test_rtn_dcopf2.py +0 -103
  37. tests/test_rtn_ed.py +0 -279
  38. tests/test_rtn_opf.py +0 -142
  39. tests/test_rtn_pflow.py +0 -147
  40. tests/test_rtn_pypower.py +0 -315
  41. tests/test_rtn_rted.py +0 -273
  42. tests/test_rtn_uc.py +0 -248
  43. tests/test_service.py +0 -73
  44. {ltbams-1.0.12.dist-info → ltbams-1.0.13.dist-info}/WHEEL +0 -0
  45. {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
- from typing import Optional, Union, Type, Iterable, Dict
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 installed.")
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("Gurobi is not installed.")
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-incorporated Modeling Framework for Stability
93
- Constrained Scheduling Under High-penetration of Renewable Energy," in IEEE
94
- Transactions on Sustainable Energy, doi: 10.1109/TSTE.2025.3528027.
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::
@@ -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.12
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 | ![Project Status: Active](https://www.repostatus.org/badges/latest/active.svg) | ![Repo Size](https://img.shields.io/github/repo-size/CURENT/ams) |
64
+ | Python | [![Python Versions](https://img.shields.io/badge/Python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)](https://www.python.org/) |
63
65
  | Version | [![PyPI Version](https://img.shields.io/pypi/v/ltbams.svg)](https://pypi.org/project/ltbams/) | [![Anaconda-Server Badge](https://anaconda.org/conda-forge/ltbams/badges/version.svg)](https://anaconda.org/conda-forge/ltbams) |
64
66
  | Tag | [![GitHub Tag](https://img.shields.io/github/v/tag/CURENT/ams)](https://github.com/CURENT/ams/tags) | ![GitHub commits since latest release (branch)](https://img.shields.io/github/commits-since/curent/ams/latest/develop) |
65
67
  | Documentation | [![Read the Docs](https://img.shields.io/readthedocs/ams?label=stable)](https://ltb.readthedocs.io/projects/ams/en/stable/?badge=stable) | [![Read the Docs](https://img.shields.io/readthedocs/ams?label=develop)](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-incorporated Modeling Framework for Stability Constrained Scheduling Under High-penetration of Renewable Energy," in IEEE Transactions on Sustainable Energy, doi: 10.1109/TSTE.2025.3528027.
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=jNLhv-DaZngBxRAi3mCJd0jmQgAAbgAoAn-N8TbLgbQ,498
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=4sY2U0sghs_S2V6C7Z0OyQ6WZRfpCXk2_Cf_Mg24Vr4,3900
9
- ams/system.py,sha256=bGbZQrN5N2tx1tnxoPz6JSGE568EGH1Oi1zQIyLFLug,31948
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=gOEqg5xYpzmj4aMgTdzYeOPaL-5Bp493TrxUVmMaiTw,26453
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=R8ynl88bWJAzISYZKfMQi7AFRUINwqk_e-Zsh_pnVCE,27541
52
- ams/io/psse.py,sha256=S2JqpEFaXEiazbVtU77i93BA4ZnoKP7jDZ1rQGg24sE,13684
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=oVtjNHzdWvYHV-8PdRehAxjledsQxpxatdNgMLeWS5o,3935
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=RjrMq6XPHeBEbf-Pt9sLk2D1vnXZYYwaic4BP8lbACg,5480
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=3nKm7VoVXWsiiBK0fEdHv0W2T2AsJ4a6Nqb9ts-1u1A,27214
94
- ams/routines/routine.py,sha256=teafNQ7DmXntwNP-RbtJJ9Ixa5xOEioO-nXFhY1psmA,35574
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=N5phQS5RIyYs-NZo_5yYB8LjvHzOKLeXzRA-M8i-g3Q,2688
108
- docs/source/release-notes.rst,sha256=zBHZ9dALCLSKKz5lwwalCQJiNCD2l2d3iJjISWtUiPg,14031
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
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
- tests/test_1st_system.py,sha256=WoCgeyUCjBVwyYCqzwDkYy8F3dWArMQBESqIUQk6tOk,1907
140
- tests/test_addressing.py,sha256=MIT713KCqMg0h2o4rBDZsGUrpGadmMlXnrrdq-wB77E,1364
141
- tests/test_case.py,sha256=b_YZhwIN9sX3FCMD03hRNygV-mYthNj7cOhEv7-by-g,8857
142
- tests/test_cli.py,sha256=TtCGBy2e7Ll_2gJTFo9juZtzhaakho_MqkcqhG2w2dk,870
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]))