ltbams 0.9.5__tar.gz → 0.9.7__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-0.9.5 → ltbams-0.9.7}/LICENSE +2 -2
- {ltbams-0.9.5/ltbams.egg-info → ltbams-0.9.7}/PKG-INFO +5 -5
- {ltbams-0.9.5 → ltbams-0.9.7}/README.md +3 -3
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/__init__.py +2 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/_version.py +3 -3
- ltbams-0.9.7/ams/cases/5bus/pjm5bus_uced_ev.xlsx +0 -0
- ltbams-0.9.7/ams/core/matprocessor.py +539 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/core/model.py +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/core/service.py +1 -1
- ltbams-0.9.7/ams/extension/__init__.py +5 -0
- ltbams-0.9.7/ams/extension/eva.py +401 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/interop/andes.py +82 -16
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/io/matpower.py +31 -23
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/__init__.py +2 -2
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/bus.py +7 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/distributed/__init__.py +1 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/distributed/esd1.py +1 -1
- ltbams-0.9.7/ams/models/distributed/ev.py +60 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/distributed/pvd1.py +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/group.py +4 -4
- ltbams-0.9.7/ams/models/line.py +210 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/renewable/regc.py +4 -4
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/static/gen.py +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/timeslot.py +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/opt/omodel.py +10 -13
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/routines/pflow.py +4 -7
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/__init__.py +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/acopf.py +50 -89
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/dcopf.py +66 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/dcpf.py +39 -38
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/ed.py +7 -7
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/pflow.py +5 -13
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/routine.py +55 -35
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/rted.py +28 -17
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/uc.py +2 -2
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/system.py +13 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/conf.py +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/formats/pypower.rst +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/index.rst +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/overview.rst +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/index.rst +4 -4
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/modeling/example.rst +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/modeling/routine.rst +5 -5
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/release-notes.rst +78 -1
- {ltbams-0.9.5 → ltbams-0.9.7/ltbams.egg-info}/PKG-INFO +5 -5
- {ltbams-0.9.5 → ltbams-0.9.7}/ltbams.egg-info/SOURCES.txt +5 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ltbams.egg-info/requires.txt +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/requirements.txt +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/setup.py +1 -1
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_andes.py +93 -12
- ltbams-0.9.7/tests/test_mats.py +180 -0
- ltbams-0.9.7/tests/test_routine.py +180 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_service.py +1 -43
- ltbams-0.9.5/ams/core/matprocessor.py +0 -281
- ltbams-0.9.5/ams/models/line.py +0 -41
- ltbams-0.9.5/tests/test_routine.py +0 -95
- {ltbams-0.9.5 → ltbams-0.9.7}/CONTRIBUTING.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/MANIFEST.in +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/__main__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/5bus/pjm5bus_demo.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/5bus/pjm5bus_uced.json +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/5bus/pjm5bus_uced.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/5bus/pjm5bus_uced_esd1.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee123/ieee123.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee123/ieee123_regcv1.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee14/ieee14.json +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee14/ieee14.raw +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee14/ieee14_uced.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee39/ieee39.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee39/ieee39_uced.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee39/ieee39_uced_esd1.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee39/ieee39_uced_pvd1.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/ieee39/ieee39_uced_vis.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/matpower/case118.m +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/matpower/case14.m +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/matpower/case300.m +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/matpower/case39.m +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/matpower/case5.m +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/matpower/case_ACTIVSg2000.m +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/npcc/npcc.m +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/npcc/npcc_uced.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/pglib/pglib_opf_case39_epri__api.m +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/wecc/wecc.m +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cases/wecc/wecc_uced.xlsx +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/cli.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/core/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/core/documenter.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/core/param.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/core/symprocessor.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/core/var.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/interop/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/io/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/io/json.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/io/psse.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/io/pypower.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/io/xlsx.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/main.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/area.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/cost.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/info.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/region.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/renewable/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/reserve.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/shunt.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/static/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/models/static/pq.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/opt/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/_compat.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/core/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/core/pips.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/core/ppoption.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/core/ppver.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/core/solver.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/eps.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/idx.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/io.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/make/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/make/matrices.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/make/pdv.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/routines/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/routines/cpf.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/routines/cpf_callbacks.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/routines/opf.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/routines/opffcns.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/toggle.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/pypower/utils.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/report.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/cpf.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/dopf.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/routines/type.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/shared.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/utils/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ams/utils/paths.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/Makefile +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/make.bat +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/_templates/autosummary/base.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/_templates/autosummary/class.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/_templates/autosummary/module.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/_templates/autosummary/module_toctree.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/api.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/examples/index.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/copyright.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/formats/index.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/formats/matpower.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/formats/psse.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/formats/xlsx.png +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/formats/xlsx.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/install.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/testcase.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/getting_started/verification.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/images/dcopf_time.png +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/images/sponsors/CURENT_Logo_NameOnTrans.png +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/images/sponsors/CURENT_Logo_Transparent.png +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/images/sponsors/CURENT_Logo_Transparent_Name.png +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/images/sponsors/doe.png +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/modeling/index.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/modeling/model.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/docs/source/modeling/system.rst +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ltbams.egg-info/dependency_links.txt +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ltbams.egg-info/entry_points.txt +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/ltbams.egg-info/top_level.txt +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/requirements-extra.txt +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/setup.cfg +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/__init__.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_1st_system.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_addressing.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_case.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_cli.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_dctypes.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_export_csv.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_group.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_known_good.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_model.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_paths.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_report.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/tests/test_repr.py +0 -0
- {ltbams-0.9.5 → ltbams-0.9.7}/versioneer.py +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
AMS: Python Software for
|
1
|
+
AMS: Python Software for Scheduling Modeling and Co-Simulation with Dynanic
|
2
2
|
|
3
3
|
Copyright (c) 2023-2024 Jinning Wang
|
4
4
|
|
@@ -649,7 +649,7 @@ to attach them to the start of each source file to most effectively
|
|
649
649
|
state the exclusion of warranty; and each file should have at least
|
650
650
|
the "copyright" line and a pointer to where the full notice is found.
|
651
651
|
|
652
|
-
AMS, a python software for
|
652
|
+
AMS, a python software for scheduling modeling and co-simulation with dynanic
|
653
653
|
Copyright (C) 2023 Jinning Wang
|
654
654
|
|
655
655
|
This program is free software: you can redistribute it and/or modify
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ltbams
|
3
|
-
Version: 0.9.
|
4
|
-
Summary: Python software for
|
3
|
+
Version: 0.9.7
|
4
|
+
Summary: Python software for scheduling modeling and co-simulation with dynanics.
|
5
5
|
Home-page: https://github.com/CURENT/ams
|
6
6
|
Author: Jinning Wang
|
7
7
|
Author-email: jinninggm@gmail.com
|
@@ -33,7 +33,7 @@ License-File: LICENSE
|
|
33
33
|
|
34
34
|
# LTB AMS
|
35
35
|
|
36
|
-
Python Software for Power System
|
36
|
+
Python Software for Power System Scheduling Modeling and Co-Simulation with Dynanic, serving as the market simulator for the [CURENT Largescale Testbed][LTB Repository].
|
37
37
|
|
38
38
|
[](https://github.com/CURENT/ams/blob/master/LICENSE)
|
39
39
|

|
@@ -64,7 +64,7 @@ Python Software for Power System Dispatch Modeling and Co-Simulation with Dynani
|
|
64
64
|
|
65
65
|
With the built-in interface with dynamic simulation engine, ANDES, AMS enables Dynamics Interfaced Stability Constrained Production Cost and Market Operation Modeling.
|
66
66
|
|
67
|
-
AMS produces credible
|
67
|
+
AMS produces credible scheduling results and competitive performance.
|
68
68
|
The following results show the comparison of DCOPF between AMS and other tools.
|
69
69
|
|
70
70
|
| Cost [\$] | AMS | MATPOWER | pandapower |
|
@@ -112,7 +112,7 @@ pip install git+https://github.com/CURENT/ams.git
|
|
112
112
|
```
|
113
113
|
|
114
114
|
# Sponsors and Contributors
|
115
|
-
AMS is the
|
115
|
+
AMS is the scheduling simulation engine for the CURENT Largescale Testbed (LTB).
|
116
116
|
More information about CURENT LTB can be found at the [LTB Repository][LTB Repository].
|
117
117
|
|
118
118
|
This work was supported in part by the Engineering Research Center Program of the National Science Foundation and the Department of Energy
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# LTB AMS
|
2
2
|
|
3
|
-
Python Software for Power System
|
3
|
+
Python Software for Power System Scheduling Modeling and Co-Simulation with Dynanic, serving as the market simulator for the [CURENT Largescale Testbed][LTB Repository].
|
4
4
|
|
5
5
|
[](https://github.com/CURENT/ams/blob/master/LICENSE)
|
6
6
|

|
@@ -31,7 +31,7 @@ Python Software for Power System Dispatch Modeling and Co-Simulation with Dynani
|
|
31
31
|
|
32
32
|
With the built-in interface with dynamic simulation engine, ANDES, AMS enables Dynamics Interfaced Stability Constrained Production Cost and Market Operation Modeling.
|
33
33
|
|
34
|
-
AMS produces credible
|
34
|
+
AMS produces credible scheduling results and competitive performance.
|
35
35
|
The following results show the comparison of DCOPF between AMS and other tools.
|
36
36
|
|
37
37
|
| Cost [\$] | AMS | MATPOWER | pandapower |
|
@@ -79,7 +79,7 @@ pip install git+https://github.com/CURENT/ams.git
|
|
79
79
|
```
|
80
80
|
|
81
81
|
# Sponsors and Contributors
|
82
|
-
AMS is the
|
82
|
+
AMS is the scheduling simulation engine for the CURENT Largescale Testbed (LTB).
|
83
83
|
More information about CURENT LTB can be found at the [LTB Repository][LTB Repository].
|
84
84
|
|
85
85
|
This work was supported in part by the Engineering Research Center Program of the National Science Foundation and the Department of Energy
|
@@ -9,6 +9,7 @@ from ams import routines # NOQA
|
|
9
9
|
from ams import opt # NOQA
|
10
10
|
from ams import pypower # NOQA
|
11
11
|
from ams import report # NOQA
|
12
|
+
from ams import extension # NOQA
|
12
13
|
|
13
14
|
from ams.main import config_logger, load, run # NOQA
|
14
15
|
from ams.utils.paths import get_case # NOQA
|
@@ -16,4 +17,4 @@ from ams.shared import ppc2df # NOQA
|
|
16
17
|
|
17
18
|
__author__ = 'Jining Wang'
|
18
19
|
|
19
|
-
__all__ = ['io', 'utils', 'models', 'system']
|
20
|
+
__all__ = ['io', 'utils', 'models', 'system', 'extension']
|
@@ -8,11 +8,11 @@ import json
|
|
8
8
|
|
9
9
|
version_json = '''
|
10
10
|
{
|
11
|
-
"date": "2024-
|
11
|
+
"date": "2024-05-24T15:44:01-0400",
|
12
12
|
"dirty": false,
|
13
13
|
"error": null,
|
14
|
-
"full-revisionid": "
|
15
|
-
"version": "0.9.
|
14
|
+
"full-revisionid": "bc97bef7420651060bce99b80588ccb4d23a322b",
|
15
|
+
"version": "0.9.7"
|
16
16
|
}
|
17
17
|
''' # END VERSION_JSON
|
18
18
|
|
Binary file
|
@@ -0,0 +1,539 @@
|
|
1
|
+
"""
|
2
|
+
Module for system matrix make.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import logging
|
6
|
+
from typing import Optional
|
7
|
+
|
8
|
+
import numpy as np
|
9
|
+
|
10
|
+
from scipy.sparse import csr_matrix as c_sparse
|
11
|
+
from scipy.sparse import csc_matrix as csc_sparse
|
12
|
+
from scipy.sparse import lil_matrix as l_sparse
|
13
|
+
|
14
|
+
from andes.utils.misc import elapsed
|
15
|
+
from andes.thirdparty.npfunc import safe_div
|
16
|
+
|
17
|
+
from ams.opt.omodel import Param
|
18
|
+
|
19
|
+
logger = logging.getLogger(__name__)
|
20
|
+
|
21
|
+
|
22
|
+
class MParam(Param):
|
23
|
+
"""
|
24
|
+
Class for matrix parameters built from the system.
|
25
|
+
|
26
|
+
MParam is designed to be a subclass of RParam for routine parameters
|
27
|
+
management.
|
28
|
+
|
29
|
+
Parameters
|
30
|
+
----------
|
31
|
+
name : str, optional
|
32
|
+
Name of this parameter. If not provided, `name` will be set
|
33
|
+
to the attribute name.
|
34
|
+
tex_name : str, optional
|
35
|
+
LaTeX-formatted parameter name. If not provided, `tex_name`
|
36
|
+
will be assigned the same as `name`.
|
37
|
+
info : str, optional
|
38
|
+
A description of this parameter
|
39
|
+
unit : str, optional
|
40
|
+
Unit of the parameter.
|
41
|
+
v : np.ndarray, optional
|
42
|
+
Matrix value of the parameter.
|
43
|
+
owner : object, optional
|
44
|
+
Owner of the MParam, usually the MatProcessor instance.
|
45
|
+
"""
|
46
|
+
|
47
|
+
def __init__(self,
|
48
|
+
name: Optional[str] = None,
|
49
|
+
tex_name: Optional[str] = None,
|
50
|
+
info: Optional[str] = None,
|
51
|
+
unit: Optional[str] = None,
|
52
|
+
v: Optional[np.ndarray] = None,
|
53
|
+
sparse: Optional[bool] = False,
|
54
|
+
):
|
55
|
+
self.name = name
|
56
|
+
self.tex_name = tex_name if (tex_name is not None) else name
|
57
|
+
self.info = info
|
58
|
+
self.unit = unit
|
59
|
+
self._v = v
|
60
|
+
self.sparse = sparse
|
61
|
+
self.owner = None
|
62
|
+
|
63
|
+
@property
|
64
|
+
def v(self):
|
65
|
+
"""
|
66
|
+
Return the value of the parameter.
|
67
|
+
"""
|
68
|
+
# NOTE: scipy.sparse matrix will return 2D array
|
69
|
+
# so we squeeze it here if only one row
|
70
|
+
if isinstance(self._v, (c_sparse, l_sparse, csc_sparse)):
|
71
|
+
out = self._v.toarray()
|
72
|
+
if out.shape[0] == 1:
|
73
|
+
return np.squeeze(out)
|
74
|
+
else:
|
75
|
+
return out
|
76
|
+
return self._v
|
77
|
+
|
78
|
+
@property
|
79
|
+
def shape(self):
|
80
|
+
"""
|
81
|
+
Return the shape of the parameter.
|
82
|
+
"""
|
83
|
+
return self.v.shape
|
84
|
+
|
85
|
+
@property
|
86
|
+
def n(self):
|
87
|
+
"""
|
88
|
+
Return the szie of the parameter.
|
89
|
+
"""
|
90
|
+
return len(self.v)
|
91
|
+
|
92
|
+
@property
|
93
|
+
def class_name(self):
|
94
|
+
"""
|
95
|
+
Return the class name
|
96
|
+
"""
|
97
|
+
return self.__class__.__name__
|
98
|
+
|
99
|
+
|
100
|
+
class MatProcessor:
|
101
|
+
"""
|
102
|
+
Class for matrix processing in AMS system.
|
103
|
+
"""
|
104
|
+
|
105
|
+
def __init__(self, system):
|
106
|
+
self.system = system
|
107
|
+
self.initialized = False
|
108
|
+
|
109
|
+
self.Cft = MParam(name='Cft', tex_name=r'C_{ft}',
|
110
|
+
info='Line connectivity matrix',
|
111
|
+
v=None, sparse=True)
|
112
|
+
self.CftT = MParam(name='CftT', tex_name=r'C_{ft}^{T}',
|
113
|
+
info='Line connectivity matrix transpose',
|
114
|
+
v=None, sparse=True)
|
115
|
+
self.Cg = MParam(name='Cg', tex_name=r'C_g',
|
116
|
+
info='Generator connectivity matrix',
|
117
|
+
v=None, sparse=True)
|
118
|
+
self.Cl = MParam(name='Cl', tex_name=r'Cl',
|
119
|
+
info='Load connectivity matrix',
|
120
|
+
v=None, sparse=True)
|
121
|
+
self.Csh = MParam(name='Csh', tex_name=r'C_{sh}',
|
122
|
+
info='Shunt connectivity matrix',
|
123
|
+
v=None, sparse=True)
|
124
|
+
|
125
|
+
self.Bbus = MParam(name='Bbus', tex_name=r'B_{bus}',
|
126
|
+
info='Bus admittance matrix',
|
127
|
+
v=None, sparse=True)
|
128
|
+
self.Bf = MParam(name='Bf', tex_name=r'B_{f}',
|
129
|
+
info='Bf matrix',
|
130
|
+
v=None, sparse=True)
|
131
|
+
self.Pbusinj = MParam(name='Pbusinj', tex_name=r'P_{bus}^{inj}',
|
132
|
+
info='Bus power injection vector',
|
133
|
+
v=None,)
|
134
|
+
self.Pfinj = MParam(name='Pfinj', tex_name=r'P_{f}^{inj}',
|
135
|
+
info='Line power injection vector',
|
136
|
+
v=None,)
|
137
|
+
|
138
|
+
self.PTDF = MParam(name='PTDF', tex_name=r'P_{TDF}',
|
139
|
+
info='Power transfer distribution factor',
|
140
|
+
v=None)
|
141
|
+
self.LODF = MParam(name='LODF', tex_name=r'O_{TDF}',
|
142
|
+
info='Line outage distribution factor',
|
143
|
+
v=None)
|
144
|
+
|
145
|
+
def build(self):
|
146
|
+
"""
|
147
|
+
Build the system matrices.
|
148
|
+
It build connectivity matrices first: Cg, Cl, Csh, Cft, and CftT.
|
149
|
+
Then build bus matrices: Bf, Bbus, Pfinj, and Pbusinj.
|
150
|
+
|
151
|
+
Returns
|
152
|
+
-------
|
153
|
+
initialized : bool
|
154
|
+
True if the matrices are built successfully.
|
155
|
+
"""
|
156
|
+
t_mat, _ = elapsed()
|
157
|
+
|
158
|
+
# --- connectivity matrices ---
|
159
|
+
_ = self.build_cg()
|
160
|
+
_ = self.build_cl()
|
161
|
+
_ = self.build_csh()
|
162
|
+
_ = self.build_cft()
|
163
|
+
|
164
|
+
# --- bus matrices ---
|
165
|
+
_ = self.build_bf()
|
166
|
+
_ = self.build_bbus()
|
167
|
+
_ = self.build_pfinj()
|
168
|
+
_ = self.build_pbusinj()
|
169
|
+
_, s_mat = elapsed(t_mat)
|
170
|
+
|
171
|
+
logger.debug(f"Built system matrices in {s_mat}.")
|
172
|
+
self.initialized = True
|
173
|
+
return self.initialized
|
174
|
+
|
175
|
+
@property
|
176
|
+
def class_name(self):
|
177
|
+
"""
|
178
|
+
Return the class name
|
179
|
+
"""
|
180
|
+
return self.__class__.__name__
|
181
|
+
|
182
|
+
@property
|
183
|
+
def n(self):
|
184
|
+
"""
|
185
|
+
To fit the RParam style.
|
186
|
+
"""
|
187
|
+
return 2
|
188
|
+
|
189
|
+
def build_cg(self):
|
190
|
+
"""
|
191
|
+
Build generator connectivity matrix Cg, and store it in the MParam `Cg`.
|
192
|
+
|
193
|
+
Returns
|
194
|
+
-------
|
195
|
+
Cg : scipy.sparse.csr_matrix
|
196
|
+
Generator connectivity matrix.
|
197
|
+
"""
|
198
|
+
system = self.system
|
199
|
+
|
200
|
+
# common variables
|
201
|
+
nb = system.Bus.n
|
202
|
+
ng = system.StaticGen.n
|
203
|
+
|
204
|
+
# bus indices: idx -> uid
|
205
|
+
idx_gen = system.StaticGen.get_idx()
|
206
|
+
u_gen = system.StaticGen.get(src='u', attr='v', idx=idx_gen)
|
207
|
+
on_gen = np.flatnonzero(u_gen) # uid of online generators
|
208
|
+
on_gen_idx = [idx_gen[i] for i in on_gen] # idx of online generators
|
209
|
+
on_gen_bus = system.StaticGen.get(src='bus', attr='v', idx=on_gen_idx)
|
210
|
+
|
211
|
+
row = np.array([system.Bus.idx2uid(x) for x in on_gen_bus])
|
212
|
+
col = np.array([idx_gen.index(x) for x in on_gen_idx])
|
213
|
+
self.Cg._v = c_sparse((np.ones(len(on_gen_idx)), (row, col)), (nb, ng))
|
214
|
+
return self.Cg._v
|
215
|
+
|
216
|
+
def build_cl(self):
|
217
|
+
"""
|
218
|
+
Build load connectivity matrix Cl, and store it in the MParam `Cl`.
|
219
|
+
|
220
|
+
Returns
|
221
|
+
-------
|
222
|
+
Cl : scipy.sparse.csr_matrix
|
223
|
+
Load connectivity matrix.
|
224
|
+
"""
|
225
|
+
system = self.system
|
226
|
+
|
227
|
+
# common variables
|
228
|
+
nb = system.Bus.n
|
229
|
+
npq = system.PQ.n
|
230
|
+
|
231
|
+
# load indices: idx -> uid
|
232
|
+
idx_load = system.PQ.idx.v
|
233
|
+
u_load = system.PQ.get(src='u', attr='v', idx=idx_load)
|
234
|
+
on_load = np.flatnonzero(u_load)
|
235
|
+
on_load_idx = [idx_load[i] for i in on_load]
|
236
|
+
on_load_bus = system.PQ.get(src='bus', attr='v', idx=on_load_idx)
|
237
|
+
|
238
|
+
row = np.array([system.Bus.idx2uid(x) for x in on_load_bus])
|
239
|
+
col = np.array([system.PQ.idx2uid(x) for x in on_load_idx])
|
240
|
+
self.Cl._v = c_sparse((np.ones(len(on_load_idx)), (row, col)), (nb, npq))
|
241
|
+
return self.Cl._v
|
242
|
+
|
243
|
+
def build_csh(self):
|
244
|
+
"""
|
245
|
+
Build shunt connectivity matrix Csh, and store it in the MParam `Csh`.
|
246
|
+
|
247
|
+
Returns
|
248
|
+
-------
|
249
|
+
Csh : spmatrix
|
250
|
+
Shunt connectivity matrix.
|
251
|
+
"""
|
252
|
+
system = self.system
|
253
|
+
|
254
|
+
# common variables
|
255
|
+
nb = system.Bus.n
|
256
|
+
nsh = system.Shunt.n
|
257
|
+
|
258
|
+
# shunt indices: idx -> uid
|
259
|
+
idx_shunt = system.Shunt.idx.v
|
260
|
+
u_shunt = system.Shunt.get(src='u', attr='v', idx=idx_shunt)
|
261
|
+
on_shunt = np.flatnonzero(u_shunt)
|
262
|
+
on_shunt_idx = [idx_shunt[i] for i in on_shunt]
|
263
|
+
on_shunt_bus = system.Shunt.get(src='bus', attr='v', idx=on_shunt_idx)
|
264
|
+
|
265
|
+
row = np.array([system.Bus.idx2uid(x) for x in on_shunt_bus])
|
266
|
+
col = np.array([system.Shunt.idx2uid(x) for x in on_shunt_idx])
|
267
|
+
self.Csh._v = c_sparse((np.ones(len(on_shunt_idx)), (row, col)), (nb, nsh))
|
268
|
+
return self.Csh._v
|
269
|
+
|
270
|
+
def build_cft(self):
|
271
|
+
"""
|
272
|
+
Build line connectivity matrix Cft and its transpose CftT.
|
273
|
+
The Cft and CftT are stored in the MParam `Cft` and `CftT`, respectively.
|
274
|
+
|
275
|
+
Returns
|
276
|
+
-------
|
277
|
+
Cft : scipy.sparse.csr_matrix
|
278
|
+
Line connectivity matrix.
|
279
|
+
"""
|
280
|
+
system = self.system
|
281
|
+
|
282
|
+
# common variables
|
283
|
+
nb = system.Bus.n
|
284
|
+
nl = system.Line.n
|
285
|
+
|
286
|
+
# line indices: idx -> uid
|
287
|
+
idx_line = system.Line.idx.v
|
288
|
+
u_line = system.Line.get(src='u', attr='v', idx=idx_line)
|
289
|
+
on_line = np.flatnonzero(u_line)
|
290
|
+
on_line_idx = [idx_line[i] for i in on_line]
|
291
|
+
on_line_bus1 = system.Line.get(src='bus1', attr='v', idx=on_line_idx)
|
292
|
+
on_line_bus2 = system.Line.get(src='bus2', attr='v', idx=on_line_idx)
|
293
|
+
|
294
|
+
data_line = np.ones(2*len(on_line_idx))
|
295
|
+
data_line[len(on_line_idx):] = -1
|
296
|
+
row_line = np.array([system.Bus.idx2uid(x) for x in on_line_bus1 + on_line_bus2])
|
297
|
+
col_line = np.array([system.Line.idx2uid(x) for x in on_line_idx + on_line_idx])
|
298
|
+
self.Cft._v = c_sparse((data_line, (row_line, col_line)), (nb, nl))
|
299
|
+
self.CftT._v = self.Cft._v.T
|
300
|
+
return self.Cft._v
|
301
|
+
|
302
|
+
def build_bf(self):
|
303
|
+
"""
|
304
|
+
Build DC Bf matrix and store it in the MParam `Bf`.
|
305
|
+
|
306
|
+
Returns
|
307
|
+
-------
|
308
|
+
Bf : scipy.sparse.csr_matrix
|
309
|
+
Bf matrix.
|
310
|
+
"""
|
311
|
+
system = self.system
|
312
|
+
|
313
|
+
# common variables
|
314
|
+
nb = system.Bus.n
|
315
|
+
nl = system.Line.n
|
316
|
+
|
317
|
+
# line parameters
|
318
|
+
idx_line = system.Line.idx.v
|
319
|
+
b = self._calc_b()
|
320
|
+
|
321
|
+
# build Bf such that Bf * Va is the vector of real branch powers injected
|
322
|
+
# at each branch's "from" bus
|
323
|
+
f = system.Bus.idx2uid(system.Line.get(src='bus1', attr='v', idx=idx_line))
|
324
|
+
t = system.Bus.idx2uid(system.Line.get(src='bus2', attr='v', idx=idx_line))
|
325
|
+
ir = np.r_[range(nl), range(nl)] # double set of row indices
|
326
|
+
self.Bf._v = c_sparse((np.r_[b, -b], (ir, np.r_[f, t])), (nl, nb))
|
327
|
+
return self.Bf._v
|
328
|
+
|
329
|
+
def build_bbus(self):
|
330
|
+
"""
|
331
|
+
Build Bdc matrix and store it in the MParam `Bbus`.
|
332
|
+
|
333
|
+
Returns
|
334
|
+
-------
|
335
|
+
Bdc : scipy.sparse.csr_matrix
|
336
|
+
DC bus admittance matrix.
|
337
|
+
"""
|
338
|
+
self.Bbus._v = self.Cft._v * self.Bf._v
|
339
|
+
return self.Bbus._v
|
340
|
+
|
341
|
+
def build_pfinj(self):
|
342
|
+
"""
|
343
|
+
Build DC Pfinj vector and store it in the MParam `Pfinj`.
|
344
|
+
|
345
|
+
Returns
|
346
|
+
-------
|
347
|
+
Pfinj : np.ndarray
|
348
|
+
Line power injection vector.
|
349
|
+
"""
|
350
|
+
idx_line = self.system.Line.idx.v
|
351
|
+
b = self._calc_b()
|
352
|
+
phi = self.system.Line.get(src='phi', attr='v', idx=idx_line)
|
353
|
+
self.Pfinj._v = b * (-phi)
|
354
|
+
return self.Pfinj._v
|
355
|
+
|
356
|
+
def build_pbusinj(self):
|
357
|
+
"""
|
358
|
+
Build DC Pbusinj vector and store it in the MParam `Pbusinj`.
|
359
|
+
|
360
|
+
Returns
|
361
|
+
-------
|
362
|
+
Pbusinj : np.ndarray
|
363
|
+
Bus power injection vector.
|
364
|
+
"""
|
365
|
+
self.Pbusinj._v = self.Cft._v * self.Pfinj._v
|
366
|
+
return self.Pbusinj._v
|
367
|
+
|
368
|
+
def _calc_b(self):
|
369
|
+
"""
|
370
|
+
Calculate DC series susceptance for each line.
|
371
|
+
|
372
|
+
Returns
|
373
|
+
-------
|
374
|
+
b : np.ndarray
|
375
|
+
Series susceptance for each line.
|
376
|
+
"""
|
377
|
+
system = self.system
|
378
|
+
nl = system.Line.n
|
379
|
+
|
380
|
+
# line parameters
|
381
|
+
idx_line = system.Line.idx.v
|
382
|
+
x = system.Line.get(src='x', attr='v', idx=idx_line)
|
383
|
+
u_line = system.Line.get(src='u', attr='v', idx=idx_line)
|
384
|
+
b = u_line / x # series susceptance
|
385
|
+
|
386
|
+
# in DC, tap is assumed to be 1
|
387
|
+
tap0 = system.Line.get(src='tap', attr='v', idx=idx_line)
|
388
|
+
tap = np.ones(nl)
|
389
|
+
i = np.flatnonzero(tap0)
|
390
|
+
tap[i] = tap0[i] # assign non-zero tap ratios
|
391
|
+
b = b / tap # adjusted series susceptance
|
392
|
+
|
393
|
+
return b
|
394
|
+
|
395
|
+
def build_ptdf(self, dtype='float64', no_store=False):
|
396
|
+
"""
|
397
|
+
Build the DC PTDF matrix and store it in the MParam `PTDF`.
|
398
|
+
|
399
|
+
`PTDF[m, n]` means the increased line flow on line `m` when there is
|
400
|
+
1 p.u. power injection at bus `n`.
|
401
|
+
|
402
|
+
It requires DC Bbus and Bf.
|
403
|
+
|
404
|
+
Note that there is discrepency between the PTDF-based line flow and
|
405
|
+
DCOPF calcualted line flow. The gap is ignorable for small cases.
|
406
|
+
|
407
|
+
Try to use 'float32' for dtype if memory is a concern.
|
408
|
+
|
409
|
+
Parameters
|
410
|
+
----------
|
411
|
+
dtype : str, optional
|
412
|
+
Data type of the PTDF matrix. Default is 'float64'.
|
413
|
+
no_store : bool, optional
|
414
|
+
If True, the PTDF will not be stored into `MatProcessor.PTDF._v`.
|
415
|
+
|
416
|
+
Returns
|
417
|
+
-------
|
418
|
+
PTDF : np.ndarray
|
419
|
+
Power transfer distribution factor.
|
420
|
+
"""
|
421
|
+
system = self.system
|
422
|
+
|
423
|
+
# use first slack bus as reference slack bus
|
424
|
+
slack = system.Slack.bus.v[0]
|
425
|
+
|
426
|
+
# use first bus for voltage angle reference
|
427
|
+
noref_idx = system.Bus.idx.v[1:]
|
428
|
+
noref = system.Bus.idx2uid(noref_idx)
|
429
|
+
|
430
|
+
noslack = [system.Bus.idx2uid(bus) for bus in system.Bus.idx.v if bus != slack]
|
431
|
+
|
432
|
+
# build other matrices if not built
|
433
|
+
if not self.initialized:
|
434
|
+
logger.debug("System matrices are not built. Building now.")
|
435
|
+
self.build()
|
436
|
+
|
437
|
+
# use dense representation
|
438
|
+
Bbus = self.Bbus._v.todense().astype(dtype)
|
439
|
+
Bf = self.Bf._v.todense().astype(dtype)
|
440
|
+
|
441
|
+
# initialize PTDF matrix
|
442
|
+
H = np.zeros((system.Line.n, system.Bus.n), dtype=dtype)
|
443
|
+
# calculate PTDF
|
444
|
+
H[:, noslack] = np.linalg.solve(Bbus[np.ix_(noslack, noref)].T, Bf[:, noref].T).T
|
445
|
+
|
446
|
+
if not no_store:
|
447
|
+
self.PTDF._v = H
|
448
|
+
|
449
|
+
return H
|
450
|
+
|
451
|
+
def build_lodf(self, dtype='float64', no_store=False):
|
452
|
+
"""
|
453
|
+
Build the DC LODF matrix and store it in the MParam `LODF`.
|
454
|
+
|
455
|
+
`LODF[m, n]` means the increased line flow on line `m` when there is
|
456
|
+
1 p.u. line flow decrease on line `n` due to line `n` outage.
|
457
|
+
|
458
|
+
It requires DC PTDF and Cft.
|
459
|
+
|
460
|
+
Try to use 'float32' for dtype if memory is a concern.
|
461
|
+
|
462
|
+
Parameters
|
463
|
+
----------
|
464
|
+
dtype : str, optional
|
465
|
+
Data type of the LODF matrix. Default is 'float64'.
|
466
|
+
no_store : bool, optional
|
467
|
+
If True, the LODF will not be stored into `MatProcessor.LODF._v`.
|
468
|
+
|
469
|
+
Returns
|
470
|
+
-------
|
471
|
+
LODF : np.ndarray
|
472
|
+
Line outage distribution factor.
|
473
|
+
"""
|
474
|
+
nl = self.system.Line.n
|
475
|
+
|
476
|
+
# build PTDF if not built
|
477
|
+
if self.PTDF._v is None:
|
478
|
+
ptdf = self.build_ptdf(dtype=dtype, no_store=True)
|
479
|
+
else:
|
480
|
+
ptdf = self.PTDF._v
|
481
|
+
|
482
|
+
H = ptdf * self.Cft._v
|
483
|
+
h = np.diag(H, 0)
|
484
|
+
LODF = safe_div(H, np.ones((nl, nl)) - np.ones((nl, 1)) * h.T)
|
485
|
+
LODF = LODF - np.diag(np.diag(LODF)) - np.eye(nl, nl)
|
486
|
+
|
487
|
+
if not no_store:
|
488
|
+
self.LODF._v = LODF.astype(dtype)
|
489
|
+
return LODF.astype(dtype)
|
490
|
+
|
491
|
+
def build_otdf(self, line=None, dtype='float64'):
|
492
|
+
"""
|
493
|
+
Build the DC OTDF matrix for line outage:
|
494
|
+
:math:`OTDF_k = PTDF + LODF[:, k] @ PTDF[k, ]`,
|
495
|
+
where k is the outage line locations.
|
496
|
+
|
497
|
+
OTDF_k[m, n] means the increased line flow on line `m` when there is
|
498
|
+
1 p.u. line flow decrease on line `k` due to line `k` outage.
|
499
|
+
|
500
|
+
Note that the OTDF is not stored in the MatProcessor.
|
501
|
+
|
502
|
+
Try to use 'float32' for dtype if memory is a concern.
|
503
|
+
|
504
|
+
Parameters
|
505
|
+
----------
|
506
|
+
line : int, str, list, optional
|
507
|
+
Lines index for which the OTDF is calculated. It takes both single
|
508
|
+
or multiple line indices.
|
509
|
+
If not given, the first line is used by default.
|
510
|
+
dtype : str, optional
|
511
|
+
Data type of the OTDF matrix. Default is 'float64'.
|
512
|
+
|
513
|
+
Returns
|
514
|
+
-------
|
515
|
+
OTDF : np.ndarray
|
516
|
+
Line outage distribution factor.
|
517
|
+
"""
|
518
|
+
if self.PTDF._v is None:
|
519
|
+
ptdf = self.build_ptdf(dtype=dtype, no_store=True)
|
520
|
+
else:
|
521
|
+
ptdf = self.PTDF._v
|
522
|
+
|
523
|
+
if self.LODF._v is None:
|
524
|
+
lodf = self.build_lodf(dtype=dtype, no_store=True)
|
525
|
+
else:
|
526
|
+
lodf = self.LODF._v
|
527
|
+
|
528
|
+
if line is None:
|
529
|
+
luid = [0]
|
530
|
+
elif isinstance(line, (int, str)):
|
531
|
+
try:
|
532
|
+
luid = [self.system.Line.idx2uid(line)]
|
533
|
+
except ValueError:
|
534
|
+
raise ValueError(f"Line {line} not found.")
|
535
|
+
elif isinstance(line, list):
|
536
|
+
luid = self.system.Line.idx2uid(line)
|
537
|
+
|
538
|
+
otdf = ptdf + lodf[:, luid] @ ptdf[luid, :]
|
539
|
+
return otdf.astype(dtype)
|
@@ -497,7 +497,7 @@ class MinDur(NumOpDual):
|
|
497
497
|
n_gen = self.u.n
|
498
498
|
n_ts = self.u.horizon.n
|
499
499
|
tout = np.zeros((n_gen, n_ts))
|
500
|
-
t = self.rtn.config.t #
|
500
|
+
t = self.rtn.config.t # scheduling interval
|
501
501
|
|
502
502
|
# minimum online/offline duration
|
503
503
|
td = np.ceil(self.u2.v/t).astype(int)
|