ltbams 1.0.10__tar.gz → 1.0.12__tar.gz
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.
- {ltbams-1.0.10/ltbams.egg-info → ltbams-1.0.12}/PKG-INFO +7 -10
- {ltbams-1.0.10 → ltbams-1.0.12}/README.md +6 -9
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/_version.py +3 -3
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/core/documenter.py +130 -62
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/core/matprocessor.py +13 -14
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/interface.py +2 -2
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/io/matpower.py +51 -20
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/io/psse.py +2 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/grbopt.py +14 -9
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/pypower.py +20 -20
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/routine.py +9 -14
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/system.py +43 -5
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/utils/paths.py +67 -3
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/examples/index.rst +2 -1
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/genroutineref.py +1 -1
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/release-notes.rst +35 -22
- {ltbams-1.0.10 → ltbams-1.0.12/ltbams.egg-info}/PKG-INFO +7 -10
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_1st_system.py +1 -1
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_io.py +10 -0
- ltbams-1.0.12/tests/test_paths.py +89 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_rtn_dcopf.py +20 -0
- ltbams-1.0.10/tests/test_paths.py +0 -22
- {ltbams-1.0.10 → ltbams-1.0.12}/CONTRIBUTING.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/LICENSE +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/MANIFEST.in +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/__main__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/5bus/pjm5bus_demo.json +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/5bus/pjm5bus_demo.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/5bus/pjm5bus_ev.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/5bus/pjm5bus_jumper.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/hawaii40/Hawaii40.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee123/ieee123.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee123/ieee123_regcv1.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee14/ieee14.json +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee14/ieee14.raw +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee14/ieee14_conn.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee14/ieee14_uced.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee39/ieee39.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee39/ieee39_uced.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee39/ieee39_uced_esd1.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee39/ieee39_uced_pvd1.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/ieee39/ieee39_uced_vis.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/matpower/benchmark.json +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/matpower/case118.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/matpower/case14.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/matpower/case300.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/matpower/case39.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/matpower/case5.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/matpower/case_ACTIVSg2000.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/npcc/npcc.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/npcc/npcc_uced.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/pglib/pglib_opf_case39_epri__api.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/wecc/wecc.m +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cases/wecc/wecc_uced.xlsx +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/cli.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/core/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/core/common.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/core/model.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/core/param.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/core/service.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/core/symprocessor.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/core/var.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/extension/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/extension/eva.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/io/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/io/json.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/io/pypower.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/io/xlsx.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/main.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/area.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/bus.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/cost.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/distributed/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/distributed/esd1.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/distributed/ev.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/distributed/pvd1.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/group.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/info.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/line.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/renewable/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/renewable/regc.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/reserve.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/shunt.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/static/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/static/gen.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/static/pq.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/timeslot.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/models/zone.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/opt/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/opt/constraint.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/opt/exprcalc.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/opt/expression.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/opt/objective.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/opt/omodel.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/opt/optzbase.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/opt/param.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/opt/var.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/report.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/acopf.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/dcopf.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/dcopf2.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/dcpf.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/dopf.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/ed.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/pflow.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/rted.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/type.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/routines/uc.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/shared.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/utils/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ams/utils/misc.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/Makefile +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/make.bat +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/_templates/autosummary/base.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/_templates/autosummary/class.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/_templates/autosummary/module.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/_templates/autosummary/module_toctree.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/api.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/conf.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/genmodelref.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/copyright.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/formats/index.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/formats/matpower.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/formats/psse.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/formats/pypower.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/formats/xlsx.png +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/formats/xlsx.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/index.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/install.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/overview.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/testcase.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/getting_started/verification.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/images/curent.ico +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/images/dcopf_time.png +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/images/educ_pie.png +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/images/sponsors/CURENT_Logo_NameOnTrans.png +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/images/sponsors/CURENT_Logo_Transparent.png +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/images/sponsors/CURENT_Logo_Transparent_Name.png +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/images/sponsors/doe.png +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/index.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/modeling/example.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/modeling/index.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/modeling/model.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/modeling/routine.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/docs/source/modeling/system.rst +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ltbams.egg-info/SOURCES.txt +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ltbams.egg-info/dependency_links.txt +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ltbams.egg-info/entry_points.txt +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ltbams.egg-info/requires.txt +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/ltbams.egg-info/top_level.txt +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/pyproject.toml +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/requirements-dev.txt +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/requirements.txt +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/setup.cfg +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/setup.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/__init__.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_addressing.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_case.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_cli.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_export_csv.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_group.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_interface.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_jumper.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_known_good.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_matp.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_model.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_omodel.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_report.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_repr.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_routine.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_rtn_acopf.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_rtn_dcopf2.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_rtn_ed.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_rtn_opf.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_rtn_pflow.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_rtn_pypower.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_rtn_rted.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_rtn_uc.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/tests/test_service.py +0 -0
- {ltbams-1.0.10 → ltbams-1.0.12}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ltbams
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.12
|
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
|
@@ -57,21 +57,18 @@ Python Software for Power System Scheduling Modeling and Co-Simulation with Dyna
|
|
57
57
|
|
58
58
|
<img src="docs/source/images/sponsors/CURENT_Logo_NameOnTrans.png" alt="CURENT ERC Logo" width="300" height="auto">
|
59
59
|
|
60
|
-
| | Stable | Develop |
|
61
|
-
|---|---|---|
|
62
|
-
| Documentation | [](https://ams.readthedocs.io/en/stable/?badge=stable) | [](https://ams.readthedocs.io/en/develop/?badge=develop) |
|
63
|
-
|
64
60
|
| Badges | | |
|
65
61
|
|---|---|---|
|
66
62
|
| Repo |  |  |
|
67
|
-
| Version |  | ](https://pypi.org/project/ltbams/) | [](https://anaconda.org/conda-forge/ltbams) |
|
68
64
|
| Tag | [](https://github.com/CURENT/ams/tags) |  |
|
69
|
-
|
|
65
|
+
| Documentation | [](https://ltb.readthedocs.io/projects/ams/en/stable/?badge=stable) | [](https://ltb.readthedocs.io/projects/ams/en/develop/?badge=develop) |
|
66
|
+
| Download | [](https://pypi.org/project/ltbams/) | [](https://anaconda.org/conda-forge/ltbams) |
|
70
67
|
| Code Quality |  |  |
|
71
68
|
| Code Cov |  | |
|
72
69
|
| Last Commit |  |  |
|
73
|
-
| CI | ](https://github.com/CURENT/ams/actions/workflows/compatibility.yml) | [](https://dev.azure.com/curentltb/ams/_build/latest?definitionId=2&branchName=scuc) |
|
71
|
+
| CD | [](https://github.com/CURENT/ams/actions/workflows/publish-pypi.yml) | |
|
75
72
|
| Structure | [](https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=CURENT%2Fams) | [](https://deepwiki.com/CURENT/ams) |
|
76
73
|
| Dependency | [](https://libraries.io/pypi/ltbams) | |
|
77
74
|
| Try on Binder | [](https://mybinder.org/v2/gh/curent/ams/master) | |
|
@@ -237,7 +234,7 @@ See [GitHub contributors][GitHub contributors] for the contributor list.
|
|
237
234
|
AMS is licensed under the [GPL v3 License](./LICENSE).
|
238
235
|
|
239
236
|
# Related Projects
|
240
|
-
- [Popular Open Source Libraries for Power System Analysis](https://github.com/
|
237
|
+
- [Popular Open Source Libraries for Power System Analysis](https://github.com/ps-wiki/best-of-ps)
|
241
238
|
- [G-PST Tools Portal](https://g-pst.github.io/tools/): An open tools portal with a classification approach
|
242
239
|
- [Open Source Software (OSS) for Electricity Market Research, Teaching, and Training](https://www2.econ.iastate.edu/tesfatsi/ElectricOSS.htm)
|
243
240
|
|
@@ -7,21 +7,18 @@ Python Software for Power System Scheduling Modeling and Co-Simulation with Dyna
|
|
7
7
|
|
8
8
|
<img src="docs/source/images/sponsors/CURENT_Logo_NameOnTrans.png" alt="CURENT ERC Logo" width="300" height="auto">
|
9
9
|
|
10
|
-
| | Stable | Develop |
|
11
|
-
|---|---|---|
|
12
|
-
| Documentation | [](https://ams.readthedocs.io/en/stable/?badge=stable) | [](https://ams.readthedocs.io/en/develop/?badge=develop) |
|
13
|
-
|
14
10
|
| Badges | | |
|
15
11
|
|---|---|---|
|
16
12
|
| Repo |  |  |
|
17
|
-
| Version |  | ](https://pypi.org/project/ltbams/) | [](https://anaconda.org/conda-forge/ltbams) |
|
18
14
|
| Tag | [](https://github.com/CURENT/ams/tags) |  |
|
19
|
-
|
|
15
|
+
| Documentation | [](https://ltb.readthedocs.io/projects/ams/en/stable/?badge=stable) | [](https://ltb.readthedocs.io/projects/ams/en/develop/?badge=develop) |
|
16
|
+
| Download | [](https://pypi.org/project/ltbams/) | [](https://anaconda.org/conda-forge/ltbams) |
|
20
17
|
| Code Quality |  |  |
|
21
18
|
| Code Cov |  | |
|
22
19
|
| Last Commit |  |  |
|
23
|
-
| CI | ](https://github.com/CURENT/ams/actions/workflows/compatibility.yml) | [](https://dev.azure.com/curentltb/ams/_build/latest?definitionId=2&branchName=scuc) |
|
21
|
+
| CD | [](https://github.com/CURENT/ams/actions/workflows/publish-pypi.yml) | |
|
25
22
|
| Structure | [](https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=CURENT%2Fams) | [](https://deepwiki.com/CURENT/ams) |
|
26
23
|
| Dependency | [](https://libraries.io/pypi/ltbams) | |
|
27
24
|
| Try on Binder | [](https://mybinder.org/v2/gh/curent/ams/master) | |
|
@@ -187,7 +184,7 @@ See [GitHub contributors][GitHub contributors] for the contributor list.
|
|
187
184
|
AMS is licensed under the [GPL v3 License](./LICENSE).
|
188
185
|
|
189
186
|
# Related Projects
|
190
|
-
- [Popular Open Source Libraries for Power System Analysis](https://github.com/
|
187
|
+
- [Popular Open Source Libraries for Power System Analysis](https://github.com/ps-wiki/best-of-ps)
|
191
188
|
- [G-PST Tools Portal](https://g-pst.github.io/tools/): An open tools portal with a classification approach
|
192
189
|
- [Open Source Software (OSS) for Electricity Market Research, Teaching, and Training](https://www2.econ.iastate.edu/tesfatsi/ElectricOSS.htm)
|
193
190
|
|
@@ -8,11 +8,11 @@ import json
|
|
8
8
|
|
9
9
|
version_json = '''
|
10
10
|
{
|
11
|
-
"date": "2025-05-
|
11
|
+
"date": "2025-05-29T20:16:06-0400",
|
12
12
|
"dirty": false,
|
13
13
|
"error": null,
|
14
|
-
"full-revisionid": "
|
15
|
-
"version": "1.0.
|
14
|
+
"full-revisionid": "2166f4368af3d382720af38408153a70502eb9f5",
|
15
|
+
"version": "1.0.12"
|
16
16
|
}
|
17
17
|
''' # END VERSION_JSON
|
18
18
|
|
@@ -6,26 +6,12 @@ import re
|
|
6
6
|
|
7
7
|
import logging
|
8
8
|
from collections import OrderedDict
|
9
|
-
from andes.core.documenter import Documenter as andes_Documenter
|
10
9
|
from andes.utils.tab import make_doc_table, math_wrap
|
11
10
|
|
12
11
|
logger = logging.getLogger(__name__)
|
13
12
|
|
14
13
|
|
15
|
-
|
16
|
-
def wrapper(*args, **kwargs):
|
17
|
-
msg = f"Method `{func.__name__}` is included in ANDES Documenter but not supported in AMS Documenter."
|
18
|
-
logger.warning(msg)
|
19
|
-
return None
|
20
|
-
return wrapper
|
21
|
-
|
22
|
-
|
23
|
-
def disable_methods(methods):
|
24
|
-
for method in methods:
|
25
|
-
setattr(Documenter, method, disable_method(getattr(Documenter, method)))
|
26
|
-
|
27
|
-
|
28
|
-
class Documenter(andes_Documenter):
|
14
|
+
class Documenter:
|
29
15
|
"""
|
30
16
|
Helper class for documenting models.
|
31
17
|
|
@@ -37,16 +23,6 @@ class Documenter(andes_Documenter):
|
|
37
23
|
|
38
24
|
def __init__(self, parent):
|
39
25
|
self.parent = parent
|
40
|
-
self.system = parent.system
|
41
|
-
self.class_name = parent.class_name
|
42
|
-
self.config = parent.config
|
43
|
-
self.params = parent.params
|
44
|
-
self.algebs = parent.algebs
|
45
|
-
self.services = parent.services
|
46
|
-
|
47
|
-
func_to_disable = ['_init_doc', '_eq_doc',
|
48
|
-
'_discrete_doc', '_block_doc']
|
49
|
-
disable_methods(func_to_disable)
|
50
26
|
|
51
27
|
def get(self, max_width=78, export='plain'):
|
52
28
|
"""
|
@@ -68,14 +44,15 @@ class Documenter(andes_Documenter):
|
|
68
44
|
if export == 'rest':
|
69
45
|
max_width = 0
|
70
46
|
model_header = '-' * 80 + '\n'
|
71
|
-
out += f'.. _{self.class_name}:\n\n'
|
47
|
+
out += f'.. _{self.parent.class_name}:\n\n'
|
72
48
|
else:
|
73
49
|
model_header = ''
|
74
50
|
|
75
51
|
if export == 'rest':
|
76
|
-
out += model_header + f'{self.class_name}\n' + model_header
|
52
|
+
out += model_header + f'{self.parent.class_name}\n' + model_header
|
77
53
|
else:
|
78
|
-
out += model_header +
|
54
|
+
out += model_header + \
|
55
|
+
f'Model <{self.parent.class_name}> in Group <{self.parent.group}>\n' + model_header
|
79
56
|
|
80
57
|
if self.parent.__doc__ is not None:
|
81
58
|
out += inspect.cleandoc(self.parent.__doc__)
|
@@ -86,20 +63,35 @@ class Documenter(andes_Documenter):
|
|
86
63
|
out += self._var_doc(max_width=max_width, export=export)
|
87
64
|
out += self._service_doc(max_width=max_width, export=export)
|
88
65
|
# TODO: fix and add the config doc later on
|
89
|
-
# out += self.config.doc(max_width=max_width, export=export)
|
66
|
+
# out += self.parent.config.doc(max_width=max_width, export=export)
|
90
67
|
|
91
68
|
return out
|
92
69
|
|
93
70
|
def _var_doc(self, max_width=78, export='plain'):
|
71
|
+
"""
|
72
|
+
Export formatted model variable documentation as a string.
|
73
|
+
|
74
|
+
Parameters
|
75
|
+
----------
|
76
|
+
max_width : int, optional = 80
|
77
|
+
Maximum table width. If export format is ``rest`` it will be unlimited.
|
78
|
+
export : str, optional = 'plain'
|
79
|
+
Export format, 'plain' for plain text, 'rest' for restructuredText.
|
80
|
+
|
81
|
+
Returns
|
82
|
+
-------
|
83
|
+
str
|
84
|
+
Tabulated output in a string
|
85
|
+
"""
|
94
86
|
# variable documentation
|
95
|
-
if len(self.algebs) == 0:
|
87
|
+
if len(self.parent.algebs) == 0:
|
96
88
|
return ''
|
97
89
|
|
98
90
|
names, symbols, units = list(), list(), list()
|
99
91
|
info = list()
|
100
92
|
units_rest, ty = list(), list()
|
101
93
|
|
102
|
-
for p in self.algebs.values():
|
94
|
+
for p in self.parent.algebs.values():
|
103
95
|
names.append(p.name)
|
104
96
|
ty.append(p.class_name)
|
105
97
|
info.append(p.info if p.info else '')
|
@@ -110,7 +102,7 @@ class Documenter(andes_Documenter):
|
|
110
102
|
|
111
103
|
# replace with latex math expressions if export is ``rest``
|
112
104
|
if export == 'rest':
|
113
|
-
symbols = [item.tex_name for item in self.algebs.values()]
|
105
|
+
symbols = [item.tex_name for item in self.parent.algebs.values()]
|
114
106
|
symbols = math_wrap(symbols, export=export)
|
115
107
|
title = 'Variables\n---------'
|
116
108
|
|
@@ -132,14 +124,29 @@ class Documenter(andes_Documenter):
|
|
132
124
|
rest_dict=rest_dict)
|
133
125
|
|
134
126
|
def _service_doc(self, max_width=78, export='plain'):
|
135
|
-
|
127
|
+
"""
|
128
|
+
Export formatted model service documentation as a string.
|
129
|
+
|
130
|
+
Parameters
|
131
|
+
----------
|
132
|
+
max_width : int, optional = 80
|
133
|
+
Maximum table width. If export format is ``rest`` it will be unlimited.
|
134
|
+
export : str, optional = 'plain'
|
135
|
+
Export format, 'plain' for plain text, 'rest' for restructuredText.
|
136
|
+
|
137
|
+
Returns
|
138
|
+
-------
|
139
|
+
str
|
140
|
+
Tabulated output in a string
|
141
|
+
"""
|
142
|
+
if len(self.parent.services) == 0:
|
136
143
|
return ''
|
137
144
|
|
138
145
|
names, symbols = list(), list()
|
139
146
|
info = list()
|
140
147
|
class_names = list()
|
141
148
|
|
142
|
-
for p in self.services.values():
|
149
|
+
for p in self.parent.services.values():
|
143
150
|
names.append(p.name)
|
144
151
|
class_names.append(p.class_name)
|
145
152
|
info.append(p.info if p.info else '')
|
@@ -165,6 +172,74 @@ class Documenter(andes_Documenter):
|
|
165
172
|
plain_dict=plain_dict,
|
166
173
|
rest_dict=rest_dict)
|
167
174
|
|
175
|
+
def _param_doc(self, max_width=78, export='plain'):
|
176
|
+
"""
|
177
|
+
Export formatted model parameter documentation as a string.
|
178
|
+
|
179
|
+
Parameters
|
180
|
+
----------
|
181
|
+
max_width : int, optional = 80
|
182
|
+
Maximum table width. If export format is ``rest`` it will be unlimited.
|
183
|
+
|
184
|
+
export : str, optional = 'plain'
|
185
|
+
Export format, 'plain' for plain text, 'rest' for restructuredText.
|
186
|
+
|
187
|
+
Returns
|
188
|
+
-------
|
189
|
+
str
|
190
|
+
Tabulated output in a string
|
191
|
+
"""
|
192
|
+
if len(self.parent.params) == 0:
|
193
|
+
return ''
|
194
|
+
|
195
|
+
# prepare temporary lists
|
196
|
+
names, units, class_names = list(), list(), list()
|
197
|
+
info, defaults, properties = list(), list(), list()
|
198
|
+
units_rest = list()
|
199
|
+
|
200
|
+
for p in self.parent.params.values():
|
201
|
+
names.append(p.name)
|
202
|
+
class_names.append(p.class_name)
|
203
|
+
info.append(p.info if p.info else '')
|
204
|
+
defaults.append(p.default if p.default is not None else '')
|
205
|
+
units.append(f'{p.unit}' if p.unit else '')
|
206
|
+
units_rest.append(f'*{p.unit}*' if p.unit else '')
|
207
|
+
|
208
|
+
plist = []
|
209
|
+
for key, val in p.property.items():
|
210
|
+
if val is True:
|
211
|
+
plist.append(key)
|
212
|
+
properties.append(','.join(plist))
|
213
|
+
|
214
|
+
# symbols based on output format
|
215
|
+
if export == 'rest':
|
216
|
+
symbols = [item.tex_name for item in self.parent.params.values()]
|
217
|
+
symbols = math_wrap(symbols, export=export)
|
218
|
+
title = 'Parameters\n----------'
|
219
|
+
else:
|
220
|
+
symbols = [item.name for item in self.parent.params.values()]
|
221
|
+
title = 'Parameters'
|
222
|
+
|
223
|
+
plain_dict = OrderedDict([('Name', names),
|
224
|
+
('Description', info),
|
225
|
+
('Default', defaults),
|
226
|
+
('Unit', units),
|
227
|
+
('Properties', properties)])
|
228
|
+
|
229
|
+
rest_dict = OrderedDict([('Name', names),
|
230
|
+
('Symbol', symbols),
|
231
|
+
('Description', info),
|
232
|
+
('Default', defaults),
|
233
|
+
('Unit', units_rest),
|
234
|
+
('Properties', properties)])
|
235
|
+
|
236
|
+
# convert to rows and export as table
|
237
|
+
return make_doc_table(title=title,
|
238
|
+
max_width=max_width,
|
239
|
+
export=export,
|
240
|
+
plain_dict=plain_dict,
|
241
|
+
rest_dict=rest_dict)
|
242
|
+
|
168
243
|
|
169
244
|
class RDocumenter:
|
170
245
|
"""
|
@@ -172,20 +247,12 @@ class RDocumenter:
|
|
172
247
|
|
173
248
|
Parameters
|
174
249
|
----------
|
175
|
-
parent :
|
176
|
-
The `
|
250
|
+
parent : ams.core.routine.RoutineBase
|
251
|
+
The `RoutineBase` instance to document
|
177
252
|
"""
|
178
253
|
|
179
254
|
def __init__(self, parent):
|
180
255
|
self.parent = parent
|
181
|
-
self.system = parent.system
|
182
|
-
self.class_name = parent.class_name
|
183
|
-
self.config = parent.config
|
184
|
-
self.services = parent.services
|
185
|
-
self.rparams = parent.rparams
|
186
|
-
self.vars = parent.vars
|
187
|
-
self.constrs = parent.constrs
|
188
|
-
self.obj = parent.obj
|
189
256
|
|
190
257
|
def get(self, max_width=78, export='plain'):
|
191
258
|
"""
|
@@ -207,14 +274,15 @@ class RDocumenter:
|
|
207
274
|
if export == 'rest':
|
208
275
|
max_width = 0
|
209
276
|
model_header = '-' * 80 + '\n'
|
210
|
-
out += f'.. _{self.class_name}:\n\n'
|
277
|
+
out += f'.. _{self.parent.class_name}:\n\n'
|
211
278
|
else:
|
212
279
|
model_header = ''
|
213
280
|
|
214
281
|
if export == 'rest':
|
215
|
-
out += model_header + f'{self.class_name}\n' + model_header
|
282
|
+
out += model_header + f'{self.parent.class_name}\n' + model_header
|
216
283
|
else:
|
217
|
-
out += model_header +
|
284
|
+
out += model_header + \
|
285
|
+
f'Routine <{self.parent.class_name}> in Type <{self.parent.type}>\n' + model_header
|
218
286
|
|
219
287
|
if self.parent.__doc__ is not None:
|
220
288
|
out += inspect.cleandoc(self.parent.__doc__)
|
@@ -229,20 +297,20 @@ class RDocumenter:
|
|
229
297
|
out += self._exprc_doc(max_width=max_width, export=export)
|
230
298
|
out += self._service_doc(max_width=max_width, export=export)
|
231
299
|
out += self._param_doc(max_width=max_width, export=export)
|
232
|
-
out += self.config.doc(max_width=max_width, export=export)
|
300
|
+
out += self.parent.config.doc(max_width=max_width, export=export)
|
233
301
|
|
234
302
|
return out
|
235
303
|
|
236
304
|
def _service_doc(self, max_width=78, export='plain'):
|
237
305
|
# routine service documentation
|
238
|
-
if len(self.services) == 0:
|
306
|
+
if len(self.parent.services) == 0:
|
239
307
|
return ''
|
240
308
|
|
241
309
|
names, symbols = list(), list()
|
242
310
|
info = list()
|
243
311
|
class_names = list()
|
244
312
|
|
245
|
-
for p in self.services.values():
|
313
|
+
for p in self.parent.services.values():
|
246
314
|
names.append(p.name)
|
247
315
|
info.append(p.info if p.info else '')
|
248
316
|
class_names.append(p.class_name)
|
@@ -251,7 +319,7 @@ class RDocumenter:
|
|
251
319
|
|
252
320
|
# replace with latex math expressions if export is ``rest``
|
253
321
|
if export == 'rest':
|
254
|
-
symbols = [item.tex_name for item in self.services.values()]
|
322
|
+
symbols = [item.tex_name for item in self.parent.services.values()]
|
255
323
|
symbols = math_wrap(symbols, export=export)
|
256
324
|
title = 'Services\n---------'
|
257
325
|
|
@@ -272,13 +340,13 @@ class RDocumenter:
|
|
272
340
|
|
273
341
|
def _constr_doc(self, max_width=78, export='plain'):
|
274
342
|
# constraint documentation
|
275
|
-
if len(self.constrs) == 0:
|
343
|
+
if len(self.parent.constrs) == 0:
|
276
344
|
return ''
|
277
345
|
|
278
346
|
# prepare temporary lists
|
279
347
|
names, class_names, info = list(), list(), list()
|
280
348
|
|
281
|
-
for p in self.constrs.values():
|
349
|
+
for p in self.parent.constrs.values():
|
282
350
|
names.append(p.name)
|
283
351
|
class_names.append(p.class_name)
|
284
352
|
info.append(p.info if p.info else '')
|
@@ -286,7 +354,7 @@ class RDocumenter:
|
|
286
354
|
# expressions based on output format
|
287
355
|
expressions = []
|
288
356
|
if export == 'rest':
|
289
|
-
for p in self.constrs.values():
|
357
|
+
for p in self.parent.constrs.values():
|
290
358
|
expr = _tex_pre(self, p, self.parent.syms.tex_map)
|
291
359
|
if p.is_eq:
|
292
360
|
expr = f'{expr} = 0'
|
@@ -460,7 +528,7 @@ class RDocumenter:
|
|
460
528
|
# NOTE: this is for the optimization variables
|
461
529
|
# not the _var_doc for ANDES parameters
|
462
530
|
# variable documentation
|
463
|
-
if len(self.vars) == 0:
|
531
|
+
if len(self.parent.vars) == 0:
|
464
532
|
return ''
|
465
533
|
|
466
534
|
# prepare temporary lists
|
@@ -469,7 +537,7 @@ class RDocumenter:
|
|
469
537
|
sources = list()
|
470
538
|
units_rest = list()
|
471
539
|
|
472
|
-
for p in self.vars.values():
|
540
|
+
for p in self.parent.vars.values():
|
473
541
|
names.append(p.name)
|
474
542
|
class_names.append(p.class_name)
|
475
543
|
info.append(p.info if p.info else '')
|
@@ -493,11 +561,11 @@ class RDocumenter:
|
|
493
561
|
|
494
562
|
# symbols based on output format
|
495
563
|
if export == 'rest':
|
496
|
-
symbols = [item.tex_name for item in self.vars.values()]
|
564
|
+
symbols = [item.tex_name for item in self.parent.vars.values()]
|
497
565
|
symbols = math_wrap(symbols, export=export)
|
498
566
|
title = 'Vars\n----------------------------------'
|
499
567
|
else:
|
500
|
-
symbols = [item.name for item in self.vars.values()]
|
568
|
+
symbols = [item.name for item in self.parent.vars.values()]
|
501
569
|
title = 'Vars'
|
502
570
|
|
503
571
|
plain_dict = OrderedDict([('Name', names),
|
@@ -536,7 +604,7 @@ class RDocumenter:
|
|
536
604
|
str
|
537
605
|
Tabulated output in a string
|
538
606
|
"""
|
539
|
-
if len(self.rparams) == 0:
|
607
|
+
if len(self.parent.rparams) == 0:
|
540
608
|
return ''
|
541
609
|
|
542
610
|
# prepare temporary lists
|
@@ -545,7 +613,7 @@ class RDocumenter:
|
|
545
613
|
sources = list()
|
546
614
|
units_rest = list()
|
547
615
|
|
548
|
-
for p in self.rparams.values():
|
616
|
+
for p in self.parent.rparams.values():
|
549
617
|
names.append(p.name)
|
550
618
|
class_names.append(p.class_name)
|
551
619
|
info.append(p.info if p.info else '')
|
@@ -562,11 +630,11 @@ class RDocumenter:
|
|
562
630
|
|
563
631
|
# symbols based on output format
|
564
632
|
if export == 'rest':
|
565
|
-
symbols = [item.tex_name for item in self.rparams.values()]
|
633
|
+
symbols = [item.tex_name for item in self.parent.rparams.values()]
|
566
634
|
symbols = math_wrap(symbols, export=export)
|
567
635
|
title = 'Parameters\n----------------------------------'
|
568
636
|
else:
|
569
|
-
symbols = [item.name for item in self.rparams.values()]
|
637
|
+
symbols = [item.name for item in self.parent.rparams.values()]
|
570
638
|
title = 'Parameters'
|
571
639
|
|
572
640
|
plain_dict = OrderedDict([('Name', names),
|
@@ -3,7 +3,6 @@ Module for system matrix make.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import logging
|
6
|
-
import os
|
7
6
|
import sys
|
8
7
|
from typing import Optional
|
9
8
|
|
@@ -14,6 +13,9 @@ from andes.shared import tqdm, tqdm_nb
|
|
14
13
|
from andes.utils.misc import elapsed, is_notebook
|
15
14
|
|
16
15
|
from ams.opt import Param
|
16
|
+
|
17
|
+
from ams.utils.paths import get_export_path
|
18
|
+
|
17
19
|
from ams.shared import pd, sps
|
18
20
|
|
19
21
|
logger = logging.getLogger(__name__)
|
@@ -75,31 +77,28 @@ class MParam(Param):
|
|
75
77
|
"""
|
76
78
|
Export the matrix to a CSV file.
|
77
79
|
|
80
|
+
In the exported CSV, columns are the bus idxes, and Line idxes are
|
81
|
+
used as row indexes.
|
82
|
+
|
78
83
|
Parameters
|
79
84
|
----------
|
80
85
|
path : str, optional
|
81
|
-
Path
|
86
|
+
Path of the csv file to export.
|
82
87
|
|
83
88
|
Returns
|
84
89
|
-------
|
85
90
|
str
|
86
|
-
The
|
91
|
+
The exported csv file name
|
87
92
|
"""
|
88
93
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
else:
|
94
|
-
file_name = os.path.splitext(self.owner.system.files.fullname)[0]
|
95
|
-
file_name += f'_{self.name}'
|
96
|
-
path = os.path.join(os.getcwd(), file_name + '.csv')
|
97
|
-
else:
|
98
|
-
file_name = os.path.splitext(os.path.basename(path))[0]
|
94
|
+
path, file_name = get_export_path(self.owner.system,
|
95
|
+
self.name,
|
96
|
+
path=path,
|
97
|
+
fmt='csv')
|
99
98
|
|
100
99
|
pd.DataFrame(data=self.v, columns=self.col_names, index=self.row_names).to_csv(path)
|
101
100
|
|
102
|
-
return file_name
|
101
|
+
return file_name
|
103
102
|
|
104
103
|
@property
|
105
104
|
def v(self):
|
@@ -8,7 +8,7 @@ import logging
|
|
8
8
|
from collections import OrderedDict, Counter
|
9
9
|
|
10
10
|
from andes.utils.misc import elapsed
|
11
|
-
from andes.system import System as
|
11
|
+
from andes.system import System as adSystem
|
12
12
|
|
13
13
|
from ams.utils import create_entry
|
14
14
|
from ams.io import input_formats
|
@@ -107,7 +107,7 @@ def to_andes_pflow(system, no_output=False, default_config=True, **kwargs):
|
|
107
107
|
Additional arguments to be passed to ``andes.system.System()``.
|
108
108
|
"""
|
109
109
|
|
110
|
-
adsys =
|
110
|
+
adsys = adSystem(no_outpu=no_output, default_config=default_config, **kwargs)
|
111
111
|
# FIXME: is there a systematic way to do this? Other config might be needed
|
112
112
|
adsys.config.freq = system.config.freq
|
113
113
|
adsys.config.mva = system.config.mva
|
@@ -455,16 +455,6 @@ def system2mpc(system) -> dict:
|
|
455
455
|
|
456
456
|
This function is revised from ``andes.io.matpower.system2mpc``.
|
457
457
|
|
458
|
-
In the ``gen`` section, slack generators are listed before PV generators.
|
459
|
-
|
460
|
-
In the converted MPC, the indices of area (bus[:, 6]) and zone (bus[:, 10])
|
461
|
-
may differ from the original MPC. However, the mapping relationship is preserved.
|
462
|
-
For example, if the original MPC numbers areas starting from 1, the converted
|
463
|
-
MPC may number them starting from 0.
|
464
|
-
|
465
|
-
The coefficients ``c2`` and ``c1`` in the generator cost data are scaled by
|
466
|
-
``base_mva`` to match MATPOWER's unit convention (MW).
|
467
|
-
|
468
458
|
Parameters
|
469
459
|
----------
|
470
460
|
system : ams.core.system.System
|
@@ -474,6 +464,21 @@ def system2mpc(system) -> dict:
|
|
474
464
|
-------
|
475
465
|
mpc : dict
|
476
466
|
A dictionary in MATPOWER format representing the converted AMS system.
|
467
|
+
|
468
|
+
Notes
|
469
|
+
-----
|
470
|
+
- In the `gen` section, slack generators are listed before PV generators.
|
471
|
+
- For uncontrolled generators (`ctrl.v == 0`), their max and min power
|
472
|
+
limits are set to their initial power (`p0.v`) in the converted MPC.
|
473
|
+
- In the converted MPC, the indices of area (`bus[:, 6]`) and zone (`bus[:, 10]`)
|
474
|
+
may differ from the original MPC. However, the mapping relationship is preserved.
|
475
|
+
For example, if the original MPC numbers areas starting from 1, the converted
|
476
|
+
MPC may number them starting from 0.
|
477
|
+
- The coefficients `c2` and `c1` in the generator cost data are scaled by
|
478
|
+
`baseMVA`.
|
479
|
+
- Unlike the XLSX and JSON converters, this implementation uses value providers
|
480
|
+
(`v`) instead of vin. As a result, any changes made through `model.set` will be
|
481
|
+
reflected in the generated MPC.
|
477
482
|
"""
|
478
483
|
|
479
484
|
mpc = dict(version='2',
|
@@ -514,15 +519,31 @@ def system2mpc(system) -> dict:
|
|
514
519
|
# --- PQ ---
|
515
520
|
if system.PQ.n > 0:
|
516
521
|
pq_pos = system.Bus.idx2uid(system.PQ.bus.v)
|
517
|
-
|
518
|
-
|
519
|
-
|
522
|
+
|
523
|
+
p0e = system.PQ.u.v * system.PQ.p0.v
|
524
|
+
q0e = system.PQ.u.v * system.PQ.q0.v
|
525
|
+
|
526
|
+
# NOTE: ensure multiple PQ on the same bus are summed
|
527
|
+
# rather than overwritten. Same for Shunt.
|
528
|
+
p = np.zeros(system.Bus.n)
|
529
|
+
q = np.zeros(system.Bus.n)
|
530
|
+
np.add.at(p, pq_pos, p0e)
|
531
|
+
np.add.at(q, pq_pos, q0e)
|
532
|
+
bus[:, 2] = p * base_mva
|
533
|
+
bus[:, 3] = q * base_mva
|
520
534
|
|
521
535
|
# --- Shunt ---
|
522
536
|
if system.Shunt.n > 0:
|
523
537
|
shunt_pos = system.Bus.idx2uid(system.Shunt.bus.v)
|
524
|
-
|
525
|
-
|
538
|
+
|
539
|
+
ge = system.Shunt.u.v * system.Shunt.g.v
|
540
|
+
be = system.Shunt.u.v * system.Shunt.b.v
|
541
|
+
g = np.zeros(system.Bus.n)
|
542
|
+
b = np.zeros(system.Bus.n)
|
543
|
+
np.add.at(g, shunt_pos, ge)
|
544
|
+
np.add.at(b, shunt_pos, be)
|
545
|
+
bus[:, 4] = g * base_mva
|
546
|
+
bus[:, 5] = b * base_mva
|
526
547
|
|
527
548
|
# --- PV ---
|
528
549
|
if system.PV.n > 0:
|
@@ -709,11 +730,6 @@ def write(system, outfile: str, overwrite: bool = None) -> bool:
|
|
709
730
|
This function converts an AMS system object into a MATPOWER-compatible
|
710
731
|
mpc dictionary and writes it to a specified output file in MATPOWER format.
|
711
732
|
|
712
|
-
In the converted MPC, the indices of area (bus[:, 6]) and zone (bus[:, 10])
|
713
|
-
may differ from the original MPC. However, the mapping relationship is preserved.
|
714
|
-
For example, if the original MPC numbers areas starting from 1, the converted
|
715
|
-
MPC may number them starting from 0.
|
716
|
-
|
717
733
|
Parameters
|
718
734
|
----------
|
719
735
|
system : ams.system.System
|
@@ -727,6 +743,21 @@ def write(system, outfile: str, overwrite: bool = None) -> bool:
|
|
727
743
|
-------
|
728
744
|
bool
|
729
745
|
True if the file was successfully written, False otherwise.
|
746
|
+
|
747
|
+
Notes
|
748
|
+
-----
|
749
|
+
- In the `gen` section, slack generators are listed before PV generators.
|
750
|
+
- For uncontrolled generators (`ctrl.v == 0`), their max and min power
|
751
|
+
limits are set to their initial power (`p0.v`) in the converted MPC.
|
752
|
+
- In the converted MPC, the indices of area (`bus[:, 6]`) and zone (`bus[:, 10]`)
|
753
|
+
may differ from the original MPC. However, the mapping relationship is preserved.
|
754
|
+
For example, if the original MPC numbers areas starting from 1, the converted
|
755
|
+
MPC may number them starting from 0.
|
756
|
+
- The coefficients `c2` and `c1` in the generator cost data are scaled by
|
757
|
+
`baseMVA`.
|
758
|
+
- Unlike the XLSX and JSON converters, this implementation uses value providers
|
759
|
+
(`v`) instead of vin. As a result, any changes made through `model.set` will be
|
760
|
+
reflected in the generated MPC.
|
730
761
|
"""
|
731
762
|
if not confirm_overwrite(outfile, overwrite=overwrite):
|
732
763
|
return False
|