diff --git a/inc/1a_definitions.gms b/inc/1a_definitions.gms index d5d00332fef6594fe9c3414da1a8e46790dc3952..543d88cc6e863396365dcfa23ed5ad80c9310458 100644 --- a/inc/1a_definitions.gms +++ b/inc/1a_definitions.gms @@ -174,6 +174,7 @@ Sets ts_priceChange ts_price ts_unavailability + ts_storageValue / ; // END Sets @@ -221,6 +222,7 @@ param_gn "Possible parameters for grid, node" / boundStartToEnd "Force the last states to equal the first state" * forecastLength "Length of forecasts in use for the node (hours). After this, the node will use the central forecast." // NOT IMPLEMENTED capacityMargin "Capacity margin used in invest mode (MW)" + storageValueUseTimeSeries "A flag to determine whether to use time series form `storageValue`" / param_gnBoundaryTypes "Types of boundaries that can be set for a node with a state variable" / diff --git a/inc/1c_parameters.gms b/inc/1c_parameters.gms index 9397c43177daf899049e26357895402841559067..9c9f62f962a53d6467ecfcab450cca4c9b7dff5a 100644 --- a/inc/1c_parameters.gms +++ b/inc/1c_parameters.gms @@ -47,6 +47,7 @@ Scalars Parameters p_gn(grid, node, param_gn) "Properties for energy nodes" p_gnBoundaryPropertiesForStates(grid, node, param_gnBoundaryTypes, param_gnBoundaryProperties) "Properties of different state boundaries and limits" + p_storageValue(grid, node) "Constant value of stored something at the end of a time step (EUR/)" p_gnn(grid, node, node, param_gnn) "Data for interconnections between energy nodes" p_gnu(grid, node, unit, param_gnu) "Unit data where energy type matters" p_gnu_io(grid, node, unit, input_output, param_gnu) "Unit data where energy type matters" @@ -162,6 +163,7 @@ Parameters ts_cf(flow, node, f, t) "Available capacity factor time series (p.u.)" ts_reserveDemand(restype, up_down, group, f, t) "Reserve demand in region in the time step (MW)" ts_node(grid, node, param_gnBoundaryTypes, f, t) "Fix the states of a node according to time-series form exogenous input ([v_state])" + ts_storageValue(grid, node, f, t) "Timeseries value of stored something at the end of a time step (EUR/)" ts_priceChange(node, t) "Initial commodity price and consequent changes in commodity price (EUR/MWh)" ts_price(node, t) "Commodity price time series (EUR/MWh)" ts_unavailability(unit, t) "Unavailability of a unit in the time step (p.u.)" @@ -171,6 +173,7 @@ Parameters ts_cf_(flow, node, s, f, t) "Mean available capacity factor time series (p.u.)" ts_reserveDemand_(restype, up_down, group, f, t) "Mean reserve demand in region in the time step (MW)" ts_node_(grid, node, param_gnBoundaryTypes, s, f, t) "Mean value of ts_node" + ts_storageValue_(grid, node, s, f, t) "Mean value of ts_storageValue" ts_vomCost_(grid, node, unit, t) "Calculated variable O&M cost that includes O&M cost, fuel cost and emission cost" ts_startupCost_(unit, starttype, t) "Calculated variable startup cost that includes startup cost, fuel cost and emission cost" @@ -201,7 +204,6 @@ Parameters * --- Other time dependent parameters ----------------------------------------- Parameters - p_storageValue(grid, node, t) "Value of stored something at the end of a time step" p_stepLength(mType, f, t) "Length of an interval in hours" p_stepLengthNoReset(mType, f, t) "Length of an interval in hours - includes also lengths of previously realized intervals" p_s_discountFactor(s) "Discount factor for samples when using a multi-year horizon" diff --git a/inc/1e_inputs.gms b/inc/1e_inputs.gms index 649d3248f42bb3f979f00b6bd5233c98a720a578..49b0fab5348c604da4ac5602d57da2a2c6c7e7cf 100644 --- a/inc/1e_inputs.gms +++ b/inc/1e_inputs.gms @@ -37,9 +37,9 @@ $ifthen exist '%input_dir%/inputData.gdx' $$loaddc p_gnu_io $$loaddc p_gnuBoundaryProperties $$loaddc p_unit + $$loaddc ts_unit $$loaddc p_unitConstraint $$loaddc p_unitConstraintNode - $$loaddc ts_unit $$loaddc restype $$loaddc restypeDirection $$loaddc restypeReleasedForRealization @@ -66,6 +66,7 @@ $ifthen exist '%input_dir%/inputData.gdx' $$loaddc t_invest $$loaddc utAvailabilityLimits $$loaddc p_storageValue + $$loaddc ts_storageValue $$loaddc uGroup $$loaddc gnuGroup $$loaddc gn2nGroup diff --git a/inc/1e_scenChanges.gms b/inc/1e_scenChanges.gms index 1cfb76209382d5d7bb913b14ecc94546bdd0fdba..34e568d876d5fdd96573d0f737fb7833a52c388c 100644 --- a/inc/1e_scenChanges.gms +++ b/inc/1e_scenChanges.gms @@ -206,6 +206,30 @@ $ifthen exist '%input_dir%/ts_unit3.gdx' $$gdxin $endif +$ifthen exist '%input_dir%/p_unitConstraint2.gdx' + $$gdxin '%input_dir%/p_unitConstraint2.gdx' + $$loaddcm p_unitConstraint + $$gdxin +$endif + +$ifthen exist '%input_dir%/p_unitConstraint3.gdx' + $$gdxin '%input_dir%/p_unitConstraint3.gdx' + $$loaddcm p_unitConstraint + $$gdxin +$endif + +$ifthen exist '%input_dir%/p_unitConstraintNode2.gdx' + $$gdxin '%input_dir%/p_unitConstraintNode2.gdx' + $$loaddcm p_unitConstraintNode + $$gdxin +$endif + +$ifthen exist '%input_dir%/p_unitConstraintNode3.gdx' + $$gdxin '%input_dir%/p_unitConstraintNode3.gdx' + $$loaddcm p_unitConstraintNode + $$gdxin +$endif + $ifthen exist '%input_dir%/restype2.gdx' $$gdxin '%input_dir%/restype2.gdx' $$loaddcm restype @@ -386,30 +410,6 @@ $ifthen exist '%input_dir%/flowUnit3.gdx' $$gdxin $endif -$ifthen exist '%input_dir%/p_unitConstraint2.gdx' - $$gdxin '%input_dir%/p_unitConstraint2.gdx' - $$loaddcm p_unitConstraint - $$gdxin -$endif - -$ifthen exist '%input_dir%/p_unitConstraint3.gdx' - $$gdxin '%input_dir%/p_unitConstraint3.gdx' - $$loaddcm p_unitConstraint - $$gdxin -$endif - -$ifthen exist '%input_dir%/p_unitConstraintNode2.gdx' - $$gdxin '%input_dir%/p_unitConstraintNode2.gdx' - $$loaddcm p_unitConstraintNode - $$gdxin -$endif - -$ifthen exist '%input_dir%/p_unitConstraintNode3.gdx' - $$gdxin '%input_dir%/p_unitConstraintNode3.gdx' - $$loaddcm p_unitConstraintNode - $$gdxin -$endif - $ifthen exist '%input_dir%/emission2.gdx' $$gdxin '%input_dir%/emission2.gdx' $$loaddcm emission @@ -530,6 +530,18 @@ $ifthen exist '%input_dir%/p_storageValue3.gdx' $$gdxin $endif +$ifthen exist '%input_dir%/ts_storageValue2.gdx' + $$gdxin '%input_dir%/ts_storageValue2.gdx' + $$loaddcm ts_storageValue + $$gdxin +$endif + +$ifthen exist '%input_dir%/ts_storageValue3.gdx' + $$gdxin '%input_dir%/ts_storageValue3.gdx' + $$loaddcm ts_storageValue + $$gdxin +$endif + $ifthen exist '%input_dir%/uGroup2.gdx' $$gdxin '%input_dir%/uGroup2.gdx' $$loaddcm uGroup diff --git a/inc/2c_objective.gms b/inc/2c_objective.gms index a0e1d8489d963197deefe606451a51dbb8915249..9880fd59ef4fa6a22d94e85e09e6de174954dcb8 100644 --- a/inc/2c_objective.gms +++ b/inc/2c_objective.gms @@ -115,23 +115,25 @@ q_obj .. // Cost of energy storage change (note: not discounted) + sum(gn_state(grid, node), - + sum(mft_start(m, f, t)${ p_storageValue(grid, node, t) - and active(m, 'storageValue') - }, - + p_storageValue(grid, node, t) - * sum(ms(m, s)${ p_msft_probability(m, s, f, t) }, - + p_msft_probability(m, s, f, t) - * v_state(grid, node, s, f+df_central(f,t), t) - ) // END sum(s) + + sum(mft_start(m, f, t)${ active(m, 'storageValue') }, + + sum(ms(m, s)${ p_msft_probability(m, s, f, t) }, + + [ + + p_storageValue(grid, node)${ not p_gn(grid, node, 'storageValueUseTimeSeries') } + + ts_storageValue_(grid, node, s, f+df_central(f,t), t)${ p_gn(grid, node, 'storageValueUseTimeSeries') } + ] + * p_msft_probability(m, s, f, t) + * v_state(grid, node, s, f+df_central(f,t), t) + ) // END sum(s) ) // END sum(mftStart) - - sum(mft_lastSteps(m, f, t)${ p_storageValue(grid, node, t) - and active(m, 'storageValue') - }, - + p_storageValue(grid, node, t) - * sum(ms(m, s)${p_msft_probability(m, s, f, t)}, - + p_msft_probability(m, s, f, t) - * v_state(grid, node, s, f+df_central(f,t), t) - ) // END sum(s) + - sum(mft_lastSteps(m, f, t)${ active(m, 'storageValue') }, + + sum(ms(m, s)${p_msft_probability(m, s, f, t)}, + + [ + + p_storageValue(grid, node)${ not p_gn(grid, node, 'storageValueUseTimeSeries') } + + ts_storageValue_(grid, node, s, f+df_central(f,t), t)${ p_gn(grid, node, 'storageValueUseTimeSeries') } + ] + * p_msft_probability(m, s, f, t) + * v_state(grid, node, s, f+df_central(f,t), t) + ) // END sum(s) ) // END sum(mftLastSteps) ) // END sum(gn_state) diff --git a/inc/3c_inputsLoop.gms b/inc/3c_inputsLoop.gms index 2733b03a52b42f65aa546ae5d189630136eaa793..c64fc4543f6786d43298059fa7258bffacd7fb17 100644 --- a/inc/3c_inputsLoop.gms +++ b/inc/3c_inputsLoop.gms @@ -423,7 +423,19 @@ $offtext + sum((nu(node, unit), emission)$p_unitEmissionCost(unit, node, emission), + p_unStartup(unit, node, starttype) // MWh/start-up * p_unitEmissionCost(unit, node, emission) // CUR/MWh - ) // END sum(nu, emission) + ); // END sum(nu, emission) + + // `storageValue` + ts_storageValue_(gn_state(grid, node), sft(s, f, tt_interval(t)))${ p_gn(grid, node, 'storageValueUseTimeSeries') } + = sum(tt_aggregate(t, t_), + ts_storageValue(grid, node, + f + ( df_realization(f, t)$(not gn_forecasts(grid, node, 'ts_storageValue')) + + df_scenario(f, t)$gn_scenarios(grid, node, 'ts_storageValue')), + t_+ (+ dt_scenarioOffset(grid, node, 'ts_storageValue', s) + + dt_circular(t_)$(not gn_scenarios(grid, node, 'ts_storageValue')))) + ) + / mInterval(mSolve, 'stepsPerInterval', counter); + ); // END loop(counter) diff --git a/inc/4b_outputInvariant.gms b/inc/4b_outputInvariant.gms index e38f93b98f00734df5c72d4ea217d75d2fa1a9ef..5541a496517130a5601a800b67a91f42c43b60eb 100644 --- a/inc/4b_outputInvariant.gms +++ b/inc/4b_outputInvariant.gms @@ -78,15 +78,21 @@ loop(m, ); // END sum(slack) // Storage Value Change - r_gnStorageValueChange(gn_state(grid, node))${ sum(t_full(t), p_storageValue(grid, node, t)) } + r_gnStorageValueChange(gn_state(grid, node))${ active(m, 'storageValue') } = 1e-6 * [ + sum(ft_realizedNoReset(f,t)${ ord(t) = mSettings(m, 't_end') + 1 }, - + p_storageValue(grid, node, t) + + [ + + p_storageValue(grid, node)${ not p_gn(grid, node, 'storageValueUseTimeSeries') } + + ts_storageValue(grid, node, f, t)${ p_gn(grid, node, 'storageValueUseTimeSeries') } + ] * r_state(grid, node, f, t) ) // END sum(ft_realizedNoReset) - sum(ft_realizedNoReset(f,t)${ ord(t) = mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod') }, // INITIAL v_state NOW INCLUDED IN THE RESULTS - + p_storageValue(grid, node, t) + + [ + + p_storageValue(grid, node)${ not p_gn(grid, node, 'storageValueUseTimeSeries') } + + ts_storageValue(grid, node, f, t)${ p_gn(grid, node, 'storageValueUseTimeSeries') } + ] * r_state(grid, node, f, t) ) // END sum(ft_realizedNoReset) ]; // END * 1e-6