Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
12422dd
Subclass model data into thermal and renewable.
xiangao1 May 17, 2022
359863c
Treat thermal and renewable static params differently in coordiantor.
xiangao1 May 17, 2022
3839e2b
Generate different bids in selfscheduler for thermal and renewable ge…
xiangao1 May 17, 2022
59a97a2
Fix a bug.
xiangao1 May 17, 2022
7e97e8b
Update iterator capabilities.
xiangao1 May 17, 2022
0926ac3
Update the tests.
xiangao1 May 17, 2022
dd7919f
Fix conflicts.
xiangao1 May 17, 2022
b507c3f
Include initial status in the thermal model data.
xiangao1 May 18, 2022
7b1b40d
Deactivate DA power UB when DA signal is realized.
xiangao1 May 18, 2022
b4ab0b3
Use nearest historical prices first.
xiangao1 May 18, 2022
47fa831
Ignore default bids.
xiangao1 May 18, 2022
4a9cb75
Add doc strings and comments in Backcaster.
xiangao1 May 19, 2022
005c91b
2.0.0a2
lbianchi-lbl May 20, 2022
a48761e
Remove prerelease extras_require for release branch
lbianchi-lbl Jun 10, 2022
f50087b
Merge branch 'handle-renewable-gen' into 2.0.0.dev0
dguittet Jul 1, 2022
84b0b64
update ver to 2.0.0.a3
dguittet Jul 3, 2022
62e7fbc
fix some typos
dguittet Jul 5, 2022
aba0b7b
Merge branch 'main' into 2.0.0.dev4
dguittet Jul 5, 2022
2904490
Update ver.py
dguittet Jul 11, 2022
6a90192
Merge branch 'main' into 2.0_rel
lbianchi-lbl Aug 25, 2022
1042b48
2.0.0a3
lbianchi-lbl Aug 25, 2022
b2cbd7d
Merge branch 'main' into update_grid_integration
dguittet Oct 10, 2022
3327400
ver.py
dguittet Oct 10, 2022
e1579a8
black format
dguittet Oct 10, 2022
d96cc07
fix thermal_generator.py
dguittet Oct 11, 2022
b6fa9c3
Squashed commit of the following:
dguittet Oct 12, 2022
5b9bc4e
add test for RT bidding
dguittet Oct 24, 2022
4597a67
add to test_coordinator.py
dguittet Oct 24, 2022
32e41e6
Merge branch 'main' into update_grid_integration
dguittet Oct 24, 2022
5361796
black formatting
dguittet Oct 24, 2022
736978f
Merge branch 'update_grid_integration' of https://github.com/dguittet…
dguittet Oct 24, 2022
8413d5b
add real_time_underbid_power docstring & fix tests
dguittet Oct 25, 2022
73b8961
black formatting
dguittet Oct 26, 2022
e8fbccc
update bounds of agc bid
dguittet Oct 26, 2022
1b08e68
Merge branch 'grid_integration_agc_bounds' into update_grid_integration
dguittet Oct 26, 2022
466a22a
change default p_cost bid pairs
dguittet Nov 15, 2022
4026965
2.0.0b0
lbianchi-lbl Dec 1, 2022
6289a4d
Update Pyomo version
lbianchi-lbl Dec 1, 2022
028494d
Merge branch 'main' into 2.0_rel
lbianchi-lbl Dec 1, 2022
e27f02c
Update import paths deprecated in Pyomo 6.4.3
lbianchi-lbl Dec 1, 2022
b5c56aa
2.0.0b1
lbianchi-lbl Dec 1, 2022
0320582
Removes state bounds for mole_frac_comp (#1040)
MarcusHolly Dec 1, 2022
906c205
Cleanup unused imports Pt 1 (#1039)
Dec 2, 2022
0421ca4
Helmholtz fix (#1042)
dallan-keylogic Dec 2, 2022
0bdd637
2.0.0b2
lbianchi-lbl Dec 2, 2022
4c3c625
Merge branch 'main' into update_grid_integration
dguittet Dec 13, 2022
90e6619
Merge remote-tracking branch 'origin/main' into update_grid_integration
dguittet Dec 14, 2022
af45a88
Merge remote-tracking branch 'dguittet/update_grid_integration' into …
dguittet Dec 14, 2022
481833d
Merge branch '2.0_rel' into update_grid_integration
dguittet Dec 14, 2022
7350887
update model data
dguittet Jan 10, 2023
382d715
merge of "update_grid_integration" and "dguittet/update_grid_integrat…
dguittet Jan 10, 2023
1cdc8d6
fix black
dguittet Jan 10, 2023
a993790
Merge branch 'main' into update_grid_integration
dguittet Jan 10, 2023
bcc4b1d
updates
dguittet Jan 10, 2023
c7ed1a2
Merge branch 'update_grid_integration' of https://github.com/dguittet…
dguittet Jan 10, 2023
838c77d
fix tests
dguittet Jan 11, 2023
11574d9
fix minor bidder.py bug
dguittet Jan 11, 2023
83ad0f0
black formatting
dguittet Jan 11, 2023
653e43d
fix test
dguittet Jan 11, 2023
7c315e3
Merge branch 'main' into update_grid_integration
dguittet Jan 30, 2023
977c757
Merge branch 'main' into update_grid_integration
adowling2 Feb 8, 2023
de67791
Merge branch 'main' into update_grid_integration
dguittet Feb 13, 2023
111a815
add tests
dguittet Feb 13, 2023
ab94723
Merge branch 'main' into update_grid_integration
dguittet Feb 13, 2023
a6c8592
Merge branch 'main' into update_grid_integration
Feb 13, 2023
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
9 changes: 7 additions & 2 deletions idaes/apps/grid_integration/bidder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1214,8 +1214,13 @@ def _assemble_bids(self, model, power_var_name, energy_price_param_name, hour):

for t in time_index:

# make sure the orignal points in the bids
for power, marginal_cost in self.bidding_model_object.model_data.p_cost:
# always include pmin in the cost curve, but include the other points if required
if self.bidding_model_object.model_data.include_default_p_cost:
p_cost_add = self.bidding_model_object.model_data.p_cost
else:
p_cost_add = self.bidding_model_object.model_data.p_cost[0:1]

for power, marginal_cost in p_cost_add:
if round(power, 2) not in bids[t][gen]:
bids[t][gen][power] = marginal_cost

Expand Down
16 changes: 15 additions & 1 deletion idaes/apps/grid_integration/model_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ class ThermalGeneratorModelData(GeneratorModelData):
Adds run time, ramping, shutdown and startup information for thermal generators.
Requires as initial status and power production.
Bids are in ( MWh, $ ) pairs

if `include_default_p_cost` is True, then the `production_cost_bid_pairs` provided during init
will always be included in future production cost curves (see bidder.py:1221)
"""

min_down_time = RealValueValidator(min_val=0)
Expand Down Expand Up @@ -223,6 +226,8 @@ def __init__(
fixed_commitment=None,
production_cost_bid_pairs=None,
startup_cost_pairs=None,
include_default_p_cost=True,
**kwargs,
):

super().__init__(
Expand All @@ -241,6 +246,7 @@ def __init__(
self.startup_capacity = startup_capacity
self.initial_status = initial_status
self.initial_p_output = initial_p_output
self.include_default_p_cost = include_default_p_cost

self.p_cost = self._assemble_default_cost_bids(production_cost_bid_pairs)
self.startup_cost = self._assemble_default_startup_cost_bids(startup_cost_pairs)
Expand Down Expand Up @@ -290,7 +296,15 @@ def _assemble_default_cost_bids(self, production_cost_bid_pairs):
f"The first power output in the bid should be the Pmin {self.p_min}, but {production_cost_bid_pairs[0][0]} is provided."
)

if production_cost_bid_pairs[-1][0] != self.p_max:
if len(production_cost_bid_pairs) < 2:
raise ValueError(
f"A valid production_cost_bid_pairs requires at least 2 points"
)

if (
self.include_default_p_cost
and production_cost_bid_pairs[-1][0] != self.p_max
):
raise ValueError(
f"The last power output in the bid should be the Pmax {self.p_max}, but {production_cost_bid_pairs[-1][0]} is provided."
)
Expand Down
64 changes: 64 additions & 0 deletions idaes/apps/grid_integration/tests/test_bidder.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,67 @@ def test_compute_RT_bids(bidder_object):
}

pyo_unittest.assertStructuredAlmostEqual(first=expected_bids, second=bids)


@pytest.fixture
def bidder_object_pcost():

solver = pyo.SolverFactory("cbc")
forecaster = TestingForecaster(prediction=30)

# create a bidder model
testing_model_data.include_default_p_cost = False
bidding_model_object = TestingModel(model_data=testing_model_data)
bidder_object = Bidder(
bidding_model_object=bidding_model_object,
day_ahead_horizon=day_ahead_horizon,
real_time_horizon=real_time_horizon,
n_scenario=n_scenario,
solver=solver,
forecaster=forecaster,
)
return bidder_object


@pytest.mark.component
@pytest.mark.skipif(
not prescient_avail, reason="Prescient (optional dependency) not available"
)
def test_compute_RT_bids_pcost(bidder_object_pcost):
marginal_cost = bidder_object_pcost.bidding_model_object.marginal_cost
gen = bidder_object_pcost.generator
default_bids = bidder_object_pcost.bidding_model_object.model_data.p_cost
pmin = bidder_object_pcost.bidding_model_object.pmin
pmax = bidder_object_pcost.bidding_model_object.pmax
date = "2021-08-20"

# test bidding when price forecast lower than marginal cost
# expect default bids
realized_day_ahead_prices = [29] * bidder_object_pcost.real_time_horizon
realized_day_ahead_dispatches = [0] * bidder_object_pcost.real_time_horizon
shift = 1
fixed_forecast = marginal_cost - shift
bidder_object_pcost.forecaster.prediction = fixed_forecast
bids = bidder_object_pcost.compute_real_time_bids(
date=date,
hour=0,
realized_day_ahead_prices=realized_day_ahead_prices,
realized_day_ahead_dispatches=realized_day_ahead_dispatches,
)

expected_bids = {
t: {
gen: {
"p_min": pmin,
"p_max": pmin,
"p_min_agc": pmin,
"p_max_agc": pmin,
"startup_capacity": pmin,
"shutdown_capacity": pmin,
"p_cost": [(30, 0)],
}
}
for t in range(horizon)
}

pyo_unittest.assertStructuredAlmostEqual(first=expected_bids, second=bids)
13 changes: 12 additions & 1 deletion idaes/apps/grid_integration/tests/test_model_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def test_bid_missing_pmin(generator_params):

@pytest.mark.unit
def test_bid_missing_pmax(generator_params):
generator_params["production_cost_bid_pairs"].pop()
generator_params["production_cost_bid_pairs"] = [(30, 0), (45, 0)]
with pytest.raises(
ValueError, match=r"^(The last power output in the bid should be the Pmax)"
):
Expand All @@ -212,6 +212,16 @@ def test_invalid_start_up_bid(generator_params):
ThermalGeneratorModelData(**generator_params)


@pytest.mark.unit
def test_invalid_pcost(generator_params):
generator_params["production_cost_bid_pairs"] = [(30, 0)]
with pytest.raises(
ValueError,
match=r"^(A valid production_cost_bid_pairs requires at least 2 points)",
):
ThermalGeneratorModelData(**generator_params)


@pytest.mark.unit
def test_model_data_iterator(generator_data_object):

Expand All @@ -232,6 +242,7 @@ def test_model_data_iterator(generator_data_object):
"generator_type",
"initial_status",
"initial_p_output",
"include_default_p_cost",
]
iter_result = [name for name, value in generator_data_object]

Expand Down