|
12 | 12 | import pyomo.core as po # pylint: disable=import-error |
13 | 13 | import numpy as np |
14 | 14 |
|
15 | | -from calliope.backend.pyomo.util import get_param, split_comma_list |
| 15 | +from calliope.backend.pyomo.util import ( |
| 16 | + apply_equals, |
| 17 | + get_param, |
| 18 | + split_comma_list, |
| 19 | + invalid, |
| 20 | +) |
16 | 21 | from calliope import exceptions |
17 | 22 |
|
18 | 23 | ORDER = 10 # order in which to invoke constraints relative to other constraint files |
@@ -103,28 +108,21 @@ def get_capacity_constraint( |
103 | 108 |
|
104 | 109 | decision_variable = getattr(backend_model, parameter) |
105 | 110 |
|
106 | | - if not _equals: |
| 111 | + if _equals is None: |
107 | 112 | _equals = get_param(backend_model, parameter + "_equals", loc_tech) |
108 | | - if not _max: |
| 113 | + if _max is None: |
109 | 114 | _max = get_param(backend_model, parameter + "_max", loc_tech) |
110 | | - if not _min: |
| 115 | + if _min is None: |
111 | 116 | _min = get_param(backend_model, parameter + "_min", loc_tech) |
112 | | - if po.value(_equals) is not False and po.value(_equals) is not None: |
113 | | - if np.isinf(po.value(_equals)): |
114 | | - e = exceptions.ModelError |
115 | | - raise e( |
116 | | - "Cannot use inf for {}_equals for loc:tech `{}`".format( |
117 | | - parameter, loc_tech |
118 | | - ) |
119 | | - ) |
120 | | - if scale: |
| 117 | + if apply_equals(_equals): |
| 118 | + if scale is not None: |
121 | 119 | _equals *= scale |
122 | 120 | return decision_variable[loc_tech] == _equals |
123 | 121 | else: |
124 | 122 | if po.value(_min) == 0 and np.isinf(po.value(_max)): |
125 | 123 | return po.Constraint.NoConstraint |
126 | 124 | else: |
127 | | - if scale: |
| 125 | + if scale is not None: |
128 | 126 | _max *= scale |
129 | 127 | _min *= scale |
130 | 128 | return (_min, decision_variable[loc_tech], _max) |
@@ -236,10 +234,15 @@ def energy_capacity_storage_equals_constraint_rule(backend_model, loc_tech): |
236 | 234 | \\forall loc::tech \\in loc::techs_{store} |
237 | 235 |
|
238 | 236 | """ |
239 | | - return backend_model.energy_cap[loc_tech] == ( |
240 | | - backend_model.storage_cap[loc_tech] |
241 | | - * get_param(backend_model, "energy_cap_per_storage_cap_equals", loc_tech) |
| 237 | + energy_cap_per_storage_cap = get_param( |
| 238 | + backend_model, "energy_cap_per_storage_cap_equals", loc_tech |
242 | 239 | ) |
| 240 | + if apply_equals(energy_cap_per_storage_cap): |
| 241 | + return backend_model.energy_cap[loc_tech] == ( |
| 242 | + backend_model.storage_cap[loc_tech] * energy_cap_per_storage_cap |
| 243 | + ) |
| 244 | + else: |
| 245 | + return po.Constraint.Skip |
243 | 246 |
|
244 | 247 |
|
245 | 248 | def resource_capacity_constraint_rule(backend_model, loc_tech): |
@@ -321,7 +324,7 @@ def resource_area_constraint_rule(backend_model, loc_tech): |
321 | 324 | backend_model, "resource_area_per_energy_cap", loc_tech |
322 | 325 | ) |
323 | 326 |
|
324 | | - if po.value(energy_cap_max) == 0 and not po.value(area_per_energy_cap): |
| 327 | + if po.value(energy_cap_max) == 0 and invalid(area_per_energy_cap): |
325 | 328 | # If a technology has no energy_cap here, we force resource_area to zero, |
326 | 329 | # so as not to accrue spurious costs |
327 | 330 | return backend_model.resource_area[loc_tech] == 0 |
@@ -443,16 +446,12 @@ def energy_capacity_systemwide_constraint_rule(backend_model, tech): |
443 | 446 | max_systemwide = get_param(backend_model, "energy_cap_max_systemwide", tech) |
444 | 447 | equals_systemwide = get_param(backend_model, "energy_cap_equals_systemwide", tech) |
445 | 448 |
|
446 | | - if np.isinf(po.value(max_systemwide)) and not equals_systemwide: |
| 449 | + if np.isinf(po.value(max_systemwide)) and not apply_equals(equals_systemwide): |
447 | 450 | return po.Constraint.NoConstraint |
448 | | - elif equals_systemwide and np.isinf(po.value(equals_systemwide)): |
449 | | - raise exceptions.ModelError( |
450 | | - "Cannot use inf for energy_cap_equals_systemwide for tech `{}`".format(tech) |
451 | | - ) |
452 | 451 |
|
453 | 452 | sum_expr = sum(backend_model.energy_cap[loc_tech] for loc_tech in all_loc_techs) |
454 | 453 |
|
455 | | - if equals_systemwide: |
| 454 | + if not invalid(equals_systemwide): |
456 | 455 | return sum_expr == equals_systemwide * multiplier |
457 | 456 | else: |
458 | 457 | return sum_expr <= max_systemwide * multiplier |
0 commit comments