Skip to content

Commit

Permalink
Merge pull request #74 from CURENT/develop
Browse files Browse the repository at this point in the history
Prep for next patch release v0.9.5
  • Loading branch information
jinningwang committed Mar 26, 2024
2 parents 32f5a28 + 13121e3 commit 90e045b
Show file tree
Hide file tree
Showing 37 changed files with 1,062 additions and 445 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- shell: bash -el {0}
name: Test notebooks.
run: |
pytest --nbmake examples --ignore=examples/demonstration
pytest --nbmake examples --ignore=examples/verification
- name: Build a distribution if tagged
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') && matrix.os == 'ubuntu-latest' && matrix.python-version == '3.9'
run: |
Expand Down
1 change: 1 addition & 0 deletions ams/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from ams.main import config_logger, load, run # NOQA
from ams.utils.paths import get_case # NOQA
from ams.shared import ppc2df # NOQA

__author__ = 'Jining Wang'

Expand Down
Binary file modified ams/cases/5bus/pjm5bus_demo.xlsx
Binary file not shown.
8 changes: 4 additions & 4 deletions ams/cases/5bus/pjm5bus_uced.json
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@
"trans": 0.0,
"tap": 1.0,
"phi": 0.0,
"rate_a": 0.0,
"rate_a": 2.0,
"rate_b": 0.0,
"rate_c": 0.0,
"owner": null,
Expand Down Expand Up @@ -367,7 +367,7 @@
"trans": 0.0,
"tap": 1.0,
"phi": 0.0,
"rate_a": 0.0,
"rate_a": 2.0,
"rate_b": 0.0,
"rate_c": 0.0,
"owner": null,
Expand Down Expand Up @@ -397,7 +397,7 @@
"trans": 0.0,
"tap": 1.0,
"phi": 0.0,
"rate_a": 0.0,
"rate_a": 2.0,
"rate_b": 0.0,
"rate_c": 0.0,
"owner": null,
Expand Down Expand Up @@ -427,7 +427,7 @@
"trans": 0.0,
"tap": 1.0,
"phi": 0.0,
"rate_a": 0.0,
"rate_a": 2.0,
"rate_b": 0.0,
"rate_c": 0.0,
"owner": null,
Expand Down
Binary file modified ams/cases/5bus/pjm5bus_uced.xlsx
Binary file not shown.
Binary file modified ams/cases/5bus/pjm5bus_uced_esd1.xlsx
Binary file not shown.
243 changes: 243 additions & 0 deletions ams/cases/pglib/pglib_opf_case39_epri__api.m

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions ams/core/matprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import numpy as np

from scipy.sparse import csr_matrix as c_sparse
from scipy.sparse import csc_matrix as csc_sparse
from scipy.sparse import lil_matrix as l_sparse

from andes.utils.misc import elapsed
Expand Down Expand Up @@ -65,7 +66,7 @@ def v(self):
"""
# NOTE: scipy.sparse matrix will return 2D array
# so we squeeze it here if only one row
if isinstance(self._v, (c_sparse, l_sparse)):
if isinstance(self._v, (c_sparse, l_sparse, csc_sparse)):
out = self._v.toarray()
if out.shape[0] == 1:
return np.squeeze(out)
Expand Down Expand Up @@ -102,6 +103,7 @@ class MatProcessor:

def __init__(self, system):
self.system = system
self.initialized = False
self.Bbus = MParam(name='Bbus', tex_name=r'B_{bus}',
info='Bus admittance matrix',
v=None, sparse=True)
Expand Down Expand Up @@ -148,7 +150,7 @@ def make(self):
self._makeBdc()
_, s_mat = elapsed(t_mat)
logger.debug(f"Built system matrices in {s_mat}.")

self.initialized = True
return True

@property
Expand Down Expand Up @@ -232,7 +234,7 @@ def _makeC(self):
on_gen_bus_idx = system.StaticGen.get(src='bus', attr='v', idx=on_gen_idx)

row = np.array([system.Bus.idx2uid(x) for x in on_gen_bus_idx])
col = np.array([system.StaticGen.idx2uid(x) for x in on_gen_idx])
col = np.array([idx_gen.index(x) for x in on_gen_idx])
Cg = c_sparse((np.ones(len(on_gen_idx)), (row, col)), (nb, ng))

# --- Cl ---
Expand Down
1 change: 1 addition & 0 deletions ams/core/symprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def __init__(self, parent):
'interrupted': 8,
'unknown': 9,
'infeasible_or_unbounded': 1.5,
'user_limit': 10,
}

def generate_symbols(self, force_generate=False):
Expand Down
79 changes: 40 additions & 39 deletions ams/io/matpower.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def mpc2system(mpc: dict, system) -> bool:
Compared to the original one, this function includes the generator cost data.
Note that `mbase` in mpc is converted to `Sn`, but it is not actually used in
MATPOWER nor AMS.
Parameters
----------
system : andes.system.System
Expand Down Expand Up @@ -90,11 +93,10 @@ def mpc2system(mpc: dict, system) -> bool:
if mpc['gen'].shape[1] <= 10: # missing data
mpc_gen = np.zeros((mpc['gen'].shape[0], 21), dtype=np.float64)
mpc_gen[:, :10] = mpc['gen']
mbase = base_mva
mpc_gen[:, 16] = system.PV.Ragc.default * mbase / 60
mpc_gen[:, 17] = system.PV.R10.default * mbase
mpc_gen[:, 18] = system.PV.R30.default * mbase
mpc_gen[:, 19] = system.PV.Rq.default * mbase / 60
mpc_gen[:, 16] = system.PV.Ragc.default * base_mva / 60
mpc_gen[:, 17] = system.PV.R10.default * base_mva
mpc_gen[:, 18] = system.PV.R30.default * base_mva
mpc_gen[:, 19] = system.PV.Rq.default * base_mva / 60
else:
mpc_gen = mpc['gen']
for data in mpc_gen:
Expand All @@ -104,28 +106,26 @@ def mpc2system(mpc: dict, system) -> bool:
# 10 11 12 13 14 15 16 17
# ramp_30 ramp_q apf
# 18 19 20

bus_idx = int(data[0])
gen_idx += 1
vg = data[5]
status = int(data[7])
mbase = base_mva
pg = data[1] / mbase
qg = data[2] / mbase
qmax = data[3] / mbase
qmin = data[4] / mbase
pmax = data[8] / mbase
pmin = data[9] / mbase
pc1 = data[10] / mbase
pc2 = data[11] / mbase
qc1min = data[12] / mbase
qc1max = data[13] / mbase
qc2min = data[14] / mbase
qc2max = data[15] / mbase
ramp_agc = 60 * data[16] / mbase # from MW/min to MW/h
ramp_10 = data[17] / mbase # from MW to MW/h
ramp_30 = data[18] / mbase # from MW to MW/h
ramp_q = 60 * data[19] / mbase # from MVAr/min to MVAr/h
pg = data[1] / base_mva
qg = data[2] / base_mva
qmax = data[3] / base_mva
qmin = data[4] / base_mva
pmax = data[8] / base_mva
pmin = data[9] / base_mva
pc1 = data[10] / base_mva
pc2 = data[11] / base_mva
qc1min = data[12] / base_mva
qc1max = data[13] / base_mva
qc2min = data[14] / base_mva
qc2max = data[15] / base_mva
ramp_agc = 60 * data[16] / base_mva # MW/min -> MW/h
ramp_10 = data[17] / base_mva # MW -> MW/h
ramp_30 = data[18] / base_mva # MW -> MW/h
ramp_q = 60 * data[19] / base_mva # MVAr/min -> MVAr/h
apf = data[20]

uid = system.Bus.idx2uid(bus_idx)
Expand All @@ -135,7 +135,7 @@ def mpc2system(mpc: dict, system) -> bool:
if bus_idx in sw:
system.add('Slack', idx=gen_idx, bus=bus_idx, busr=bus_idx,
name='Slack ' + str(bus_idx),
u=status,
u=status, Sn=data[6],
Vn=vn, v0=vg, p0=pg, q0=qg, a0=a0,
pmax=pmax, pmin=pmin,
qmax=qmax, qmin=qmin,
Expand All @@ -148,7 +148,7 @@ def mpc2system(mpc: dict, system) -> bool:
else:
system.add('PV', idx=gen_idx, bus=bus_idx, busr=bus_idx,
name='PV ' + str(bus_idx),
u=status,
u=status, Sn=data[6],
Vn=vn, v0=vg, p0=pg, q0=qg,
pmax=pmax, pmin=pmin,
qmax=qmax, qmin=qmin,
Expand All @@ -169,11 +169,11 @@ def mpc2system(mpc: dict, system) -> bool:
r = data[2]
x = data[3]
b = data[4]
rate_a = data[5]
rate_b = data[6]
rate_c = data[7]
amin = data[11]
amax = data[12]
rate_a = data[5] / base_mva
rate_b = data[6] / base_mva
rate_c = data[7] / base_mva
amin = data[11] * deg2rad
amax = data[12] * deg2rad

status = int(data[10])

Expand Down Expand Up @@ -331,35 +331,34 @@ def system2mpc(system) -> dict:
gen[system.Slack.n:, 3] = PV.qmax.v * base_mva
gen[system.Slack.n:, 4] = PV.qmin.v * base_mva
gen[system.Slack.n:, 5] = PV.v0.v
gen[system.Slack.n:, 6] = base_mva
gen[system.Slack.n:, 6] = PV.Sn.v
gen[system.Slack.n:, 7] = PV.u.v
gen[system.Slack.n:, 8] = (PV.ctrl.v * PV.pmax.v + (1 - PV.ctrl.v) * PV.pmax.v) * base_mva
gen[system.Slack.n:, 9] = (PV.ctrl.v * PV.pmin.v + (1 - PV.ctrl.v) * PV.pmin.v) * base_mva
gen[system.Slack.n:, 16] = PV.Ragc.v * base_mva * 60 # from MW/h to MW/min
gen[system.Slack.n:, 8] = (PV.ctrl.v * PV.pmax.v + (1 - PV.ctrl.v) * PV.p0.v) * base_mva
gen[system.Slack.n:, 9] = (PV.ctrl.v * PV.pmin.v + (1 - PV.ctrl.v) * PV.p0.v) * base_mva
gen[system.Slack.n:, 16] = PV.Ragc.v * base_mva * 60 # MW/h -> MW/min
gen[system.Slack.n:, 17] = PV.R10.v * base_mva
gen[system.Slack.n:, 18] = PV.R30.v * base_mva
gen[system.Slack.n:, 19] = PV.Rq.v * base_mva * 60 # from MVAr/h to MVAr/min
gen[system.Slack.n:, 19] = PV.Rq.v * base_mva * 60 # MVAr/h -> MVAr/min

# --- Slack ---
if system.Slack.n > 0:
slack_pos = system.Bus.idx2uid(system.Slack.bus.v)
bus[slack_pos, 1] = 3
bus[slack_pos, 8] = system.Slack.a0.v * rad2deg

gen[:system.Slack.n, 0] = to_busid(system.Slack.bus.v)
gen[:system.Slack.n, 1] = system.Slack.p0.v * base_mva
gen[:system.Slack.n, 2] = system.Slack.q0.v * base_mva
gen[:system.Slack.n, 3] = system.Slack.qmax.v * base_mva
gen[:system.Slack.n, 4] = system.Slack.qmin.v * base_mva
gen[:system.Slack.n, 5] = system.Slack.v0.v
gen[:system.Slack.n, 6] = base_mva
gen[:system.Slack.n, 6] = system.Slack.Sn.v
gen[:system.Slack.n, 7] = system.Slack.u.v
gen[:system.Slack.n, 8] = system.Slack.pmax.v * base_mva
gen[:system.Slack.n, 9] = system.Slack.pmin.v * base_mva
gen[:system.Slack.n, 16] = system.Slack.Ragc.v * base_mva * 60 # from MW/h to MW/min
gen[:system.Slack.n, 16] = system.Slack.Ragc.v * base_mva * 60 # MW/h -> MW/min
gen[:system.Slack.n, 17] = system.Slack.R10.v * base_mva
gen[:system.Slack.n, 18] = system.Slack.R30.v * base_mva
gen[:system.Slack.n, 19] = system.Slack.Rq.v * base_mva * 60 # from MVAr/h to MVAr/min
gen[:system.Slack.n, 19] = system.Slack.Rq.v * base_mva * 60 # MVAr/h -> MVAr/min

if system.Line.n > 0:
branch = mpc['branch']
Expand All @@ -374,6 +373,8 @@ def system2mpc(system) -> dict:
branch[:, 8] = system.Line.tap.v
branch[:, 9] = system.Line.phi.v * rad2deg
branch[:, 10] = system.Line.u.v
branch[:, 11] = system.Line.amin.v * rad2deg
branch[:, 12] = system.Line.amax.v * rad2deg

# --- GCost ---
# NOTE: adjust GCost sequence to match the generator sequence
Expand Down
2 changes: 1 addition & 1 deletion ams/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
ams_file_classes = list([
('info', ['Summary']),
('bus', ['Bus']),
('static', ['PQ', 'PV', 'Slack']),
('static', ['PQ', 'Slack', 'PV']),
('shunt', ['Shunt']),
('line', ['Line']),
('distributed', ['PVD1', 'ESD1']),
Expand Down
10 changes: 7 additions & 3 deletions ams/models/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,21 +199,25 @@ class StaticGen(GroupBase):

def __init__(self):
super().__init__()
self.common_params.extend(('Sn', 'Vn', 'p0', 'q0', 'ra', 'xs', 'subidx'))
self.common_params.extend(('Sn', 'Vn', 'p0', 'q0', 'ra', 'xs', 'subidx',
'bus', 'pmax', 'pmin', 'pg0', 'ctrl'))
self.common_vars.extend(('p', 'q'))


class ACLine(GroupBase):
def __init__(self):
super(ACLine, self).__init__()
super().__init__()
self.common_params.extend(('bus1', 'bus2', 'r', 'x'))


class StaticLoad(GroupBase):
"""
Static load group.
"""
pass

def __init__(self):
super().__init__()
self.common_params.extend(('p0',))


class StaticShunt(GroupBase):
Expand Down
3 changes: 3 additions & 0 deletions ams/models/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ def __init__(self, system=None, config=None) -> None:
unit='rad',
tex_name=r'a_{max}',
)
self.rate_a.unit = 'p.u.'
self.rate_b.unit = 'p.u.'
self.rate_c.unit = 'p.u.'
self.rate_a.default = 999.0
self.rate_b.default = 999.0
self.rate_c.default = 999.0
Loading

0 comments on commit 90e045b

Please sign in to comment.