Skip to content

Commit

Permalink
Merge pull request #36 from grgmiller/pyomo_update
Browse files Browse the repository at this point in the history
Pyomo update (Fixes #25)
  • Loading branch information
grgmiller authored Aug 26, 2021
2 parents f410385 + 7c9139b commit 3e0307d
Show file tree
Hide file tree
Showing 22 changed files with 197 additions and 220 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
-------------------------------------------------------------------------------
Commmit 2021.08.26 (Version 0.2.0)
-------------------------------------------------------------------------------
Fixes #25
Updates the code to work with Pyomo 6.1, from Pyomo 5.6.8, so that the code is compatible with CPLEX as a solver.
The environment.yml file has been updated to require use of Pyomo>=6.0.0 and pyutilib>=6.0.0, so continued use will require updating your environment.

Specific updates include:
- pyomo elements with "Simple" in their name were renamed to "Scalar"
- For any params with string elements, needed to manually specify `within=Any` when defining the param in order to silence a deprecation warning
- Needed to manually specify `dimen=1` for Sets that are used to index parameters when loading data
- When loading data, you can no longer specify the index as a cross product of multiple sets (e.g. `index=mod.PERIODS*mod.MONTHS`). Instead, they must be specified as a list of Sets (e.g. `index=[mod.PERIODS, mod.MONTHS]`)

Other cleanup included:
- when loading data, replaced specifying multiple parameters as tuples with specifying them as lists, to speed the data loading process
- Removed `PERIODS_FOR_GEN_BLD_YR`, and `TPS_FOR_GEN_IN_PERIOD` because they are not used in the model
- changed the `gen_capacity_value` to `elcc` for Effective Load Carrying Capacity


-------------------------------------------------------------------------------
Commmit 2021.08.11
-------------------------------------------------------------------------------
Expand Down
Binary file modified MODEL_RUNS/generic_office_example/model_inputs.xlsx
Binary file not shown.
Binary file modified MODEL_RUNS/model_inputs.xlsx
Binary file not shown.
4 changes: 2 additions & 2 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ dependencies:
- pandas
- pint
- plotly
- pyomo<=5.6.8
- pyomo>=6.0.0
- python>=2.7.12
- pytz
- pyutilib<=5.7.3
- pyutilib>=6.0.0
- requests
- xlrd
10 changes: 5 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ def read(*rnames):
setup(
name='switch_model',
version=__version__,
maintainer='Switch Authors',
maintainer_email='[email protected]',
maintainer='Gregory Miller',
maintainer_email='[email protected]',
url='http://switch-model.org',
license='Apache License 2.0',
platforms=["any"],
description='Switch Power System Planning Model',
description='Switch 24x7 Planning Model',
long_description=read('README.md'),
long_description_content_type="text/markdown",
classifiers=[
Expand Down Expand Up @@ -62,11 +62,11 @@ def read(*rnames):
],
python_requires='>=2.7.12',
install_requires=[
'Pyomo>=4.4.1, <=5.6.8', # We need a version that works with glpk 4.60+
'Pyomo', # We need a version that works with glpk 4.60+
'pint', # needed by Pyomo when we run our tests, but not included
'testfixtures', # used for standard tests
'pandas', # used for input upgrades and testing that functionality
'pyutilib <=5.7.3',
'pyutilib',
],
extras_require={
# packages used for advanced demand response, progressive hedging
Expand Down
4 changes: 2 additions & 2 deletions switch_model/balancing/demand_response/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ def load_inputs(mod, switch_data, inputs_dir):
optional=True,
filename=os.path.join(inputs_dir, 'dr_data.csv'),
autoselect=True,
param=(mod.dr_shift_down_limit, mod.dr_shift_up_limit))
param=[mod.dr_shift_down_limit, mod.dr_shift_up_limit])

switch_data.load_aug(
filename=os.path.join(inputs_dir, 'days.csv'),
select=('timepoint_id','tp_day'),
index=mod.TIMEPOINTS,
param=(mod.tp_day))
param=[mod.tp_day])
2 changes: 1 addition & 1 deletion switch_model/balancing/load_zones.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def load_inputs(mod, switch_data, inputs_dir):
filename=os.path.join(inputs_dir, 'loads.csv'),
auto_select=True,
index=mod.ZONE_TIMEPOINTS,
param=(mod.zone_demand_mw))
param=[mod.zone_demand_mw])


def post_solve(instance, outdir):
Expand Down
5 changes: 2 additions & 3 deletions switch_model/balancing/renewable_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,7 @@ def load_inputs(mod, switch_data, inputs_dir):
switch_data.load_aug(
filename=os.path.join(inputs_dir, 'renewable_target.csv'),
autoselect=True,
index=mod.PERIODS,
param=(mod.renewable_target,))
param=[mod.renewable_target])

#load inputs which include costs for each timepoint in each zone
switch_data.load_aug(
Expand All @@ -171,7 +170,7 @@ def load_inputs(mod, switch_data, inputs_dir):
filename=os.path.join(inputs_dir, 'days.csv'),
select=('timepoint_id','tp_in_subset'),
index=mod.TIMEPOINTS,
param=(mod.tp_in_subset))
param=[mod.tp_in_subset])

def post_solve(instance, outdir):
"""
Expand Down
6 changes: 3 additions & 3 deletions switch_model/energy_sources/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def define_components(mod):
"""

mod.NON_FUEL_ENERGY_SOURCES = Set()
mod.FUELS = Set()
mod.FUELS = Set(dimen=1)
mod.f_co2_intensity = Param(mod.FUELS, within=NonNegativeReals)
mod.f_upstream_co2_intensity = Param(
mod.FUELS, within=Reals, default=0)
Expand All @@ -103,7 +103,7 @@ def define_components(mod):
# ENERGY_SOURCES is the union of fuel and non-fuels sets. Pipe | is
# the union operator for Pyomo sets.
mod.ENERGY_SOURCES = Set(
initialize=mod.NON_FUEL_ENERGY_SOURCES | mod.FUELS)
initialize=mod.NON_FUEL_ENERGY_SOURCES | mod.FUELS, dimen=1)
mod.min_data_check('ENERGY_SOURCES')


Expand Down Expand Up @@ -145,4 +145,4 @@ def load_inputs(mod, switch_data, inputs_dir):
filename=os.path.join(inputs_dir, 'fuels.csv'),
select=('fuel', 'co2_intensity', 'upstream_co2_intensity'),
index=mod.FUELS,
param=(mod.f_co2_intensity, mod.f_upstream_co2_intensity))
param=[mod.f_co2_intensity, mod.f_upstream_co2_intensity])
99 changes: 92 additions & 7 deletions switch_model/explore_model_instance.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 8,
"source": [
"from pathlib import Path\r\n",
"import pickle\r\n",
Expand All @@ -24,7 +24,7 @@
"import pandas as pd\r\n",
"\r\n",
"# specify where the pickle file is located\r\n",
"model_path = '../MODEL_RUNS/generic_office_example/outputs/hourly_95/'"
"model_path = '../MODEL_RUNS/generic_office_example/outputs/annual_goal/'"
],
"outputs": [],
"metadata": {}
Expand All @@ -38,7 +38,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"source": [
"# read instance file\r\n",
"with open((Path.cwd() / model_path / 'instance.pickle'), mode='rb') as file:\r\n",
Expand All @@ -47,6 +47,26 @@
"outputs": [],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 13,
"source": [
"len(instance.GENERATION_PROJECTS)"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"9"
]
},
"metadata": {},
"execution_count": 13
}
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
Expand Down Expand Up @@ -228,24 +248,89 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 9,
"source": [
"# read results file\r\n",
"with open((Path.cwd() / model_path / 'results.pickle'), 'rb') as file:\r\n",
" results = pickle.load(file)\r\n",
"\r\n",
"print(results.problem)"
],
"outputs": [],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\n",
"- Name: unknown\n",
" Lower bound: 726748.0428\n",
" Upper bound: 726748.0428\n",
" Number of objectives: 1\n",
" Number of constraints: 43803\n",
" Number of variables: 35051\n",
" Number of binary variables: <undefined>\n",
" Number of integer variables: <undefined>\n",
" Number of continuous variables: <undefined>\n",
" Number of nonzeros: 17479\n",
" Sense: minimize\n",
"\n"
]
}
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"source": [
"print(results.solver)"
],
"outputs": [],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\n",
"- Name: <undefined>\n",
" Status: ok\n",
" Return code: <undefined>\n",
" Message: <undefined>\n",
" User time: -1.0\n",
" System time: 28.21\n",
" Wallclock time: 28.21\n",
" Termination condition: optimal\n",
" Termination message: Model was solved to optimality (subject to tolerances), and an optimal solution is available.\n",
" Statistics: \n",
" Branch and bound: \n",
" Number of bounded subproblems: None\n",
" Number of created subproblems: None\n",
" Black box: \n",
" Number of function evaluations: <undefined>\n",
" Number of gradient evaluations: <undefined>\n",
" Number of iterations: 33511\n",
" Error rc: 0\n",
" Time: 28.228245973587036\n",
"\n"
]
}
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 10,
"source": [
"print(results.pyomo_solve_time)"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"26.032098054885864\n"
]
}
],
"metadata": {}
},
{
Expand Down
2 changes: 1 addition & 1 deletion switch_model/financials.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def load_inputs(mod, switch_data, inputs_dir):
switch_data.load_aug(
filename=os.path.join(inputs_dir, 'financials.csv'),
optional=False, auto_select=True,
param=(mod.base_financial_year, mod.interest_rate, mod.discount_rate)
param=[mod.base_financial_year, mod.interest_rate, mod.discount_rate]
)

def post_solve(instance, outdir):
Expand Down
6 changes: 3 additions & 3 deletions switch_model/generate_input_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ def generate_inputs(model_workspace):

# ra_requirement.csv
xl_ra_req = pd.read_excel(io=model_inputs, sheet_name='RA_requirements').dropna(axis=1, how='all')
ra_requirement = xl_ra_req[xl_ra_req['RA_RESOURCE'] != 'flexible_RA']
ra_requirement = xl_ra_req.copy()[xl_ra_req['RA_RESOURCE'] != 'flexible_RA']
ra_requirement['period'] = year
ra_requirement = ra_requirement[['period','RA_RESOURCE','tp_month','ra_requirement','ra_cost','ra_resell_value']]

# flexible_ra_requirement.csv
flexible_ra_requirement = xl_ra_req[xl_ra_req['RA_RESOURCE'] == 'flexible_RA']
flexible_ra_requirement = xl_ra_req.copy()[xl_ra_req['RA_RESOURCE'] == 'flexible_RA']
flexible_ra_requirement['period'] = year
flexible_ra_requirement = flexible_ra_requirement.drop(columns=['RA_RESOURCE'])
flexible_ra_requirement = flexible_ra_requirement.rename(columns={'ra_requirement':'flexible_ra_requirement','ra_cost':'flexible_ra_cost', 'ra_resell_value':'flexible_ra_resell_value'})
Expand All @@ -130,7 +130,7 @@ def generate_inputs(model_workspace):
# ra_capacity_value.csv
ra_capacity_value = pd.read_excel(io=model_inputs, sheet_name='RA_capacity_value').dropna(axis=1, how='all')
ra_capacity_value['period'] = year
ra_capacity_value = ra_capacity_value[['period','gen_energy_source','tp_month','gen_capacity_value']]
ra_capacity_value = ra_capacity_value[['period','gen_energy_source','tp_month','elcc']]

# ra_requirement_areas.csv
ra_requirement_areas = pd.read_excel(io=model_inputs, sheet_name='RA_areas')
Expand Down
26 changes: 10 additions & 16 deletions switch_model/generators/core/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,15 @@ def define_components(mod):
This aggregation is performed for the benefit of the objective function.
"""
mod.GENERATION_PROJECTS = Set()
mod.GENERATION_PROJECTS = Set(dimen=1)

mod.gen_tech = Param(mod.GENERATION_PROJECTS)
mod.gen_tech = Param(mod.GENERATION_PROJECTS, within=Any)
mod.GENERATION_TECHNOLOGIES = Set(initialize=lambda m:
{m.gen_tech[g] for g in m.GENERATION_PROJECTS}
{m.gen_tech[g] for g in m.GENERATION_PROJECTS},
ordered=False
)
mod.gen_energy_source = Param(mod.GENERATION_PROJECTS,
validate=lambda m,val,g: val in m.ENERGY_SOURCES or val == "multiple")
validate=lambda m,val,g: val in m.ENERGY_SOURCES or val == "multiple", within=Any)
mod.gen_load_zone = Param(mod.GENERATION_PROJECTS, within=mod.LOAD_ZONES)
mod.gen_max_age = Param(mod.GENERATION_PROJECTS, within=PositiveIntegers, default=25)
mod.gen_is_variable = Param(mod.GENERATION_PROJECTS, within=Boolean)
Expand Down Expand Up @@ -322,22 +323,15 @@ def gen_build_can_operate_in_period(m, g, build_year, period):
# mid_period = m.period_start[period] + 0.5 * m.period_length_years[period]
# return online <= m.period_start[period] and mid_period <= retirement

# The set of periods when a project built in a certain year will be online
mod.PERIODS_FOR_GEN_BLD_YR = Set(
mod.GEN_BLD_YRS,
within=mod.PERIODS,
ordered=True,
initialize=lambda m, g, bld_yr: set(
period for period in m.PERIODS
if gen_build_can_operate_in_period(m, g, bld_yr, period)))
# The set of build years that could be online in the given period
# for the given project.
mod.BLD_YRS_FOR_GEN_PERIOD = Set(
mod.GENERATION_PROJECTS, mod.PERIODS,
initialize=lambda m, g, period: set(
bld_yr for (gen, bld_yr) in m.GEN_BLD_YRS
if gen == g and
gen_build_can_operate_in_period(m, g, bld_yr, period)))
gen_build_can_operate_in_period(m, g, bld_yr, period)),
ordered=False)
# The set of periods when a generator is available to run
mod.PERIODS_FOR_GEN = Set(
mod.GENERATION_PROJECTS,
Expand Down Expand Up @@ -549,13 +543,13 @@ def load_inputs(mod, switch_data, inputs_dir):
'gen_forced_outage_rate', 'gen_capacity_limit_mw', 'gen_unit_size',
'gen_min_build_capacity', 'gen_is_cogen', 'gen_variant_group'],
index=mod.GENERATION_PROJECTS,
param=(mod.gen_tech, mod.gen_energy_source,
param=[mod.gen_tech, mod.gen_energy_source,
mod.gen_load_zone, mod.gen_is_variable, mod.gen_is_storage,
mod.gen_is_baseload, mod.gen_scheduled_outage_rate,
mod.gen_forced_outage_rate, mod.gen_capacity_limit_mw,
mod.gen_unit_size, mod.ppa_energy_cost, mod.gen_min_build_capacity,
mod.ppa_capacity_cost, mod.gen_is_cogen,
mod.gen_variant_group, mod.gen_pricing_node))
mod.gen_variant_group, mod.gen_pricing_node])
# Construct sets of capacity-limited, ccs-capable and unit-size-specified
# projects. These sets include projects for which these parameters have
# a value
Expand All @@ -575,7 +569,7 @@ def load_inputs(mod, switch_data, inputs_dir):
filename=os.path.join(inputs_dir, 'gen_build_predetermined.csv'),
auto_select=True,
index=mod.PREDETERMINED_GEN_BLD_YRS,
param=(mod.gen_predetermined_cap))
param=[mod.gen_predetermined_cap])
switch_data.load_aug(
filename=os.path.join(inputs_dir, 'gen_build_years.csv'),
set=mod.GEN_BLD_YRS)
Expand Down
Loading

0 comments on commit 3e0307d

Please sign in to comment.