ltbams 1.0.13__py3-none-any.whl → 1.0.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ams/_version.py +3 -3
- ams/cli.py +2 -7
- ams/core/common.py +7 -3
- ams/core/documenter.py +2 -1
- ams/core/matprocessor.py +4 -4
- ams/core/model.py +14 -6
- ams/core/param.py +5 -3
- ams/core/symprocessor.py +8 -2
- ams/core/var.py +1 -1
- ams/extension/eva.py +11 -7
- ams/interface.py +7 -7
- ams/io/json.py +20 -16
- ams/io/matpower.py +6 -6
- ams/io/psse.py +2 -1
- ams/io/xlsx.py +21 -16
- ams/main.py +53 -45
- ams/models/distributed/esd1.py +4 -7
- ams/models/distributed/ev.py +10 -6
- ams/models/distributed/pvd1.py +4 -7
- ams/models/group.py +17 -18
- ams/models/renewable/regc.py +14 -22
- ams/models/timeslot.py +46 -1
- ams/models/zone.py +2 -4
- ams/opt/exprcalc.py +5 -3
- ams/opt/optzbase.py +4 -3
- ams/report.py +2 -7
- ams/routines/dcopf.py +7 -4
- ams/routines/dcopf2.py +46 -21
- ams/routines/dcpf.py +5 -0
- ams/routines/dopf.py +2 -2
- ams/routines/ed.py +5 -5
- ams/routines/pflow.py +1 -1
- ams/routines/routine.py +20 -4
- ams/routines/rted.py +5 -5
- ams/routines/uc.py +2 -2
- ams/shared.py +69 -0
- ams/system.py +93 -18
- ams/utils/paths.py +6 -10
- docs/source/examples/index.rst +1 -0
- docs/source/genroutineref.py +24 -0
- docs/source/release-notes.rst +15 -0
- {ltbams-1.0.13.dist-info → ltbams-1.0.15.dist-info}/METADATA +19 -22
- {ltbams-1.0.13.dist-info → ltbams-1.0.15.dist-info}/RECORD +46 -46
- {ltbams-1.0.13.dist-info → ltbams-1.0.15.dist-info}/WHEEL +0 -0
- {ltbams-1.0.13.dist-info → ltbams-1.0.15.dist-info}/entry_points.txt +0 -0
- {ltbams-1.0.13.dist-info → ltbams-1.0.15.dist-info}/top_level.txt +0 -0
ams/models/distributed/ev.py
CHANGED
@@ -12,13 +12,17 @@ class EV1(ModelData, Model):
|
|
12
12
|
"""
|
13
13
|
Aggregated EV model for scheduling at transmission level.
|
14
14
|
|
15
|
-
For co-simulation with
|
15
|
+
For co-simulation with ANDES, it is expected to be used in
|
16
16
|
conjunction with the dynamic models `EV1` or `EV2`.
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
References
|
19
|
+
----------
|
20
|
+
1. J. Wang et al., "Electric Vehicles Charging Time Constrained
|
21
|
+
Deliverable Provision of Secondary Frequency Regulation," in IEEE
|
22
|
+
Transactions on Smart Grid, vol. 15, no. 4, pp. 3892-3903, July
|
23
|
+
2024, doi: 10.1109/TSG.2024.3356948.
|
24
|
+
2. ANDES Documentation, EV1,
|
25
|
+
https://andes.readthedocs.io/en/stable/groupdoc/DG.html#ev1
|
22
26
|
"""
|
23
27
|
|
24
28
|
def __init__(self, system, config):
|
@@ -53,7 +57,7 @@ class EV1(ModelData, Model):
|
|
53
57
|
|
54
58
|
class EV2(EV1):
|
55
59
|
"""
|
56
|
-
|
60
|
+
Alias for EV1.
|
57
61
|
"""
|
58
62
|
|
59
63
|
def __init__(self, system=None, config=None) -> None:
|
ams/models/distributed/pvd1.py
CHANGED
@@ -52,13 +52,10 @@ class PVD1(PVD1Data, Model):
|
|
52
52
|
``vt3``, ``vrflag``, ``ft0``, ``ft1``, ``ft2``, ``ft3``, ``frflag``,
|
53
53
|
``tip``, ``tiq``, ``recflag``.
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
Available:
|
60
|
-
|
61
|
-
https://docs.andes.app/en/latest/groupdoc/DG.html#pvd1
|
55
|
+
References
|
56
|
+
----------
|
57
|
+
1. ANDES Documentation, PVD1,
|
58
|
+
https://andes.readthedocs.io/en/stable/groupdoc/DG.html#pvd1
|
62
59
|
"""
|
63
60
|
|
64
61
|
def __init__(self, system, config):
|
ams/models/group.py
CHANGED
@@ -3,22 +3,24 @@ import logging
|
|
3
3
|
from andes.models.group import GroupBase as adGroupBase
|
4
4
|
from andes.core.service import BackRef
|
5
5
|
|
6
|
+
from ams.utils.misc import deprec_get_idx
|
7
|
+
|
6
8
|
logger = logging.getLogger(__name__)
|
7
9
|
|
8
10
|
|
9
11
|
class GroupBase(adGroupBase):
|
10
12
|
"""
|
11
|
-
Base class for groups
|
13
|
+
Base class for groups, revised from
|
14
|
+
`andes.models.group.GroupBase`.
|
12
15
|
|
13
16
|
Add common_vars and common_params to the group class.
|
14
|
-
|
15
|
-
This class is revised from ``andes.models.group.GroupBase``.
|
16
17
|
"""
|
17
18
|
|
18
19
|
def __init__(self):
|
19
20
|
super().__init__()
|
20
21
|
self.common_params.extend(('idx',))
|
21
22
|
|
23
|
+
@deprec_get_idx
|
22
24
|
def get_idx(self):
|
23
25
|
"""
|
24
26
|
Return the value of group idx sorted in a human-readable style.
|
@@ -27,6 +29,9 @@ class GroupBase(adGroupBase):
|
|
27
29
|
-----
|
28
30
|
This function sorts the idx values using a custom sorting key,
|
29
31
|
which handles varying length strings with letters and numbers.
|
32
|
+
|
33
|
+
.. deprecated:: 1.0.0
|
34
|
+
Use ``get_all_idxes`` instead.
|
30
35
|
"""
|
31
36
|
all_idx = [mdl.idx.v for mdl in self.models.values()]
|
32
37
|
flat_list = [item for sublist in all_idx for item in sublist]
|
@@ -94,13 +99,10 @@ class RenGen(GroupBase):
|
|
94
99
|
See ANDES Documentation SynGen here for the notes on replacing StaticGen and setting the power
|
95
100
|
ratio parameters.
|
96
101
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
Available:
|
102
|
-
|
103
|
-
https://docs.andes.app/en/latest/groupdoc/RenGen.html#rengen
|
102
|
+
References
|
103
|
+
----------
|
104
|
+
1. ANDES Documentation, RenGen,
|
105
|
+
https://andes.readthedocs.io/en/stable/groupdoc/RenGen.html#rengen
|
104
106
|
"""
|
105
107
|
|
106
108
|
def __init__(self):
|
@@ -129,13 +131,10 @@ class DG(GroupBase):
|
|
129
131
|
See ANDES Documentation SynGen here for the notes on replacing StaticGen and setting the power
|
130
132
|
ratio parameters.
|
131
133
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
Available:
|
137
|
-
|
138
|
-
https://docs.andes.app/en/latest/groupdoc/SynGen.html#syngen
|
134
|
+
References
|
135
|
+
----------
|
136
|
+
1. ANDES Documentation, SynGen,
|
137
|
+
https://andes.readthedocs.io/en/stable/groupdoc/SynGen.html#syngen
|
139
138
|
"""
|
140
139
|
|
141
140
|
def __init__(self):
|
@@ -182,7 +181,7 @@ class StaticGen(GroupBase):
|
|
182
181
|
Notes
|
183
182
|
-----
|
184
183
|
For co-simulation with ANDES, refer to the `ANDES StaticGen Documentation
|
185
|
-
<https://
|
184
|
+
<https://andes.readthedocs.io/en/stable/groupdoc/StaticGen.html#staticgen>`_ for
|
186
185
|
replacing static generators with dynamic generators.
|
187
186
|
"""
|
188
187
|
|
ams/models/renewable/regc.py
CHANGED
@@ -39,12 +39,10 @@ class REGCA1(REGCData, Model):
|
|
39
39
|
"""
|
40
40
|
Renewable generator scheduling model.
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
Available:
|
47
|
-
https://docs.andes.app/en/latest/groupdoc/RenGen.html#regca1
|
42
|
+
References
|
43
|
+
----------
|
44
|
+
1. ANDES Documentation, REGCA1,
|
45
|
+
https://andes.readthedocs.io/en/stable/groupdoc/RenGen.html#regca1
|
48
46
|
"""
|
49
47
|
|
50
48
|
def __init__(self, system=None, config=None) -> None:
|
@@ -56,7 +54,7 @@ class REGCA1(REGCData, Model):
|
|
56
54
|
class REGCV1(REGCData, Model):
|
57
55
|
"""
|
58
56
|
Voltage-controlled converter model (virtual synchronous generator) with
|
59
|
-
inertia emulation.
|
57
|
+
inertia emulation, for scheduling purposes.
|
60
58
|
|
61
59
|
Here Mmax and Dmax are assumed to be constant, but they might subject to
|
62
60
|
the operating condition of the converter.
|
@@ -67,13 +65,10 @@ class REGCV1(REGCData, Model):
|
|
67
65
|
- Generation cost is defined by model :ref:`GCost`
|
68
66
|
- Inertia emulation cost is defined by model :ref:`VSGCost`
|
69
67
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Available:
|
75
|
-
|
76
|
-
https://docs.andes.app/en/latest/groupdoc/RenGen.html#regcv1
|
68
|
+
References
|
69
|
+
----------
|
70
|
+
1. ANDES Documentation, REGCV1,
|
71
|
+
https://andes.readthedocs.io/en/stable/groupdoc/RenGen.html#regcv1
|
77
72
|
"""
|
78
73
|
|
79
74
|
def __init__(self, system=None, config=None) -> None:
|
@@ -100,15 +95,12 @@ class REGCV1(REGCData, Model):
|
|
100
95
|
|
101
96
|
class REGCV2(REGCV1):
|
102
97
|
"""
|
103
|
-
|
104
|
-
|
105
|
-
Reference:
|
106
|
-
|
107
|
-
[1] ANDES Documentation, REGCV2
|
108
|
-
|
109
|
-
Available:
|
98
|
+
Alias for REGCV1, for scheduling purposes.
|
110
99
|
|
111
|
-
|
100
|
+
References
|
101
|
+
----------
|
102
|
+
1. ANDES Documentation, REGCV2,
|
103
|
+
https://andes.readthedocs.io/en/stable/groupdoc/RenGen.html#regcv2
|
112
104
|
"""
|
113
105
|
|
114
106
|
def __init__(self, system=None, config=None) -> None:
|
ams/models/timeslot.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
Models for multi-period scheduling.
|
3
3
|
"""
|
4
4
|
|
5
5
|
from andes.core import ModelData, NumParam
|
@@ -10,12 +10,43 @@ from ams.core.model import Model
|
|
10
10
|
def str_list_oconv(x):
|
11
11
|
"""
|
12
12
|
Convert list into a list literal.
|
13
|
+
|
14
|
+
Revised from `andes.models.timeseries.str_list_oconv`, where
|
15
|
+
the output type is converted to a list of strings.
|
13
16
|
"""
|
14
17
|
# NOTE: convert elements to string from number first, then join them
|
15
18
|
str_x = [str(i) for i in x]
|
16
19
|
return ','.join(str_x)
|
17
20
|
|
18
21
|
|
22
|
+
class GCommit(ModelData, Model):
|
23
|
+
"""
|
24
|
+
UNDER DEVELOPMENT!
|
25
|
+
Time slot model for generator commitment decisions.
|
26
|
+
|
27
|
+
This class holds commitment decisions for generators,
|
28
|
+
and should be used in multi-period scheduling routines that need
|
29
|
+
generator commitment decisions.
|
30
|
+
|
31
|
+
For example, in Unit Commitment (UC) problems, there is a variable
|
32
|
+
`ugd` representing the unit commitment decisions for each generator.
|
33
|
+
After solving the UC problem, the `ugd` values can be used for
|
34
|
+
Economic Dispatch (ED) as a parameter.
|
35
|
+
"""
|
36
|
+
|
37
|
+
# TODO: .. versionadded:: 1.0.13
|
38
|
+
def __init__(self, system=None, config=None):
|
39
|
+
ModelData.__init__(self)
|
40
|
+
Model.__init__(self, system, config)
|
41
|
+
|
42
|
+
# TODO: add IdxParam of generator
|
43
|
+
self.ug = NumParam(info='unit commitment decisions',
|
44
|
+
tex_name=r'u_{g}',
|
45
|
+
iconvert=str_list_iconv,
|
46
|
+
oconvert=str_list_oconv,
|
47
|
+
vtype=int)
|
48
|
+
|
49
|
+
|
19
50
|
class TimeSlot(ModelData, Model):
|
20
51
|
"""
|
21
52
|
Base model for time slot data used in multi-interval scheduling.
|
@@ -44,6 +75,13 @@ class EDTSlot(TimeSlot):
|
|
44
75
|
`ug` is the unit commitment decisions.
|
45
76
|
Cells in `ug` should have `ng` values seperated by comma,
|
46
77
|
where `ng` is the number of `StaticGen` in the system.
|
78
|
+
|
79
|
+
Warnings
|
80
|
+
--------
|
81
|
+
The order of generators in `ug` is determined by the input
|
82
|
+
file, not by explicit mapping. This may cause misinterpretation
|
83
|
+
if the loaded data order changes.
|
84
|
+
Involved routines include: `ED` `UC` and their derivatives.
|
47
85
|
"""
|
48
86
|
|
49
87
|
def __init__(self, system=None, config=None):
|
@@ -63,6 +101,13 @@ class UCTSlot(TimeSlot):
|
|
63
101
|
`sd` is the zonal load scaling factor.
|
64
102
|
Cells in `sd` should have `nz` values seperated by comma,
|
65
103
|
where `nz` is the number of `Zone` in the system.
|
104
|
+
|
105
|
+
Warnings
|
106
|
+
--------
|
107
|
+
The order of generators in `ug` is determined by the input
|
108
|
+
file, not by explicit mapping. This may cause misinterpretation
|
109
|
+
if the loaded data order changes.
|
110
|
+
Involved routines include: `ED` `UC` and their derivatives.
|
66
111
|
"""
|
67
112
|
|
68
113
|
def __init__(self, system=None, config=None):
|
ams/models/zone.py
CHANGED
@@ -17,9 +17,8 @@ class Zone(ModelData, Model):
|
|
17
17
|
|
18
18
|
Notes
|
19
19
|
-----
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
- A zone is a collection of buses.
|
21
|
+
- The ``Zone`` model is not defined in ANDES up to version 1.9.3.
|
23
22
|
"""
|
24
23
|
|
25
24
|
def __init__(self, system, config):
|
@@ -39,7 +38,6 @@ class Zone(ModelData, Model):
|
|
39
38
|
-------
|
40
39
|
str
|
41
40
|
Formatted table
|
42
|
-
|
43
41
|
"""
|
44
42
|
if self.n:
|
45
43
|
header = ['Zone ID', 'Bus ID']
|
ams/opt/exprcalc.py
CHANGED
@@ -24,9 +24,11 @@ class ExpressionCalc(OptzBase):
|
|
24
24
|
"""
|
25
25
|
Class for calculating expressions.
|
26
26
|
|
27
|
-
|
28
|
-
in the optimization model.
|
29
|
-
|
27
|
+
This class is useful for performing post-solve calculations, but it does not
|
28
|
+
participate in the optimization model itself.
|
29
|
+
|
30
|
+
Note: `ExpressionCalc` is not a CVXPY expression and should NOT be referenced
|
31
|
+
in `e_str` by any other components, including other instances of `ExpressionCalc`.
|
30
32
|
"""
|
31
33
|
|
32
34
|
def __init__(self,
|
ams/opt/optzbase.py
CHANGED
@@ -174,13 +174,14 @@ class OptzBase:
|
|
174
174
|
"""
|
175
175
|
Return all the indexes of this item.
|
176
176
|
|
177
|
-
.. note::
|
178
|
-
New in version 1.0.0.
|
179
|
-
|
180
177
|
Returns
|
181
178
|
-------
|
182
179
|
list
|
183
180
|
A list of indexes.
|
181
|
+
|
182
|
+
Notes
|
183
|
+
-----
|
184
|
+
.. versionadded:: 1.0.0
|
184
185
|
"""
|
185
186
|
|
186
187
|
if self.is_group:
|
ams/report.py
CHANGED
@@ -30,13 +30,8 @@ def report_info(system) -> list:
|
|
30
30
|
|
31
31
|
class Report:
|
32
32
|
"""
|
33
|
-
Report class to store routine analysis reports
|
34
|
-
|
35
|
-
Notes
|
36
|
-
-----
|
37
|
-
Revised from the ANDES project (https://github.com/CURENT/andes).
|
38
|
-
Original author: Hantao Cui
|
39
|
-
License: GPL3
|
33
|
+
Report class to store routine analysis reports,
|
34
|
+
revised from `andes.report.Report`.
|
40
35
|
"""
|
41
36
|
|
42
37
|
def __init__(self, system):
|
ams/routines/dcopf.py
CHANGED
@@ -17,19 +17,22 @@ logger = logging.getLogger(__name__)
|
|
17
17
|
|
18
18
|
class DCOPF(DCPFBase):
|
19
19
|
"""
|
20
|
-
DC optimal power flow (DCOPF).
|
20
|
+
DC optimal power flow (DCOPF) using B-theta formulation.
|
21
21
|
|
22
22
|
Notes
|
23
23
|
-----
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
- The nodal price is calculated as ``pi`` in ``pic``.
|
25
|
+
- Devices online status of ``StaticGen``, ``StaticLoad``, and ``Shunt`` are considered in the connectivity
|
26
|
+
matrices ``Cft``, ``Cg``, ``Cl``, and ``Csh``.
|
27
27
|
|
28
28
|
References
|
29
29
|
----------
|
30
30
|
1. R. D. Zimmerman, C. E. Murillo-Sanchez, and R. J. Thomas, “MATPOWER: Steady-State
|
31
31
|
Operations, Planning, and Analysis Tools for Power Systems Research and Education,” IEEE
|
32
32
|
Trans. Power Syst., vol. 26, no. 1, pp. 12-19, Feb. 2011
|
33
|
+
2. Y. Chen et al., "Security-Constrained Unit Commitment for Electricity Market: Modeling,
|
34
|
+
Solution Methods, and Future Challenges," in IEEE Transactions on Power Systems, vol. 38, no. 5,
|
35
|
+
pp. 4668-4681, Sept. 2023
|
33
36
|
"""
|
34
37
|
|
35
38
|
def __init__(self, system, config):
|
ams/routines/dcopf2.py
CHANGED
@@ -18,15 +18,35 @@ logger = logging.getLogger(__name__)
|
|
18
18
|
|
19
19
|
class DCOPF2(DCOPF):
|
20
20
|
"""
|
21
|
-
DC optimal power flow (DCOPF) using PTDF.
|
21
|
+
DC optimal power flow (DCOPF) using PTDF formulation.
|
22
|
+
|
22
23
|
For large cases, it is recommended to build the PTDF first, especially when incremental
|
23
24
|
build is necessary.
|
24
25
|
|
25
26
|
Notes
|
26
27
|
-----
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
- This routine requires PTDF matrix.
|
29
|
+
- LMP ``pi`` is calculated with two parts, energy price and congestion price.
|
30
|
+
- Bus angle ``aBus`` is calculated after solving the problem.
|
31
|
+
- In export results, ``pi`` and ``pic`` are kept for each bus, while ``pie``
|
32
|
+
can be restored manually by ``pie = pi - pic`` if needed.
|
33
|
+
|
34
|
+
Warning
|
35
|
+
-------
|
36
|
+
In this implementation, the dual variables for constraints have opposite signs compared
|
37
|
+
to the mathematical formulation: 1. The dual of `pb` returns a negative value, so energy
|
38
|
+
price is computed as `-pb.dual_variables[0]`. 2. Similarly, a minus sign is applied to
|
39
|
+
the duals of `plfub` and `plflb` when calculating congestion price. The reason for this
|
40
|
+
sign difference is not yet fully understood.
|
41
|
+
|
42
|
+
References
|
43
|
+
----------
|
44
|
+
1. R. D. Zimmerman, C. E. Murillo-Sanchez, and R. J. Thomas, “MATPOWER: Steady-State
|
45
|
+
Operations, Planning, and Analysis Tools for Power Systems Research and Education,” IEEE
|
46
|
+
Trans. Power Syst., vol. 26, no. 1, pp. 12-19, Feb. 2011
|
47
|
+
2. Y. Chen et al., "Security-Constrained Unit Commitment for Electricity Market: Modeling,
|
48
|
+
Solution Methods, and Future Challenges," in IEEE Transactions on Power Systems, vol. 38, no. 5,
|
49
|
+
pp. 4668-4681, Sept. 2023
|
30
50
|
"""
|
31
51
|
|
32
52
|
def __init__(self, system, config):
|
@@ -51,29 +71,34 @@ class DCOPF2(DCOPF):
|
|
51
71
|
name='PTDF', tex_name=r'P_{TDF}',
|
52
72
|
model='mats', src='PTDF',
|
53
73
|
no_parse=True, sparse=True)
|
74
|
+
self.PTDFt = NumOp(u=self.PTDF,
|
75
|
+
name='PTDFt', tex_name=r'P_{TDF}^T',
|
76
|
+
info='PTDF transpose',
|
77
|
+
fun=np.transpose, no_parse=True)
|
78
|
+
|
79
|
+
# --- rewrite Constraint pb: power balance ---
|
80
|
+
self.pb.e_str = 'sum(pg) - sum(pd)'
|
54
81
|
|
55
82
|
# --- rewrite Expression plf: line flow---
|
56
83
|
self.plf.e_str = 'PTDF @ (Cg@pg - Cl@pd - Csh@gsh - Pbusinj)'
|
57
84
|
|
58
85
|
# --- rewrite nodal price ---
|
59
|
-
self.
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
self.
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
model='Bus', src=None,
|
74
|
-
e_str='pb.dual_variables[0]')
|
75
|
-
pi = 'pb.dual_variables[0] + Cft@(plfub.dual_variables[0] - plflb.dual_variables[0])'
|
86
|
+
self.pie = ExpressionCalc(info='Energy price',
|
87
|
+
name='pie', unit='$/p.u.',
|
88
|
+
e_str='-pb.dual_variables[0]')
|
89
|
+
pic = '-PTDFt@(plfub.dual_variables[0] - plflb.dual_variables[0])'
|
90
|
+
self.pic = ExpressionCalc(info='Congestion price',
|
91
|
+
name='pic', unit='$/p.u.',
|
92
|
+
e_str=pic,
|
93
|
+
model='Bus', src=None)
|
94
|
+
|
95
|
+
# NOTE: another implementation of self.pi.e_str can be:
|
96
|
+
# self.pi.e_str = self.pie.e_str + self.pic.e_str
|
97
|
+
# but it is less intuitive to read, as this implementation is not likely
|
98
|
+
# to be used again in other routines.
|
99
|
+
pi = '-pb.dual_variables[0] - PTDFt@(plfub.dual_variables[0] - plflb.dual_variables[0])'
|
76
100
|
self.pi.e_str = pi
|
101
|
+
self.pi.info = 'locational marginal price (LMP)'
|
77
102
|
|
78
103
|
def _post_solve(self):
|
79
104
|
"""Calculate aBus"""
|
ams/routines/dcpf.py
CHANGED
@@ -3,6 +3,8 @@ Power flow routines.
|
|
3
3
|
"""
|
4
4
|
import logging
|
5
5
|
|
6
|
+
import numpy as np
|
7
|
+
|
6
8
|
from ams.opt import Var, Constraint, Expression, Objective
|
7
9
|
from ams.routines.routine import RoutineBase
|
8
10
|
|
@@ -173,6 +175,9 @@ class DCPFBase(RoutineBase):
|
|
173
175
|
"""
|
174
176
|
Post-solve calculations.
|
175
177
|
"""
|
178
|
+
# NOTE: for DC type routines, set vBus to 1.0 p.u. as placeholder
|
179
|
+
self.vBus.v = np.ones(self.vBus.shape)
|
180
|
+
|
176
181
|
# NOTE: unpack Expressions if owner and arc are available
|
177
182
|
for expr in self.exprs.values():
|
178
183
|
if expr.owner and expr.src:
|
ams/routines/dopf.py
CHANGED
@@ -17,7 +17,7 @@ class DOPF(DCOPF):
|
|
17
17
|
UNDER DEVELOPMENT!
|
18
18
|
|
19
19
|
References
|
20
|
-
|
20
|
+
----------
|
21
21
|
1. L. Bai, J. Wang, C. Wang, C. Chen, and F. Li, “Distribution Locational Marginal Pricing (DLMP)
|
22
22
|
for Congestion Management and Voltage Support,” IEEE Trans. Power Syst., vol. 33, no. 4,
|
23
23
|
pp. 4061-4073, Jul. 2018, doi: 10.1109/TPWRS.2017.2767632.
|
@@ -116,7 +116,7 @@ class DOPFVIS(DOPF):
|
|
116
116
|
UNDER DEVELOPMENT!
|
117
117
|
|
118
118
|
References
|
119
|
-
|
119
|
+
----------
|
120
120
|
1. L. Bai, J. Wang, C. Wang, C. Chen, and F. Li, “Distribution Locational Marginal Pricing (DLMP)
|
121
121
|
for Congestion Management and Voltage Support,” IEEE Trans. Power Syst., vol. 33, no. 4,
|
122
122
|
pp. 4061-4073, Jul. 2018, doi: 10.1109/TPWRS.2017.2767632.
|
ams/routines/ed.py
CHANGED
@@ -120,11 +120,11 @@ class ED(RTED, MPBase, SRBase):
|
|
120
120
|
|
121
121
|
Notes
|
122
122
|
-----
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
123
|
+
- Formulations has been adjusted with interval ``config.t``
|
124
|
+
- The tie-line flow is not implemented in this model.
|
125
|
+
- ``EDTSlot.ug`` is used instead of ``StaticGen.u`` for generator commitment.
|
126
|
+
- Following reserves are balanced for each "Area": RegUp reserve ``rbu``,
|
127
|
+
RegDn reserve ``rbd``, and Spinning reserve ``rsr``.
|
128
128
|
"""
|
129
129
|
|
130
130
|
def __init__(self, system, config):
|
ams/routines/pflow.py
CHANGED
@@ -30,7 +30,7 @@ class PFlow(RoutineBase):
|
|
30
30
|
----------
|
31
31
|
1. M. L. Crow, Computational methods for electric power systems. 2015.
|
32
32
|
2. ANDES Documentation - Simulation and Plot.
|
33
|
-
https://
|
33
|
+
https://andes.readthedocs.io/en/stable/_examples/ex1.html
|
34
34
|
"""
|
35
35
|
|
36
36
|
def __init__(self, system, config):
|
ams/routines/routine.py
CHANGED
@@ -21,7 +21,7 @@ from ams.opt import Param, Var, Constraint, Objective, ExpressionCalc, Expressio
|
|
21
21
|
|
22
22
|
from ams.utils.paths import get_export_path
|
23
23
|
|
24
|
-
from ams.shared import pd
|
24
|
+
from ams.shared import pd, summary_row, summary_name
|
25
25
|
|
26
26
|
logger = logging.getLogger(__name__)
|
27
27
|
|
@@ -445,6 +445,8 @@ class RoutineBase:
|
|
445
445
|
-------
|
446
446
|
bool
|
447
447
|
True if the loading is successful, False otherwise.
|
448
|
+
|
449
|
+
.. versionadded:: 1.0.13
|
448
450
|
"""
|
449
451
|
try:
|
450
452
|
with open(path, 'r') as f:
|
@@ -496,15 +498,26 @@ class RoutineBase:
|
|
496
498
|
-------
|
497
499
|
str
|
498
500
|
The exported json file name
|
501
|
+
|
502
|
+
.. versionadded:: 1.0.13
|
499
503
|
"""
|
500
504
|
if not self.converged:
|
501
505
|
logger.warning("Routine did not converge, aborting export.")
|
502
506
|
return None
|
503
507
|
|
504
|
-
path, file_name = get_export_path(self.system,
|
508
|
+
path, file_name = get_export_path(self.system,
|
509
|
+
self.class_name + '_out',
|
505
510
|
path=path, fmt='json')
|
506
511
|
|
507
|
-
data_dict =
|
512
|
+
data_dict = OrderedDict()
|
513
|
+
|
514
|
+
# insert summary
|
515
|
+
df = pd.DataFrame([summary_row])
|
516
|
+
df.index.name = "uid"
|
517
|
+
data_dict.update({summary_name: df.to_dict(orient='records')})
|
518
|
+
|
519
|
+
# insert objective value
|
520
|
+
data_dict.update(OrderedDict(Objective=self.obj.v))
|
508
521
|
|
509
522
|
group_data(self, data_dict, self.vars, 'v')
|
510
523
|
group_data(self, data_dict, self.exprs, 'v')
|
@@ -1111,7 +1124,8 @@ def collect_data(rtn: RoutineBase, data_dict: Dict, items: Dict, attr: str):
|
|
1111
1124
|
|
1112
1125
|
def group_data(rtn: RoutineBase, data_dict: Dict, items: Dict, attr: str):
|
1113
1126
|
"""
|
1114
|
-
Collect data for export
|
1127
|
+
Collect data for export by groups, adding device idx in each group.
|
1128
|
+
This is useful when exporting to dictionary formats like JSON.
|
1115
1129
|
|
1116
1130
|
Parameters
|
1117
1131
|
----------
|
@@ -1123,6 +1137,8 @@ def group_data(rtn: RoutineBase, data_dict: Dict, items: Dict, attr: str):
|
|
1123
1137
|
Dictionary of items to collect data from.
|
1124
1138
|
attr : str
|
1125
1139
|
Attribute to collect data for.
|
1140
|
+
|
1141
|
+
.. versionadded:: 1.0.13
|
1126
1142
|
"""
|
1127
1143
|
for key, item in items.items():
|
1128
1144
|
if item.owner is None:
|
ams/routines/rted.py
CHANGED
@@ -125,10 +125,10 @@ class RTED(DCOPF, RTEDBase, SFRBase):
|
|
125
125
|
|
126
126
|
Notes
|
127
127
|
-----
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
128
|
+
- Formulations has been adjusted with interval ``config.t``, 5/60 [Hour] by default.
|
129
|
+
- The tie-line flow related constraints are ommited in this formulation.
|
130
|
+
- Power generation is balanced for the entire system.
|
131
|
+
- SFR is balanced for each area.
|
132
132
|
"""
|
133
133
|
|
134
134
|
def __init__(self, system, config):
|
@@ -487,7 +487,7 @@ class RTEDVIS(RTED, VISBase):
|
|
487
487
|
Please ensure that the parameters `dvm` and `dvd` are set according to the system base.
|
488
488
|
|
489
489
|
References
|
490
|
-
|
490
|
+
----------
|
491
491
|
1. B. She, F. Li, H. Cui, J. Wang, Q. Zhang and R. Bo, "Virtual Inertia Scheduling (VIS) for
|
492
492
|
Real-Time Economic Dispatch of IBR-Penetrated Power Systems," in IEEE Transactions on
|
493
493
|
Sustainable Energy, vol. 15, no. 2, pp. 938-951, April 2024, doi: 10.1109/TSTE.2023.3319307.
|
ams/routines/uc.py
CHANGED
@@ -69,8 +69,8 @@ class UC(DCOPF, RTEDBase, MPBase, SRBase, NSRBase):
|
|
69
69
|
|
70
70
|
Notes
|
71
71
|
-----
|
72
|
-
|
73
|
-
|
72
|
+
- The formulations has been adjusted with interval ``config.t``
|
73
|
+
- The tie-line flow has not been implemented in formulations.
|
74
74
|
|
75
75
|
References
|
76
76
|
----------
|