Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replacing __getitem__() with at() for ordered sets #243

Merged
merged 6 commits into from
Aug 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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