Merge branch 'master' into enspreso-biomass
This commit is contained in:
commit
ad23a648c4
18
Snakefile
18
Snakefile
@ -228,10 +228,10 @@ rule build_industrial_production_per_country_tomorrow:
|
|||||||
input:
|
input:
|
||||||
industrial_production_per_country="resources/industrial_production_per_country.csv"
|
industrial_production_per_country="resources/industrial_production_per_country.csv"
|
||||||
output:
|
output:
|
||||||
industrial_production_per_country_tomorrow="resources/industrial_production_per_country_tomorrow.csv"
|
industrial_production_per_country_tomorrow="resources/industrial_production_per_country_tomorrow_{planning_horizons}.csv"
|
||||||
threads: 1
|
threads: 1
|
||||||
resources: mem_mb=1000
|
resources: mem_mb=1000
|
||||||
benchmark: "benchmarks/build_industrial_production_per_country_tomorrow"
|
benchmark: "benchmarks/build_industrial_production_per_country_tomorrow_{planning_horizons}"
|
||||||
script: 'scripts/build_industrial_production_per_country_tomorrow.py'
|
script: 'scripts/build_industrial_production_per_country_tomorrow.py'
|
||||||
|
|
||||||
|
|
||||||
@ -251,25 +251,25 @@ rule build_industrial_distribution_key:
|
|||||||
rule build_industrial_production_per_node:
|
rule build_industrial_production_per_node:
|
||||||
input:
|
input:
|
||||||
industrial_distribution_key="resources/industrial_distribution_key_elec_s{simpl}_{clusters}.csv",
|
industrial_distribution_key="resources/industrial_distribution_key_elec_s{simpl}_{clusters}.csv",
|
||||||
industrial_production_per_country_tomorrow="resources/industrial_production_per_country_tomorrow.csv"
|
industrial_production_per_country_tomorrow="resources/industrial_production_per_country_tomorrow_{planning_horizons}.csv"
|
||||||
output:
|
output:
|
||||||
industrial_production_per_node="resources/industrial_production_elec_s{simpl}_{clusters}.csv"
|
industrial_production_per_node="resources/industrial_production_elec_s{simpl}_{clusters}_{planning_horizons}.csv"
|
||||||
threads: 1
|
threads: 1
|
||||||
resources: mem_mb=1000
|
resources: mem_mb=1000
|
||||||
benchmark: "benchmarks/build_industrial_production_per_node/s{simpl}_{clusters}"
|
benchmark: "benchmarks/build_industrial_production_per_node/s{simpl}_{clusters}_{planning_horizons}"
|
||||||
script: 'scripts/build_industrial_production_per_node.py'
|
script: 'scripts/build_industrial_production_per_node.py'
|
||||||
|
|
||||||
|
|
||||||
rule build_industrial_energy_demand_per_node:
|
rule build_industrial_energy_demand_per_node:
|
||||||
input:
|
input:
|
||||||
industry_sector_ratios="resources/industry_sector_ratios.csv",
|
industry_sector_ratios="resources/industry_sector_ratios.csv",
|
||||||
industrial_production_per_node="resources/industrial_production_elec_s{simpl}_{clusters}.csv",
|
industrial_production_per_node="resources/industrial_production_elec_s{simpl}_{clusters}_{planning_horizons}.csv",
|
||||||
industrial_energy_demand_per_node_today="resources/industrial_energy_demand_today_elec_s{simpl}_{clusters}.csv"
|
industrial_energy_demand_per_node_today="resources/industrial_energy_demand_today_elec_s{simpl}_{clusters}.csv"
|
||||||
output:
|
output:
|
||||||
industrial_energy_demand_per_node="resources/industrial_energy_demand_elec_s{simpl}_{clusters}.csv"
|
industrial_energy_demand_per_node="resources/industrial_energy_demand_elec_s{simpl}_{clusters}_{planning_horizons}.csv"
|
||||||
threads: 1
|
threads: 1
|
||||||
resources: mem_mb=1000
|
resources: mem_mb=1000
|
||||||
benchmark: "benchmarks/build_industrial_energy_demand_per_node/s{simpl}_{clusters}"
|
benchmark: "benchmarks/build_industrial_energy_demand_per_node/s{simpl}_{clusters}_{planning_horizons}"
|
||||||
script: 'scripts/build_industrial_energy_demand_per_node.py'
|
script: 'scripts/build_industrial_energy_demand_per_node.py'
|
||||||
|
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ rule prepare_sector_network:
|
|||||||
busmap=pypsaeur("resources/busmap_elec_s{simpl}_{clusters}.csv"),
|
busmap=pypsaeur("resources/busmap_elec_s{simpl}_{clusters}.csv"),
|
||||||
clustered_pop_layout="resources/pop_layout_elec_s{simpl}_{clusters}.csv",
|
clustered_pop_layout="resources/pop_layout_elec_s{simpl}_{clusters}.csv",
|
||||||
simplified_pop_layout="resources/pop_layout_elec_s{simpl}.csv",
|
simplified_pop_layout="resources/pop_layout_elec_s{simpl}.csv",
|
||||||
industrial_demand="resources/industrial_energy_demand_elec_s{simpl}_{clusters}.csv",
|
industrial_demand="resources/industrial_energy_demand_elec_s{simpl}_{clusters}_{planning_horizons}.csv",
|
||||||
heat_demand_urban="resources/heat_demand_urban_elec_s{simpl}_{clusters}.nc",
|
heat_demand_urban="resources/heat_demand_urban_elec_s{simpl}_{clusters}.nc",
|
||||||
heat_demand_rural="resources/heat_demand_rural_elec_s{simpl}_{clusters}.nc",
|
heat_demand_rural="resources/heat_demand_rural_elec_s{simpl}_{clusters}.nc",
|
||||||
heat_demand_total="resources/heat_demand_total_elec_s{simpl}_{clusters}.nc",
|
heat_demand_total="resources/heat_demand_total_elec_s{simpl}_{clusters}.nc",
|
||||||
|
@ -175,6 +175,15 @@ sector:
|
|||||||
transport_fuel_cell_efficiency: 0.5
|
transport_fuel_cell_efficiency: 0.5
|
||||||
transport_internal_combustion_efficiency: 0.3
|
transport_internal_combustion_efficiency: 0.3
|
||||||
shipping_average_efficiency: 0.4 #For conversion of fuel oil to propulsion in 2011
|
shipping_average_efficiency: 0.4 #For conversion of fuel oil to propulsion in 2011
|
||||||
|
shipping_hydrogen_liquefaction: true # whether to consider liquefaction costs for shipping H2 demands
|
||||||
|
shipping_hydrogen_share: # 1 means all hydrogen FC
|
||||||
|
2020: 0
|
||||||
|
2025: 0
|
||||||
|
2030: 0.05
|
||||||
|
2035: 0.15
|
||||||
|
2040: 0.3
|
||||||
|
2045: 0.6
|
||||||
|
2050: 1
|
||||||
time_dep_hp_cop: true #time dependent heat pump coefficient of performance
|
time_dep_hp_cop: true #time dependent heat pump coefficient of performance
|
||||||
heat_pump_sink_T: 55. # Celsius, based on DTU / large area radiators; used in build_cop_profiles.py
|
heat_pump_sink_T: 55. # Celsius, based on DTU / large area radiators; used in build_cop_profiles.py
|
||||||
# conservatively high to cover hot water and space heating in poorly-insulated buildings
|
# conservatively high to cover hot water and space heating in poorly-insulated buildings
|
||||||
@ -229,10 +238,32 @@ sector:
|
|||||||
|
|
||||||
|
|
||||||
industry:
|
industry:
|
||||||
St_primary_fraction: 0.3 # fraction of steel produced via primary route (DRI + EAF) versus secondary route (EAF); today fraction is 0.6
|
St_primary_fraction: # fraction of steel produced via primary route versus secondary route (scrap+EAF); today fraction is 0.6
|
||||||
|
2020: 0.6
|
||||||
|
2025: 0.55
|
||||||
|
2030: 0.5
|
||||||
|
2035: 0.45
|
||||||
|
2040: 0.4
|
||||||
|
2045: 0.35
|
||||||
|
2050: 0.3
|
||||||
|
DRI_fraction: # fraction of the primary route converted to DRI + EAF
|
||||||
|
2020: 0
|
||||||
|
2025: 0
|
||||||
|
2030: 0.05
|
||||||
|
2035: 0.2
|
||||||
|
2040: 0.4
|
||||||
|
2045: 0.7
|
||||||
|
2050: 1
|
||||||
H2_DRI: 1.7 #H2 consumption in Direct Reduced Iron (DRI), MWh_H2,LHV/ton_Steel from 51kgH2/tSt in Vogl et al (2018) doi:10.1016/j.jclepro.2018.08.279
|
H2_DRI: 1.7 #H2 consumption in Direct Reduced Iron (DRI), MWh_H2,LHV/ton_Steel from 51kgH2/tSt in Vogl et al (2018) doi:10.1016/j.jclepro.2018.08.279
|
||||||
elec_DRI: 0.322 #electricity consumption in Direct Reduced Iron (DRI) shaft, MWh/tSt HYBRIT brochure https://ssabwebsitecdn.azureedge.net/-/media/hybrit/files/hybrit_brochure.pdf
|
elec_DRI: 0.322 #electricity consumption in Direct Reduced Iron (DRI) shaft, MWh/tSt HYBRIT brochure https://ssabwebsitecdn.azureedge.net/-/media/hybrit/files/hybrit_brochure.pdf
|
||||||
Al_primary_fraction: 0.2 # fraction of aluminium produced via the primary route versus scrap; today fraction is 0.4
|
Al_primary_fraction: # fraction of aluminium produced via the primary route versus scrap; today fraction is 0.4
|
||||||
|
2020: 0.4
|
||||||
|
2025: 0.375
|
||||||
|
2030: 0.35
|
||||||
|
2035: 0.325
|
||||||
|
2040: 0.3
|
||||||
|
2045: 0.25
|
||||||
|
2050: 0.2
|
||||||
MWh_CH4_per_tNH3_SMR: 10.8 # 2012's demand from https://ec.europa.eu/docsroom/documents/4165/attachments/1/translations/en/renditions/pdf
|
MWh_CH4_per_tNH3_SMR: 10.8 # 2012's demand from https://ec.europa.eu/docsroom/documents/4165/attachments/1/translations/en/renditions/pdf
|
||||||
MWh_elec_per_tNH3_SMR: 0.7 # same source, assuming 94-6% split methane-elec of total energy demand 11.5 MWh/tNH3
|
MWh_elec_per_tNH3_SMR: 0.7 # same source, assuming 94-6% split methane-elec of total energy demand 11.5 MWh/tNH3
|
||||||
MWh_H2_per_tNH3_electrolysis: 6.5 # from https://doi.org/10.1016/j.joule.2018.04.017, around 0.197 tH2/tHN3 (>3/17 since some H2 lost and used for energy)
|
MWh_H2_per_tNH3_electrolysis: 6.5 # from https://doi.org/10.1016/j.joule.2018.04.017, around 0.197 tH2/tHN3 (>3/17 since some H2 lost and used for energy)
|
||||||
@ -472,4 +503,8 @@ plotting:
|
|||||||
solid biomass: '#DAA520'
|
solid biomass: '#DAA520'
|
||||||
today: '#D2691E'
|
today: '#D2691E'
|
||||||
shipping: '#6495ED'
|
shipping: '#6495ED'
|
||||||
|
shipping oil: "#6495ED"
|
||||||
|
shipping oil emissions: "#6495ED"
|
||||||
electricity distribution grid: '#333333'
|
electricity distribution grid: '#333333'
|
||||||
|
H2 for industry: "#222222"
|
||||||
|
H2 for shipping: "#6495ED"
|
||||||
|
@ -60,11 +60,13 @@ Future release
|
|||||||
These are included in the environment specifications of PyPSA-Eur.
|
These are included in the environment specifications of PyPSA-Eur.
|
||||||
* Consistent use of ``__main__`` block and further unspecific code cleaning.
|
* Consistent use of ``__main__`` block and further unspecific code cleaning.
|
||||||
* Distinguish costs for home battery storage and inverter from utility-scale battery costs.
|
* Distinguish costs for home battery storage and inverter from utility-scale battery costs.
|
||||||
|
* Added option for hydrogen liquefaction costs for hydrogen demand in shipping.
|
||||||
|
This introduces a new ``H2 liquid`` bus at each location.
|
||||||
|
It is activated via ``sector: shipping_hydrogen_liquefaction: true``.
|
||||||
|
* The share of shipping transformed into hydrogen fuel cell can be now defined for different years in the ``config.yaml`` file. The carbon emission from the remaining share is treated as a negative load on the atmospheric carbon dioxide bus, just like aviation and land transport emissions.
|
||||||
|
* The transformation of the Steel and Aluminium production can be now defined for different years in the ``config.yaml`` file.
|
||||||
* Include the option to alter the maximum energy capacity of a store via the ``carrier+factor`` in the ``{sector_opts}`` wildcard. This can be useful for sensitivity analyses. Example: ``co2 stored+e2`` multiplies the ``e_nom_max`` by factor 2. In this example, ``e_nom_max`` represents the CO2 sequestration potential in Europe.
|
* Include the option to alter the maximum energy capacity of a store via the ``carrier+factor`` in the ``{sector_opts}`` wildcard. This can be useful for sensitivity analyses. Example: ``co2 stored+e2`` multiplies the ``e_nom_max`` by factor 2. In this example, ``e_nom_max`` represents the CO2 sequestration potential in Europe.
|
||||||
|
|
||||||
|
|
||||||
PyPSA-Eur-Sec 0.5.0 (21st May 2021)
|
PyPSA-Eur-Sec 0.5.0 (21st May 2021)
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
|
from prepare_sector_network import get
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if 'snakemake' not in globals():
|
if 'snakemake' not in globals():
|
||||||
from helper import mock_snakemake
|
from helper import mock_snakemake
|
||||||
@ -9,27 +11,35 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
config = snakemake.config["industry"]
|
config = snakemake.config["industry"]
|
||||||
|
|
||||||
|
investment_year = int(snakemake.wildcards.planning_horizons)
|
||||||
|
|
||||||
fn = snakemake.input.industrial_production_per_country
|
fn = snakemake.input.industrial_production_per_country
|
||||||
production = pd.read_csv(fn, index_col=0)
|
production = pd.read_csv(fn, index_col=0)
|
||||||
|
|
||||||
keys = ["Integrated steelworks", "Electric arc"]
|
keys = ["Integrated steelworks", "Electric arc"]
|
||||||
total_steel = production[keys].sum(axis=1)
|
total_steel = production[keys].sum(axis=1)
|
||||||
|
|
||||||
|
st_primary_fraction = get(config["St_primary_fraction"], investment_year)
|
||||||
|
dri_fraction = get(config["DRI_fraction"], investment_year)
|
||||||
int_steel = production["Integrated steelworks"].sum()
|
int_steel = production["Integrated steelworks"].sum()
|
||||||
fraction_persistent_primary = config["St_primary_fraction"] * total_steel.sum() / int_steel
|
fraction_persistent_primary = st_primary_fraction * total_steel.sum() / int_steel
|
||||||
|
|
||||||
dri = fraction_persistent_primary * production["Integrated steelworks"]
|
dri = dri_fraction * fraction_persistent_primary * production["Integrated steelworks"]
|
||||||
production.insert(2, "DRI + Electric arc", dri)
|
production.insert(2, "DRI + Electric arc", dri)
|
||||||
|
|
||||||
production["Electric arc"] = total_steel - production["DRI + Electric arc"]
|
not_dri = (1 - dri_fraction)
|
||||||
production["Integrated steelworks"] = 0.
|
production["Integrated steelworks"] = not_dri * fraction_persistent_primary * production["Integrated steelworks"]
|
||||||
|
production["Electric arc"] = total_steel - production["DRI + Electric arc"] - production["Integrated steelworks"]
|
||||||
|
|
||||||
keys = ["Aluminium - primary production", "Aluminium - secondary production"]
|
keys = ["Aluminium - primary production", "Aluminium - secondary production"]
|
||||||
total_aluminium = production[keys].sum(axis=1)
|
total_aluminium = production[keys].sum(axis=1)
|
||||||
|
|
||||||
key_pri = "Aluminium - primary production"
|
key_pri = "Aluminium - primary production"
|
||||||
key_sec = "Aluminium - secondary production"
|
key_sec = "Aluminium - secondary production"
|
||||||
fraction_persistent_primary = config["Al_primary_fraction"] * total_aluminium.sum() / production[key_pri].sum()
|
|
||||||
|
al_primary_fraction = get(config["Al_primary_fraction"], investment_year)
|
||||||
|
fraction_persistent_primary = al_primary_fraction * total_aluminium.sum() / production[key_pri].sum()
|
||||||
|
|
||||||
production[key_pri] = fraction_persistent_primary * production[key_pri]
|
production[key_pri] = fraction_persistent_primary * production[key_pri]
|
||||||
production[key_sec] = total_aluminium - production[key_pri]
|
production[key_sec] = total_aluminium - production[key_pri]
|
||||||
|
|
||||||
|
@ -34,7 +34,9 @@ def rename_techs(label):
|
|||||||
rename_if_contains_dict = {
|
rename_if_contains_dict = {
|
||||||
"water tanks": "hot water storage",
|
"water tanks": "hot water storage",
|
||||||
"retrofitting": "building retrofitting",
|
"retrofitting": "building retrofitting",
|
||||||
"H2": "hydrogen storage",
|
"H2 Electrolysis": "hydrogen storage",
|
||||||
|
"H2 Fuel Cell": "hydrogen storage",
|
||||||
|
"H2 pipeline": "hydrogen storage",
|
||||||
"battery": "battery storage",
|
"battery": "battery storage",
|
||||||
"CC": "CC"
|
"CC": "CC"
|
||||||
}
|
}
|
||||||
|
@ -906,7 +906,7 @@ def add_storage(n, costs):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# hydrogen stored overground (where not already underground)
|
# hydrogen stored overground (where not already underground)
|
||||||
h2_capital_cost = costs.at["hydrogen storage tank", "fixed"]
|
h2_capital_cost = costs.at["hydrogen storage tank incl. compressor", "fixed"]
|
||||||
nodes_overground = cavern_nodes.index.symmetric_difference(nodes)
|
nodes_overground = cavern_nodes.index.symmetric_difference(nodes)
|
||||||
|
|
||||||
n.madd("Store",
|
n.madd("Store",
|
||||||
@ -941,9 +941,9 @@ def add_storage(n, costs):
|
|||||||
p_min_pu=-1,
|
p_min_pu=-1,
|
||||||
p_nom_extendable=True,
|
p_nom_extendable=True,
|
||||||
length=h2_links.length.values,
|
length=h2_links.length.values,
|
||||||
capital_cost=costs.at['H2 pipeline', 'fixed'] * h2_links.length.values,
|
capital_cost=costs.at['H2 (g) pipeline', 'fixed'] * h2_links.length.values,
|
||||||
carrier="H2 pipeline",
|
carrier="H2 pipeline",
|
||||||
lifetime=costs.at['H2 pipeline', 'lifetime']
|
lifetime=costs.at['H2 (g) pipeline', 'lifetime']
|
||||||
)
|
)
|
||||||
|
|
||||||
n.add("Carrier", "battery")
|
n.add("Carrier", "battery")
|
||||||
@ -997,7 +997,7 @@ def add_storage(n, costs):
|
|||||||
carrier="Sabatier",
|
carrier="Sabatier",
|
||||||
efficiency=costs.at["methanation", "efficiency"],
|
efficiency=costs.at["methanation", "efficiency"],
|
||||||
efficiency2=-costs.at["methanation", "efficiency"] * costs.at['gas', 'CO2 intensity'],
|
efficiency2=-costs.at["methanation", "efficiency"] * costs.at['gas', 'CO2 intensity'],
|
||||||
capital_cost=costs.at["methanation", "fixed"],
|
capital_cost=costs.at["methanation", "fixed"] * costs.at["methanation", "efficiency"], # costs given per kW_gas
|
||||||
lifetime=costs.at['methanation', 'lifetime']
|
lifetime=costs.at['methanation', 'lifetime']
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1711,18 +1711,66 @@ def add_industry(n, costs):
|
|||||||
p_set=industrial_demand.loc[nodes, "hydrogen"] / 8760
|
p_set=industrial_demand.loc[nodes, "hydrogen"] / 8760
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if options["shipping_hydrogen_liquefaction"]:
|
||||||
|
|
||||||
|
n.madd("Bus",
|
||||||
|
nodes,
|
||||||
|
suffix=" H2 liquid",
|
||||||
|
carrier="H2 liquid",
|
||||||
|
location=nodes
|
||||||
|
)
|
||||||
|
|
||||||
|
n.madd("Link",
|
||||||
|
nodes + " H2 liquefaction",
|
||||||
|
bus0=nodes + " H2",
|
||||||
|
bus1=nodes + " H2 liquid",
|
||||||
|
carrier="H2 liquefaction",
|
||||||
|
efficiency=costs.at["H2 liquefaction", 'efficiency'],
|
||||||
|
capital_cost=costs.at["H2 liquefaction", 'fixed'],
|
||||||
|
p_nom_extendable=True,
|
||||||
|
lifetime=costs.at['H2 liquefaction', 'lifetime']
|
||||||
|
)
|
||||||
|
|
||||||
|
shipping_bus = nodes + " H2 liquid"
|
||||||
|
else:
|
||||||
|
shipping_bus = nodes + " H2"
|
||||||
|
|
||||||
all_navigation = ["total international navigation", "total domestic navigation"]
|
all_navigation = ["total international navigation", "total domestic navigation"]
|
||||||
efficiency = options['shipping_average_efficiency'] / costs.at["fuel cell", "efficiency"]
|
efficiency = options['shipping_average_efficiency'] / costs.at["fuel cell", "efficiency"]
|
||||||
p_set = nodal_energy_totals.loc[nodes, all_navigation].sum(axis=1) * 1e6 * efficiency / 8760
|
shipping_hydrogen_share = get(options['shipping_hydrogen_share'], investment_year)
|
||||||
|
p_set = shipping_hydrogen_share * nodal_energy_totals.loc[nodes, all_navigation].sum(axis=1) * 1e6 * efficiency / 8760
|
||||||
|
|
||||||
n.madd("Load",
|
n.madd("Load",
|
||||||
nodes,
|
nodes,
|
||||||
suffix=" H2 for shipping",
|
suffix=" H2 for shipping",
|
||||||
bus=nodes + " H2",
|
bus=shipping_bus,
|
||||||
carrier="H2 for shipping",
|
carrier="H2 for shipping",
|
||||||
p_set=p_set
|
p_set=p_set
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if shipping_hydrogen_share < 1:
|
||||||
|
|
||||||
|
shipping_oil_share = 1 - shipping_hydrogen_share
|
||||||
|
|
||||||
|
p_set = shipping_oil_share * nodal_energy_totals.loc[nodes, all_navigation].sum(axis=1) * 1e6 / 8760.
|
||||||
|
|
||||||
|
n.madd("Load",
|
||||||
|
nodes,
|
||||||
|
suffix=" shipping oil",
|
||||||
|
bus="EU oil",
|
||||||
|
carrier="shipping oil",
|
||||||
|
p_set=p_set
|
||||||
|
)
|
||||||
|
|
||||||
|
co2 = shipping_oil_share * nodal_energy_totals.loc[nodes, all_navigation].sum().sum() * 1e6 / 8760 * costs.at["oil", "CO2 intensity"]
|
||||||
|
|
||||||
|
n.add("Load",
|
||||||
|
"shipping oil emissions",
|
||||||
|
bus="co2 atmosphere",
|
||||||
|
carrier="shipping oil emissions",
|
||||||
|
p_set=-co2
|
||||||
|
)
|
||||||
|
|
||||||
if "EU oil" not in n.buses.index:
|
if "EU oil" not in n.buses.index:
|
||||||
|
|
||||||
n.add("Bus",
|
n.add("Bus",
|
||||||
|
@ -151,7 +151,6 @@ def add_chp_constraints(n):
|
|||||||
|
|
||||||
|
|
||||||
def extra_functionality(n, snapshots):
|
def extra_functionality(n, snapshots):
|
||||||
add_chp_constraints(n)
|
|
||||||
add_battery_constraints(n)
|
add_battery_constraints(n)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user