Skip to content

Commit

Permalink
Curtailment costs included in the objective function
Browse files Browse the repository at this point in the history
  • Loading branch information
MPavicevic committed Sep 17, 2021
1 parent 85274c0 commit 8cf4b05
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 12 deletions.
Binary file modified ConfigFiles/ConfigTest.xlsx
Binary file not shown.
34 changes: 25 additions & 9 deletions dispaset/GAMS/UCM_h.gms
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ CostH2Slack(p2h2,h) [EUR\MWh] Cost of supplying H2 by other m
H2Demand(p2h2,h) [MW] H2 rigid demand
CostLoadShedding(n,h) [EUR\MWh] Cost of load shedding
Curtailment(n) [n.a] Curtailment allowed or not {1 0} at node n
CostCurtailment(n,h) [EUR\MWh] Cost of VRES curtailment
Demand(mk,n,h) [MW] Demand
Efficiency(p2h,h) [%] Efficiency
EmissionMaximum(n,p) [tP] Emission limit
Expand Down Expand Up @@ -221,6 +222,7 @@ $LOAD CostShutDown
$LOAD CostStartUp
$LOAD CostVariable
$LOAD Curtailment
$LOAD CostCurtailment
$LOAD Demand
$LOAD StorageDischargeEfficiency
$LOAD Efficiency
Expand Down Expand Up @@ -510,6 +512,7 @@ EQ_No_Flexible_Demand
EQ_Tot_DemandPtL
EQ_Max_Capacity_PtL
EQ_PtL_Demand
EQ_Curtailed_Power
$If %RetrieveStatus% == 1 EQ_CommittedCalc
;

Expand Down Expand Up @@ -541,7 +544,9 @@ EQ_SystemCost(i)..
+Config("ValueOfLostLoad","val")*(sum(n,(LL_MaxPower(n,i)+LL_MinPower(n,i))*TimeStep))
+0.8*Config("ValueOfLostLoad","val")*(sum(n,(LL_2U(n,i)+LL_2D(n,i)+LL_3U(n,i))*TimeStep))
+0.7*Config("ValueOfLostLoad","val")*sum(u,(LL_RampUp(u,i)+LL_RampDown(u,i))*TimeStep)
+Config("CostOfSpillage","val")*sum(wat,spillage(wat,i));
+Config("CostOfSpillage","val")*sum(wat,spillage(wat,i))
+sum(n,CurtailedPower(n,i) * CostCurtailment(n,i) * TimeStep)
;
$else

EQ_SystemCost(i)..
Expand All @@ -561,7 +566,9 @@ EQ_SystemCost(i)..
+Config("ValueOfLostLoad","val")*(sum(n,(LL_MaxPower(n,i)+LL_MinPower(n,i))*TimeStep))
+0.8*Config("ValueOfLostLoad","val")*(sum(n,(LL_2U(n,i)+LL_2D(n,i)+LL_3U(n,i))*TimeStep))
+0.7*Config("ValueOfLostLoad","val")*sum(u,(LL_RampUp(u,i)+LL_RampDown(u,i))*TimeStep)
+Config("CostOfSpillage","val")*sum(wat,spillage(wat,i));
+Config("CostOfSpillage","val")*sum(wat,spillage(wat,i))
+sum(n,CurtailedPower(n,i) * CostCurtailment(n,i) * TimeStep)
;

$endIf
;
Expand All @@ -572,7 +579,7 @@ EQ_Objective_function..
SystemCostD
=E=
sum(i,SystemCost(i))
+Config("WaterValue","val")*sum(s,WaterSlack(s))
+Config("WaterValue","val")*sum(au,WaterSlack(au))
;

* 3 binary commitment status
Expand Down Expand Up @@ -711,9 +718,17 @@ EQ_Demand_balance_2D(n,i)..
sum((au),Reserve_2D(au,i)*Reserve(au)*Location(au,n))
=E=
Demand("2D",n,i)
-LL_2D(n,i)
- LL_2D(n,i)
;

*Curtailed power
EQ_Curtailed_Power(n,i)..
CurtailedPower(n,i)
=E=
sum(u,(Nunits(u)*PowerCapacity(u)*LoadMaximum(u,i)-Power(u,i))$(sum(tr,Technology(u,tr))>=1) * Location(u,n))
;

* Reserve capability
EQ_Reserve_2U_capability(u,i)..
Reserve_2U(u,i)
=L=
Expand Down Expand Up @@ -1078,6 +1093,7 @@ EQ_PtL_Demand(p2h2,i)..
*===============================================================================
MODEL UCM_SIMPLE /
EQ_Objective_function,
EQ_Curtailed_Power,
EQ_CHP_extraction_Pmax,
EQ_CHP_extraction,
EQ_CHP_backpressure,
Expand Down Expand Up @@ -1218,13 +1234,13 @@ if(UCM_SIMPLE.Modelstat <> 1 and UCM_SIMPLE.Modelstat <> 8 and not failed, Commi
$If %ActivateFlexibleDemand% == 1 AccumulatedOverSupply_inital(n) = sum(i$(ord(i)=LastKeptHour-FirstHour+1),AccumulatedOverSupply.L(n,i));

* Assigning waterslack (one value per optimization horizon) to the last element of storageslack
StorageSlack.L(s,i)$(ord(i)=LastKeptHour-FirstHour+1) =StorageSlack.L(s,i)+ Waterslack.L(s);
StorageSlack.L(au,i)$(ord(i)=LastKeptHour-FirstHour+1) =StorageSlack.L(au,i)+ Waterslack.L(au);

*Loop variables to display after solving:
$If %Verbose% == 1 Display LastKeptHour,PowerInitial,StorageInitial;
);

CurtailedPower.L(n,z)=sum(u,(Nunits(u)*PowerCapacity(u)*LoadMaximum(u,z)-Power.L(u,z))$(sum(tr,Technology(u,tr))>=1) * Location(u,n)) + sum(s,spillage.L(s,z)* Location(s,n));
*CurtailedPower.L(n,z)=sum(u,(Nunits(u)*PowerCapacity(u)*LoadMaximum(u,z)-Power.L(u,z))$(sum(tr,Technology(u,tr))>=1) * Location(u,n)) + sum(s,spillage.L(s,z)* Location(s,n));
CurtailedHeat.L(n_th,z)=sum(hu,(Nunits(hu)*PowerCapacity(hu)*LoadMaximum(hu,z)-Heat.L(hu,z))$(sum(tr,Technology(hu,tr))>=1) * Location_th(hu,n_th));


Expand Down Expand Up @@ -1262,7 +1278,7 @@ $If %MTS%==0 LostLoad_RampDown(n,h)
OutputGenMargin(n,h)
OutputHeat(au,h)
OutputHeatSlack(n_th,h)
LostLoad_WaterSlack(s)
LostLoad_WaterSlack(au)
StorageShadowPrice(au,h)
H2ShadowPrice(p2h2,h)
OutputPtLDemand(p2h2,h)
Expand Down Expand Up @@ -1299,7 +1315,7 @@ OutputStorageSlack(s,z) = StorageSlack.L(s,z);
OutputSystemCost(z)=SystemCost.L(z);
OutputSpillage(s,z) = Spillage.L(s,z) ;
OutputShedLoad(n,z) = ShedLoad.L(n,z);
OutputCurtailedPower(n,z)=CurtailedPower.L(n,z);
OutputCurtailedPower(n,z)=CurtailedPower.L(n,z) + spillage.L(s,z)*Location(s,n);
OutputCurtailedHeat(n_th,z)=CurtailedHeat.L(n_th,z);
$If %ActivateFlexibleDemand% == 1 OutputDemandModulation(n,z)=DemandModulation.L(n,z);
LostLoad_MaxPower(n,z) = LL_MaxPower.L(n,z);
Expand All @@ -1312,7 +1328,7 @@ $If %MTS%==0 LostLoad_RampDown(n,z) = sum(u,LL_RampDown.L(u,z)*Location(u,n));
ShadowPrice(n,z) = EQ_Demand_balance_DA.m(n,z);
*HeatShadowPrice(au,z) = EQ_CHP_demand_satisfaction.m(au,z);
HeatShadowPrice(n_th,z) = EQ_Heat_Demand_balance.m(n_th,z);
LostLoad_WaterSlack(s) = WaterSlack.L(s);
LostLoad_WaterSlack(au) = WaterSlack.L(au);
StorageShadowPrice(s,z) = 0 ;
OutputPtLDemand(p2h2,z) = PtLDemand.L(p2h2,z);
*EQ_Storage_balance.m(s,z);
Expand Down
7 changes: 6 additions & 1 deletion dispaset/preprocessing/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ def build_single_run(config, profiles=None, PtLDemand=None, MTS=0):
Reserve2D = NodeBasedTable('Reserve2D', config, default=None)
Reserve2U = NodeBasedTable('Reserve2U', config, default=None)

# Curtailment:
CostCurtailment = NodeBasedTable('CostCurtailment', config, default=config['default']['CostCurtailment'])

# Power plants:
plants = pd.DataFrame()
if os.path.isfile(config['PowerPlantData']):
Expand Down Expand Up @@ -435,7 +438,7 @@ def build_single_run(config, profiles=None, PtLDemand=None, MTS=0):
# Formatting all time series (merging, resempling) and store in the FinalTS dict
finalTS = {'Load': Load, 'Reserve2D': reserve_2D_tot, 'Reserve2U': reserve_2U_tot,
'Efficiencies': Efficiencies, 'NTCs': NTCs, 'Inter_RoW': Inter_RoW,
'LoadShedding': LoadShedding, 'CostLoadShedding': CostLoadShedding,
'LoadShedding': LoadShedding, 'CostLoadShedding': CostLoadShedding, 'CostCurtailment': CostCurtailment,
'ScaledInflows': ReservoirScaledInflows, 'ReservoirLevels': ReservoirLevels,
'Outages': Outages, 'AvailabilityFactors': AF, 'CostHeatSlack': CostHeatSlack,
'HeatDemand': HeatDemand, 'ShareOfFlexibleDemand': ShareOfFlexibleDemand,
Expand Down Expand Up @@ -522,6 +525,7 @@ def build_single_run(config, profiles=None, PtLDemand=None, MTS=0):
sets_param['CostStartUp'] = ['au']
sets_param['CostVariable'] = ['au', 'h']
sets_param['Curtailment'] = ['n']
sets_param['CostCurtailment'] = ['n', 'h']
sets_param['Demand'] = ['mk', 'n', 'h']
sets_param['Efficiency'] = ['p2h', 'h']
sets_param['EmissionMaximum'] = ['n', 'p']
Expand Down Expand Up @@ -706,6 +710,7 @@ def build_single_run(config, profiles=None, PtLDemand=None, MTS=0):
for i, c in enumerate(sets['n']):
parameters['LoadShedding']['val'][i] = finalTS['LoadShedding'][c] * PeakLoad[c]
parameters['CostLoadShedding']['val'][i] = finalTS['CostLoadShedding'][c]
parameters['CostCurtailment']['val'][i] = finalTS['CostCurtailment'][c]

# %%###############################################################################################################
# Variable Cost
Expand Down
4 changes: 2 additions & 2 deletions dispaset/preprocessing/data_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ def load_config_excel(ConfigFile, AbsPath=True):
'Reserve2U': 160, 'Reserve2D': 161,
# Other costs related data
'PriceOfCO2': 166, 'CostHeatSlack': 167, 'CostLoadShedding': 168, 'PriceTransmission': 169,
'CostH2Slack': 170,
'CostH2Slack': 170, 'CostCurtailment': 171,
# Fuel price related data
'PriceOfNuclear': 180, 'PriceOfBlackCoal': 181, 'PriceOfGas': 182, 'PriceOfFuelOil': 183,
'PriceOfBiomass': 184, 'PriceOfLignite': 185, 'PriceOfPeat': 186
Expand All @@ -616,7 +616,7 @@ def load_config_excel(ConfigFile, AbsPath=True):
'PriceOfBiomass': 184, 'PriceOfLignite': 185, 'PriceOfPeat': 186,
# Other price defaults
'PriceOfCO2': 166, 'CostHeatSlack': 167, 'CostLoadShedding': 168, 'PriceTransmission': 169,
'CostH2Slack': 170,
'CostH2Slack': 170, 'CostCurtailment': 171,
# Optimization and infeasibility cost data
'ShareOfFlexibleDemand': 125, 'LoadShedding': 129,
'DemandFlexibility': 162, 'ShareOfQuickStartUnits': 163,
Expand Down

0 comments on commit 8cf4b05

Please sign in to comment.