1414def define_components (mod ):
1515 mod .GEN_TECH_PER_PERIOD = Set (
1616 initialize = lambda m : m .GENERATION_TECHNOLOGIES * m .PERIODS ,
17- dimen = 2
17+ dimen = 2 ,
18+ doc = "Set of generation technologies and periods"
1819 )
1920
2021 mod .minimum_capacity_mw = Param (
2122 mod .GEN_TECH_PER_PERIOD ,
2223 within = NonNegativeReals ,
23- default = 0
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)"
2433 )
2534
2635 mod .GenCapacityPerTech = Expression (
2736 mod .GEN_TECH_PER_PERIOD ,
28- rule = lambda m , tech , p : sum (m .GenCapacity [g , p ] for g in m .GENS_BY_TECHNOLOGY [tech ])
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)."
2945 )
3046
47+ power_scaling_factor = 1e-4
48+
3149 mod .Enforce_Minimum_Capacity_Per_Tech = Constraint (
3250 mod .GEN_TECH_PER_PERIOD ,
3351 rule = lambda m , tech , p :
34- Constraint .Skip if m .minimum_capacity_mw [tech , p ] == 0 else m .GenCapacityPerTech [tech , p ] >=
35- m .minimum_capacity_mw [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"
3667 )
3768
3869
@@ -41,15 +72,16 @@ def load_inputs(mod, switch_data, inputs_dir):
4172 Expected input file:
4273
4374 min_per_tech.csv with the following format:
44- gen_tech,period,minimum_capacity_mw
45- Nuclear,2040,10
75+ gen_tech,period,minimum_capacity_mw,minimum_energy_capacity_mwh
76+ Nuclear,2040,10,.
4677 """
4778 switch_data .load_aug (
4879 filename = os .path .join (inputs_dir , "min_per_tech.csv" ),
49- param = mod .minimum_capacity_mw ,
80+ param = ( mod .minimum_capacity_mw , mod . minimum_energy_capacity_mwh ) ,
5081 auto_select = True ,
5182 # We want this module to run even if we don't specify a constraint so we still get the useful outputs
52- optional = True
83+ optional = True ,
84+ optional_params = (mod .minimum_capacity_mw , mod .minimum_energy_capacity_mwh )
5385 )
5486
5587
@@ -58,6 +90,10 @@ def post_solve(mod, outdir):
5890 mod ,
5991 mod .GEN_TECH_PER_PERIOD ,
6092 output_file = os .path .join (outdir , "gen_cap_per_tech.csv" ),
61- headings = ("gen_tech" , "period" , "gen_capacity" , "minimum_capacity_mw" ),
62- values = lambda m , tech , p : (tech , p , m .GenCapacityPerTech [tech , p ], m .minimum_capacity_mw [tech , p ])
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 ])
6399 )
0 commit comments