Skip to content

Commit

Permalink
Merge pull request grid-parity-exchange#13 from bknueven/uc_improvements
Browse files Browse the repository at this point in the history
UC improvements
  • Loading branch information
carldlaird authored Apr 5, 2019
2 parents a780edd + 718f5a8 commit 585c58e
Show file tree
Hide file tree
Showing 10 changed files with 585 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ install:
- ls -l /home/travis/miniconda/envs/test_env/lib
- pip install pyomo
- conda install -c conda-forge ipopt
- conda install -c conda-forge glpk
- conda install -c conda-forge coincbc
- python setup.py develop

script:
Expand Down
3 changes: 2 additions & 1 deletion egret/model_library/unit_commitment/uc_model_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
'production_costs',
'uptime_downtime',
'startup_costs',
'network_constraints',
]
)

Expand Down Expand Up @@ -122,7 +123,7 @@ def _get_formulation_from_UCFormulation( uc_formulation ):
uc_formulation.production_costs,
uc_formulation.uptime_downtime,
uc_formulation.startup_costs,
'power_balance_constraints',
uc_formulation.network_constraints,
'MLR_reserve_constraints' if uc_formulation.reserve_vars in ['MLR_reserve_vars'] else 'CA_reserve_constraints',
'basic_objective',
]
28 changes: 28 additions & 0 deletions egret/models/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# ___________________________________________________________________________
#
# EGRET: Electrical Grid Research and Engineering Tools
# Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC
# (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
# Government retains certain rights in this software.
# This software is distributed under the Revised BSD License.
# ___________________________________________________________________________

'''
pytest configuration options for test_unit_commitment.py,
per the pytest examples
'''
import pytest

def pytest_addoption(parser):
parser.addoption("--runmip", action="store_true", default=False,
help="If enabled, this solves the MIP for each unit "
"commitment instance. For now, the solver gurobi "
"is required for this test."
)

def pytest_collection_modifyitems(config, items):
if not config.getoption("--runmip"):
skip_mip = pytest.mark.skip(reason="need --runmip option to run")
for item in items:
if "mip" in item.keywords:
item.add_marker(skip_mip)
100 changes: 94 additions & 6 deletions egret/models/tests/test_unit_commitment.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# ___________________________________________________________________________
#
# EGRET: Electrical Grid Research and Engineering Tools
# Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC
# (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
# Government retains certain rights in this software.
# This software is distributed under the Revised BSD License.
# ___________________________________________________________________________

'''
unit commitment tester
'''
Expand All @@ -6,24 +15,103 @@
import math

import pytest
import unittest
from pyomo.opt import SolverFactory, TerminationCondition
from pyomo.core.plugins.transform.relax_integrality \
import RelaxIntegrality
from egret.models.unit_commitment import *
from egret.data.model_data import ModelData

current_dir = os.path.dirname(os.path.abspath(__file__))

test_cases = [os.path.join(current_dir,'uc_test_instances', 'test_case_{}.json'.format(i)) for i in range(1,6)]
test_objvals = [4218219.415648285, 5476393.707647482, 6023692.988920629, 5484256.685824468, 6091360.072517976]
test_int_objvals = [4201915.017320504, 5454367.7670904165, 5999272.361123627, 5461120.3231092375, 6062406.32677043]

def test_tight_uc_model():
def _test_uc_model(uc_model, relax=False, test_objvals=test_int_objvals):

for test_case, ref_objval in zip(test_cases, test_objvals):

md_dict = json.load(open(test_case,'r'))
md = ModelData(md_dict)
model = create_tight_unit_commitment_model(md)
opt = SolverFactory('glpk')

if relax:
model = uc_model(md, relaxed=relax)
opt = SolverFactory('cbc')
else:
model = uc_model(md)
opt = SolverFactory('gurobi')
opt.options['mipgap'] = 0.0

result = opt.solve(model, tee=False)

assert result.solver.termination_condition == TerminationCondition.optimal
assert math.isclose(ref_objval, model.TotalCostObjective())
assert math.isclose(ref_objval, result.problem.upper_bound)

## definitely skip if we don't have gurobi
@unittest.skipUnless(SolverFactory('gurobi').available(), "Solver gurobi unavailabe")
@pytest.mark.mip
def test_int_all_uc_models():
_test_uc_model(create_tight_unit_commitment_model)
_test_uc_model(create_compact_unit_commitment_model)
_test_uc_model(create_KOW_unit_commitment_model)
_test_uc_model(create_ALS_unit_commitment_model)
_test_uc_model(create_MLR_unit_commitment_model)
_test_uc_model(create_random1_unit_commitment_model)
_test_uc_model(create_random2_unit_commitment_model)
_test_uc_model(create_OAV_unit_commitment_model)
_test_uc_model(create_OAV_tighter_unit_commitment_model)
_test_uc_model(create_OAV_original_unit_commitment_model)
_test_uc_model(create_OAV_up_downtime_unit_commitment_model)
_test_uc_model(create_CA_unit_commitment_model)

def test_tight_uc_model():
lp_obj_list = [4194720.23424, 5441076.85034, 5988496.92621, 5453617.47912, 6055376.54656]
_test_uc_model(create_tight_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_compact_uc_model():
lp_obj_list = [4194304.94748, 5440720.727, 5988068.23178, 5453218.02764, 6055020.46427]
_test_uc_model(create_compact_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_KOW_uc_model():
lp_obj_list = [4193749.67682, 5440148.79074, 5987686.94763, 5452888.22712, 6054163.40576]
_test_uc_model(create_KOW_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_ALS_uc_model():
lp_obj_list = [4193603.40346, 5439977.63794, 5987392.27642, 5452580.38476, 6054545.74347]
_test_uc_model(create_ALS_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_MLR_uc_model():
lp_obj_list = [4193700.64155, 5440122.0449, 5987617.01183, 5452837.51833, 6054088.71399]
_test_uc_model(create_MLR_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_random1_uc_model():
lp_obj_list = [4194304.94748, 5440720.727, 5988068.23178, 5453218.02764, 6055020.46427]
_test_uc_model(create_random1_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_random2_uc_model():
lp_obj_list = [4194686.42109, 5441087.41223, 5988465.58558, 5453619.48855, 6055360.5608]
_test_uc_model(create_random2_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_OAV_uc_model():
lp_obj_list = [4190770.57777, 5436680.81342, 5984071.37653, 5449824.53072, 6051451.70067]
_test_uc_model(create_OAV_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_OAV_tighter_uc_model():
lp_obj_list = [4190774.76258, 5436685.6315, 5984097.794, 5449825.81448, 6051485.86608]
_test_uc_model(create_OAV_tighter_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_OAV_original_uc_model():
lp_obj_list = [4186901.74384, 5428888.70061, 5975676.69077, 5443849.68783, 6041296.59018]
_test_uc_model(create_OAV_original_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_OAV_up_downtime_uc_model():
lp_obj_list = [4190745.01259, 5436634.52576, 5984052.06305, 5449795.75874, 6051432.92077]
_test_uc_model(create_OAV_up_downtime_unit_commitment_model, relax=True, test_objvals=lp_obj_list)

def test_CA_uc_model():
lp_obj_list = [4185855.30972, 5423650.80043, 5965411.93718, 5439434.94733, 6029118.03019]
_test_uc_model(create_CA_unit_commitment_model, relax=True, test_objvals=lp_obj_list)





2 changes: 1 addition & 1 deletion egret/models/tests/uc_test_instances/test_case_1.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion egret/models/tests/uc_test_instances/test_case_2.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion egret/models/tests/uc_test_instances/test_case_3.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion egret/models/tests/uc_test_instances/test_case_4.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion egret/models/tests/uc_test_instances/test_case_5.json

Large diffs are not rendered by default.

Loading

0 comments on commit 585c58e

Please sign in to comment.