|
| 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 | + ) |
0 commit comments