ltbams 1.0.9__py3-none-any.whl → 1.0.10__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 (79) hide show
  1. ams/__init__.py +0 -1
  2. ams/_version.py +3 -3
  3. ams/cases/5bus/pjm5bus_demo.json +1324 -0
  4. ams/core/__init__.py +1 -0
  5. ams/core/common.py +30 -0
  6. ams/core/model.py +1 -1
  7. ams/core/symprocessor.py +1 -1
  8. ams/extension/eva.py +1 -1
  9. ams/interface.py +40 -24
  10. ams/io/matpower.py +31 -17
  11. ams/io/psse.py +278 -1
  12. ams/main.py +2 -2
  13. ams/models/group.py +2 -1
  14. ams/models/static/pq.py +7 -3
  15. ams/opt/param.py +1 -2
  16. ams/routines/__init__.py +2 -3
  17. ams/routines/acopf.py +5 -108
  18. ams/routines/dcopf.py +8 -0
  19. ams/routines/dcpf.py +1 -1
  20. ams/routines/ed.py +4 -2
  21. ams/routines/grbopt.py +150 -0
  22. ams/routines/pflow.py +2 -2
  23. ams/routines/pypower.py +631 -0
  24. ams/routines/routine.py +4 -10
  25. ams/routines/uc.py +2 -2
  26. ams/shared.py +26 -43
  27. ams/system.py +118 -2
  28. docs/source/api.rst +2 -0
  29. docs/source/getting_started/install.rst +9 -6
  30. docs/source/images/dcopf_time.png +0 -0
  31. docs/source/images/educ_pie.png +0 -0
  32. docs/source/release-notes.rst +21 -47
  33. {ltbams-1.0.9.dist-info → ltbams-1.0.10.dist-info}/METADATA +87 -47
  34. {ltbams-1.0.9.dist-info → ltbams-1.0.10.dist-info}/RECORD +54 -71
  35. {ltbams-1.0.9.dist-info → ltbams-1.0.10.dist-info}/WHEEL +1 -1
  36. tests/test_1st_system.py +1 -1
  37. tests/test_case.py +14 -14
  38. tests/test_export_csv.py +1 -1
  39. tests/test_interface.py +24 -2
  40. tests/test_io.py +50 -0
  41. tests/test_omodel.py +1 -1
  42. tests/test_report.py +6 -6
  43. tests/test_routine.py +2 -2
  44. tests/test_rtn_acopf.py +75 -0
  45. tests/test_rtn_dcopf.py +1 -1
  46. tests/test_rtn_dcopf2.py +1 -1
  47. tests/test_rtn_ed.py +9 -9
  48. tests/test_rtn_opf.py +142 -0
  49. tests/test_rtn_pflow.py +0 -72
  50. tests/test_rtn_pypower.py +315 -0
  51. tests/test_rtn_rted.py +8 -8
  52. tests/test_rtn_uc.py +18 -18
  53. ams/pypower/__init__.py +0 -8
  54. ams/pypower/_compat.py +0 -9
  55. ams/pypower/core/__init__.py +0 -8
  56. ams/pypower/core/pips.py +0 -894
  57. ams/pypower/core/ppoption.py +0 -244
  58. ams/pypower/core/ppver.py +0 -18
  59. ams/pypower/core/solver.py +0 -2451
  60. ams/pypower/eps.py +0 -6
  61. ams/pypower/idx.py +0 -174
  62. ams/pypower/io.py +0 -604
  63. ams/pypower/make/__init__.py +0 -11
  64. ams/pypower/make/matrices.py +0 -665
  65. ams/pypower/make/pdv.py +0 -506
  66. ams/pypower/routines/__init__.py +0 -7
  67. ams/pypower/routines/cpf.py +0 -513
  68. ams/pypower/routines/cpf_callbacks.py +0 -114
  69. ams/pypower/routines/opf.py +0 -1803
  70. ams/pypower/routines/opffcns.py +0 -1946
  71. ams/pypower/routines/pflow.py +0 -852
  72. ams/pypower/toggle.py +0 -1098
  73. ams/pypower/utils.py +0 -293
  74. ams/routines/cpf.py +0 -65
  75. ams/routines/dcpf0.py +0 -196
  76. ams/routines/pflow0.py +0 -113
  77. tests/test_rtn_dcpf.py +0 -77
  78. {ltbams-1.0.9.dist-info → ltbams-1.0.10.dist-info}/entry_points.txt +0 -0
  79. {ltbams-1.0.9.dist-info → ltbams-1.0.10.dist-info}/top_level.txt +0 -0
ams/shared.py CHANGED
@@ -6,7 +6,6 @@ This module is supplementary to the ``andes.shared`` module.
6
6
  import logging
7
7
  import unittest
8
8
  from functools import wraps
9
- from collections import OrderedDict
10
9
  from time import strftime
11
10
 
12
11
  import cvxpy as cp
@@ -21,10 +20,16 @@ logger = logging.getLogger(__name__)
21
20
  sps = LazyImport('import scipy.sparse as sps')
22
21
  np = LazyImport('import numpy as np')
23
22
  pd = LazyImport('import pandas as pd')
23
+ ppoption = LazyImport('from pypower.ppoption import ppoption')
24
+ runpf = LazyImport('from pypower.runpf import runpf')
25
+ runopf = LazyImport('from pypower.runopf import runopf')
26
+ opf = LazyImport('from gurobi_optimods import opf')
24
27
 
25
28
  # --- an empty ANDES system ---
26
29
  empty_adsys = adSystem(autogen_stale=False)
27
30
  ad_models = list(empty_adsys.models.keys())
31
+ ad_pf_models = [mname for mname, model in empty_adsys.models.items() if model.flags.pflow]
32
+ ad_dyn_models = [mname for mname, model in empty_adsys.models.items() if model.flags.tds and not model.flags.pflow]
28
33
 
29
34
  # --- NumPy constants ---
30
35
  # NOTE: In NumPy 2.0, np.Inf and np.NaN are deprecated.
@@ -105,49 +110,27 @@ def skip_unittest_without_MISOCP(f):
105
110
  return wrapper
106
111
 
107
112
 
108
- ppc_cols = OrderedDict([
109
- ('bus', ['bus_i', 'type', 'pd', 'qd', 'gs', 'bs', 'area', 'vm', 'va',
110
- 'baseKV', 'zone', 'vmax', 'vmin', 'lam_p', 'lam_q',
111
- 'mu_vmax', 'mu_vmin']),
112
- ('branch', ['fbus', 'tbus', 'r', 'x', 'b', 'rate_a', 'rateB_b', 'rate_c',
113
- 'tap', 'shift', 'status', 'angmin',
114
- 'angmax', 'pf', 'qf', 'pt', 'qt', 'mu_sf', 'mu_st',
115
- 'mu_angmin', 'mu_angmax']),
116
- ('gen', ['bus', 'pg', 'qg', 'qmax', 'qmin', 'vg', 'mbase', 'status',
117
- 'pmax', 'pmin', 'pc1', 'pc2', 'qc1min', 'qc1max', 'qc2min',
118
- 'qc2max', 'ramp_agc', 'ramp_10', 'ramp_30', 'ramp_q',
119
- 'apf', 'mu_pmax', 'mu_pmin', 'mu_qmax', 'mu_qmin']),
120
- ('gencost', ['model', 'startup', 'shutdown', 'n', 'c2', 'c1', 'c0']),
121
- ])
113
+ def skip_unittest_without_PYPOWER(f):
114
+ """
115
+ Decorator for skipping tests that require PYPOWER.
116
+ """
117
+ def wrapper(*args, **kwargs):
118
+ try:
119
+ import pypower # NOQA
120
+ except ImportError:
121
+ raise unittest.SkipTest("PYPOWER is not installed.")
122
+ return f(*args, **kwargs)
123
+ return wrapper
122
124
 
123
125
 
124
- def ppc2df(ppc, model='bus', ppc_cols=ppc_cols):
126
+ def skip_unittest_without_gurobi_optimods(f):
125
127
  """
126
- Convert PYPOWER dict to pandas DataFrame.
127
-
128
- Parameters
129
- ----------
130
- ppc : dict
131
- PYPOWER case dict.
132
- model : str
133
- Model name.
134
- ppc_cols : dict
135
- Column names.
136
-
137
- Returns
138
- -------
139
- pandas.DataFrame
140
- DataFrame.
141
-
142
- Examples
143
- --------
144
- >>> import ams
145
- >>> sp = ams.system.example()
146
- >>> ppc = ams.io.pypower.system2ppc(sp)
147
- >>> ppc_bus = ams.shared.ppc2df(ppc, 'bus')
128
+ Decorator for skipping tests that require gurobi_optimods.
148
129
  """
149
- if model not in ppc_cols.keys():
150
- raise ValueError(f"Invalid model {model}")
151
-
152
- df = pd.DataFrame(ppc[model], columns=ppc_cols[model][0:ppc[model].shape[1]])
153
- return df
130
+ def wrapper(*args, **kwargs):
131
+ try:
132
+ import gurobi_optimods # NOQA
133
+ except ImportError:
134
+ raise unittest.SkipTest("Gurobi is not installed.")
135
+ return f(*args, **kwargs)
136
+ return wrapper
ams/system.py CHANGED
@@ -9,7 +9,6 @@ from typing import Dict, Optional
9
9
 
10
10
  import numpy as np
11
11
 
12
- from andes.core import Config
13
12
  from andes.system import System as andes_System
14
13
  from andes.system import (_config_numpy, load_config_rc)
15
14
  from andes.variables import FileMan
@@ -23,9 +22,17 @@ from ams.routines.type import TypeBase
23
22
  from ams.models import file_classes
24
23
  from ams.routines import all_routines
25
24
  from ams.utils.paths import get_config_path
25
+ from ams.core import Config
26
26
  from ams.core.matprocessor import MatProcessor
27
27
  from ams.interface import to_andes
28
28
  from ams.report import Report
29
+ from ams.shared import ad_dyn_models
30
+
31
+ from ams.io.matpower import system2mpc
32
+ from ams.io.matpower import write as wrtite_m
33
+ from ams.io.xlsx import write as write_xlsx
34
+ from ams.io.json import write as write_json
35
+ from ams.io.psse import write_raw
29
36
 
30
37
  logger = logging.getLogger(__name__)
31
38
 
@@ -389,6 +396,43 @@ class System(andes_System):
389
396
  self.is_setup = False
390
397
  self.setup()
391
398
 
399
+ def add(self, model, param_dict=None, **kwargs):
400
+ """
401
+ Add a device instance for an existing model.
402
+
403
+ Revised from ``andes.system.System.add()``.
404
+ """
405
+ if model not in self.models and (model not in self.model_aliases):
406
+ if model in ad_dyn_models:
407
+ logger.debug("ANDES dynamic model <%s> is skipped.", model)
408
+ else:
409
+ logger.warning("<%s> is not an existing model.", model)
410
+ return
411
+
412
+ if self.is_setup:
413
+ raise NotImplementedError("Adding devices are not allowed after setup.")
414
+
415
+ group_name = self.__dict__[model].group
416
+ group = self.groups[group_name]
417
+
418
+ if param_dict is None:
419
+ param_dict = {}
420
+ if kwargs is not None:
421
+ param_dict.update(kwargs)
422
+
423
+ # remove `uid` field
424
+ param_dict.pop('uid', None)
425
+
426
+ idx = param_dict.pop('idx', None)
427
+ if idx is not None and (not isinstance(idx, str) and np.isnan(idx)):
428
+ idx = None
429
+
430
+ idx = group.get_next_idx(idx=idx, model_name=model)
431
+ self.__dict__[model].add(idx=idx, **param_dict)
432
+ group.add(idx=idx, model=self.__dict__[model])
433
+
434
+ return idx
435
+
392
436
  def setup(self):
393
437
  """
394
438
  Set up system for studies.
@@ -421,7 +465,16 @@ class System(andes_System):
421
465
  adjusted_params_str = ', '.join(adjusted_params)
422
466
  msg = f"Zero Line parameters detected, adjusted to default values: {adjusted_params_str}."
423
467
  logger.info(msg)
424
-
468
+ # --- bus type correction ---
469
+ pq_bus = self.PQ.bus.v
470
+ pv_bus = self.PV.bus.v
471
+ slack_bus = self.Slack.bus.v
472
+ # TODO: how to include islanded buses?
473
+ if self.Bus.n > 0 and np.all(self.Bus.type.v == 1):
474
+ self.Bus.alter(src='type', idx=pq_bus, value=1)
475
+ self.Bus.alter(src='type', idx=pv_bus, value=2)
476
+ self.Bus.alter(src='type', idx=slack_bus, value=3)
477
+ logger.info("All bus type are PQ, adjusted given load and generator connection status.")
425
478
  # === no device addition or removal after this point ===
426
479
  self.calc_pu_coeff() # calculate parameters in system per units
427
480
 
@@ -662,10 +715,73 @@ class System(andes_System):
662
715
 
663
716
  return False
664
717
 
718
+ def to_mpc(self):
719
+ """
720
+ Export an AMS system to a MATPOWER dict.
721
+
722
+ Returns
723
+ -------
724
+ dict
725
+ A dictionary representing the MATPOWER case.
726
+ """
727
+ return system2mpc(self)
728
+
729
+ def to_m(self, outfile: str, overwrite: bool = None):
730
+ """
731
+ Export an AMS system to a MATPOWER M-file.
732
+
733
+ Parameters
734
+ ----------
735
+ outfile : str
736
+ The output file name.
737
+ overwrite : bool, optional
738
+ If True, overwrite the existing file. Default is None.
739
+ """
740
+ return wrtite_m(self, outfile=outfile, overwrite=overwrite)
741
+
742
+ def to_xlsx(self, outfile: str, overwrite: bool = None):
743
+ """
744
+ Export an AMS system to an Excel file.
745
+
746
+ Parameters
747
+ ----------
748
+ outfile : str
749
+ The output file name.
750
+ overwrite : bool, optional
751
+ If True, overwrite the existing file. Default is None.
752
+ """
753
+ return write_xlsx(self, outfile=outfile, overwrite=overwrite)
754
+
755
+ def to_json(self, outfile: str, overwrite: bool = None):
756
+ """
757
+ Export an AMS system to a JSON file.
758
+
759
+ Parameters
760
+ ----------
761
+ outfile : str
762
+ The output file name.
763
+ overwrite : bool, optional
764
+ If True, overwrite the existing file. Default is None.
765
+ """
766
+ return write_json(self, outfile=outfile, overwrite=overwrite)
767
+
768
+ def to_raw(self, outfile: str, overwrite: bool = None):
769
+ """
770
+ Export an AMS system to a v33 PSS/E RAW file.
771
+
772
+ Parameters
773
+ ----------
774
+ outfile : str
775
+ The output file name.
776
+ overwrite : bool, optional
777
+ If True, overwrite the existing file. Default is None.
778
+ """
779
+ return write_raw(self, outfile=outfile, overwrite=overwrite)
665
780
 
666
781
  # --------------- Helper Functions ---------------
667
782
  # NOTE: _config_numpy, load_config_rc are imported from andes.system
668
783
 
784
+
669
785
  def example(setup=True, no_output=True, **kwargs):
670
786
  """
671
787
  Return an :py:class:`ams.system.System` object for the
docs/source/api.rst CHANGED
@@ -48,6 +48,8 @@ Routines
48
48
  ams.routines.routine
49
49
  ams.routines.dcopf
50
50
  ams.routines.pflow
51
+ ams.routines.pypower
52
+ ams.routines.grbopt
51
53
 
52
54
 
53
55
  Optimization
@@ -43,7 +43,7 @@ Create an environment for AMS (recommended)
43
43
 
44
44
  .. code:: bash
45
45
 
46
- mamba create --name ams python=3.8
46
+ mamba create --name ams python=3.10
47
47
 
48
48
  Activate the new environment with
49
49
 
@@ -83,10 +83,7 @@ To install packages in the ``dev`` when installing AMS, do:
83
83
 
84
84
  .. code:: bash
85
85
 
86
- pip install -r requirements-dev.txt
87
-
88
- One can also inspect the ``requirements-dev.txt`` to identify the packages
89
- for manual installation.
86
+ pip install .[dev]
90
87
 
91
88
  .. _Develop Install:
92
89
 
@@ -131,6 +128,7 @@ Install dependencies with
131
128
  mamba install --file requirements.txt
132
129
  mamba install --file requirements-dev.txt
133
130
  mamba install --file requirements-doc.txt
131
+ mamba install --file requirements-nlp.txt
134
132
 
135
133
  Alternatively, you can install them with ``pip``:
136
134
 
@@ -139,12 +137,17 @@ Alternatively, you can install them with ``pip``:
139
137
  pip install -r requirements.txt
140
138
  pip install -r requirements-dev.txt
141
139
  pip install -r requirements-doc.txt
140
+ pip install -r requirements-nlp.txt
141
+
142
+ Alternatively, if you have a modern version of pip (>=23.1), you can install all dependencies specified in ``pyproject.toml`` with:
143
+
144
+ pip install .[dev,doc,nlp]
142
145
 
143
146
  Step 3: Install AMS in the development mode using
144
147
 
145
148
  .. code:: bash
146
149
 
147
- python3 -m pip install -e .
150
+ python3 -m pip install -e .
148
151
 
149
152
  Note the dot at the end. Pip will take care of the rest.
150
153
 
Binary file
Binary file
@@ -9,6 +9,27 @@ 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.10 (2024-xx-xx)
13
+ --------------------
14
+
15
+ - Add bus type correction in ``system.System.setup()``
16
+ - Revise ``ams.io.psse.read`` to complete model Zone when necessary
17
+ - Use numerical Area and Zone idx in MATPOWER and PSSE RAW file conversion
18
+ - Support JSON format addfile when converting to ANDES case
19
+ - Add PSS/E v33 RAW file writer
20
+ - In class ``System``, add wrapper methods ``to_mpc``, ``to_m``, ``to_xlsx``,
21
+ ``to_json``, and ``to_raw`` for easier case file export
22
+ - Add wrapper routines for PYPOWER: ``DCPF1``, ``PFlow1``, ``DCOPF1``, and ``ACOPF1``
23
+ - In routine ``DCOPF`` and its derivatives, add ExpressionCalc ``mu1`` ``mu2`` to
24
+ calculate Lagrange multipliers of line flow limits constraints
25
+ - Add wrapper routine ``OPF`` for gurobi_optimods
26
+ - Add a demo to show newly added wrapper routines, see
27
+ ``examples/demonstration/demo_wrapper_routines.ipynb``
28
+ - Revise ``andes.common.config.Config.update`` to ensure configuration parameters
29
+ are consistently updated in both the object and its internal ``_dict``
30
+ - Remove legacy revised PYPOWER module
31
+ - Remove function ``ams.shared.ppc2df``
32
+
12
33
  v1.0.9 (2024-04-23)
13
34
  --------------------
14
35
 
@@ -408,50 +429,3 @@ v0.4 (2023-01)
408
429
  -------------------
409
430
 
410
431
  This release outlines the package.
411
-
412
- Known Limitations
413
- =================
414
-
415
- - For builit-in PYPOWER-based ACOPF, the known largest solvable case is "pglib_opf_case1354_pegase.m"
416
- - Batch processing is not supported yet
417
- - Routine ``DCOPF`` has been extensively benchmarked with pandapower and MATPOWER.
418
- - Routines besides above mentioned are not fully benchmarked yet.
419
-
420
- Roadmap
421
- =======
422
-
423
- This section lists out some potential features that may be added in the future.
424
- Note that the proposed features are not guaranteed to be implemented and subject to change.
425
-
426
- Electric Vehicle for Grid Service
427
- ------------------------------------------
428
-
429
- A charging-time-constrained EV aggregation based on the state-space model
430
-
431
- References:
432
-
433
- [1] J. Wang et al., "Electric Vehicles Charging Time Constrained Deliverable Provision of Secondary
434
- Frequency Regulation," in IEEE Transactions on Smart Grid, doi: 10.1109/TSG.2024.3356948.
435
-
436
- [2] M. Wang et al., "State Space Model of Aggregated Electric Vehicles for Frequency Regulation," in
437
- IEEE Transactions on Smart Grid, vol. 11, no. 2, pp. 981-994, March 2020, doi: 10.1109/TSG.2019.2929052.
438
-
439
- Distribution OPF
440
- --------------------------
441
-
442
- - Distribution networks OPF and its LMP
443
- - DG siting and sizing considering energy equity
444
-
445
- References:
446
-
447
- [1] H. Yuan, F. Li, Y. Wei and J. Zhu, "Novel Linearized Power Flow and Linearized OPF Models for
448
- Active Distribution Networks With Application in Distribution LMP," in IEEE Transactions on Smart Grid,
449
- vol. 9, no. 1, pp. 438-448, Jan. 2018, doi: 10.1109/TSG.2016.2594814.
450
-
451
- [2] C. Li, F. Li, S. Jiang, X. Wang and J. Wang, "Siting and Sizing of DG Units Considering Energy
452
- Equity: Model, Solution, and Guidelines," in IEEE Transactions on Smart Grid, doi: 10.1109/TSG.2024.3350914.
453
-
454
- Planning
455
- --------------------------
456
-
457
- - Transmission expansion planning
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ltbams
3
- Version: 1.0.9
3
+ Version: 1.0.10
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,28 @@ Requires-Dist: openpyxl
23
23
  Requires-Dist: andes>=1.9.3
24
24
  Requires-Dist: pybind11
25
25
  Requires-Dist: cvxpy
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest; extra == "dev"
28
+ Requires-Dist: pytest-cov; extra == "dev"
29
+ Requires-Dist: coverage; extra == "dev"
30
+ Requires-Dist: flake8; extra == "dev"
31
+ Requires-Dist: numpydoc; extra == "dev"
32
+ Requires-Dist: toml; extra == "dev"
33
+ Provides-Extra: nlp
34
+ Requires-Dist: PYPOWER; extra == "nlp"
35
+ Requires-Dist: pyoptinterface; extra == "nlp"
36
+ Requires-Dist: gurobipy; extra == "nlp"
37
+ Requires-Dist: gurobi-optimods; extra == "nlp"
38
+ Provides-Extra: doc
39
+ Requires-Dist: pandoc; extra == "doc"
40
+ Requires-Dist: ipython; extra == "doc"
41
+ Requires-Dist: sphinx; extra == "doc"
42
+ Requires-Dist: pydata-sphinx-theme; extra == "doc"
43
+ Requires-Dist: numpydoc; extra == "doc"
44
+ Requires-Dist: sphinx-copybutton; extra == "doc"
45
+ Requires-Dist: sphinx-panels; extra == "doc"
46
+ Requires-Dist: myst-parser; extra == "doc"
47
+ Requires-Dist: nbsphinx; extra == "doc"
26
48
  Dynamic: author
27
49
  Dynamic: home-page
28
50
 
@@ -30,40 +52,29 @@ Dynamic: home-page
30
52
 
31
53
  Python Software for Power System Scheduling Modeling and Co-Simulation with Dynamics, serving as the market simulator for the [CURENT Largescale Testbed][LTB Repository].
32
54
 
33
- [![License: GPL-3.0](https://img.shields.io/badge/License-GPL--3.0-blue.svg)](https://github.com/CURENT/ams/blob/master/LICENSE)
34
- ![platforms](https://anaconda.org/conda-forge/ltbams/badges/platforms.svg)
35
- [![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/)
55
+ ![License: GPL-3.0](https://img.shields.io/badge/License-GPL--3.0-blue.svg)
36
56
  [![DOI:10.1109/TSTE.2025.3528027](https://zenodo.org/badge/DOI/10.1109/TSTE.2025.3528027.svg)](https://ieeexplore.ieee.org/document/10836855)
37
- [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
38
- [![codecov](https://codecov.io/gh/CURENT/ams/graph/badge.svg?token=RZI5GLLBQH)](https://codecov.io/gh/CURENT/ams)
39
-
40
- [![GitHub Tag](https://img.shields.io/github/v/tag/CURENT/ams)](https://github.com/CURENT/ams/tags)
41
- ![GitHub commits since latest release (branch)](https://img.shields.io/github/commits-since/curent/ams/latest/develop)
42
- [![GitHub last commit (master)](https://img.shields.io/github/last-commit/CURENT/ams/master?label=last%20commit%20to%20master)](https://github.com/CURENT/ams/commits/master/)
43
- [![GitHub last commit (develop)](https://img.shields.io/github/last-commit/CURENT/ams/develop?label=last%20commit%20to%20develop)](https://github.com/CURENT/ams/commits/develop/)
44
-
45
- [![libraries](https://img.shields.io/librariesio/release/pypi/ltbams)](https://libraries.io/pypi/ltbams)
46
- ![Repo Size](https://img.shields.io/github/repo-size/CURENT/ams)
47
- [![Structure](https://img.shields.io/badge/code_base-visualize-blue)](https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=CURENT%2Fams)
48
-
49
- [![Compatibility Tests](https://github.com/CURENT/ams/actions/workflows/compatibility.yml/badge.svg)](https://github.com/CURENT/ams/actions/workflows/compatibility.yml)
50
- [![Publish to TestPyPI and PyPI](https://github.com/CURENT/ams/actions/workflows/publish-pypi.yml/badge.svg?branch=master)](https://github.com/CURENT/ams/actions/workflows/publish-pypi.yml)
51
- [![Azure Pipline](https://dev.azure.com/curentltb/ams/_apis/build/status%2FCURENT.ams?branchName=master)](https://dev.azure.com/curentltb/ams/_build/latest?definitionId=2&branchName=master)
52
57
 
53
58
  <img src="docs/source/images/sponsors/CURENT_Logo_NameOnTrans.png" alt="CURENT ERC Logo" width="300" height="auto">
54
59
 
55
- | | Stable | Develop |
56
- |---------------|-----------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
57
- | Documentation | [![Documentation Status](https://readthedocs.org/projects/ams/badge/?version=stable)](https://ams.readthedocs.io/en/stable/?badge=stable) | [![Develop Documentation](https://readthedocs.org/projects/ams/badge/?version=develop)](https://ams.readthedocs.io/en/develop/?badge=develop) |
58
-
59
-
60
- | Badges | | |
61
- |---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
62
- | Downloads | [![PyPI Version](https://img.shields.io/pypi/v/ltbams.svg)](https://pypi.python.org/pypi/ltbams) | [![Conda Version](https://anaconda.org/conda-forge/ltbams/badges/version.svg)](https://anaconda.org/conda-forge/ltbams) |
63
- | Try on Binder | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/curent/ams/master) | |
64
- | Code Quality |[![Codacy Badge](https://app.codacy.com/project/badge/Grade/69456da1b8634f2f984bd769e35f0050)](https://app.codacy.com/gh/CURENT/ams/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)| [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/69456da1b8634f2f984bd769e35f0050)](https://app.codacy.com/gh/CURENT/ams/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage) |
65
-
66
-
60
+ | | Stable | Develop |
61
+ |---|---|---|
62
+ | Documentation | [![Documentation Status](https://readthedocs.org/projects/ams/badge/?version=stable)](https://ams.readthedocs.io/en/stable/?badge=stable) | [![Develop Documentation](https://readthedocs.org/projects/ams/badge/?version=develop)](https://ams.readthedocs.io/en/develop/?badge=develop) |
63
+
64
+ | Badges | | |
65
+ |---|---|---|
66
+ | Repo | ![Project Status: Active](https://www.repostatus.org/badges/latest/active.svg) | ![Repo Size](https://img.shields.io/github/repo-size/CURENT/ams) |
67
+ | Version | ![PyPI Version](https://img.shields.io/pypi/v/ltbams.svg) | ![Conda Version](https://anaconda.org/conda-forge/ltbams/badges/version.svg) |
68
+ | 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) |
69
+ | Download | ![PyPI - Downloads](https://img.shields.io/pypi/dm/ltbams) | ![Anaconda-Server Badge](https://anaconda.org/conda-forge/ltbams/badges/downloads.svg) |
70
+ | Code Quality | ![Codacy Badge](https://app.codacy.com/project/badge/Grade/69456da1b8634f2f984bd769e35f0050) | ![Codacy Badge](https://app.codacy.com/project/badge/Coverage/69456da1b8634f2f984bd769e35f0050) |
71
+ | Code Cov | ![codecov](https://codecov.io/gh/CURENT/ams/graph/badge.svg?token=RZI5GLLBQH) | |
72
+ | Last Commit | ![GitHub last commit (master)](https://img.shields.io/github/last-commit/CURENT/ams/master?label=last%20commit%20to%20master) | ![GitHub last commit (develop)](https://img.shields.io/github/last-commit/CURENT/ams/develop?label=last%20commit%20to%20develop) |
73
+ | CI | ![Compatibility Tests](https://github.com/CURENT/ams/actions/workflows/compatibility.yml/badge.svg) | ![Azure Pipline](https://dev.azure.com/curentltb/ams/_apis/build/status%2FCURENT.ams?branchName=master) |
74
+ | CD | ![Publish to TestPyPI and PyPI](https://github.com/CURENT/ams/actions/workflows/publish-pypi.yml/badge.svg?branch=master) | |
75
+ | Structure | [![Structure](https://img.shields.io/badge/code_base-visualize-blue)](https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=CURENT%2Fams) | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/CURENT/ams) |
76
+ | Dependency | [![libraries](https://img.shields.io/librariesio/release/pypi/ltbams)](https://libraries.io/pypi/ltbams) | |
77
+ | Try on Binder | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/curent/ams/master) | |
67
78
 
68
79
  # Why AMS
69
80
 
@@ -82,25 +93,27 @@ and solved with third-party solvers.
82
93
 
83
94
  AMS produces credible scheduling results and competitive performance.
84
95
  The following results show the comparison of DCOPF between AMS and other tools.
85
-
86
- | Cost [\$] | AMS | pandapower | MATPOWER |
87
- |-----------------------|--------------|--------------|--------------|
88
- | IEEE 14-Bus | 7,642.59 | 7,642.59 | 7,642.59 |
89
- | IEEE 39-Bus | 41,263.94 | 41,263.94 | 41,263.94 |
90
- | PEGASE 89-Bus | 5,733.37 | 5,733.37 | 5,733.37 |
91
- | IEEE 118-Bus | 125,947.88 | 125,947.88 | 125,947.88 |
92
- | NPCC 140-Bus | 810,033.37 | 810,016.06 | 810,033.37 |
93
- | WECC 179-Bus | 411,706.13 | 411,706.13 | 411,706.13 |
94
- | IEEE 300-Bus | 706,292.32 | 706,292.32 | 706,292.32 |
95
- | PEGASE 1354-Bus | 1,218,096.86 | 1,218,096.86 | 1,218,096.86 |
96
- | PEGASE 2869-Bus | 2,386,235.33 | 2,386,235.33 | 2,386,235.33 |
97
- | GOC 4020-Bus | 793,634.11 | 793,634.11 | 793,634.11 |
98
- | EPIGRIDS 5658-Bus | 1,195,466.12 | 1,195,466.12 | 1,195,466.12 |
99
- | EPIGRIDS 7336-Bus | 1,855,870.94 | 1,855,870.94 | 1,855,870.94 |
96
+ In the table, **AMS Gap** is the difference between the AMS and MATPOWER results,
97
+ and **pandapower Gap** is the difference between the pandapower and MATPOWER results.
98
+
99
+ | Case | MATPOWER [\$] | AMS Gap [\$] | pandapower Gap [\$] |
100
+ |------------------|--------------|--------------|---------------------|
101
+ | IEEE 14-Bus | 7,642.59 | 0.00 | 0.00 |
102
+ | IEEE 39-Bus | 41,263.94 | 0.00 | 0.00 |
103
+ | PEGASE 89-Bus | 5,733.37 | 0.00 | 0.00 |
104
+ | IEEE 118-Bus | 125,947.88 | 0.00 | 0.00 |
105
+ | NPCC 140-Bus | 810,033.37 | 0.00 | **-17.31** |
106
+ | WECC 179-Bus | 411,706.13 | 0.00 | 0.00 |
107
+ | IEEE 300-Bus | 706,292.32 | 0.00 | 0.00 |
108
+ | PEGASE 1354-Bus | 1,218,096.86 | 0.00 | 0.00 |
109
+ | PEGASE 2869-Bus | 2,386,235.33 | 0.00 | 0.00 |
110
+ | GOC 4020-Bus | 793,634.11 | 0.00 | 0.00 |
111
+ | EPIGRIDS 5658-Bus| 1,195,466.12 | 0.00 | 0.00 |
112
+ | EPIGRIDS 7336-Bus| 1,855,870.94 | 0.00 | 0.00 |
100
113
 
101
114
  <div style="text-align: left;">
102
115
  <img src="docs/source/images/dcopf_time.png" alt="DCOPF Time" width="480" height="auto">
103
- <p><strong>Figure:</strong> Computation time of OPF on small-scale cases.</p>
116
+ <p><strong>Figure:</strong> Computation time of OPF on medium to large cases.</p>
104
117
  </div>
105
118
 
106
119
  In the bar chart, the gray bar labeled "AMS Symbolic Processing" represents the time spent
@@ -113,6 +126,19 @@ Regarding the baselines, the blue and green bars represent the running time of M
113
126
  solver MIPS and pandapower using solver PIPS, respectively.
114
127
  The results for AMS, pandapower, and matpower are the average time consumed over ten repeat tests.
115
128
 
129
+ <div style="text-align: left;">
130
+ <img src="docs/source/images/educ_pie.png" alt="DCOPF Time" width="480" height="auto">
131
+ <p><strong>Figure:</strong> Computation time distribution for multi-period economic dispatch and
132
+ unit commitment using a 31,777-bus case.</p>
133
+ </div>
134
+
135
+ To further demonstrate AMS's scalability, we validated multi-period economic dispatch and unit commitment
136
+ on an ultra-large power system case with 31,777 buses, 4,664 generators, 41,573 transmission lines,
137
+ and 5 time intervals.
138
+ The computation time distribution for this case is shown in the figure below. Notably, the time spent
139
+ on symbolic processing remains negligible even at this scale, highlighting AMS's efficiency for
140
+ large-scale studies.
141
+
116
142
  AMS is currently under active development.
117
143
  Use the following resources to get involved.
118
144
 
@@ -136,6 +162,20 @@ Install from PyPI using pip:
136
162
  pip install ltbams
137
163
  ```
138
164
 
165
+ You can also install with optional dependencies, such as ``dev``, ``docs``, and ``nlp``:
166
+
167
+ ```bash
168
+ pip install ltbams[dev]
169
+ pip install ltbams[docs]
170
+ pip install ltbams[nlp]
171
+ ```
172
+
173
+ Or install with all optional dependencies:
174
+
175
+ ```bash
176
+ pip install ltbams[all]
177
+ ```
178
+
139
179
  Install from conda-forge using conda:
140
180
 
141
181
  ```bash