Skip to content

Commit

Permalink
Merge pull request #243 from bknueven/set_getitem_fix
Browse files Browse the repository at this point in the history
Replacing __getitem__() with at() for ordered sets
  • Loading branch information
michaelbynum authored Aug 23, 2021
2 parents 9a9c29c + 7fc28de commit c4e5a05
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 56 deletions.
15 changes: 5 additions & 10 deletions .github/workflows/egret.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,17 @@ jobs:
matrix:
os: [ubuntu-latest]
python-version: [3.7, 3.8, 3.9]
pyomo-version: [5.7.1]
pyutilib-version: [6.0.0]
pyomo-version: [6.1.2]
include:
- os: macos-latest
python-version: 3.7
pyomo-version: 5.7.1
pyutilib-version: 6.0.0
pyomo-version: 6.1.2
- os: windows-latest
python-version: 3.7
pyomo-version: 5.7.1
pyutilib-version: 6.0.0
pyomo-version: 6.1.2
- os: ubuntu-latest
python-version: 3.7
pyomo-version: main
pyutilib-version: master
steps:
- uses: actions/checkout@v2
- uses: conda-incubator/setup-miniconda@v2
Expand All @@ -66,6 +62,8 @@ jobs:
else
conda install -c conda-forge coincbc
fi
# test cbc executable
cbc -quit
- name: Install IPOPT
run: |
if [ ${{ matrix.os }} = windows-latest ]
Expand Down Expand Up @@ -111,9 +109,6 @@ jobs:
- name: Install Cython/Numpy/Pandas
run: |
pip install cython numpy pandas
- name: Instal Pyutilib
run: |
pip install git+https://github.com/PyUtilib/pyutilib.git@${{ matrix.pyutilib-version }}
- name: Install Pyomo
run: |
pip install git+https://github.com/Pyomo/pyomo.git@${{ matrix.pyomo-version }}
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/prescient.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ defaults:

jobs:
build:
name: Prescient master, ${{ matrix.os }}, Python ${{ matrix.python-version }}, Pyomo ${{ matrix.pyomo-version }}
name: Prescient main, ${{ matrix.os }}, Python ${{ matrix.python-version }}, Pyomo ${{ matrix.pyomo-version }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python-version: [3.7]
pyomo-version: [5.7.1]
pyomo-version: [6.1.2]
steps:
- uses: actions/checkout@v2
- uses: conda-incubator/setup-miniconda@v2
Expand All @@ -47,6 +47,8 @@ jobs:
else
conda install -c conda-forge coincbc
fi
# test cbc executable
cbc -quit
- name: Install Pyomo
run: |
pip install git+https://github.com/Pyomo/pyomo.git@${{ matrix.pyomo-version }}
Expand All @@ -58,7 +60,6 @@ jobs:
cd ..
git clone --depth=1 https://github.com/grid-parity-exchange/Prescient.git
cd Prescient
conda env update --name test_env --file environment.yml
python setup.py develop
- name: Run Prescient Tests
run: |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ EGRET is available under the BSD License (see [LICENSE.txt](https://github.com/g
### Requirements

* Python 3.7 or later
* Pyomo version 5.7.1 or later
* Pyomo version 6.1.2 or later
* pytest
* Optimization solvers for Pyomo - specific requirements depends on the models being solved. EGRET is tested with Gurobi or CPLEX for MIP-based problems (e.g., unit commitment) and Ipopt (with HSL linear solvers) for NLP problems.

Expand Down
8 changes: 4 additions & 4 deletions egret/model_library/unit_commitment/power_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,19 @@ def power_generated_startup_shutdown_expr_rule(m, g, t):
future_startup_past_shutdown_production = 0.
future_startup_power_index = time_periods_before_startup + m.NumTimePeriods - t
if future_startup_power_index <= len(startup_curve):
future_startup_past_shutdown_production += startup_curve[future_startup_power_index]
future_startup_past_shutdown_production += startup_curve.at(future_startup_power_index)

past_shutdown_power_index = time_periods_since_shutdown + t
if past_shutdown_power_index <= len(shutdown_curve):
future_startup_past_shutdown_production += shutdown_curve[past_shutdown_power_index]
future_startup_past_shutdown_production += shutdown_curve.at(past_shutdown_power_index)

linear_vars, linear_coefs = m._get_power_generated_lists(m,g,t)
for startup_idx in range(1, min( len(startup_curve)+1, m.NumTimePeriods+1-t )):
linear_vars.append(m.UnitStart[g,t+startup_idx])
linear_coefs.append(startup_curve[startup_idx])
linear_coefs.append(startup_curve.at(startup_idx))
for shutdown_idx in range(1, min( len(shutdown_curve)+1, t+1 )):
linear_vars.append(m.UnitStop[g,t-shutdown_idx+1])
linear_coefs.append(shutdown_curve[shutdown_idx])
linear_coefs.append(shutdown_curve.at(shutdown_idx))
linear_expr = get_linear_expr(m.UnitOn, m.UnitStart, m.UnitStop)
return linear_expr(linear_vars=linear_vars, linear_coefs=linear_coefs, constant=future_startup_past_shutdown_production)

Expand Down
74 changes: 37 additions & 37 deletions egret/model_library/unit_commitment/startup_costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ def ComputeStartupCost2_rule(m,g,t):

for tp in m.ShutdownsByStartups[g,t]:
for s in m.StartupCostIndices[g]:
this_lag = startup_lags[s]
next_lag = startup_lags[s+1]
this_lag = startup_lags.at(s)
next_lag = startup_lags.at(s+1)
if this_lag <= t - tp < next_lag:
linear_vars.append(m.StartupIndicator[g,tp,t])
linear_coefs.append(startup_costs[s] - last_startup_cost)
linear_coefs.append(startup_costs.at(s) - last_startup_cost)
break

return (linear_expr(linear_vars=linear_vars, linear_coefs=linear_coefs), 0.)
Expand Down Expand Up @@ -195,8 +195,8 @@ def delta_ineq_rule(m,g,s,t):
## the last startup indicator doesn't have a lag
if s == len(m.StartupCostIndices[g]):
return Constraint.Skip
this_lag = m.ScaledStartupLags[g][s]
next_lag = m.ScaledStartupLags[g][s+1]
this_lag = m.ScaledStartupLags[g].at(s)
next_lag = m.ScaledStartupLags[g].at(s+1)
## this is negative if the generator has previously been off
generator_t0_state = int(round(value(m.UnitOnT0State[g])/value(m.TimePeriodLengthHours)))

Expand Down Expand Up @@ -236,7 +236,7 @@ def delta_ineq_rule(m,g,s,t):
linear_expr = get_linear_expr()
def ComputeStartupCost2_rule(m,g,t):
linear_vars = [m.delta[g,s,t] for s in m.StartupCostIndices[g]]
linear_coefs = [m.StartupCosts[g][s] for s in m.StartupCostIndices[g]]
linear_coefs = [m.StartupCosts[g].at(s) for s in m.StartupCostIndices[g]]
linear_vars.append(m.StartupCost[g,t])
linear_coefs.append(-1.)
return (linear_expr(linear_vars, linear_coefs),0.)
Expand Down Expand Up @@ -272,8 +272,8 @@ def startup_costs_index_set_generator(m):

def compute_startup_costs_rule(m, g, t, i):
# irios, Nov 18th: I had to change this because the last version didn't work with the last update in coopr.
this_lag = m.ScaledStartupLags[g][i]
this_cost = m.StartupCosts[g][i]
this_lag = m.ScaledStartupLags[g].at(i)
this_cost = m.StartupCosts[g].at(i)

startup_lags = m.ScaledStartupLags[g]
startup_costs = m.StartupCosts[g]
Expand All @@ -299,17 +299,17 @@ def compute_startup_costs_rule(m, g, t, i):
if m.status_vars == 'garver_2bin_vars':
## This is just the equation below with the UnitStop's projected out
return m.StartupCost[g, t] >= this_cost * m.UnitStart[g, t] \
- sum((this_cost - startup_costs[j])*
( (m.UnitOn[g,t-startup_lags[j+1]] if t-startup_lags[j+1] > 0 else ( m.UnitOnT0[g] if t-startup_lags[j+1] == 0 else 0. ))
- (m.UnitOn[g,t-startup_lags[j]] if t-startup_lags[j] > 0 else ( m.UnitOnT0[g] if t-startup_lags[j] == 0 else 0. ))
+ sum(m.UnitStart[g, t-k] for k in range(startup_lags[j], startup_lags[j+1]) if k < t ) )
- sum((this_cost - startup_costs.at(j))*
( (m.UnitOn[g,t-startup_lags.at(j+1)] if t-startup_lags.at(j+1) > 0 else ( m.UnitOnT0[g] if t-startup_lags.at(j+1) == 0 else 0. ))
- (m.UnitOn[g,t-startup_lags.at(j)] if t-startup_lags.at(j) > 0 else ( m.UnitOnT0[g] if t-startup_lags.at(j) == 0 else 0. ))
+ sum(m.UnitStart[g, t-k] for k in range(startup_lags.at(j), startup_lags.at(j+1)) if k < t ) )
for j in range(1, i) )
else:
return m.StartupCost[g, t] >= this_cost * m.UnitStart[g, t] \
- sum(
sum(
(this_cost - startup_costs[j])*m.UnitStop[g, t-k]
for k in range(startup_lags[j], startup_lags[j+1]) if k < t )
(this_cost - startup_costs.at(j))*m.UnitStop[g, t-k]
for k in range(startup_lags.at(j), startup_lags.at(j+1)) if k < t )
for j in range(1, i) )

model.ComputeStartupCosts = Constraint(model.StartupCostsIndexSet, rule=compute_startup_costs_rule)
Expand Down Expand Up @@ -346,8 +346,8 @@ def startup_costs_index_set_generator(m):

def compute_startup_costs_rule(m, g, t, i):
# irios, Nov 18th: I had to change this because the last version didn't work with the last update in coopr.
this_lag = m.ScaledStartupLags[g][i]
this_cost = m.StartupCosts[g][i]
this_lag = m.ScaledStartupLags[g].at(i)
this_cost = m.StartupCosts[g].at(i)

startup_lags = m.ScaledStartupLags[g]
startup_costs = m.StartupCosts[g]
Expand All @@ -371,8 +371,8 @@ def compute_startup_costs_rule(m, g, t, i):

# can only "look back" in terms of UnitOn variable state (t-1) or this_lag time periods - whichever is smallest.
# the rest of the time period is captured in the unit T0 state, and is handled in the logic above.
return m.StartupCost[g, t] >= this_cost * m.UnitOn[g, t] - sum( (this_cost)*m.UnitOn[g, t - k] for k in range(1, min(t, startup_lags[1]+1))) \
- sum( sum( (this_cost - startup_costs[j])*m.UnitOn[g, t-k] for k in range(startup_lags[j]+1, startup_lags[j+1]+1) if k < t )\
return m.StartupCost[g, t] >= this_cost * m.UnitOn[g, t] - sum( (this_cost)*m.UnitOn[g, t - k] for k in range(1, min(t, startup_lags.first()+1))) \
- sum( sum( (this_cost - startup_costs.at(j))*m.UnitOn[g, t-k] for k in range(startup_lags.at(j)+1, startup_lags.at(j+1)+1) if k < t )\
for j in range(1, i) )

model.ComputeStartupCosts = Constraint(model.StartupCostsIndexSet, rule=compute_startup_costs_rule)
Expand Down Expand Up @@ -406,8 +406,8 @@ def startup_costs_index_set_generator(m):

def compute_startup_costs_rule(m, g, t, i):
# irios, Nov 18th: I had to change this because the last version didn't work with the last update in coopr.
this_lag = m.ScaledStartupLags[g][i]
this_cost = m.StartupCosts[g][i]
this_lag = m.ScaledStartupLags[g].at(i)
this_cost = m.StartupCosts[g].at(i)

generator_t0_state = int(round(value(m.UnitOnT0State[g])/value(m.TimePeriodLengthHours)))

Expand Down Expand Up @@ -462,8 +462,8 @@ def compute_startup_costs_rule(m, g, t, i):
if i == 1:
return Constraint.Skip
# irios, Nov 18th: I had to change this because the last version didn't work with the last update in coopr.
this_lag = m.ScaledStartupLags[g][i]
this_cost = m.StartupCosts[g][i]
this_lag = m.ScaledStartupLags[g].at(i)
this_cost = m.StartupCosts[g].at(i)

startup_lags = m.ScaledStartupLags[g]
startup_costs = m.StartupCosts[g]
Expand Down Expand Up @@ -540,8 +540,8 @@ def compute_startup_costs_rule(m, g, t, i):
if i == 1:
return Constraint.Skip
# irios, Nov 18th: I had to change this because the last version didn't work with the last update in coopr.
this_lag = m.ScaledStartupLags[g][i]
this_cost = m.StartupCosts[g][i]
this_lag = m.ScaledStartupLags[g].at(i)
this_cost = m.StartupCosts[g].at(i)

generator_t0_state = int(round(value(m.UnitOnT0State[g])/value(m.TimePeriodLengthHours)))

Expand Down Expand Up @@ -601,8 +601,8 @@ def compute_startup_costs_rule(m, g, t, i):
if i == 1:
return Constraint.Skip
# irios, Nov 18th: I had to change this because the last version didn't work with the last update in coopr.
this_lag = m.ScaledStartupLags[g][i]
this_cost = m.StartupCosts[g][i]
this_lag = m.ScaledStartupLags[g].at(i)
this_cost = m.StartupCosts[g].at(i)

startup_lags = m.ScaledStartupLags[g]
startup_costs = m.StartupCosts[g]
Expand All @@ -628,17 +628,17 @@ def compute_startup_costs_rule(m, g, t, i):
if m.status_vars == 'garver_2bin_vars':
## This is just the equation below with the UnitStop's projected out
return m.StartupCostOverHot[g, t] >= (this_cost -m.StartupCosts[g].first()) * m.UnitStart[g, t] \
- sum((this_cost - startup_costs[j])*
( (m.UnitOn[g,t-startup_lags[j+1]] if t-startup_lags[j+1] > 0 else ( m.UnitOnT0[g] if t-startup_lags[j+1] == 0 else 0. ))
- (m.UnitOn[g,t-startup_lags[j]] if t-startup_lags[j] > 0 else ( m.UnitOnT0[g] if t-startup_lags[j] == 0 else 0. ))
+ sum(m.UnitStart[g, t-k] for k in range(startup_lags[j], startup_lags[j+1]) if k < t ) )
- sum((this_cost - startup_costs.at(j))*
( (m.UnitOn[g,t-startup_lags.at(j+1)] if t-startup_lags.at(j+1) > 0 else ( m.UnitOnT0[g] if t-startup_lags.at(j+1) == 0 else 0. ))
- (m.UnitOn[g,t-startup_lags.at(j)] if t-startup_lags.at(j) > 0 else ( m.UnitOnT0[g] if t-startup_lags.at(j) == 0 else 0. ))
+ sum(m.UnitStart[g, t-k] for k in range(startup_lags.at(j), startup_lags.at(j+1)) if k < t ) )
for j in range(1, i) )
else:
return m.StartupCostOverHot[g, t] >= (this_cost -m.StartupCosts[g].first())* m.UnitStart[g, t] \
- sum(
sum(
(this_cost - startup_costs[j])*m.UnitStop[g, t-k]
for k in range(startup_lags[j], startup_lags[j+1]) if k < t )
(this_cost - startup_costs.at(j))*m.UnitStop[g, t-k]
for k in range(startup_lags.at(j), startup_lags.at(j+1)) if k < t )
for j in range(1, i) )

model.ComputeStartupCostsOverHot = Constraint(model.StartupCostsIndexSet, rule=compute_startup_costs_rule)
Expand Down Expand Up @@ -691,8 +691,8 @@ def delta_ineq_rule(m,g,s,t):
assert(m.InitialTime == 1)
if s == len(m.StartupCostIndices[g]):
return Constraint.Skip
this_lag = m.ScaledStartupLags[g][s]
next_lag = m.ScaledStartupLags[g][s+1]
this_lag = m.ScaledStartupLags[g].at(s)
next_lag = m.ScaledStartupLags[g].at(s+1)
## this is negative if the generator has previously been off
generator_t0_state = int(round(value(m.UnitOnT0State[g])/value(m.TimePeriodLengthHours)))

Expand All @@ -719,7 +719,7 @@ def delta_ineq_rule(m,g,s,t):

def ComputeStartupCost2_rule(m,g,t):
return m.StartupCost[g,t] == m.StartupCosts[g].last()*m.UnitStart[g,t] + \
sum(m.delta[g,s,t]*(m.StartupCosts[g][s] - m.StartupCosts[g].last()) for s in m.StartupCostIndices[g] if s < len(m.StartupCostIndices[g]))
sum(m.delta[g,s,t]*(m.StartupCosts[g].at(s) - m.StartupCosts[g].last()) for s in m.StartupCostIndices[g] if s < len(m.StartupCostIndices[g]))
model.ComputeStartupCosts=Constraint(model.SingleFuelGenerators, model.TimePeriods, rule=ComputeStartupCost2_rule)

return
Expand Down Expand Up @@ -826,8 +826,8 @@ def unit_fin_arcs_rule(m, g):

def ComputeStartupCost_rule(m,g,t):
return m.StartupCost[g,t] == m.StartupCosts[g].last()*m.UnitStart[g,t] + \
sum( (m.StartupCosts[g][s] - m.StartupCosts[g].last()) * \
sum( (m.StartupCosts[g].at(s) - m.StartupCosts[g].last()) * \
sum( m.ShutdownStartupIndicator[g,tp,t] for tp in m.ShutdownTimePeriods[g] \
if (m.StartupLags[g][s] <= t - tp < (m.StartupLags[g][s+1])) ) \
if (m.StartupLags[g].at(s) <= t - tp < (m.StartupLags[g].at(s+1))) ) \
for s in m.StartupCostIndices[g] if s < len(m.StartupCostIndices[g]))
model.ComputeStartupCost=Constraint(model.ThermalGenerators, model.TimePeriods, rule=ComputeStartupCost_rule)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
'zip_safe': False,
'scripts': [],
'include_package_data': True,
'install_requires': ['pyomo>=5.7.1', 'numpy', 'pytest', 'pandas',
'install_requires': ['pyomo>=6.1.2', 'numpy', 'pytest', 'pandas',
'matplotlib', 'seaborn', 'scipy', 'networkx',
'coramin==0.1.0'],
'python_requires' : '>=3.7, <4',
Expand Down

0 comments on commit c4e5a05

Please sign in to comment.