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

Singlecost #240

Merged
merged 6 commits into from
Jul 7, 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
24 changes: 15 additions & 9 deletions egret/model_library/transmission/gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,18 @@ def _pw_cost_helper(cost_dict, cost_var, gen_var, pw_cost_set, gen_name, indexed
p_min=gen_var.lb,
p_max=gen_var.ub,
gen_name=gen_name)
for ndx, ((pt1, cost1), (pt2, cost2)) in enumerate(zip(cleaned_values, cleaned_values[1:])):
slope = (cost2 - cost1) / (pt2 - pt1)
intercept = cost2 - slope * pt2
pw_cost_set.add((gen_name, ndx))
indexed_pw_cost_con[gen_name, ndx] = cost_var >= slope * gen_var + intercept
if len(cleaned_values) > 1:
for ndx, ((pt1, cost1), (pt2, cost2)) in enumerate(zip(cleaned_values, cleaned_values[1:])):
slope = (cost2 - cost1) / (pt2 - pt1)
intercept = cost2 - slope * pt2
pw_cost_set.add((gen_name, ndx))
indexed_pw_cost_con[gen_name, ndx] = cost_var >= slope * gen_var + intercept
else:
intercept = cleaned_values[0][1]
pw_cost_set.add((gen_name, 0))
indexed_pw_cost_con[gen_name, 0] = cost_var == intercept
else:
raise ValueError(f"Unrecognized cost_cureve_type: {cost_dict['cost_curve_type']}")
raise ValueError(f"Unrecognized cost_curve_type: {cost_dict['cost_curve_type']}")


def declare_piecewise_pg_cost_cons(model, index_set, p_costs):
Expand Down Expand Up @@ -217,9 +222,10 @@ def declare_expression_pg_operating_cost(model, index_set, p_costs, pw_formulati
p_max=p_max,
gen_name=gen_name)
expr = cleaned_values[0][1]
for ndx, ((o1, c1), (o2, c2)) in enumerate(zip(cleaned_values, cleaned_values[1:])):
slope = (c2 - c1) / (o2 - o1)
expr += slope * m.delta_pg[gen_name, ndx]
if len(cleaned_values) > 1:
for ndx, ((o1, c1), (o2, c2)) in enumerate(zip(cleaned_values, cleaned_values[1:])):
slope = (c2 - c1) / (o2 - o1)
expr += slope * m.delta_pg[gen_name, ndx]
m.pg_operating_cost[gen_name] = expr
else:
m.pg_operating_cost[gen_name] = m.pg_cost[gen_name]
Expand Down
16 changes: 8 additions & 8 deletions egret/model_library/transmission/tests/test_tx_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def test_pw_low_p_min(self):
t=None)
self.assertEqual(cleaned_values, expected_values)
self.assertIsNot(cleaned_values, curve['values'])
self.assertEqual(cm.output, ['WARNING:egret.model_library.transmission.tx_utils:WARNING: Extending piecewise linear cost curve beyond p_min and/or p_max for generator foo'])
self.assertEqual(cm.output, ['WARNING:egret.model_library.transmission.tx_utils:WARNING: Extending piecewise linear cost curve beyond p_min and/or p_max for generator foo (and perhaps others)'])
# reset for next test
tx_utils.validate_and_clean_cost_curve._printed_warning = False

Expand All @@ -131,7 +131,7 @@ def test_pw_high_p_max(self):
t=None)
self.assertEqual(cleaned_values, expected_values)
self.assertIsNot(cleaned_values, curve['values'])
self.assertEqual(cm.output, ['WARNING:egret.model_library.transmission.tx_utils:WARNING: Extending piecewise linear cost curve beyond p_min and/or p_max for generator foo'])
self.assertEqual(cm.output, ['WARNING:egret.model_library.transmission.tx_utils:WARNING: Extending piecewise linear cost curve beyond p_min and/or p_max for generator foo (and perhaps others)'])
# reset for next test
tx_utils.validate_and_clean_cost_curve._printed_warning = False

Expand Down Expand Up @@ -256,7 +256,7 @@ def test_pw_pmin_is_pmax_on_curve(self):
p_max=40,
gen_name='foo',
t=None)
expected_values = [(40, 128), (40, 128)]
expected_values = [(40, 128)]
self.assertEqual(cleaned_values, expected_values)
self.assertIsNot(expected_values, curve['values'])

Expand All @@ -272,7 +272,7 @@ def test_pw_pmin_is_pmax_single_point(self):
p_max=40,
gen_name='foo',
t=None)
expected_values = [(40, 128), (40, 128)]
expected_values = [(40, 128)]
self.assertEqual(cleaned_values, expected_values)
self.assertIsNot(expected_values, curve['values'])

Expand All @@ -297,7 +297,7 @@ def test_pmax_less_than_first_point2(self):
p_max=5,
gen_name='foo',
t=None)
expected_values = [(5, 3), (5, 3)]
expected_values = [(5, 3)]
self.assertEqual(cleaned_values, expected_values)
self.assertIsNot(expected_values, curve['values'])
tx_utils.validate_and_clean_cost_curve._printed_warning = False
Expand All @@ -323,7 +323,7 @@ def test_pmax_is_first_point2(self):
p_max=10,
gen_name='foo',
t=None)
expected_values = [(10, 18), (10, 18)]
expected_values = [(10, 18)]
self.assertEqual(cleaned_values, expected_values)
self.assertIsNot(expected_values, curve['values'])
tx_utils.validate_and_clean_cost_curve._printed_warning = False
Expand All @@ -349,7 +349,7 @@ def test_pmin_greater_than_last_point2(self):
p_max=100,
gen_name='foo',
t=None)
expected_values = [(100, 588), (100, 588)]
expected_values = [(100, 588)]
self.assertEqual(cleaned_values, expected_values)
self.assertIsNot(expected_values, curve['values'])
tx_utils.validate_and_clean_cost_curve._printed_warning = False
Expand All @@ -375,7 +375,7 @@ def test_pmin_is_last_point2(self):
p_max=90,
gen_name='foo',
t=None)
expected_values = [(90, 498), (90, 498)]
expected_values = [(90, 498)]
self.assertEqual(cleaned_values, expected_values)
self.assertIsNot(expected_values, curve['values'])
tx_utils.validate_and_clean_cost_curve._printed_warning = False
Expand Down
14 changes: 10 additions & 4 deletions egret/model_library/transmission/tx_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ def validate_and_clean_cost_curve(curve, curve_type, p_min, p_max, gen_name, t=N
o1, c1 = values[0]
# allow and resolve some FP error
if math.isclose(p_min, p_max) and (math.isclose(p_min, o1) or math.isclose(p_max, o1)):
return [(p_min,c1), (p_max,c1)]
return [(p_min,c1)]
else:
at_time_t = "" if (t is None) else f"at time {t}"
raise ValueError(f"Generator {gen_name} {at_time_t} has only a single point on its "
Expand All @@ -617,7 +617,7 @@ def validate_and_clean_cost_curve(curve, curve_type, p_min, p_max, gen_name, t=N
if validate_and_clean_cost_curve._printed_warning:
logger.debug(msg)
else:
logger.warning(msg)
logger.warning(msg+" (and perhaps others)")
validate_and_clean_cost_curve._printed_warning = True

# we should have copied the user's data at this point, and this
Expand All @@ -634,10 +634,10 @@ def validate_and_clean_cost_curve(curve, curve_type, p_min, p_max, gen_name, t=N
if math.isclose(p_min, p_max):
of, cf = values[0]
if math.isclose(p_min, of):
return [(p_min,cf), (p_max,cf)]
return [(p_min,cf)]
ol, cl = values[-1]
if math.isclose(p_max, ol):
return [(p_min,cl), (p_max,cl)]
return [(p_max,cl)]

cleaned_values = list()
last_slope = None
Expand Down Expand Up @@ -678,6 +678,12 @@ def validate_and_clean_cost_curve(curve, curve_type, p_min, p_max, gen_name, t=N
_insert_first_point(p_min, cleaned_values, pop=True)
_insert_last_point(p_max, cleaned_values, pop=True)

# If p_min is p_max, we'll have two identical
# (or close to identical) points. In this case
# we'll just take the last one.
if math.isclose(p_min, p_max):
cleaned_values.pop(0)

# if we have a quadratic cost curve, ensure its convexity
elif curve[curve_type + '_type'] == 'polynomial':
if set(values.keys()) <= {0, 1, 2}:
Expand Down