|
| 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( |
| 38 | + m.GenCapacity[g, p] for g in m.GENS_BY_TECHNOLOGY[tech] |
| 39 | + ), |
| 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).", |
| 51 | + ) |
| 52 | + |
| 53 | + power_scaling_factor = 1e-4 |
| 54 | + |
| 55 | + mod.Enforce_Minimum_Capacity_Per_Tech = Constraint( |
| 56 | + mod.GEN_TECH_PER_PERIOD, |
| 57 | + rule=lambda m, tech, p: Constraint.Skip |
| 58 | + if m.minimum_capacity_mw[tech, p] == 0 |
| 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", |
| 73 | + ) |
| 74 | + |
| 75 | + |
| 76 | +def load_inputs(mod, switch_data, inputs_dir): |
| 77 | + """ |
| 78 | + Expected input file: |
| 79 | +
|
| 80 | + min_per_tech.csv with the following format: |
| 81 | + gen_tech,period,minimum_capacity_mw,minimum_energy_capacity_mwh |
| 82 | + Nuclear,2040,10,. |
| 83 | + """ |
| 84 | + switch_data.load_aug( |
| 85 | + filename=os.path.join(inputs_dir, "min_per_tech.csv"), |
| 86 | + param=(mod.minimum_capacity_mw, mod.minimum_energy_capacity_mwh), |
| 87 | + auto_select=True, |
| 88 | + # We want this module to run even if we don't specify a constraint so we still get the useful outputs |
| 89 | + optional=True, |
| 90 | + optional_params=(mod.minimum_capacity_mw, mod.minimum_energy_capacity_mwh), |
| 91 | + ) |
| 92 | + |
| 93 | + |
| 94 | +def post_solve(mod, outdir): |
| 95 | + write_table( |
| 96 | + mod, |
| 97 | + mod.GEN_TECH_PER_PERIOD, |
| 98 | + output_file=os.path.join(outdir, "gen_cap_per_tech.csv"), |
| 99 | + headings=( |
| 100 | + "gen_tech", |
| 101 | + "period", |
| 102 | + "gen_capacity", |
| 103 | + "minimum_capacity_mw", |
| 104 | + "energy_capacity", |
| 105 | + "minimum_energy_capacity_mwh", |
| 106 | + ), |
| 107 | + values=lambda m, tech, p: ( |
| 108 | + tech, |
| 109 | + p, |
| 110 | + m.GenCapacityPerTech[tech, p], |
| 111 | + m.minimum_capacity_mw[tech, p], |
| 112 | + m.GenEnergyCapacityPerTech[tech, p], |
| 113 | + m.minimum_energy_capacity_mwh[tech, p], |
| 114 | + ), |
| 115 | + ) |
0 commit comments