Merge branch 'nomopyomo'
This commit is contained in:
commit
105aeba215
@ -219,7 +219,7 @@ rule solve_network:
|
|||||||
memory="logs/" + config['run'] + "/{network}_s{simpl}_{clusters}_lv{lv}_{opts}_{sector_opts}_memory.log"
|
memory="logs/" + config['run'] + "/{network}_s{simpl}_{clusters}_lv{lv}_{opts}_{sector_opts}_memory.log"
|
||||||
benchmark: "benchmarks/solve_network/{network}_s{simpl}_{clusters}_lv{lv}_{opts}_{sector_opts}"
|
benchmark: "benchmarks/solve_network/{network}_s{simpl}_{clusters}_lv{lv}_{opts}_{sector_opts}"
|
||||||
threads: 4
|
threads: 4
|
||||||
resources: mem=120000 #memory in MB; 40 GB enough for 45+B+I; 100 GB based on RESI usage for 128
|
resources: mem=50000 #memory in MB; 40 GB enough for 45+B+I; 100 GB based on RESI usage for 128
|
||||||
# group: "solve" # with group, threads is ignored https://bitbucket.org/snakemake/snakemake/issues/971/group-job-description-does-not-contain
|
# group: "solve" # with group, threads is ignored https://bitbucket.org/snakemake/snakemake/issues/971/group-job-description-does-not-contain
|
||||||
script: "scripts/solve_network.py"
|
script: "scripts/solve_network.py"
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ logging_level: INFO
|
|||||||
|
|
||||||
results_dir: 'results/'
|
results_dir: 'results/'
|
||||||
summary_dir: results
|
summary_dir: results
|
||||||
run: '191108-h2_pipeline_network'
|
run: '191212-ccs'
|
||||||
|
|
||||||
scenario:
|
scenario:
|
||||||
sectors: [E] # ,E+EV,E+BEV,E+BEV+V2G] # [ E+EV, E+BEV, E+BEV+V2G ]
|
sectors: [E] # ,E+EV,E+BEV,E+BEV+V2G] # [ E+EV, E+BEV, E+BEV+V2G ]
|
||||||
@ -10,7 +10,7 @@ scenario:
|
|||||||
lv: [1.0]#, 1.125, 1.25, 1.5, 2.0]# or opt
|
lv: [1.0]#, 1.125, 1.25, 1.5, 2.0]# or opt
|
||||||
clusters: [50] #[90, 128, 181] #[45, 64, 90, 128, 181, 256] #, 362] # (2**np.r_[5.5:9:.5]).astype(int) minimum is 37
|
clusters: [50] #[90, 128, 181] #[45, 64, 90, 128, 181, 256] #, 362] # (2**np.r_[5.5:9:.5]).astype(int) minimum is 37
|
||||||
opts: [''] #for pypsa-eur
|
opts: [''] #for pypsa-eur
|
||||||
sector_opts: [Co2L0-3H-T-H-B-I,Co2L0-5H-T-H-B-I]#,Co2L0p1-3H-T-H-B-I,Co2L0p25-3H-T-H-B-I,Co2L0p5-3H-T-H-B-I]#[Co2L0-3H-T-H-B-I-onwind0-solar3,Co2L0-3H-T-H-B-I-onwind0p125-solar3,Co2L0-3H-T-H-B-I-onwind0p25-solar3,Co2L0-3H-T-H-B-I-onwind0p50-solar3,Co2L0-3H-T-H-B-I-solar3]#,Co2L0-3H-T-H-B-I-onwind0p25-solar3]#,Co2L0p05-3H-T-H-B-I,Co2L0p10-3H-T-H-B-I,Co2L0p20-3H-T-H-B-I,Co2L0p30-3H-T-H-B-I,Co2L0p50-3H-T-H-B-I]#[Co2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0-3H-T-H,Co2L0p20-3H-T-H] #Co2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0p20-3H-T-HCo2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0p30-3H-T-H,Co2L0p50-3H-T-H] #Co2L-3H,Co2L-3H-T,, LC-FL, LC-T, Ep-T, Co2L-T]
|
sector_opts: [Co2L0-3H-T-H-B-I,Co2L0p2-3H-T-H-B-I,Co2L0p5-3H-T-H-B-I]#,Co2L0p1-3H-T-H-B-I,Co2L0p25-3H-T-H-B-I,Co2L0p5-3H-T-H-B-I]#[Co2L0-3H-T-H-B-I-onwind0-solar3,Co2L0-3H-T-H-B-I-onwind0p125-solar3,Co2L0-3H-T-H-B-I-onwind0p25-solar3,Co2L0-3H-T-H-B-I-onwind0p50-solar3,Co2L0-3H-T-H-B-I-solar3]#,Co2L0-3H-T-H-B-I-onwind0p25-solar3]#,Co2L0p05-3H-T-H-B-I,Co2L0p10-3H-T-H-B-I,Co2L0p20-3H-T-H-B-I,Co2L0p30-3H-T-H-B-I,Co2L0p50-3H-T-H-B-I]#[Co2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0-3H-T-H,Co2L0p20-3H-T-H] #Co2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0p20-3H-T-HCo2L-3H-T-H,Co2L0p10-3H-T-H,Co2L0p30-3H-T-H,Co2L0p50-3H-T-H] #Co2L-3H,Co2L-3H-T,, LC-FL, LC-T, Ep-T, Co2L-T]
|
||||||
# Co2L will give default (5%); Co2L0p25 will give 25% CO2 emissions; Co2Lm0p05 will give 5% negative emissions
|
# Co2L will give default (5%); Co2L0p25 will give 25% CO2 emissions; Co2Lm0p05 will give 5% negative emissions
|
||||||
|
|
||||||
|
|
||||||
@ -73,11 +73,6 @@ sector:
|
|||||||
'tes_tau' : 3.
|
'tes_tau' : 3.
|
||||||
'boilers' : True
|
'boilers' : True
|
||||||
'chp' : True
|
'chp' : True
|
||||||
'chp_parameters':
|
|
||||||
'eta_elec' : 0.468 #electrical efficiency with no heat output
|
|
||||||
'c_v' : 0.15 #loss of fuel for each addition of heat
|
|
||||||
'c_m' : 0.75 #backpressure ratio
|
|
||||||
'p_nom_ratio' : 1. #ratio of max heat output to max electrical output
|
|
||||||
'solar_thermal' : True
|
'solar_thermal' : True
|
||||||
'solar_cf_correction': 0.788457 # = >>> 1/1.2683
|
'solar_cf_correction': 0.788457 # = >>> 1/1.2683
|
||||||
'marginal_cost_storage' : 0. #1e-4
|
'marginal_cost_storage' : 0. #1e-4
|
||||||
|
@ -73,15 +73,15 @@ CCGT,2030,efficiency,0.5,per unit,DIW DataDoc http://hdl.handle.net/10419/80348
|
|||||||
biomass,2030,efficiency,0.468,per unit,DIW DataDoc http://hdl.handle.net/10419/80348
|
biomass,2030,efficiency,0.468,per unit,DIW DataDoc http://hdl.handle.net/10419/80348
|
||||||
geothermal,2030,efficiency,0.239,per unit,DIW DataDoc http://hdl.handle.net/10419/80348
|
geothermal,2030,efficiency,0.239,per unit,DIW DataDoc http://hdl.handle.net/10419/80348
|
||||||
nuclear,2030,efficiency,0.337,per unit,DIW DataDoc http://hdl.handle.net/10419/80348
|
nuclear,2030,efficiency,0.337,per unit,DIW DataDoc http://hdl.handle.net/10419/80348
|
||||||
gas,2030,CO2 intensity,0.187,tCO2/MWth,https://www.eia.gov/environment/emissions/co2_vol_mass.php
|
gas,2030,CO2 intensity,0.187,tCO2/MWhth,https://www.eia.gov/environment/emissions/co2_vol_mass.php
|
||||||
coal,2030,efficiency,0.464,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 PC (Advanced/SuperC)
|
coal,2030,efficiency,0.464,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 PC (Advanced/SuperC)
|
||||||
lignite,2030,efficiency,0.447,per unit,DIW DataDoc http://hdl.handle.net/10419/80348
|
lignite,2030,efficiency,0.447,per unit,DIW DataDoc http://hdl.handle.net/10419/80348
|
||||||
oil,2030,efficiency,0.393,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 CT
|
oil,2030,efficiency,0.393,per unit,DIW DataDoc http://hdl.handle.net/10419/80348 CT
|
||||||
coal,2030,CO2 intensity,0.354,tCO2/MWth,https://www.eia.gov/environment/emissions/co2_vol_mass.php
|
coal,2030,CO2 intensity,0.354,tCO2/MWhth,https://www.eia.gov/environment/emissions/co2_vol_mass.php
|
||||||
lignite,2030,CO2 intensity,0.4,tCO2/MWth,German sources
|
lignite,2030,CO2 intensity,0.4,tCO2/MWhth,German sources
|
||||||
oil,2030,CO2 intensity,0.248,tCO2/MWth,https://www.eia.gov/environment/emissions/co2_vol_mass.php
|
oil,2030,CO2 intensity,0.248,tCO2/MWhth,https://www.eia.gov/environment/emissions/co2_vol_mass.php
|
||||||
geothermal,2030,CO2 intensity,0.026,tCO2/MWth,https://www.eia.gov/environment/emissions/co2_vol_mass.php
|
geothermal,2030,CO2 intensity,0.026,tCO2/MWhth,https://www.eia.gov/environment/emissions/co2_vol_mass.php
|
||||||
solid biomass,2030,CO2 intensity,0.3,tCO2/MWth,TODO
|
solid biomass,2030,CO2 intensity,0.3,tCO2/MWhth,TODO
|
||||||
electrolysis,2030,investment,350,EUR/kWel,Palzer Thesis
|
electrolysis,2030,investment,350,EUR/kWel,Palzer Thesis
|
||||||
electrolysis,2030,FOM,4,%/year,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013
|
electrolysis,2030,FOM,4,%/year,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013
|
||||||
electrolysis,2030,lifetime,18,years,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013
|
electrolysis,2030,lifetime,18,years,NREL http://www.nrel.gov/docs/fy09osti/45873.pdf; budischak2013
|
||||||
@ -109,6 +109,14 @@ SMR,2030,investment,540.56,EUR/kWCH4,https://www.gov.uk/government/publications/
|
|||||||
SMR,2030,lifetime,25,years,TODO
|
SMR,2030,lifetime,25,years,TODO
|
||||||
SMR,2030,FOM,5.4,%/year,https://www.gov.uk/government/publications/hydrogen-supply-chain-evidence-base; slide 42 assumption for 2030
|
SMR,2030,FOM,5.4,%/year,https://www.gov.uk/government/publications/hydrogen-supply-chain-evidence-base; slide 42 assumption for 2030
|
||||||
SMR,2030,efficiency,0.74,per unit,https://www.gov.uk/government/publications/hydrogen-supply-chain-evidence-base; slide 42 assumption for 2030
|
SMR,2030,efficiency,0.74,per unit,https://www.gov.uk/government/publications/hydrogen-supply-chain-evidence-base; slide 42 assumption for 2030
|
||||||
|
SMR CCS,2030,investment,1032,EUR/kWCH4,https://www.gov.uk/government/publications/hydrogen-supply-chain-evidence-base; slide 42 assumption for 2030; GBP 466 exchange 1.16; CCS costed at 300 EUR/tCO2/a
|
||||||
|
SMR CCS,2030,lifetime,25,years,TODO
|
||||||
|
SMR CCS,2030,FOM,5.4,%/year,https://www.gov.uk/government/publications/hydrogen-supply-chain-evidence-base; slide 42 assumption for 2030
|
||||||
|
SMR CCS,2030,efficiency,0.67,per unit,https://www.gov.uk/government/publications/hydrogen-supply-chain-evidence-base; slide 42 assumption for 2030; CCS uses 10% of gas
|
||||||
|
industry CCS,2030,investment,300,EUR/tCO2/a,Saygin et al 2013 https://doi.org/10.1016/j.ijggc.2013.05.032
|
||||||
|
industry CCS,2030,FOM,2,%/year,Saygin et al 2013 https://doi.org/10.1016/j.ijggc.2013.05.032
|
||||||
|
industry CCS,2030,lifetime,25,years,Saygin et al 2013 https://doi.org/10.1016/j.ijggc.2013.05.032
|
||||||
|
industry CCS,2030,efficiency,0.9,per unit,Saygin et al 2013 https://doi.org/10.1016/j.ijggc.2013.05.032
|
||||||
Fischer-Tropsch,2030,investment,677.6,EUR/kWH2,Fasihi doi:10.3390/su9020306 (60 kEUR/bpd = 847 EUR/kWL (1b = 1.7 MWh) 847*0.8 = 677.6)
|
Fischer-Tropsch,2030,investment,677.6,EUR/kWH2,Fasihi doi:10.3390/su9020306 (60 kEUR/bpd = 847 EUR/kWL (1b = 1.7 MWh) 847*0.8 = 677.6)
|
||||||
Fischer-Tropsch,2030,lifetime,30,years,doi:10.3390/su9020306
|
Fischer-Tropsch,2030,lifetime,30,years,doi:10.3390/su9020306
|
||||||
Fischer-Tropsch,2030,FOM,3,%/year,doi:10.3390/su9020306
|
Fischer-Tropsch,2030,FOM,3,%/year,doi:10.3390/su9020306
|
||||||
@ -118,7 +126,7 @@ DAC,2030,lifetime,30,years,Fasihi
|
|||||||
DAC,2030,FOM,4,%/year,Fasihi
|
DAC,2030,FOM,4,%/year,Fasihi
|
||||||
battery inverter,2030,investment,411,USD/kWel,budischak2013
|
battery inverter,2030,investment,411,USD/kWel,budischak2013
|
||||||
battery inverter,2030,lifetime,20,years,budischak2013
|
battery inverter,2030,lifetime,20,years,budischak2013
|
||||||
battery inverter,2030,efficiency,0.81,per unit,budischak2013; Lund and Kempton (2008) http://dx.doi.org/10.1016/j.enpol.2008.06.007
|
battery inverter,2030,efficiency,0.81,per unit,budischak2013; Lund and Kempton (2008) https://doi.org/10.1016/j.enpol.2008.06.007
|
||||||
battery inverter,2030,FOM,3,%/year,budischak2013
|
battery inverter,2030,FOM,3,%/year,budischak2013
|
||||||
battery storage,2030,investment,192,USD/kWh,budischak2013
|
battery storage,2030,investment,192,USD/kWh,budischak2013
|
||||||
battery storage,2030,lifetime,15,years,budischak2013
|
battery storage,2030,lifetime,15,years,budischak2013
|
||||||
@ -175,9 +183,38 @@ decentral CHP,2030,lifetime,25,years,HP
|
|||||||
decentral CHP,2030,investment,1400,EUR/kWel,HP
|
decentral CHP,2030,investment,1400,EUR/kWel,HP
|
||||||
decentral CHP,2030,FOM,3,%/year,HP
|
decentral CHP,2030,FOM,3,%/year,HP
|
||||||
decentral CHP,2030,discount rate,0.04,per unit,Palzer thesis
|
decentral CHP,2030,discount rate,0.04,per unit,Palzer thesis
|
||||||
central CHP,2030,lifetime,25,years,HP
|
central gas CHP,2030,lifetime,30,years,DEA
|
||||||
central CHP,2030,investment,650,EUR/kWel,HP
|
central gas CHP,2030,investment,1300,EUR/kWel,DEA
|
||||||
central CHP,2030,FOM,3,%/year,HP
|
central gas CHP,2030,FOM,3,%/year,DEA
|
||||||
|
central gas CHP,2030,efficiency,0.45,per unit,DEA (condensation mode)
|
||||||
|
central gas CHP,2030,c_b,0.7,per unit,DEA (backpressure ratio)
|
||||||
|
central gas CHP,2030,c_v,0.17,per unit,DEA (loss of fuel for additional heat)
|
||||||
|
central gas CHP,2030,p_nom_ratio,1.,per unit,
|
||||||
|
central gas CHP,2030,VOM,0.82,EUR/MWh,DEA
|
||||||
|
central gas CHP CCS,2030,lifetime,30,years,DEA
|
||||||
|
central gas CHP CCS,2030,investment,1900,EUR/kWel,DEA + DIW extra for CCS on gas plant
|
||||||
|
central gas CHP CCS,2030,FOM,3,%/year,DEA
|
||||||
|
central gas CHP CCS,2030,efficiency,0.405,per unit,DEA (condensation mode + efficiency loss due to capture)
|
||||||
|
central gas CHP CCS,2030,c_b,0.7,per unit,DEA (backpressure ratio)
|
||||||
|
central gas CHP CCS,2030,c_v,0.17,per unit,DEA (loss of fuel for additional heat)
|
||||||
|
central gas CHP CCS,2030,p_nom_ratio,1.,per unit,
|
||||||
|
central gas CHP CCS,2030,VOM,0.82,EUR/MWh,DEA
|
||||||
|
central solid biomass CHP,2030,lifetime,40,years,DEA for wood pellets CHP
|
||||||
|
central solid biomass CHP,2030,investment,1990,EUR/kWel,DEA for wood pellets CHP
|
||||||
|
central solid biomass CHP,2030,FOM,3,%/year,DEA for wood pellets CHP
|
||||||
|
central solid biomass CHP,2030,efficiency,0.52,per unit,DEA for wood pellets CHP (condensation mode)
|
||||||
|
central solid biomass CHP,2030,c_b,1.01,per unit,DEA for wood pellets CHP (backpressure ratio)
|
||||||
|
central solid biomass CHP,2030,c_v,0.15,per unit,DEA for wood pellets CHP (loss of fuel for additional heat)
|
||||||
|
central solid biomass CHP,2030,p_nom_ratio,1.,per unit,
|
||||||
|
central solid biomass CHP,2030,VOM,2.2,EUR/MWh,DEA for wood pellets CHP
|
||||||
|
central solid biomass CHP CCS,2030,lifetime,40,years,DEA for wood pellets CHP
|
||||||
|
central solid biomass CHP CCS,2030,investment,2590,EUR/kWel,DEA for wood pellets CHP + DIW extra for CCS on gas plant
|
||||||
|
central solid biomass CHP CCS,2030,FOM,3,%/year,DEA for wood pellets CHP
|
||||||
|
central solid biomass CHP CCS,2030,efficiency,0.468,per unit,DEA for wood pellets CHP (condensation mode + efficiency loss due to capture)
|
||||||
|
central solid biomass CHP CCS,2030,c_b,1.01,per unit,DEA for wood pellets CHP (backpressure ratio)
|
||||||
|
central solid biomass CHP CCS,2030,c_v,0.15,per unit,DEA for wood pellets CHP (loss of fuel for additional heat)
|
||||||
|
central solid biomass CHP CCS,2030,p_nom_ratio,1.,per unit,
|
||||||
|
central solid biomass CHP CCS,2030,VOM,2.2,EUR/MWh,DEA for wood pellets CHP
|
||||||
micro CHP,2030,lifetime,20,years,DEA for PEMFC with methane (for unit consuming 2kW CH4)
|
micro CHP,2030,lifetime,20,years,DEA for PEMFC with methane (for unit consuming 2kW CH4)
|
||||||
micro CHP,2030,investment,4500,EUR/kWCH4,DEA for PEMFC with methane (for unit consuming 2kW CH4)
|
micro CHP,2030,investment,4500,EUR/kWCH4,DEA for PEMFC with methane (for unit consuming 2kW CH4)
|
||||||
micro CHP,2030,FOM,6,%/year,DEA for PEMFC with methane (for unit consuming 2kW CH4)
|
micro CHP,2030,FOM,6,%/year,DEA for PEMFC with methane (for unit consuming 2kW CH4)
|
||||||
|
|
@ -36,6 +36,8 @@ override_component_attrs["Link"].loc["efficiency2"] = ["static or series","per u
|
|||||||
override_component_attrs["Link"].loc["efficiency3"] = ["static or series","per unit",1.,"3rd bus efficiency","Input (optional)"]
|
override_component_attrs["Link"].loc["efficiency3"] = ["static or series","per unit",1.,"3rd bus efficiency","Input (optional)"]
|
||||||
override_component_attrs["Link"].loc["p2"] = ["series","MW",0.,"2nd bus output","Output"]
|
override_component_attrs["Link"].loc["p2"] = ["series","MW",0.,"2nd bus output","Output"]
|
||||||
override_component_attrs["Link"].loc["p3"] = ["series","MW",0.,"3rd bus output","Output"]
|
override_component_attrs["Link"].loc["p3"] = ["series","MW",0.,"3rd bus output","Output"]
|
||||||
|
override_component_attrs["StorageUnit"].loc["p_dispatch"] = ["series","MW",0.,"Storage discharging.","Output"]
|
||||||
|
override_component_attrs["StorageUnit"].loc["p_store"] = ["series","MW",0.,"Storage charging.","Output"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -77,7 +79,7 @@ def calculate_nodal_cfs(n,label,nodal_cfs):
|
|||||||
cf_c = p_c/capacities_c
|
cf_c = p_c/capacities_c
|
||||||
|
|
||||||
index = pd.MultiIndex.from_tuples([(c.list_name,) + t for t in cf_c.index.to_list()])
|
index = pd.MultiIndex.from_tuples([(c.list_name,) + t for t in cf_c.index.to_list()])
|
||||||
nodal_cfs = nodal_cfs.reindex(nodal_cfs.index|index)
|
nodal_cfs = nodal_cfs.reindex(index|nodal_cfs.index)
|
||||||
nodal_cfs.loc[index,label] = cf_c.values
|
nodal_cfs.loc[index,label] = cf_c.values
|
||||||
|
|
||||||
return nodal_cfs
|
return nodal_cfs
|
||||||
@ -102,7 +104,7 @@ def calculate_cfs(n,label,cfs):
|
|||||||
|
|
||||||
cf_c = p_c/capacities_c
|
cf_c = p_c/capacities_c
|
||||||
|
|
||||||
cfs = cfs.reindex(cfs.index|pd.MultiIndex.from_product([[c.list_name],cf_c.index]))
|
cfs = cfs.reindex(pd.MultiIndex.from_product([[c.list_name],cf_c.index])|cfs.index)
|
||||||
|
|
||||||
cfs.loc[idx[c.list_name,list(cf_c.index)],label] = cf_c.values
|
cfs.loc[idx[c.list_name,list(cf_c.index)],label] = cf_c.values
|
||||||
|
|
||||||
@ -116,7 +118,7 @@ def calculate_nodal_costs(n,label,nodal_costs):
|
|||||||
for c in n.iterate_components(n.branch_components|n.controllable_one_port_components^{"Load"}):
|
for c in n.iterate_components(n.branch_components|n.controllable_one_port_components^{"Load"}):
|
||||||
capital_costs = (c.df.capital_cost*c.df[opt_name.get(c.name,"p") + "_nom_opt"]).groupby((c.df.location,c.df.carrier)).sum()
|
capital_costs = (c.df.capital_cost*c.df[opt_name.get(c.name,"p") + "_nom_opt"]).groupby((c.df.location,c.df.carrier)).sum()
|
||||||
index = pd.MultiIndex.from_tuples([(c.list_name,"capital") + t for t in capital_costs.index.to_list()])
|
index = pd.MultiIndex.from_tuples([(c.list_name,"capital") + t for t in capital_costs.index.to_list()])
|
||||||
nodal_costs = nodal_costs.reindex(nodal_costs.index|index)
|
nodal_costs = nodal_costs.reindex(index|nodal_costs.index)
|
||||||
nodal_costs.loc[index,label] = capital_costs.values
|
nodal_costs.loc[index,label] = capital_costs.values
|
||||||
|
|
||||||
if c.name == "Link":
|
if c.name == "Link":
|
||||||
@ -137,7 +139,7 @@ def calculate_nodal_costs(n,label,nodal_costs):
|
|||||||
|
|
||||||
marginal_costs = (p*c.df.marginal_cost).groupby((c.df.location,c.df.carrier)).sum()
|
marginal_costs = (p*c.df.marginal_cost).groupby((c.df.location,c.df.carrier)).sum()
|
||||||
index = pd.MultiIndex.from_tuples([(c.list_name,"marginal") + t for t in marginal_costs.index.to_list()])
|
index = pd.MultiIndex.from_tuples([(c.list_name,"marginal") + t for t in marginal_costs.index.to_list()])
|
||||||
nodal_costs = nodal_costs.reindex(nodal_costs.index|index)
|
nodal_costs = nodal_costs.reindex(index|nodal_costs.index)
|
||||||
nodal_costs.loc[index,label] = marginal_costs.values
|
nodal_costs.loc[index,label] = marginal_costs.values
|
||||||
|
|
||||||
return nodal_costs
|
return nodal_costs
|
||||||
@ -149,7 +151,7 @@ def calculate_costs(n,label,costs):
|
|||||||
capital_costs = c.df.capital_cost*c.df[opt_name.get(c.name,"p") + "_nom_opt"]
|
capital_costs = c.df.capital_cost*c.df[opt_name.get(c.name,"p") + "_nom_opt"]
|
||||||
capital_costs_grouped = capital_costs.groupby(c.df.carrier).sum()
|
capital_costs_grouped = capital_costs.groupby(c.df.carrier).sum()
|
||||||
|
|
||||||
costs = costs.reindex(costs.index|pd.MultiIndex.from_product([[c.list_name],["capital"],capital_costs_grouped.index]))
|
costs = costs.reindex(pd.MultiIndex.from_product([[c.list_name],["capital"],capital_costs_grouped.index])|costs.index)
|
||||||
|
|
||||||
costs.loc[idx[c.list_name,"capital",list(capital_costs_grouped.index)],label] = capital_costs_grouped.values
|
costs.loc[idx[c.list_name,"capital",list(capital_costs_grouped.index)],label] = capital_costs_grouped.values
|
||||||
|
|
||||||
@ -173,7 +175,7 @@ def calculate_costs(n,label,costs):
|
|||||||
|
|
||||||
marginal_costs_grouped = marginal_costs.groupby(c.df.carrier).sum()
|
marginal_costs_grouped = marginal_costs.groupby(c.df.carrier).sum()
|
||||||
|
|
||||||
costs = costs.reindex(costs.index|pd.MultiIndex.from_product([[c.list_name],["marginal"],marginal_costs_grouped.index]))
|
costs = costs.reindex(pd.MultiIndex.from_product([[c.list_name],["marginal"],marginal_costs_grouped.index])|costs.index)
|
||||||
|
|
||||||
costs.loc[idx[c.list_name,"marginal",list(marginal_costs_grouped.index)],label] = marginal_costs_grouped.values
|
costs.loc[idx[c.list_name,"marginal",list(marginal_costs_grouped.index)],label] = marginal_costs_grouped.values
|
||||||
|
|
||||||
@ -198,7 +200,7 @@ def calculate_nodal_capacities(n,label,nodal_capacities):
|
|||||||
for c in n.iterate_components(n.branch_components|n.controllable_one_port_components^{"Load"}):
|
for c in n.iterate_components(n.branch_components|n.controllable_one_port_components^{"Load"}):
|
||||||
nodal_capacities_c = c.df[opt_name.get(c.name,"p") + "_nom_opt"].groupby((c.df.location,c.df.carrier)).sum()
|
nodal_capacities_c = c.df[opt_name.get(c.name,"p") + "_nom_opt"].groupby((c.df.location,c.df.carrier)).sum()
|
||||||
index = pd.MultiIndex.from_tuples([(c.list_name,) + t for t in nodal_capacities_c.index.to_list()])
|
index = pd.MultiIndex.from_tuples([(c.list_name,) + t for t in nodal_capacities_c.index.to_list()])
|
||||||
nodal_capacities = nodal_capacities.reindex(nodal_capacities.index|index)
|
nodal_capacities = nodal_capacities.reindex(index|nodal_capacities.index)
|
||||||
nodal_capacities.loc[index,label] = nodal_capacities_c.values
|
nodal_capacities.loc[index,label] = nodal_capacities_c.values
|
||||||
|
|
||||||
return nodal_capacities
|
return nodal_capacities
|
||||||
@ -211,7 +213,7 @@ def calculate_capacities(n,label,capacities):
|
|||||||
for c in n.iterate_components(n.branch_components|n.controllable_one_port_components^{"Load"}):
|
for c in n.iterate_components(n.branch_components|n.controllable_one_port_components^{"Load"}):
|
||||||
capacities_grouped = c.df[opt_name.get(c.name,"p") + "_nom_opt"].groupby(c.df.carrier).sum()
|
capacities_grouped = c.df[opt_name.get(c.name,"p") + "_nom_opt"].groupby(c.df.carrier).sum()
|
||||||
|
|
||||||
capacities = capacities.reindex(capacities.index|pd.MultiIndex.from_product([[c.list_name],capacities_grouped.index]))
|
capacities = capacities.reindex(pd.MultiIndex.from_product([[c.list_name],capacities_grouped.index])|capacities.index)
|
||||||
|
|
||||||
capacities.loc[idx[c.list_name,list(capacities_grouped.index)],label] = capacities_grouped.values
|
capacities.loc[idx[c.list_name,list(capacities_grouped.index)],label] = capacities_grouped.values
|
||||||
|
|
||||||
@ -238,7 +240,7 @@ def calculate_energy(n,label,energy):
|
|||||||
for port in [col[3:] for col in c.df.columns if col[:3] == "bus"]:
|
for port in [col[3:] for col in c.df.columns if col[:3] == "bus"]:
|
||||||
c_energies -= c.pnl["p"+port].multiply(n.snapshot_weightings,axis=0).sum().groupby(c.df.carrier).sum()
|
c_energies -= c.pnl["p"+port].multiply(n.snapshot_weightings,axis=0).sum().groupby(c.df.carrier).sum()
|
||||||
|
|
||||||
energy = energy.reindex(energy.index|pd.MultiIndex.from_product([[c.list_name],c_energies.index]))
|
energy = energy.reindex(pd.MultiIndex.from_product([[c.list_name],c_energies.index])|energy.index)
|
||||||
|
|
||||||
energy.loc[idx[c.list_name,list(c_energies.index)],label] = c_energies.values
|
energy.loc[idx[c.list_name,list(c_energies.index)],label] = c_energies.values
|
||||||
|
|
||||||
@ -246,17 +248,13 @@ def calculate_energy(n,label,energy):
|
|||||||
|
|
||||||
|
|
||||||
def calculate_supply(n,label,supply):
|
def calculate_supply(n,label,supply):
|
||||||
"""calculate the max dispatch of each component at the buses where the loads are attached"""
|
"""calculate the max dispatch of each component at the buses aggregated by carrier"""
|
||||||
|
|
||||||
load_types = n.loads.carrier.value_counts().index
|
bus_carriers = n.buses.carrier.unique()
|
||||||
|
|
||||||
for i in load_types:
|
for i in bus_carriers:
|
||||||
|
bus_map = (n.buses.carrier == i)
|
||||||
buses = n.loads.bus[n.loads.carrier == i].values
|
bus_map.at[""] = False
|
||||||
|
|
||||||
bus_map = pd.Series(False,index=n.buses.index)
|
|
||||||
|
|
||||||
bus_map.loc[buses] = True
|
|
||||||
|
|
||||||
for c in n.iterate_components(n.one_port_components):
|
for c in n.iterate_components(n.one_port_components):
|
||||||
|
|
||||||
@ -267,15 +265,15 @@ def calculate_supply(n,label,supply):
|
|||||||
|
|
||||||
s = c.pnl.p[items].max().multiply(c.df.loc[items,'sign']).groupby(c.df.loc[items,'carrier']).sum()
|
s = c.pnl.p[items].max().multiply(c.df.loc[items,'sign']).groupby(c.df.loc[items,'carrier']).sum()
|
||||||
|
|
||||||
supply = supply.reindex(supply.index|pd.MultiIndex.from_product([[i],[c.list_name],s.index]))
|
supply = supply.reindex(pd.MultiIndex.from_product([[i],[c.list_name],s.index])|supply.index)
|
||||||
supply.loc[idx[i,c.list_name,list(s.index)],label] = s.values
|
supply.loc[idx[i,c.list_name,list(s.index)],label] = s.values
|
||||||
|
|
||||||
|
|
||||||
for c in n.iterate_components(n.branch_components):
|
for c in n.iterate_components(n.branch_components):
|
||||||
|
|
||||||
for end in ["0","1"]:
|
for end in [col[3:] for col in c.df.columns if col[:3] == "bus"]:
|
||||||
|
|
||||||
items = c.df.index[c.df["bus" + end].map(bus_map)]
|
items = c.df.index[c.df["bus" + end].map(bus_map,na_action=False)]
|
||||||
|
|
||||||
if len(items) == 0:
|
if len(items) == 0:
|
||||||
continue
|
continue
|
||||||
@ -283,23 +281,20 @@ def calculate_supply(n,label,supply):
|
|||||||
#lots of sign compensation for direction and to do maximums
|
#lots of sign compensation for direction and to do maximums
|
||||||
s = (-1)**(1-int(end))*((-1)**int(end)*c.pnl["p"+end][items]).max().groupby(c.df.loc[items,'carrier']).sum()
|
s = (-1)**(1-int(end))*((-1)**int(end)*c.pnl["p"+end][items]).max().groupby(c.df.loc[items,'carrier']).sum()
|
||||||
|
|
||||||
supply = supply.reindex(supply.index|pd.MultiIndex.from_product([[i],[c.list_name],s.index]))
|
supply = supply.reindex(pd.MultiIndex.from_product([[i],[c.list_name],s.index+end])|supply.index)
|
||||||
supply.loc[idx[i,c.list_name,list(s.index)],label] = s.values
|
supply.loc[idx[i,c.list_name,list(s.index+end)],label] = s.values
|
||||||
|
|
||||||
return supply
|
return supply
|
||||||
|
|
||||||
def calculate_supply_energy(n,label,supply_energy):
|
def calculate_supply_energy(n,label,supply_energy):
|
||||||
"""calculate the total dispatch of each component at the buses where the loads are attached"""
|
"""calculate the total energy supply/consuption of each component at the buses aggregated by carrier"""
|
||||||
|
|
||||||
load_types = n.loads.carrier.value_counts().index
|
|
||||||
|
|
||||||
for i in load_types:
|
bus_carriers = n.buses.carrier.unique()
|
||||||
|
|
||||||
buses = n.loads.bus[n.loads.carrier == i].values
|
for i in bus_carriers:
|
||||||
|
bus_map = (n.buses.carrier == i)
|
||||||
bus_map = pd.Series(False,index=n.buses.index)
|
bus_map.at[""] = False
|
||||||
|
|
||||||
bus_map.loc[buses] = True
|
|
||||||
|
|
||||||
for c in n.iterate_components(n.one_port_components):
|
for c in n.iterate_components(n.one_port_components):
|
||||||
|
|
||||||
@ -308,31 +303,31 @@ def calculate_supply_energy(n,label,supply_energy):
|
|||||||
if len(items) == 0:
|
if len(items) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
s = c.pnl.p[items].sum().multiply(c.df.loc[items,'sign']).groupby(c.df.loc[items,'carrier']).sum()
|
s = c.pnl.p[items].multiply(n.snapshot_weightings,axis=0).sum().multiply(c.df.loc[items,'sign']).groupby(c.df.loc[items,'carrier']).sum()
|
||||||
|
|
||||||
supply_energy = supply_energy.reindex(supply_energy.index|pd.MultiIndex.from_product([[i],[c.list_name],s.index]))
|
supply_energy = supply_energy.reindex(pd.MultiIndex.from_product([[i],[c.list_name],s.index])|supply_energy.index)
|
||||||
supply_energy.loc[idx[i,c.list_name,list(s.index)],label] = s.values
|
supply_energy.loc[idx[i,c.list_name,list(s.index)],label] = s.values
|
||||||
|
|
||||||
|
|
||||||
for c in n.iterate_components(n.branch_components):
|
for c in n.iterate_components(n.branch_components):
|
||||||
|
|
||||||
for end in ["0","1"]:
|
for end in [col[3:] for col in c.df.columns if col[:3] == "bus"]:
|
||||||
|
|
||||||
items = c.df.index[c.df["bus" + end].map(bus_map)]
|
items = c.df.index[c.df["bus" + str(end)].map(bus_map,na_action=False)]
|
||||||
|
|
||||||
if len(items) == 0:
|
if len(items) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
s = (-1)*c.pnl["p"+end][items].sum().groupby(c.df.loc[items,'carrier']).sum()
|
s = (-1)*c.pnl["p"+end][items].multiply(n.snapshot_weightings,axis=0).sum().groupby(c.df.loc[items,'carrier']).sum()
|
||||||
|
|
||||||
supply_energy = supply_energy.reindex(supply_energy.index|pd.MultiIndex.from_product([[i],[c.list_name],s.index]))
|
supply_energy = supply_energy.reindex(pd.MultiIndex.from_product([[i],[c.list_name],s.index+end])|supply_energy.index)
|
||||||
supply_energy.loc[idx[i,c.list_name,list(s.index)],label] = s.values
|
supply_energy.loc[idx[i,c.list_name,list(s.index+end)],label] = s.values
|
||||||
|
|
||||||
return supply_energy
|
return supply_energy
|
||||||
|
|
||||||
def calculate_metrics(n,label,metrics):
|
def calculate_metrics(n,label,metrics):
|
||||||
|
|
||||||
metrics = metrics.reindex(metrics.index|pd.Index(["line_volume","line_volume_limit","line_volume_AC","line_volume_DC","line_volume_shadow","co2_shadow"]))
|
metrics = metrics.reindex(pd.Index(["line_volume","line_volume_limit","line_volume_AC","line_volume_DC","line_volume_shadow","co2_shadow"])|metrics.index)
|
||||||
|
|
||||||
metrics.at["line_volume_DC",label] = (n.links.length*n.links.p_nom_opt)[n.links.carrier == "DC"].sum()
|
metrics.at["line_volume_DC",label] = (n.links.length*n.links.p_nom_opt)[n.links.carrier == "DC"].sum()
|
||||||
metrics.at["line_volume_AC",label] = (n.lines.length*n.lines.s_nom_opt).sum()
|
metrics.at["line_volume_AC",label] = (n.lines.length*n.lines.s_nom_opt).sum()
|
||||||
@ -402,7 +397,7 @@ def calculate_weighted_prices(n,label,weighted_prices):
|
|||||||
if names.empty:
|
if names.empty:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
load += n.links_t.p0[names].groupby(n.links.loc[names,"bus0"],axis=1).sum(axis=1)
|
load += n.links_t.p0[names].groupby(n.links.loc[names,"bus0"],axis=1).sum()
|
||||||
|
|
||||||
#Add H2 Store when charging
|
#Add H2 Store when charging
|
||||||
#if carrier == "H2":
|
#if carrier == "H2":
|
||||||
|
@ -32,6 +32,9 @@ override_component_attrs["Link"].loc["efficiency2"] = ["static or series","per u
|
|||||||
override_component_attrs["Link"].loc["efficiency3"] = ["static or series","per unit",1.,"3rd bus efficiency","Input (optional)"]
|
override_component_attrs["Link"].loc["efficiency3"] = ["static or series","per unit",1.,"3rd bus efficiency","Input (optional)"]
|
||||||
override_component_attrs["Link"].loc["p2"] = ["series","MW",0.,"2nd bus output","Output"]
|
override_component_attrs["Link"].loc["p2"] = ["series","MW",0.,"2nd bus output","Output"]
|
||||||
override_component_attrs["Link"].loc["p3"] = ["series","MW",0.,"3rd bus output","Output"]
|
override_component_attrs["Link"].loc["p3"] = ["series","MW",0.,"3rd bus output","Output"]
|
||||||
|
override_component_attrs["StorageUnit"].loc["p_dispatch"] = ["series","MW",0.,"Storage discharging.","Output"]
|
||||||
|
override_component_attrs["StorageUnit"].loc["p_store"] = ["series","MW",0.,"Storage charging.","Output"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def rename_techs_tyndp(tech):
|
def rename_techs_tyndp(tech):
|
||||||
|
@ -623,16 +623,27 @@ def add_storage(network):
|
|||||||
|
|
||||||
if options['SMR']:
|
if options['SMR']:
|
||||||
network.madd("Link",
|
network.madd("Link",
|
||||||
nodes + " SMR",
|
nodes + " SMR CCS",
|
||||||
bus0=["EU gas"]*len(nodes),
|
bus0=["EU gas"]*len(nodes),
|
||||||
bus1=nodes+" H2",
|
bus1=nodes+" H2",
|
||||||
bus2="co2 atmosphere",
|
bus2="co2 atmosphere",
|
||||||
bus3="co2 stored",
|
bus3="co2 stored",
|
||||||
p_nom_extendable=True,
|
p_nom_extendable=True,
|
||||||
carrier="SMR",
|
carrier="SMR CCS",
|
||||||
efficiency=costs.at["SMR","efficiency"],
|
efficiency=costs.at["SMR CCS","efficiency"],
|
||||||
efficiency2=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]),
|
efficiency2=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]),
|
||||||
efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"],
|
efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"],
|
||||||
|
capital_cost=costs.at["SMR CCS","fixed"])
|
||||||
|
|
||||||
|
network.madd("Link",
|
||||||
|
nodes + " SMR",
|
||||||
|
bus0=["EU gas"]*len(nodes),
|
||||||
|
bus1=nodes+" H2",
|
||||||
|
bus2="co2 atmosphere",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
carrier="SMR",
|
||||||
|
efficiency=costs.at["SMR","efficiency"],
|
||||||
|
efficiency2=costs.at['gas','CO2 intensity'],
|
||||||
capital_cost=costs.at["SMR","fixed"])
|
capital_cost=costs.at["SMR","fixed"])
|
||||||
|
|
||||||
|
|
||||||
@ -765,7 +776,7 @@ def add_heat(network):
|
|||||||
|
|
||||||
network.madd("Load",
|
network.madd("Load",
|
||||||
nodes[name],
|
nodes[name],
|
||||||
suffix=" " + name + "heat",
|
suffix=" " + name + " heat",
|
||||||
bus=nodes[name] + " " + name + " heat",
|
bus=nodes[name] + " " + name + " heat",
|
||||||
carrier=name + " heat",
|
carrier=name + " heat",
|
||||||
p_set=heat_load)
|
p_set=heat_load)
|
||||||
@ -868,47 +879,72 @@ def add_heat(network):
|
|||||||
if options["chp"]:
|
if options["chp"]:
|
||||||
|
|
||||||
if name == "urban central":
|
if name == "urban central":
|
||||||
#additional bus, to which we can also connect biomass
|
#add gas CHP; biomass CHP is added in biomass section
|
||||||
network.madd("Bus",
|
network.madd("Link",
|
||||||
nodes[name] + " urban central CHP",
|
nodes[name] + " urban central gas CHP electric",
|
||||||
carrier="urban central CHP")
|
bus0="EU gas",
|
||||||
|
bus1=nodes[name],
|
||||||
|
bus2="co2 atmosphere",
|
||||||
|
carrier="urban central gas CHP electric",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
capital_cost=costs.at['central gas CHP','fixed']*costs.at['central gas CHP','efficiency'],
|
||||||
|
marginal_cost=costs.at['central gas CHP','VOM'],
|
||||||
|
efficiency=costs.at['central gas CHP','efficiency'],
|
||||||
|
efficiency2=costs.at['gas','CO2 intensity'],
|
||||||
|
c_b=costs.at['central gas CHP','c_b'],
|
||||||
|
c_v=costs.at['central gas CHP','c_v'],
|
||||||
|
p_nom_ratio=costs.at['central gas CHP','p_nom_ratio'])
|
||||||
|
|
||||||
network.madd("Link",
|
network.madd("Link",
|
||||||
nodes[name] + " gas to urban central CHP",
|
nodes[name] + " urban central gas CHP heat",
|
||||||
bus0="EU gas",
|
bus0="EU gas",
|
||||||
bus1=nodes[name] + " urban central CHP",
|
bus1=nodes[name] + " urban central heat",
|
||||||
|
bus2="co2 atmosphere",
|
||||||
|
carrier="urban central gas CHP heat",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
marginal_cost=costs.at['central gas CHP','VOM'],
|
||||||
|
efficiency=costs.at['central gas CHP','efficiency']/costs.at['central gas CHP','c_v'],
|
||||||
|
efficiency2=costs.at['gas','CO2 intensity'])
|
||||||
|
|
||||||
|
network.madd("Link",
|
||||||
|
nodes[name] + " urban central gas CHP CCS electric",
|
||||||
|
bus0="EU gas",
|
||||||
|
bus1=nodes[name],
|
||||||
bus2="co2 atmosphere",
|
bus2="co2 atmosphere",
|
||||||
bus3="co2 stored",
|
bus3="co2 stored",
|
||||||
|
carrier="urban central gas CHP CCS electric",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
capital_cost=costs.at['central gas CHP CCS','fixed']*costs.at['central gas CHP CCS','efficiency'],
|
||||||
|
marginal_cost=costs.at['central gas CHP CCS','VOM'],
|
||||||
|
efficiency=costs.at['central gas CHP CCS','efficiency'],
|
||||||
efficiency2=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]),
|
efficiency2=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]),
|
||||||
efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"],
|
efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"],
|
||||||
carrier="gas to central CHP",
|
c_b=costs.at['central gas CHP CCS','c_b'],
|
||||||
p_nom_extendable=True)
|
c_v=costs.at['central gas CHP CCS','c_v'],
|
||||||
|
p_nom_ratio=costs.at['central gas CHP CCS','p_nom_ratio'])
|
||||||
|
|
||||||
network.madd("Link",
|
network.madd("Link",
|
||||||
nodes[name] + " urban central CHP electric",
|
nodes[name] + " urban central gas CHP CCS heat",
|
||||||
bus0=nodes[name] + " urban central CHP",
|
bus0="EU gas",
|
||||||
bus1=nodes[name],
|
|
||||||
carrier="urban central CHP electric",
|
|
||||||
p_nom_extendable=True,
|
|
||||||
capital_cost=costs.at['central CHP','fixed']*options['chp_parameters']['eta_elec'],
|
|
||||||
efficiency=options['chp_parameters']['eta_elec'])
|
|
||||||
|
|
||||||
network.madd("Link",
|
|
||||||
nodes[name] + " urban central CHP heat",
|
|
||||||
bus0=nodes[name] + " urban central CHP",
|
|
||||||
bus1=nodes[name] + " urban central heat",
|
bus1=nodes[name] + " urban central heat",
|
||||||
carrier="urban central CHP heat",
|
bus2="co2 atmosphere",
|
||||||
|
bus3="co2 stored",
|
||||||
|
carrier="urban central gas CHP CCS heat",
|
||||||
p_nom_extendable=True,
|
p_nom_extendable=True,
|
||||||
efficiency=options['chp_parameters']['eta_elec']/options['chp_parameters']['c_v'])
|
marginal_cost=costs.at['central gas CHP CCS','VOM'],
|
||||||
|
efficiency=costs.at['central gas CHP CCS','efficiency']/costs.at['central gas CHP CCS','c_v'],
|
||||||
|
efficiency2=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]),
|
||||||
|
efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
network.madd("Link",
|
network.madd("Link",
|
||||||
nodes[name] + " " + name + " micro CHP",
|
nodes[name] + " " + name + " micro gas CHP",
|
||||||
p_nom_extendable=True,
|
p_nom_extendable=True,
|
||||||
bus0=["EU gas"]*len(nodes[name]),
|
bus0="EU gas",
|
||||||
bus1=nodes[name],
|
bus1=nodes[name],
|
||||||
bus2=nodes[name] + " " + name + " heat",
|
bus2=nodes[name] + " " + name + " heat",
|
||||||
bus3="co2 atmosphere",
|
bus3="co2 atmosphere",
|
||||||
carrier=name + " micro CHP",
|
carrier=name + " micro gas CHP",
|
||||||
efficiency=costs.at['micro CHP','efficiency'],
|
efficiency=costs.at['micro CHP','efficiency'],
|
||||||
efficiency2=costs.at['micro CHP','efficiency-heat'],
|
efficiency2=costs.at['micro CHP','efficiency-heat'],
|
||||||
efficiency3=costs.at['gas','CO2 intensity'],
|
efficiency3=costs.at['gas','CO2 intensity'],
|
||||||
@ -1028,20 +1064,61 @@ def add_biomass(network):
|
|||||||
|
|
||||||
#AC buses with district heating
|
#AC buses with district heating
|
||||||
urban_central = n.buses.index[n.buses.carrier == "urban central heat"]
|
urban_central = n.buses.index[n.buses.carrier == "urban central heat"]
|
||||||
if not urban_central.empty:
|
if not urban_central.empty and options["chp"]:
|
||||||
urban_central = urban_central.str[:-len(" urban central heat")]
|
urban_central = urban_central.str[:-len(" urban central heat")]
|
||||||
|
|
||||||
#with BECCS
|
|
||||||
network.madd("Link",
|
network.madd("Link",
|
||||||
urban_central + " solid biomass to urban central CHP",
|
urban_central + " urban central solid biomass CHP electric",
|
||||||
bus0="EU solid biomass",
|
bus0="EU solid biomass",
|
||||||
bus1=urban_central + " urban central CHP",
|
bus1=urban_central,
|
||||||
|
carrier="urban central solid biomass CHP electric",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
capital_cost=costs.at['central solid biomass CHP','fixed']*costs.at['central solid biomass CHP','efficiency'],
|
||||||
|
marginal_cost=costs.at['central solid biomass CHP','VOM'],
|
||||||
|
efficiency=costs.at['central solid biomass CHP','efficiency'],
|
||||||
|
c_b=costs.at['central solid biomass CHP','c_b'],
|
||||||
|
c_v=costs.at['central solid biomass CHP','c_v'],
|
||||||
|
p_nom_ratio=costs.at['central solid biomass CHP','p_nom_ratio'])
|
||||||
|
|
||||||
|
|
||||||
|
network.madd("Link",
|
||||||
|
urban_central + " urban central solid biomass CHP heat",
|
||||||
|
bus0="EU solid biomass",
|
||||||
|
bus1=urban_central + " urban central heat",
|
||||||
|
carrier="urban central solid biomass CHP heat",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
marginal_cost=costs.at['central solid biomass CHP','VOM'],
|
||||||
|
efficiency=costs.at['central solid biomass CHP','efficiency']/costs.at['central solid biomass CHP','c_v'])
|
||||||
|
|
||||||
|
network.madd("Link",
|
||||||
|
urban_central + " urban central solid biomass CHP CCS electric",
|
||||||
|
bus0="EU solid biomass",
|
||||||
|
bus1=urban_central,
|
||||||
bus2="co2 atmosphere",
|
bus2="co2 atmosphere",
|
||||||
bus3="co2 stored",
|
bus3="co2 stored",
|
||||||
|
carrier="urban central solid biomass CHP CCS electric",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
capital_cost=costs.at['central solid biomass CHP CCS','fixed']*costs.at['central solid biomass CHP CCS','efficiency'],
|
||||||
|
marginal_cost=costs.at['central solid biomass CHP CCS','VOM'],
|
||||||
|
efficiency=costs.at['central solid biomass CHP CCS','efficiency'],
|
||||||
efficiency2=-costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"],
|
efficiency2=-costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"],
|
||||||
efficiency3=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"],
|
efficiency3=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"],
|
||||||
carrier="solid biomass to urban central CHP",
|
c_b=costs.at['central solid biomass CHP','c_b'],
|
||||||
p_nom_extendable=True)
|
c_v=costs.at['central solid biomass CHP','c_v'],
|
||||||
|
p_nom_ratio=costs.at['central solid biomass CHP','p_nom_ratio'])
|
||||||
|
|
||||||
|
network.madd("Link",
|
||||||
|
urban_central + " urban central solid biomass CHP CCS heat",
|
||||||
|
bus0="EU solid biomass",
|
||||||
|
bus1=urban_central + " urban central heat",
|
||||||
|
bus2="co2 atmosphere",
|
||||||
|
bus3="co2 stored",
|
||||||
|
carrier="urban central solid biomass CHP CCS heat",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
marginal_cost=costs.at['central solid biomass CHP CCS','VOM'],
|
||||||
|
efficiency=costs.at['central solid biomass CHP CCS','efficiency']/costs.at['central solid biomass CHP CCS','c_v'],
|
||||||
|
efficiency2=-costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"],
|
||||||
|
efficiency3=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"])
|
||||||
|
|
||||||
|
|
||||||
def add_industry(network):
|
def add_industry(network):
|
||||||
@ -1057,43 +1134,70 @@ def add_industry(network):
|
|||||||
solid_biomass_by_country = industrial_demand["solid biomass"].groupby(pop_layout.ct).sum()
|
solid_biomass_by_country = industrial_demand["solid biomass"].groupby(pop_layout.ct).sum()
|
||||||
countries = solid_biomass_by_country.index
|
countries = solid_biomass_by_country.index
|
||||||
|
|
||||||
|
network.madd("Bus",
|
||||||
|
["solid biomass for industry"],
|
||||||
|
carrier="solid biomass for industry")
|
||||||
|
|
||||||
network.madd("Load",
|
network.madd("Load",
|
||||||
["solid biomass for industry"],
|
["solid biomass for industry"],
|
||||||
bus="EU solid biomass",
|
bus="solid biomass for industry",
|
||||||
carrier="solid biomass for industry",
|
carrier="solid biomass for industry",
|
||||||
p_set=solid_biomass_by_country.sum()/8760.)
|
p_set=solid_biomass_by_country.sum()/8760.)
|
||||||
|
|
||||||
#Net transfer of CO2 from atmosphere to stored
|
network.madd("Link",
|
||||||
network.madd("Load",
|
["solid biomass for industry"],
|
||||||
["solid biomass for industry co2 from atmosphere"],
|
bus0="EU solid biomass",
|
||||||
bus="co2 atmosphere",
|
bus1="solid biomass for industry",
|
||||||
carrier="solid biomass for industry co2 from atmosphere",
|
carrier="solid biomass for industry",
|
||||||
p_set=solid_biomass_by_country.sum()*costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"]/8760.)
|
p_nom_extendable=True,
|
||||||
|
efficiency=1.)
|
||||||
|
|
||||||
network.madd("Load",
|
network.madd("Link",
|
||||||
["solid biomass for industry co2 to stored"],
|
["solid biomass for industry CCS"],
|
||||||
bus="co2 stored",
|
bus0="EU solid biomass",
|
||||||
carrier="solid biomass for industry co2 to stored",
|
bus1="solid biomass for industry",
|
||||||
p_set=-solid_biomass_by_country.sum()*costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"]/8760.)
|
bus2="co2 atmosphere",
|
||||||
|
bus3="co2 stored",
|
||||||
|
carrier="solid biomass for industry CCS",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
capital_cost=costs.at["industry CCS","fixed"]*costs.at['solid biomass','CO2 intensity']*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h)
|
||||||
|
efficiency=0.9,
|
||||||
|
efficiency2=-costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"],
|
||||||
|
efficiency3=costs.at['solid biomass','CO2 intensity']*options["ccs_fraction"])
|
||||||
|
|
||||||
|
|
||||||
|
network.madd("Bus",
|
||||||
|
["gas for industry"],
|
||||||
|
carrier="gas for industry")
|
||||||
|
|
||||||
network.madd("Load",
|
network.madd("Load",
|
||||||
["gas for industry"],
|
["gas for industry"],
|
||||||
bus="EU gas",
|
bus="gas for industry",
|
||||||
carrier="gas for industry",
|
carrier="gas for industry",
|
||||||
p_set=industrial_demand.loc[nodes,"methane"].sum()/8760.)
|
p_set=industrial_demand.loc[nodes,"methane"].sum()/8760.)
|
||||||
|
|
||||||
network.madd("Load",
|
network.madd("Link",
|
||||||
["gas for industry co2 to atmosphere"],
|
["gas for industry"],
|
||||||
bus="co2 atmosphere",
|
bus0="EU gas",
|
||||||
carrier="gas for industry co2 to atmosphere",
|
bus1="gas for industry",
|
||||||
p_set=-industrial_demand.loc[nodes,"methane"].sum()*costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"])/8760.)
|
bus2="co2 atmosphere",
|
||||||
|
carrier="gas for industry",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
efficiency=1.,
|
||||||
|
efficiency2=costs.at['gas','CO2 intensity'])
|
||||||
|
|
||||||
network.madd("Load",
|
network.madd("Link",
|
||||||
["gas for industry co2 to stored"],
|
["gas for industry CCS"],
|
||||||
bus="co2 stored",
|
bus0="EU gas",
|
||||||
carrier="gas for industry co2 to stored",
|
bus1="gas for industry",
|
||||||
p_set=-industrial_demand.loc[nodes,"methane"].sum()*costs.at['gas','CO2 intensity']*options["ccs_fraction"]/8760.)
|
bus2="co2 atmosphere",
|
||||||
|
bus3="co2 stored",
|
||||||
|
carrier="gas for industry CCS",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
capital_cost=costs.at["industry CCS","fixed"]*costs.at['gas','CO2 intensity']*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h)
|
||||||
|
efficiency=0.9,
|
||||||
|
efficiency2=costs.at['gas','CO2 intensity']*(1-options["ccs_fraction"]),
|
||||||
|
efficiency3=costs.at['gas','CO2 intensity']*options["ccs_fraction"])
|
||||||
|
|
||||||
|
|
||||||
network.madd("Load",
|
network.madd("Load",
|
||||||
@ -1184,17 +1288,37 @@ def add_industry(network):
|
|||||||
carrier="industry new electricity",
|
carrier="industry new electricity",
|
||||||
p_set = (industrial_demand.loc[nodes,"electricity"]-industrial_demand.loc[nodes,"current electricity"])/8760.)
|
p_set = (industrial_demand.loc[nodes,"electricity"]-industrial_demand.loc[nodes,"current electricity"])/8760.)
|
||||||
|
|
||||||
network.madd("Load",
|
network.madd("Bus",
|
||||||
["process emissions to atmosphere"],
|
["process emissions"],
|
||||||
bus="co2 atmosphere",
|
carrier="process emissions")
|
||||||
carrier="process emissions to atmosphere",
|
|
||||||
p_set = -industrial_demand.loc[nodes,"process emission"].sum()*(1-options["ccs_fraction"])/8760.)
|
|
||||||
|
|
||||||
|
#this should be process emissions fossil+feedstock
|
||||||
|
#then need load on atmosphere for feedstock emissions that are currently going to atmosphere via Link Fischer-Tropsch demand
|
||||||
network.madd("Load",
|
network.madd("Load",
|
||||||
["process emissions to stored"],
|
["process emissions"],
|
||||||
bus="co2 stored",
|
bus="process emissions",
|
||||||
carrier="process emissions to stored",
|
carrier="process emissions",
|
||||||
p_set = -industrial_demand.loc[nodes,"process emission"].sum()*options["ccs_fraction"]/8760.)
|
p_set = -industrial_demand.loc[nodes,"process emission"].sum()/8760.)
|
||||||
|
|
||||||
|
network.madd("Link",
|
||||||
|
["process emissions"],
|
||||||
|
bus0="process emissions",
|
||||||
|
bus1="co2 atmosphere",
|
||||||
|
carrier="process emissions",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
efficiency=1.)
|
||||||
|
|
||||||
|
#assume enough local waste heat for CCS
|
||||||
|
network.madd("Link",
|
||||||
|
["process emissions CCS"],
|
||||||
|
bus0="process emissions",
|
||||||
|
bus1="co2 atmosphere",
|
||||||
|
bus2="co2 stored",
|
||||||
|
carrier="process emissions CCS",
|
||||||
|
p_nom_extendable=True,
|
||||||
|
capital_cost=costs.at["industry CCS","fixed"]*8760, #8760 converts EUR/(tCO2/a) to EUR/(tCO2/h)
|
||||||
|
efficiency=(1-options["ccs_fraction"]),
|
||||||
|
efficiency2=options["ccs_fraction"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
os.system("conda config --add channels http://conda.anaconda.org/gurobi")
|
||||||
|
|
||||||
|
os.system("conda install -y gurobi=8.1.0")
|
||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path = ["/home/vres/data/tom/lib/pypsa"] + sys.path
|
sys.path = ["pypsa"] + sys.path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@ -12,6 +20,8 @@ import os
|
|||||||
|
|
||||||
import pypsa
|
import pypsa
|
||||||
|
|
||||||
|
from pypsa.linopt import get_var, linexpr, define_constraints
|
||||||
|
|
||||||
from pypsa.descriptors import free_output_series_dataframes
|
from pypsa.descriptors import free_output_series_dataframes
|
||||||
|
|
||||||
# Suppress logging of the slack bus choices
|
# Suppress logging of the slack bus choices
|
||||||
@ -103,80 +113,74 @@ def add_opts_constraints(n, opts=None):
|
|||||||
ext_gens_i = n.generators.index[n.generators.carrier.isin(conv_techs) & n.generators.p_nom_extendable]
|
ext_gens_i = n.generators.index[n.generators.carrier.isin(conv_techs) & n.generators.p_nom_extendable]
|
||||||
n.model.safe_peakdemand = pypsa.opt.Constraint(expr=sum(n.model.generator_p_nom[gen] for gen in ext_gens_i) >= peakdemand - exist_conv_caps)
|
n.model.safe_peakdemand = pypsa.opt.Constraint(expr=sum(n.model.generator_p_nom[gen] for gen in ext_gens_i) >= peakdemand - exist_conv_caps)
|
||||||
|
|
||||||
def add_lv_constraint(n):
|
|
||||||
line_volume = getattr(n, 'line_volume_limit', None)
|
|
||||||
if line_volume is not None and not np.isinf(line_volume):
|
|
||||||
n.model.line_volume_constraint = pypsa.opt.Constraint(
|
|
||||||
expr=((sum(n.model.passive_branch_s_nom["Line",line]*n.lines.at[line,"length"]
|
|
||||||
for line in n.lines.index[n.lines.s_nom_extendable]) +
|
|
||||||
sum(n.model.link_p_nom[link]*n.links.at[link,"length"]
|
|
||||||
for link in n.links.index[(n.links.carrier=='DC') &
|
|
||||||
n.links.p_nom_extendable]))
|
|
||||||
<= line_volume)
|
|
||||||
)
|
|
||||||
|
|
||||||
def add_eps_storage_constraint(n):
|
def add_eps_storage_constraint(n):
|
||||||
if not hasattr(n, 'epsilon'):
|
if not hasattr(n, 'epsilon'):
|
||||||
n.epsilon = 1e-5
|
n.epsilon = 1e-5
|
||||||
fix_sus_i = n.storage_units.index[~ n.storage_units.p_nom_extendable]
|
fix_sus_i = n.storage_units.index[~ n.storage_units.p_nom_extendable]
|
||||||
n.model.objective.expr += sum(n.epsilon * n.model.state_of_charge[su, n.snapshots[0]] for su in fix_sus_i)
|
n.model.objective.expr += sum(n.epsilon * n.model.state_of_charge[su, n.snapshots[0]] for su in fix_sus_i)
|
||||||
|
|
||||||
def add_battery_constraints(network):
|
def add_battery_constraints(n):
|
||||||
|
|
||||||
nodes = list(network.buses.index[network.buses.carrier == "battery"])
|
nodes = n.buses.index[n.buses.carrier == "battery"]
|
||||||
|
|
||||||
def battery(model, node):
|
link_p_nom = get_var(n, "Link", "p_nom")
|
||||||
return model.link_p_nom[node + " charger"] == model.link_p_nom[node + " discharger"]*network.links.at[node + " charger","efficiency"]
|
|
||||||
|
|
||||||
network.model.battery = pypsa.opt.Constraint(nodes, rule=battery)
|
lhs = linexpr((1,link_p_nom[nodes + " charger"]),
|
||||||
|
(-n.links.loc[nodes + " discharger", "efficiency"].values,
|
||||||
|
link_p_nom[nodes + " discharger"].values))
|
||||||
|
define_constraints(n, lhs, "=", 0, 'Link', 'charger_ratio')
|
||||||
|
|
||||||
|
|
||||||
|
def add_chp_constraints(n):
|
||||||
|
|
||||||
def add_chp_constraints(network):
|
electric = n.links.index[n.links.index.str.contains("urban central") & n.links.index.str.contains("CHP") & n.links.index.str.contains("electric")]
|
||||||
|
heat = n.links.index[n.links.index.str.contains("urban central") & n.links.index.str.contains("CHP") & n.links.index.str.contains("heat")]
|
||||||
|
|
||||||
options = snakemake.config["sector"]
|
if not electric.empty:
|
||||||
|
|
||||||
if hasattr(network.links.index,"str") and network.links.index.str.contains("CHP").any():
|
link_p_nom = get_var(n, "Link", "p_nom")
|
||||||
|
|
||||||
#AC buses with district heating
|
#ratio of output heat to electricity set by p_nom_ratio
|
||||||
urban_central = n.buses.index[n.buses.carrier == "urban central heat"]
|
lhs = linexpr((n.links.loc[electric,"efficiency"]
|
||||||
if not urban_central.empty:
|
*n.links.loc[electric,'p_nom_ratio'],
|
||||||
urban_central = urban_central.str[:-len(" urban central heat")]
|
link_p_nom[electric]),
|
||||||
|
(-n.links.loc[heat,"efficiency"].values,
|
||||||
|
link_p_nom[heat].values))
|
||||||
|
define_constraints(n, lhs, "=", 0, 'chplink', 'fix_p_nom_ratio')
|
||||||
|
|
||||||
|
link_p = get_var(n, "Link", "p")
|
||||||
|
|
||||||
def chp_nom(model,node):
|
#backpressure
|
||||||
return network.links.at[node + " urban central CHP electric","efficiency"]*options['chp_parameters']['p_nom_ratio']*model.link_p_nom[node + " urban central CHP electric"] == network.links.at[node + " urban central CHP heat","efficiency"]*options['chp_parameters']['p_nom_ratio']*model.link_p_nom[node + " urban central CHP heat"]
|
lhs = linexpr((n.links.loc[electric,'c_b'].values
|
||||||
|
*n.links.loc[heat,"efficiency"],
|
||||||
|
link_p[heat]),
|
||||||
|
(-n.links.loc[electric,"efficiency"].values,
|
||||||
|
link_p[electric].values))
|
||||||
|
|
||||||
|
define_constraints(n, lhs, "<=", 0, 'chplink', 'backpressure')
|
||||||
|
|
||||||
network.model.chp_nom = pypsa.opt.Constraint(urban_central,rule=chp_nom)
|
#top_iso_fuel_line
|
||||||
|
lhs = linexpr((1,link_p[heat]),
|
||||||
|
(1,link_p[electric].values),
|
||||||
|
(-1,link_p_nom[electric].values))
|
||||||
|
|
||||||
|
define_constraints(n, lhs, "<=", 0, 'chplink', 'top_iso_fuel_line')
|
||||||
|
|
||||||
def backpressure(model,node,snapshot):
|
def extra_functionality(n, snapshots):
|
||||||
return options['chp_parameters']['c_m']*network.links.at[node + " urban central CHP heat","efficiency"]*model.link_p[node + " urban central CHP heat",snapshot] <= network.links.at[node + " urban central CHP electric","efficiency"]*model.link_p[node + " urban central CHP electric",snapshot]
|
#add_opts_constraints(n, opts)
|
||||||
|
#add_eps_storage_constraint(n)
|
||||||
network.model.backpressure = pypsa.opt.Constraint(urban_central,list(network.snapshots),rule=backpressure)
|
add_chp_constraints(n)
|
||||||
|
add_battery_constraints(n)
|
||||||
|
|
||||||
def top_iso_fuel_line(model,node,snapshot):
|
|
||||||
return model.link_p[node + " urban central CHP heat",snapshot] + model.link_p[node + " urban central CHP electric",snapshot] <= model.link_p_nom[node + " urban central CHP electric"]
|
|
||||||
|
|
||||||
network.model.top_iso_fuel_line = pypsa.opt.Constraint(urban_central,list(network.snapshots),rule=top_iso_fuel_line)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def fix_branches(n, lines_s_nom=None, links_p_nom=None):
|
def fix_branches(n, lines_s_nom=None, links_p_nom=None):
|
||||||
if lines_s_nom is not None and len(lines_s_nom) > 0:
|
if lines_s_nom is not None and len(lines_s_nom) > 0:
|
||||||
for l, s_nom in lines_s_nom.iteritems():
|
n.lines.loc[lines_s_nom.index,"s_nom"] = lines_s_nom.values
|
||||||
n.model.passive_branch_s_nom["Line", l].fix(s_nom)
|
n.lines.loc[lines_s_nom.index,"s_nom_extendable"] = False
|
||||||
if isinstance(n.opt, pypsa.opf.PersistentSolver):
|
|
||||||
n.opt.update_var(n.model.passive_branch_s_nom)
|
|
||||||
|
|
||||||
if links_p_nom is not None and len(links_p_nom) > 0:
|
if links_p_nom is not None and len(links_p_nom) > 0:
|
||||||
for l, p_nom in links_p_nom.iteritems():
|
n.links.loc[links_p_nom.index,"p_nom"] = links_p_nom.values
|
||||||
n.model.link_p_nom[l].fix(p_nom)
|
n.links.loc[links_p_nom.index,"p_nom_extendable"] = False
|
||||||
if isinstance(n.opt, pypsa.opf.PersistentSolver):
|
|
||||||
n.opt.update_var(n.model.link_p_nom)
|
|
||||||
|
|
||||||
def solve_network(n, config=None, solver_log=None, opts=None):
|
def solve_network(n, config=None, solver_log=None, opts=None):
|
||||||
if config is None:
|
if config is None:
|
||||||
@ -191,16 +195,6 @@ def solve_network(n, config=None, solver_log=None, opts=None):
|
|||||||
def run_lopf(n, allow_warning_status=False, fix_zero_lines=False, fix_ext_lines=False):
|
def run_lopf(n, allow_warning_status=False, fix_zero_lines=False, fix_ext_lines=False):
|
||||||
free_output_series_dataframes(n)
|
free_output_series_dataframes(n)
|
||||||
|
|
||||||
if not hasattr(n, 'opt') or not isinstance(n.opt, pypsa.opf.PersistentSolver):
|
|
||||||
pypsa.opf.network_lopf_build_model(n, formulation=solve_opts['formulation'])
|
|
||||||
add_opts_constraints(n, opts)
|
|
||||||
add_lv_constraint(n)
|
|
||||||
#add_eps_storage_constraint(n)
|
|
||||||
add_battery_constraints(n)
|
|
||||||
add_chp_constraints(n)
|
|
||||||
|
|
||||||
pypsa.opf.network_lopf_prepare_solver(n, solver_name=solver_name)
|
|
||||||
|
|
||||||
if fix_zero_lines:
|
if fix_zero_lines:
|
||||||
fix_lines_b = (n.lines.s_nom_opt == 0.) & n.lines.s_nom_extendable
|
fix_lines_b = (n.lines.s_nom_opt == 0.) & n.lines.s_nom_extendable
|
||||||
fix_links_b = (n.links.carrier=='DC') & (n.links.p_nom_opt == 0.) & n.links.p_nom_extendable
|
fix_links_b = (n.links.carrier=='DC') & (n.links.p_nom_opt == 0.) & n.links.p_nom_extendable
|
||||||
@ -212,19 +206,19 @@ def solve_network(n, config=None, solver_log=None, opts=None):
|
|||||||
fix_branches(n,
|
fix_branches(n,
|
||||||
lines_s_nom=n.lines.loc[n.lines.s_nom_extendable, 's_nom_opt'],
|
lines_s_nom=n.lines.loc[n.lines.s_nom_extendable, 's_nom_opt'],
|
||||||
links_p_nom=n.links.loc[(n.links.carrier=='DC') & n.links.p_nom_extendable, 'p_nom_opt'])
|
links_p_nom=n.links.loc[(n.links.carrier=='DC') & n.links.p_nom_extendable, 'p_nom_opt'])
|
||||||
|
if "line_volume_constraint" in n.global_constraints.index:
|
||||||
|
n.global_constraints.drop("line_volume_constraint",inplace=True)
|
||||||
if not fix_ext_lines and hasattr(n.model, 'line_volume_constraint'):
|
|
||||||
|
|
||||||
def extra_postprocessing(n, snapshots, duals):
|
|
||||||
index = list(n.model.line_volume_constraint.keys())
|
|
||||||
cdata = pd.Series(list(n.model.line_volume_constraint.values()),
|
|
||||||
index=index)
|
|
||||||
n.line_volume_limit_dual = -cdata.map(duals).sum()
|
|
||||||
print("line volume limit dual:",n.line_volume_limit_dual)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
extra_postprocessing = None
|
if "line_volume_constraint" not in n.global_constraints.index:
|
||||||
|
line_volume = getattr(n, 'line_volume_limit', None)
|
||||||
|
if line_volume is not None and not np.isinf(line_volume):
|
||||||
|
n.add("GlobalConstraint",
|
||||||
|
"line_volume_constraint",
|
||||||
|
type="transmission_volume_expansion_limit",
|
||||||
|
carrier_attribute="AC,DC",
|
||||||
|
sense="<=",
|
||||||
|
constant=line_volume)
|
||||||
|
|
||||||
|
|
||||||
# Firing up solve will increase memory consumption tremendously, so
|
# Firing up solve will increase memory consumption tremendously, so
|
||||||
# make sure we freed everything we can
|
# make sure we freed everything we can
|
||||||
@ -237,21 +231,25 @@ def solve_network(n, config=None, solver_log=None, opts=None):
|
|||||||
#sys.exit()
|
#sys.exit()
|
||||||
|
|
||||||
|
|
||||||
status, termination_condition = \
|
status, termination_condition = n.lopf(pyomo=False,
|
||||||
pypsa.opf.network_lopf_solve(n,
|
solver_name=solver_name,
|
||||||
solver_logfile=solver_log,
|
solver_logfile=solver_log,
|
||||||
solver_options=solver_options,
|
solver_options=solver_options,
|
||||||
formulation=solve_opts['formulation'],
|
extra_functionality=extra_functionality,
|
||||||
extra_postprocessing=extra_postprocessing
|
formulation=solve_opts['formulation'])
|
||||||
#keep_files=True
|
#extra_postprocessing=extra_postprocessing
|
||||||
#free_memory={'pypsa'}
|
#keep_files=True
|
||||||
)
|
#free_memory={'pypsa'}
|
||||||
|
|
||||||
assert status == "ok" or allow_warning_status and status == 'warning', \
|
assert status == "ok" or allow_warning_status and status == 'warning', \
|
||||||
("network_lopf did abort with status={} "
|
("network_lopf did abort with status={} "
|
||||||
"and termination_condition={}"
|
"and termination_condition={}"
|
||||||
.format(status, termination_condition))
|
.format(status, termination_condition))
|
||||||
|
|
||||||
|
if not fix_ext_lines and "line_volume_constraint" in n.global_constraints.index:
|
||||||
|
n.line_volume_limit_dual = n.global_constraints.at["line_volume_constraint","mu"]
|
||||||
|
print("line volume limit dual:",n.line_volume_limit_dual)
|
||||||
|
|
||||||
return status, termination_condition
|
return status, termination_condition
|
||||||
|
|
||||||
lines_ext_b = n.lines.s_nom_extendable
|
lines_ext_b = n.lines.s_nom_extendable
|
||||||
@ -286,21 +284,6 @@ def solve_network(n, config=None, solver_log=None, opts=None):
|
|||||||
)
|
)
|
||||||
logger.debug("lines.num_parallel={}".format(n.lines.loc[lines_ext_typed_b, 'num_parallel']))
|
logger.debug("lines.num_parallel={}".format(n.lines.loc[lines_ext_typed_b, 'num_parallel']))
|
||||||
|
|
||||||
if isinstance(n.opt, pypsa.opf.PersistentSolver):
|
|
||||||
n.calculate_dependent_values()
|
|
||||||
|
|
||||||
assert solve_opts['formulation'] == 'kirchhoff', \
|
|
||||||
"Updating persistent solvers has only been implemented for the kirchhoff formulation for now"
|
|
||||||
|
|
||||||
n.opt.remove_constraint(n.model.cycle_constraints)
|
|
||||||
del n.model.cycle_constraints_index
|
|
||||||
del n.model.cycle_constraints_index_0
|
|
||||||
del n.model.cycle_constraints_index_1
|
|
||||||
del n.model.cycle_constraints
|
|
||||||
|
|
||||||
pypsa.opf.define_passive_branch_flows_with_kirchhoff(n, n.snapshots, skip_vars=True)
|
|
||||||
n.opt.add_constraint(n.model.cycle_constraints)
|
|
||||||
|
|
||||||
iteration = 1
|
iteration = 1
|
||||||
|
|
||||||
lines['s_nom_opt'] = lines['s_nom'] * n.lines['num_parallel'].where(n.lines.type != '', 1.)
|
lines['s_nom_opt'] = lines['s_nom'] * n.lines['num_parallel'].where(n.lines.type != '', 1.)
|
||||||
|
Loading…
Reference in New Issue
Block a user