Skip to content

Commit 1575847

Browse files
authored
Merge pull request #83 from staadecker/min_per_type
Add the min_per_tech module
2 parents 8bc6d5e + 8c160de commit 1575847

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"""
2+
This module allows defining a constraint that specifies a minimum buildout for a certain type of gen_tech.
3+
4+
The advantage of this module is that it stills allows switch to decide where to place
5+
the specified technology.
6+
"""
7+
import os
8+
9+
from pyomo.environ import *
10+
11+
from switch_model.reporting import write_table
12+
13+
14+
def define_components(mod):
15+
mod.GEN_TECH_PER_PERIOD = Set(
16+
initialize=lambda m: m.GENERATION_TECHNOLOGIES * m.PERIODS,
17+
dimen=2,
18+
doc="Set of generation technologies and periods"
19+
)
20+
21+
mod.minimum_capacity_mw = Param(
22+
mod.GEN_TECH_PER_PERIOD,
23+
within=NonNegativeReals,
24+
default=0,
25+
doc="The minimum amount of capacity for a period and generation technology"
26+
)
27+
28+
mod.minimum_energy_capacity_mwh = Param(
29+
mod.GEN_TECH_PER_PERIOD,
30+
within=NonNegativeReals,
31+
default=0,
32+
doc="The minimum amount of energy capacity for a period and generation technology (only considers storage)"
33+
)
34+
35+
mod.GenCapacityPerTech = Expression(
36+
mod.GEN_TECH_PER_PERIOD,
37+
rule=lambda m, tech, p: sum(m.GenCapacity[g, p] for g in m.GENS_BY_TECHNOLOGY[tech]),
38+
doc="The amount of power capacity for a period and technology."
39+
)
40+
41+
mod.GenEnergyCapacityPerTech = Expression(
42+
mod.GEN_TECH_PER_PERIOD,
43+
rule=lambda m, tech, p: sum(m.StorageEnergyCapacity[g, p] for g in m.STORAGE_GENS if m.gen_tech[g] == tech),
44+
doc="The amount of energy capacity for a period and technology (only considers storage from the storage module)."
45+
)
46+
47+
power_scaling_factor = 1e-4
48+
49+
mod.Enforce_Minimum_Capacity_Per_Tech = Constraint(
50+
mod.GEN_TECH_PER_PERIOD,
51+
rule=lambda m, tech, p:
52+
Constraint.Skip if m.minimum_capacity_mw[tech, p] == 0
53+
else m.GenCapacityPerTech[tech, p] * power_scaling_factor >=
54+
m.minimum_capacity_mw[tech, p] * power_scaling_factor,
55+
doc="Constraint enforcing that the power capacity > minimum"
56+
)
57+
58+
energy_scaling_factor = 1e-5
59+
60+
mod.Enforce_Minimum_Energy_Capacity_Per_Tech = Constraint(
61+
mod.GEN_TECH_PER_PERIOD,
62+
rule=lambda m, tech, p:
63+
Constraint.Skip if m.minimum_energy_capacity_mwh[tech, p] == 0
64+
else m.GenEnergyCapacityPerTech[tech, p] * energy_scaling_factor >=
65+
m.minimum_energy_capacity_mwh[tech, p] * energy_scaling_factor,
66+
doc="Constraint enforcing that the energy capacity > minimum"
67+
)
68+
69+
70+
def load_inputs(mod, switch_data, inputs_dir):
71+
"""
72+
Expected input file:
73+
74+
min_per_tech.csv with the following format:
75+
gen_tech,period,minimum_capacity_mw,minimum_energy_capacity_mwh
76+
Nuclear,2040,10,.
77+
"""
78+
switch_data.load_aug(
79+
filename=os.path.join(inputs_dir, "min_per_tech.csv"),
80+
param=(mod.minimum_capacity_mw, mod.minimum_energy_capacity_mwh),
81+
auto_select=True,
82+
# We want this module to run even if we don't specify a constraint so we still get the useful outputs
83+
optional=True,
84+
optional_params=(mod.minimum_capacity_mw, mod.minimum_energy_capacity_mwh)
85+
)
86+
87+
88+
def post_solve(mod, outdir):
89+
write_table(
90+
mod,
91+
mod.GEN_TECH_PER_PERIOD,
92+
output_file=os.path.join(outdir, "gen_cap_per_tech.csv"),
93+
headings=(
94+
"gen_tech", "period", "gen_capacity", "minimum_capacity_mw", "energy_capacity",
95+
"minimum_energy_capacity_mwh"),
96+
values=lambda m, tech, p: (
97+
tech, p, m.GenCapacityPerTech[tech, p], m.minimum_capacity_mw[tech, p], m.GenEnergyCapacityPerTech[tech, p],
98+
m.minimum_energy_capacity_mwh[tech, p])
99+
)

switch_model/wecc/get_inputs/get_inputs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ def write_csv(data: Iterable[List], fname, headers: List[str], log=True):
6767
"switch_model.transmission.transport.dispatch",
6868
"switch_model.policies.carbon_policies",
6969
"switch_model.policies.rps_unbundled",
70+
"switch_model.policies.min_per_tech", # Always include since it provides useful outputs even when unused
7071
# "switch_model.reporting.basic_exports_wecc",
7172
]
7273

0 commit comments

Comments
 (0)