ltbams 1.0.10__py3-none-any.whl → 1.0.12__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/core/documenter.py +130 -62
- ams/core/matprocessor.py +13 -14
- ams/interface.py +2 -2
- ams/io/matpower.py +51 -20
- ams/io/psse.py +2 -0
- ams/routines/grbopt.py +14 -9
- ams/routines/pypower.py +20 -20
- ams/routines/routine.py +9 -14
- ams/system.py +43 -5
- ams/utils/paths.py +67 -3
- docs/source/examples/index.rst +2 -1
- docs/source/genroutineref.py +1 -1
- docs/source/release-notes.rst +35 -22
- {ltbams-1.0.10.dist-info → ltbams-1.0.12.dist-info}/METADATA +7 -10
- {ltbams-1.0.10.dist-info → ltbams-1.0.12.dist-info}/RECORD +23 -23
- {ltbams-1.0.10.dist-info → ltbams-1.0.12.dist-info}/WHEEL +1 -1
- tests/test_1st_system.py +1 -1
- tests/test_io.py +10 -0
- tests/test_paths.py +68 -1
- tests/test_rtn_dcopf.py +20 -0
- {ltbams-1.0.10.dist-info → ltbams-1.0.12.dist-info}/entry_points.txt +0 -0
- {ltbams-1.0.10.dist-info → ltbams-1.0.12.dist-info}/top_level.txt +0 -0
ams/routines/pypower.py
CHANGED
@@ -131,6 +131,15 @@ class DCPF1(RoutineBase):
|
|
131
131
|
unit='p.u.',
|
132
132
|
name='vBus', tex_name=r'v_{Bus}',
|
133
133
|
src='v', model='Bus',)
|
134
|
+
# --- load ---
|
135
|
+
self.pd = RParam(info='active demand',
|
136
|
+
name='pd', tex_name=r'p_{d}',
|
137
|
+
model='StaticLoad', src='p0',
|
138
|
+
unit='p.u.',)
|
139
|
+
self.qd = RParam(info='reactive demand',
|
140
|
+
name='qd', tex_name=r'q_{d}',
|
141
|
+
model='StaticLoad', src='q0',
|
142
|
+
unit='p.u.',)
|
134
143
|
# --- gen ---
|
135
144
|
self.pg = Var(info='Gen active power',
|
136
145
|
unit='p.u.',
|
@@ -147,8 +156,8 @@ class DCPF1(RoutineBase):
|
|
147
156
|
model='Line',)
|
148
157
|
# --- objective ---
|
149
158
|
self.obj = Objective(name='obj',
|
150
|
-
info='total cost',
|
151
|
-
e_str='0',
|
159
|
+
info='total cost, placeholder',
|
160
|
+
e_str='0', unit='$',
|
152
161
|
sense='min',)
|
153
162
|
|
154
163
|
# --- total cost ---
|
@@ -267,13 +276,13 @@ class DCPF1(RoutineBase):
|
|
267
276
|
return False
|
268
277
|
|
269
278
|
def _get_off_constrs(self):
|
270
|
-
|
279
|
+
logger.debug(f"{self.class_name} does not implement _get_off_constrs.")
|
271
280
|
|
272
281
|
def _data_check(self, info=True, **kwargs):
|
273
|
-
|
282
|
+
logger.debug(f"{self.class_name} does not implement _data_check.")
|
274
283
|
|
275
284
|
def update(self, params=None, build_mats=False, **kwargs):
|
276
|
-
|
285
|
+
logger.debug(f"{self.class_name} does not implement update.")
|
277
286
|
|
278
287
|
def enable(self, name):
|
279
288
|
raise NotImplementedError
|
@@ -282,7 +291,7 @@ class DCPF1(RoutineBase):
|
|
282
291
|
raise NotImplementedError
|
283
292
|
|
284
293
|
def _post_add_check(self):
|
285
|
-
|
294
|
+
logger.debug(f"{self.class_name} does not implement _post_add_check.")
|
286
295
|
|
287
296
|
def addRParam(self,
|
288
297
|
name: str,
|
@@ -346,16 +355,13 @@ class PFlow1(DCPF1):
|
|
346
355
|
It leverages PYPOWER's internal power flow solver and maps results back to the
|
347
356
|
AMS system.
|
348
357
|
|
349
|
-
Known Issues
|
350
|
-
------------
|
351
|
-
- Fast-Decoupled (XB version) and Fast-Decoupled (BX version) algorithms are
|
352
|
-
not fully supported yet.
|
353
|
-
|
354
358
|
Notes
|
355
359
|
-----
|
356
360
|
- This class does not implement the AMS-style power flow formulation.
|
357
361
|
- For detailed mathematical formulations and algorithmic details, refer to the
|
358
362
|
MATPOWER User's Manual, section on Power Flow.
|
363
|
+
- Fast-Decoupled (XB version) and Fast-Decoupled (BX version) algorithms are
|
364
|
+
not fully supported yet.
|
359
365
|
"""
|
360
366
|
|
361
367
|
def __init__(self, system, config):
|
@@ -380,7 +386,7 @@ class PFlow1(DCPF1):
|
|
380
386
|
pf_max_it="maximum number of iterations for Newton's method",
|
381
387
|
pf_max_it_fd="maximum number of iterations for fast decoupled method",
|
382
388
|
pf_max_it_gs="maximum number of iterations for Gauss-Seidel method",
|
383
|
-
enforce_q_lims="enforce gen reactive power limits, at expense of
|
389
|
+
enforce_q_lims="enforce gen reactive power limits, at expense of V magnitude",
|
384
390
|
)
|
385
391
|
self.config.add_extra("_alt",
|
386
392
|
pf_alg=(1, 2, 3, 4),
|
@@ -424,15 +430,12 @@ class DCOPF1(DCPF1):
|
|
424
430
|
function) is always included in the objective, regardless of the generator's
|
425
431
|
commitment status. See `pypower/opf_costfcn.py` for implementation details.
|
426
432
|
|
427
|
-
Known Issues
|
428
|
-
------------
|
429
|
-
- Algorithms 400, 500, 600, and 700 are not fully supported yet.
|
430
|
-
|
431
433
|
Notes
|
432
434
|
-----
|
433
435
|
- This class does not implement the AMS-style DC optimal power flow formulation.
|
434
436
|
- For detailed mathematical formulations and algorithmic details, refer to the
|
435
437
|
MATPOWER User's Manual, section on Optimal Power Flow.
|
438
|
+
- Algorithms 400, 500, 600, and 700 are not fully supported yet.
|
436
439
|
"""
|
437
440
|
|
438
441
|
def __init__(self, system, config):
|
@@ -522,10 +525,7 @@ class DCOPF1(DCPF1):
|
|
522
525
|
scpdipm_red_it=r'o_{scpdipm\_red\_it}',
|
523
526
|
)
|
524
527
|
|
525
|
-
self.obj =
|
526
|
-
info='total cost, placeholder',
|
527
|
-
e_str='sum(c2 * pg**2 + c1 * pg + c0)',
|
528
|
-
sense='min',)
|
528
|
+
self.obj.e_str = 'sum(c2 * pg**2 + c1 * pg + c0)'
|
529
529
|
|
530
530
|
self.pi = Var(info='Lagrange multiplier on real power mismatch',
|
531
531
|
name='pi', unit='$/p.u.',
|
ams/routines/routine.py
CHANGED
@@ -3,7 +3,6 @@ Module for routine data.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import logging
|
6
|
-
import os
|
7
6
|
from typing import Optional, Union, Type, Iterable, Dict
|
8
7
|
from collections import OrderedDict
|
9
8
|
|
@@ -19,6 +18,8 @@ from ams.core.service import RBaseService, ValueService
|
|
19
18
|
from ams.opt import OModel
|
20
19
|
from ams.opt import Param, Var, Constraint, Objective, ExpressionCalc, Expression
|
21
20
|
|
21
|
+
from ams.utils.paths import get_export_path
|
22
|
+
|
22
23
|
from ams.shared import pd
|
23
24
|
|
24
25
|
logger = logging.getLogger(__name__)
|
@@ -441,26 +442,20 @@ class RoutineBase:
|
|
441
442
|
|
442
443
|
Parameters
|
443
444
|
----------
|
444
|
-
path : str
|
445
|
-
|
445
|
+
path : str, optional
|
446
|
+
Path of the csv file to export.
|
446
447
|
|
447
448
|
Returns
|
448
449
|
-------
|
449
|
-
|
450
|
-
The
|
450
|
+
str
|
451
|
+
The exported csv file name
|
451
452
|
"""
|
452
453
|
if not self.converged:
|
453
454
|
logger.warning("Routine did not converge, aborting export.")
|
454
455
|
return None
|
455
456
|
|
456
|
-
|
457
|
-
|
458
|
-
logger.info("Input file name not detacted. Using `Untitled`.")
|
459
|
-
file_name = f'Untitled_{self.class_name}'
|
460
|
-
else:
|
461
|
-
file_name = os.path.splitext(self.system.files.fullname)[0]
|
462
|
-
file_name += f'_{self.class_name}'
|
463
|
-
path = os.path.join(os.getcwd(), file_name + '.csv')
|
457
|
+
path, file_name = get_export_path(self.system, self.class_name,
|
458
|
+
path=path, fmt='csv')
|
464
459
|
|
465
460
|
data_dict = initialize_data_dict(self)
|
466
461
|
|
@@ -473,7 +468,7 @@ class RoutineBase:
|
|
473
468
|
|
474
469
|
pd.DataFrame(data_dict).to_csv(path, index=False)
|
475
470
|
|
476
|
-
return file_name
|
471
|
+
return file_name
|
477
472
|
|
478
473
|
def summary(self, **kwargs):
|
479
474
|
"""
|
ams/system.py
CHANGED
@@ -9,7 +9,7 @@ from typing import Dict, Optional
|
|
9
9
|
|
10
10
|
import numpy as np
|
11
11
|
|
12
|
-
from andes.system import System as
|
12
|
+
from andes.system import System as adSystem
|
13
13
|
from andes.system import (_config_numpy, load_config_rc)
|
14
14
|
from andes.variables import FileMan
|
15
15
|
|
@@ -29,7 +29,7 @@ from ams.report import Report
|
|
29
29
|
from ams.shared import ad_dyn_models
|
30
30
|
|
31
31
|
from ams.io.matpower import system2mpc
|
32
|
-
from ams.io.matpower import write as
|
32
|
+
from ams.io.matpower import write as write_m
|
33
33
|
from ams.io.xlsx import write as write_xlsx
|
34
34
|
from ams.io.json import write as write_json
|
35
35
|
from ams.io.psse import write_raw
|
@@ -49,7 +49,7 @@ def disable_methods(methods):
|
|
49
49
|
setattr(System, method, disable_method(getattr(System, method)))
|
50
50
|
|
51
51
|
|
52
|
-
class System(
|
52
|
+
class System(adSystem):
|
53
53
|
"""
|
54
54
|
A subclass of ``andes.system.System``, this class encapsulates data, models,
|
55
55
|
and routines for scheduling modeling and analysis in power systems.
|
@@ -602,6 +602,7 @@ class System(andes_System):
|
|
602
602
|
**kwargs):
|
603
603
|
"""
|
604
604
|
Convert the AMS system to an ANDES system.
|
605
|
+
Wrapper method for `ams.interface.to_andes`.
|
605
606
|
|
606
607
|
A preferred dynamic system file to be added has following features:
|
607
608
|
1. The file contains both power flow and dynamic models.
|
@@ -718,17 +719,34 @@ class System(andes_System):
|
|
718
719
|
def to_mpc(self):
|
719
720
|
"""
|
720
721
|
Export an AMS system to a MATPOWER dict.
|
722
|
+
Wrapper method for `ams.io.matpower.system2mpc`.
|
721
723
|
|
722
724
|
Returns
|
723
725
|
-------
|
724
726
|
dict
|
725
727
|
A dictionary representing the MATPOWER case.
|
728
|
+
|
729
|
+
Notes
|
730
|
+
-----
|
731
|
+
- In the `gen` section, slack generators are listed before PV generators.
|
732
|
+
- For uncontrolled generators (`ctrl.v == 0`), their max and min power
|
733
|
+
limits are set to their initial power (`p0.v`) in the converted MPC.
|
734
|
+
- In the converted MPC, the indices of area (`bus[:, 6]`) and zone (`bus[:, 10]`)
|
735
|
+
may differ from the original MPC. However, the mapping relationship is preserved.
|
736
|
+
For example, if the original MPC numbers areas starting from 1, the converted
|
737
|
+
MPC may number them starting from 0.
|
738
|
+
- The coefficients `c2` and `c1` in the generator cost data are scaled by
|
739
|
+
`baseMVA`.
|
740
|
+
- Unlike the XLSX and JSON converters, this implementation uses value providers
|
741
|
+
(`v`) instead of vin. As a result, any changes made through `model.set` will be
|
742
|
+
reflected in the generated MPC.
|
726
743
|
"""
|
727
744
|
return system2mpc(self)
|
728
745
|
|
729
746
|
def to_m(self, outfile: str, overwrite: bool = None):
|
730
747
|
"""
|
731
748
|
Export an AMS system to a MATPOWER M-file.
|
749
|
+
Wrapper method for `ams.io.matpower.write`.
|
732
750
|
|
733
751
|
Parameters
|
734
752
|
----------
|
@@ -736,12 +754,28 @@ class System(andes_System):
|
|
736
754
|
The output file name.
|
737
755
|
overwrite : bool, optional
|
738
756
|
If True, overwrite the existing file. Default is None.
|
739
|
-
|
740
|
-
|
757
|
+
|
758
|
+
Notes
|
759
|
+
-----
|
760
|
+
- In the `gen` section, slack generators are listed before PV generators.
|
761
|
+
- For uncontrolled generators (`ctrl.v == 0`), their max and min power
|
762
|
+
limits are set to their initial power (`p0.v`) in the converted MPC.
|
763
|
+
- In the converted MPC, the indices of area (`bus[:, 6]`) and zone (`bus[:, 10]`)
|
764
|
+
may differ from the original MPC. However, the mapping relationship is preserved.
|
765
|
+
For example, if the original MPC numbers areas starting from 1, the converted
|
766
|
+
MPC may number them starting from 0.
|
767
|
+
- The coefficients `c2` and `c1` in the generator cost data are scaled by
|
768
|
+
`baseMVA`.
|
769
|
+
- Unlike the XLSX and JSON converters, this implementation uses value providers
|
770
|
+
(`v`) instead of vin. As a result, any changes made through `model.set` will be
|
771
|
+
reflected in the generated MPC.
|
772
|
+
"""
|
773
|
+
return write_m(self, outfile=outfile, overwrite=overwrite)
|
741
774
|
|
742
775
|
def to_xlsx(self, outfile: str, overwrite: bool = None):
|
743
776
|
"""
|
744
777
|
Export an AMS system to an Excel file.
|
778
|
+
Wrapper method for `ams.io.xlsx.write`.
|
745
779
|
|
746
780
|
Parameters
|
747
781
|
----------
|
@@ -755,6 +789,7 @@ class System(andes_System):
|
|
755
789
|
def to_json(self, outfile: str, overwrite: bool = None):
|
756
790
|
"""
|
757
791
|
Export an AMS system to a JSON file.
|
792
|
+
Wrapper method for `ams.io.json.write`.
|
758
793
|
|
759
794
|
Parameters
|
760
795
|
----------
|
@@ -768,6 +803,9 @@ class System(andes_System):
|
|
768
803
|
def to_raw(self, outfile: str, overwrite: bool = None):
|
769
804
|
"""
|
770
805
|
Export an AMS system to a v33 PSS/E RAW file.
|
806
|
+
Wrapper method for `ams.io.psse.write_raw`.
|
807
|
+
|
808
|
+
This method has not been fully benchmarked yet!
|
771
809
|
|
772
810
|
Parameters
|
773
811
|
----------
|
ams/utils/paths.py
CHANGED
@@ -184,7 +184,7 @@ def get_pycode_path(pycode_path=None, mkdir=False):
|
|
184
184
|
"""
|
185
185
|
|
186
186
|
if pycode_path is None:
|
187
|
-
pycode_path = os.path.join(
|
187
|
+
pycode_path = os.path.join(get_dot_ams_path(), 'pycode')
|
188
188
|
|
189
189
|
if mkdir is True:
|
190
190
|
os.makedirs(pycode_path, exist_ok=True)
|
@@ -203,7 +203,7 @@ def get_pkl_path():
|
|
203
203
|
|
204
204
|
"""
|
205
205
|
pkl_name = 'calls.pkl'
|
206
|
-
ams_path =
|
206
|
+
ams_path = get_dot_ams_path()
|
207
207
|
|
208
208
|
if not os.path.exists(ams_path):
|
209
209
|
os.makedirs(ams_path)
|
@@ -213,7 +213,7 @@ def get_pkl_path():
|
|
213
213
|
return pkl_path
|
214
214
|
|
215
215
|
|
216
|
-
def
|
216
|
+
def get_dot_ams_path():
|
217
217
|
"""
|
218
218
|
Return the path to ``$HOME/.ams``
|
219
219
|
"""
|
@@ -255,3 +255,67 @@ def confirm_overwrite(outfile, overwrite=None):
|
|
255
255
|
pass
|
256
256
|
|
257
257
|
return True
|
258
|
+
|
259
|
+
|
260
|
+
def get_export_path(system, fname, path=None, fmt='csv'):
|
261
|
+
"""
|
262
|
+
Get the absolute export path and the derived file name for
|
263
|
+
an AMS system export.
|
264
|
+
|
265
|
+
This function is not intended to be used directly by users.
|
266
|
+
|
267
|
+
Parameters
|
268
|
+
----------
|
269
|
+
system : ams.system.System
|
270
|
+
The AMS system to export. (Mocked in example)
|
271
|
+
fname : str
|
272
|
+
The descriptive file name, e.g., 'PTDF', or 'DCOPF'.
|
273
|
+
path : str, optional
|
274
|
+
The desired output path.
|
275
|
+
- If it's a directory, the file name will be generated.
|
276
|
+
- If it's a full file path (with extension), the filename part will be used
|
277
|
+
as the base, and the `fmt` argument will determine the final extension.
|
278
|
+
- If None, the current working directory will be used, and the filename will
|
279
|
+
be generated.
|
280
|
+
fmt : str, optional
|
281
|
+
The file format to export, e.g., 'csv', 'json'. Default is 'csv'.
|
282
|
+
|
283
|
+
Returns
|
284
|
+
-------
|
285
|
+
tuple
|
286
|
+
(str, str): A tuple containing:
|
287
|
+
- The **absolute export path** (e.g., '/home/user/project/data_Routine.csv').
|
288
|
+
- The **export file name** (e.g., 'data_Routine.csv'), including the format extension.
|
289
|
+
"""
|
290
|
+
# Determine the base name from system.files.fullname or default to "Untitled"
|
291
|
+
if system.files.fullname is None:
|
292
|
+
logger.info("Input file name not detected. Using `Untitled`.")
|
293
|
+
base_name_prefix = f'Untitled_{fname}'
|
294
|
+
else:
|
295
|
+
base_name_prefix = os.path.splitext(os.path.basename(system.files.fullname))[0]
|
296
|
+
base_name_prefix += f'_{fname}'
|
297
|
+
|
298
|
+
target_extension = fmt.lower() # Ensure consistent extension casing
|
299
|
+
|
300
|
+
if path:
|
301
|
+
abs_path = os.path.abspath(path) # Resolve to absolute path early
|
302
|
+
|
303
|
+
# Check if the provided path is likely intended as a directory
|
304
|
+
if not os.path.splitext(abs_path)[1]: # No extension implies it's a directory
|
305
|
+
dir_path = abs_path
|
306
|
+
final_file_name = f"{base_name_prefix}.{target_extension}"
|
307
|
+
full_export_path = os.path.join(dir_path, final_file_name)
|
308
|
+
else:
|
309
|
+
# Path includes a filename. Use its directory, and its base name.
|
310
|
+
dir_path = os.path.dirname(abs_path)
|
311
|
+
# Use the provided filename's base, but enforce the target_extension
|
312
|
+
provided_base_filename = os.path.splitext(os.path.basename(abs_path))[0]
|
313
|
+
final_file_name = f"{provided_base_filename}.{target_extension}"
|
314
|
+
full_export_path = os.path.join(dir_path, final_file_name)
|
315
|
+
else:
|
316
|
+
# No path provided, use current working directory
|
317
|
+
dir_path = os.getcwd()
|
318
|
+
final_file_name = f"{base_name_prefix}.{target_extension}"
|
319
|
+
full_export_path = os.path.join(dir_path, final_file_name)
|
320
|
+
|
321
|
+
return full_export_path, final_file_name
|
docs/source/examples/index.rst
CHANGED
docs/source/genroutineref.py
CHANGED
docs/source/release-notes.rst
CHANGED
@@ -9,11 +9,24 @@ The APIs before v3.0.0 are in beta and may change without prior notice.
|
|
9
9
|
v1.0
|
10
10
|
==========
|
11
11
|
|
12
|
-
v1.0.
|
13
|
-
|
12
|
+
v1.0.12 (2025-05-29)
|
13
|
+
----------------------
|
14
|
+
|
15
|
+
- Add RParam pd and qd in ``DCPF1`` for easy access to load
|
16
|
+
- Bug fix in ``RoutineBase.export_csv`` when path is specified
|
17
|
+
- Fix bug in ``io.matpower.system2mpc`` with multiple PQ at one bus
|
18
|
+
|
19
|
+
v1.0.11 (2025-05-23)
|
20
|
+
----------------------
|
21
|
+
|
22
|
+
- Refactor Documenter
|
23
|
+
- Fix bug in documentation building
|
24
|
+
|
25
|
+
v1.0.10 (2025-05-23)
|
26
|
+
----------------------
|
14
27
|
|
15
|
-
- Add bus type correction in ``system.System.setup
|
16
|
-
- Revise ``
|
28
|
+
- Add bus type correction in ``system.System.setup``
|
29
|
+
- Revise ``io.psse.read`` to complete model Zone when necessary
|
17
30
|
- Use numerical Area and Zone idx in MATPOWER and PSSE RAW file conversion
|
18
31
|
- Support JSON format addfile when converting to ANDES case
|
19
32
|
- Add PSS/E v33 RAW file writer
|
@@ -28,9 +41,9 @@ v1.0.10 (2024-xx-xx)
|
|
28
41
|
- Revise ``andes.common.config.Config.update`` to ensure configuration parameters
|
29
42
|
are consistently updated in both the object and its internal ``_dict``
|
30
43
|
- Remove legacy revised PYPOWER module
|
31
|
-
- Remove function ``
|
44
|
+
- Remove function ``shared.ppc2df``
|
32
45
|
|
33
|
-
v1.0.9 (
|
46
|
+
v1.0.9 (2025-04-23)
|
34
47
|
--------------------
|
35
48
|
|
36
49
|
Improve MATPOWER file converter:
|
@@ -38,7 +51,7 @@ Improve MATPOWER file converter:
|
|
38
51
|
- Add a M file case writer
|
39
52
|
- Include Area and Zone in both MATPOWER read and write
|
40
53
|
|
41
|
-
v1.0.8 (
|
54
|
+
v1.0.8 (2025-04-20)
|
42
55
|
--------------------
|
43
56
|
|
44
57
|
- Run workflow "Publish" only on push tag event
|
@@ -48,7 +61,7 @@ v1.0.8 (2024-04-20)
|
|
48
61
|
- Include ``gentype`` and ``genfuel`` when parsing MATPOWER cases
|
49
62
|
- Fix logging level in ``ACOPF.run``
|
50
63
|
|
51
|
-
v1.0.7 (
|
64
|
+
v1.0.7 (2025-04-14)
|
52
65
|
--------------------
|
53
66
|
|
54
67
|
- Address several wording issues in the documentation
|
@@ -56,50 +69,50 @@ v1.0.7 (2024-04-14)
|
|
56
69
|
- Extend common parameters in groups ``StaticGen`` and ``StaticLoad`` with ``area``
|
57
70
|
- Set case ``pjm5bus_demo.xlsx`` as a all-inclusive case
|
58
71
|
- Include module ``MatProcessor`` in the API documentation
|
59
|
-
- Improve Line parameters correction in ``System.setup
|
72
|
+
- Improve Line parameters correction in ``System.setup``
|
60
73
|
- Make func ``interface._to_andes_pflow`` public
|
61
74
|
- Discard ``sync_adsys`` step in func ``to_andes_pflow`` to fix mistake in
|
62
75
|
parameters conversion
|
63
76
|
- Update case files
|
64
77
|
|
65
|
-
v1.0.6 (
|
78
|
+
v1.0.6 (2025-04-10)
|
66
79
|
--------------------
|
67
80
|
|
68
81
|
- Enhance handling of Type 1 gencost: Automatically fallback to Type 2 gencost
|
69
82
|
- Add parameter correction for zero line angle difference
|
70
83
|
|
71
|
-
v1.0.5 (
|
84
|
+
v1.0.5 (2025-04-09)
|
72
85
|
--------------------
|
73
86
|
|
74
87
|
- Include sensitivity matrices calculation demo in documentation
|
75
88
|
- Add ``DCOPF2``, a PTDF-based DCOPF routine
|
76
89
|
- Fix bug when update routine parameters before it is initialized
|
77
90
|
|
78
|
-
v1.0.4 (
|
91
|
+
v1.0.4 (2025-04-05)
|
79
92
|
--------------------
|
80
93
|
|
81
94
|
- Fix format in release notes
|
82
95
|
- Add badges of GitHub relesase and commits in README
|
83
96
|
- Add a demo to show sensitivity matrices calculation
|
84
97
|
|
85
|
-
v1.0.3 (
|
98
|
+
v1.0.3 (2025-03-17)
|
86
99
|
--------------------
|
87
100
|
|
88
|
-
- Bug fix in function ``
|
101
|
+
- Bug fix in function ``interface.parse_addfile``, released in v1.0.3a1
|
89
102
|
|
90
|
-
v1.0.2 (
|
103
|
+
v1.0.2 (2025-02-01)
|
91
104
|
--------------------
|
92
105
|
|
93
106
|
- Enhance the GitHub Actions workflow file
|
94
107
|
- Deprecate andes logger configuration in ``config_logger``
|
95
108
|
- Deprecate solver specification in ``demo_ESD1``
|
96
109
|
|
97
|
-
v1.0.1 (
|
110
|
+
v1.0.1 (2025-01-26)
|
98
111
|
--------------------
|
99
112
|
|
100
113
|
Hotfix: removed dependencies on `SCIP` and `pyscipopt` to resolve installation issues
|
101
114
|
|
102
|
-
v1.0.0 (
|
115
|
+
v1.0.0 (2025-01-24)
|
103
116
|
--------------------
|
104
117
|
|
105
118
|
- **Breaking Change**: rename model ``Region`` to ``Zone`` for clarity. Prior case
|
@@ -130,10 +143,10 @@ v0.9.12 (2024-11-23)
|
|
130
143
|
|
131
144
|
- Refactor ``OModel.initialized`` as a property method
|
132
145
|
- Add a demo to show using ``Constraint.e`` for debugging
|
133
|
-
- Fix ``
|
134
|
-
- Improve ``
|
135
|
-
- Refactor module ``
|
136
|
-
- Add class ``
|
146
|
+
- Fix ``opt.omodel.Param.evaluate`` when its value is a number
|
147
|
+
- Improve ``opt.omodel.ExpressionCalc`` for better performance
|
148
|
+
- Refactor module ``opt``
|
149
|
+
- Add class ``opt.Expression``
|
137
150
|
- Switch from PYPOWER to ANDES in routine ``PFlow``
|
138
151
|
- Switch from PYPOWER to regular formulation in routine ``DCPF``
|
139
152
|
- Refactor routines ``DCPF`` and ``DCOPF``
|
@@ -376,7 +389,7 @@ v0.6.5 (2023-06-27)
|
|
376
389
|
-------------------
|
377
390
|
|
378
391
|
- Update documentation with auto-generated model and routine reference
|
379
|
-
- Add interface with ANDES ``
|
392
|
+
- Add interface with ANDES ``interop.andes``
|
380
393
|
- Add routine RTED and example of RTED-TDS co-simulation
|
381
394
|
- Draft development documentation
|
382
395
|
|
@@ -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
|
|