Skip to content

Commit 21b0bbd

Browse files
committed
Optimise O(n2) group tech-region lookups
Signed-off-by: Davey Elder <iandavidelder@gmail.com>
1 parent 04f9a16 commit 21b0bbd

11 files changed

Lines changed: 211 additions & 284 deletions

File tree

temoa/components/capacity.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
from deprecated import deprecated
1919
from pyomo.environ import value
2020

21+
from temoa.components import geography, technology
22+
2123
from .utils import get_adjusted_existing_capacity, get_capacity_factor
2224

2325
if TYPE_CHECKING:
@@ -456,15 +458,18 @@ def capacity_constraint(
456458
if t in model.tech_curtailment:
457459
# If technologies are present in the curtailment set, then enough
458460
# capacity must be available to cover both activity and curtailment.
459-
return get_capacity_factor(model, r, s, d, t, v) * value(
460-
model.capacity_to_activity[r, t]
461-
) * value(model.segment_fraction[s, d]) * model.v_capacity[
462-
r, p, t, v
463-
] == useful_activity + sum(
461+
curtailment = sum(
464462
model.v_curtailment[r, p, s, d, S_i, t, v, S_o]
465463
for S_i in model.process_inputs[r, p, t, v]
466464
for S_o in model.process_outputs_by_input[r, p, t, v, S_i]
467465
)
466+
return (
467+
get_capacity_factor(model, r, s, d, t, v)
468+
* value(model.capacity_to_activity[r, t])
469+
* value(model.segment_fraction[s, d])
470+
* model.v_capacity[r, p, t, v]
471+
== useful_activity + curtailment
472+
)
468473
else:
469474
return (
470475
get_capacity_factor(model, r, s, d, t, v)
@@ -661,3 +666,37 @@ def create_capacity_and_retirement_sets(model: TemoaModel) -> None:
661666
for r, p, t in model.active_capacity_available_rpt
662667
for v in model.process_vintages[r, p, t]
663668
}
669+
670+
671+
def gather_group_active_processes(
672+
model: TemoaModel, r: Region, p: Period, t: Technology
673+
) -> set[tuple[Region, Technology]]:
674+
"""
675+
A utility to get the valid active processes for a group-region, tech-group pair in period p.
676+
Caches the result if its a new call so we don't repeat these O(n2) lookups.
677+
"""
678+
if (r, p, t) not in model.group_active_processes:
679+
model.group_active_processes[r, p, t] = {
680+
(_r, _t)
681+
for _r in geography.gather_group_regions(model, r)
682+
for _t in technology.gather_group_techs(model, t)
683+
if (_r, p, _t) in model.process_vintages
684+
}
685+
return model.group_active_processes[r, p, t]
686+
687+
688+
def gather_group_built_processes(
689+
model: TemoaModel, r: Region, t: Technology, v: Vintage
690+
) -> set[tuple[Region, Technology]]:
691+
"""
692+
A utility to get the valid built processes for a group-region, tech-group, vintage index.
693+
Caches the result if its a new call so we don't repeat these O(n2) lookups.
694+
"""
695+
if (r, t, v) not in model.group_built_processes:
696+
model.group_built_processes[r, t, v] = {
697+
(_r, _t)
698+
for _r in geography.gather_group_regions(model, r)
699+
for _t in technology.gather_group_techs(model, t)
700+
if (_r, _t, v) in model.process_periods
701+
}
702+
return model.group_built_processes[r, t, v]

0 commit comments

Comments
 (0)