From 886c13e40f80085268b44e9dc064b0fe18f0a6b1 Mon Sep 17 00:00:00 2001 From: Dave Woodruff Date: Tue, 6 Jul 2021 20:04:16 -0700 Subject: [PATCH 1/6] handle single point cost curves --- egret/model_library/transmission/gen.py | 7 ++++--- egret/model_library/transmission/tx_utils.py | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/egret/model_library/transmission/gen.py b/egret/model_library/transmission/gen.py index f0659fe7..6e815b6b 100644 --- a/egret/model_library/transmission/gen.py +++ b/egret/model_library/transmission/gen.py @@ -217,9 +217,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] diff --git a/egret/model_library/transmission/tx_utils.py b/egret/model_library/transmission/tx_utils.py index fb99fb0b..39d1e6cc 100644 --- a/egret/model_library/transmission/tx_utils.py +++ b/egret/model_library/transmission/tx_utils.py @@ -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 " @@ -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 From 9a9ae177e5edd97b8bcbc87dbdc25e473f73fc41 Mon Sep 17 00:00:00 2001 From: David L Woodruff Date: Tue, 6 Jul 2021 20:20:52 -0700 Subject: [PATCH 2/6] fix misplaced paren and enhance a message --- egret/model_library/transmission/gen.py | 2 +- egret/model_library/transmission/tx_utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/egret/model_library/transmission/gen.py b/egret/model_library/transmission/gen.py index 6e815b6b..fe1333fe 100644 --- a/egret/model_library/transmission/gen.py +++ b/egret/model_library/transmission/gen.py @@ -217,7 +217,7 @@ 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] - if len(cleaned_values > 1): + 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] diff --git a/egret/model_library/transmission/tx_utils.py b/egret/model_library/transmission/tx_utils.py index 39d1e6cc..4a0b6c88 100644 --- a/egret/model_library/transmission/tx_utils.py +++ b/egret/model_library/transmission/tx_utils.py @@ -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 From 2813be414e365a8bb29ba9e4a46130680cd8bd49 Mon Sep 17 00:00:00 2001 From: Bernard Knueven Date: Wed, 7 Jul 2021 11:15:42 -0600 Subject: [PATCH 3/6] updating test_tx_utils --- .../transmission/tests/test_tx_utils.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/egret/model_library/transmission/tests/test_tx_utils.py b/egret/model_library/transmission/tests/test_tx_utils.py index 90e1f3f3..13db9c0d 100644 --- a/egret/model_library/transmission/tests/test_tx_utils.py +++ b/egret/model_library/transmission/tests/test_tx_utils.py @@ -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 @@ -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 @@ -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']) @@ -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']) @@ -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 @@ -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 @@ -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 @@ -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 From 9ea0cb0a31a64a49da15ce82b6054aa100ea3d6c Mon Sep 17 00:00:00 2001 From: Bernard Knueven Date: Wed, 7 Jul 2021 11:20:59 -0600 Subject: [PATCH 4/6] catching one more case --- egret/model_library/transmission/tx_utils.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/egret/model_library/transmission/tx_utils.py b/egret/model_library/transmission/tx_utils.py index 4a0b6c88..d85fae4d 100644 --- a/egret/model_library/transmission/tx_utils.py +++ b/egret/model_library/transmission/tx_utils.py @@ -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}: From d7be32c1b9b224d2a0582931866b303ac6b21b18 Mon Sep 17 00:00:00 2001 From: Bernard Knueven Date: Wed, 7 Jul 2021 11:54:31 -0600 Subject: [PATCH 5/6] adding fix for epigraph model --- egret/model_library/transmission/gen.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/egret/model_library/transmission/gen.py b/egret/model_library/transmission/gen.py index fe1333fe..c77db3b8 100644 --- a/egret/model_library/transmission/gen.py +++ b/egret/model_library/transmission/gen.py @@ -153,11 +153,15 @@ 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] + indexed_pw_cost_con[gen_name, 0] = cost_var == intercept else: raise ValueError(f"Unrecognized cost_cureve_type: {cost_dict['cost_curve_type']}") From 2dee8cf18761328823d428614c134555045d16fd Mon Sep 17 00:00:00 2001 From: Bernard Knueven Date: Wed, 7 Jul 2021 16:09:53 -0600 Subject: [PATCH 6/6] adding index and fixing typo --- egret/model_library/transmission/gen.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/egret/model_library/transmission/gen.py b/egret/model_library/transmission/gen.py index c77db3b8..d7f15b3b 100644 --- a/egret/model_library/transmission/gen.py +++ b/egret/model_library/transmission/gen.py @@ -161,9 +161,10 @@ def _pw_cost_helper(cost_dict, cost_var, gen_var, pw_cost_set, gen_name, indexed 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):