1313
1414def define_components (mod ):
1515 mod .GEN_TECH_PER_PERIOD = Set (
16- initialize = lambda m : m .GENERATION_TECHNOLOGIES * m .PERIODS , dimen = 2
16+ initialize = lambda m : m .GENERATION_TECHNOLOGIES * m .PERIODS ,
17+ dimen = 2 ,
18+ doc = "Set of generation technologies and periods" ,
1719 )
1820
1921 mod .minimum_capacity_mw = Param (
20- mod .GEN_TECH_PER_PERIOD , within = NonNegativeReals , default = 0
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)" ,
2133 )
2234
2335 mod .GenCapacityPerTech = Expression (
2436 mod .GEN_TECH_PER_PERIOD ,
2537 rule = lambda m , tech , p : sum (
2638 m .GenCapacity [g , p ] for g in m .GENS_BY_TECHNOLOGY [tech ]
2739 ),
40+ doc = "The amount of power capacity for a period and technology." ,
41+ )
42+
43+ mod .GenEnergyCapacityPerTech = Expression (
44+ mod .GEN_TECH_PER_PERIOD ,
45+ rule = lambda m , tech , p : sum (
46+ m .StorageEnergyCapacity [g , p ]
47+ for g in m .STORAGE_GENS
48+ if m .gen_tech [g ] == tech
49+ ),
50+ doc = "The amount of energy capacity for a period and technology (only considers storage from the storage module)." ,
2851 )
2952
53+ power_scaling_factor = 1e-4
54+
3055 mod .Enforce_Minimum_Capacity_Per_Tech = Constraint (
3156 mod .GEN_TECH_PER_PERIOD ,
3257 rule = lambda m , tech , p : Constraint .Skip
3358 if m .minimum_capacity_mw [tech , p ] == 0
34- else m .GenCapacityPerTech [tech , p ] >= m .minimum_capacity_mw [tech , p ],
59+ else m .GenCapacityPerTech [tech , p ] * power_scaling_factor
60+ >= m .minimum_capacity_mw [tech , p ] * power_scaling_factor ,
61+ doc = "Constraint enforcing that the power capacity > minimum" ,
62+ )
63+
64+ energy_scaling_factor = 1e-5
65+
66+ mod .Enforce_Minimum_Energy_Capacity_Per_Tech = Constraint (
67+ mod .GEN_TECH_PER_PERIOD ,
68+ rule = lambda m , tech , p : Constraint .Skip
69+ if m .minimum_energy_capacity_mwh [tech , p ] == 0
70+ else m .GenEnergyCapacityPerTech [tech , p ] * energy_scaling_factor
71+ >= m .minimum_energy_capacity_mwh [tech , p ] * energy_scaling_factor ,
72+ doc = "Constraint enforcing that the energy capacity > minimum" ,
3573 )
3674
3775
@@ -40,15 +78,16 @@ def load_inputs(mod, switch_data, inputs_dir):
4078 Expected input file:
4179
4280 min_per_tech.csv with the following format:
43- gen_tech,period,minimum_capacity_mw
44- Nuclear,2040,10
81+ gen_tech,period,minimum_capacity_mw,minimum_energy_capacity_mwh
82+ Nuclear,2040,10,.
4583 """
4684 switch_data .load_aug (
4785 filename = os .path .join (inputs_dir , "min_per_tech.csv" ),
48- param = mod .minimum_capacity_mw ,
86+ param = ( mod .minimum_capacity_mw , mod . minimum_energy_capacity_mwh ) ,
4987 auto_select = True ,
5088 # We want this module to run even if we don't specify a constraint so we still get the useful outputs
5189 optional = True ,
90+ optional_params = (mod .minimum_capacity_mw , mod .minimum_energy_capacity_mwh ),
5291 )
5392
5493
@@ -57,11 +96,20 @@ def post_solve(mod, outdir):
5796 mod ,
5897 mod .GEN_TECH_PER_PERIOD ,
5998 output_file = os .path .join (outdir , "gen_cap_per_tech.csv" ),
60- headings = ("gen_tech" , "period" , "gen_capacity" , "minimum_capacity_mw" ),
99+ headings = (
100+ "gen_tech" ,
101+ "period" ,
102+ "gen_capacity" ,
103+ "minimum_capacity_mw" ,
104+ "energy_capacity" ,
105+ "minimum_energy_capacity_mwh" ,
106+ ),
61107 values = lambda m , tech , p : (
62108 tech ,
63109 p ,
64110 m .GenCapacityPerTech [tech , p ],
65111 m .minimum_capacity_mw [tech , p ],
112+ m .GenEnergyCapacityPerTech [tech , p ],
113+ m .minimum_energy_capacity_mwh [tech , p ],
66114 ),
67115 )
0 commit comments