Commit 884e51b2 authored by jussi ikäheimo's avatar jussi ikäheimo
Browse files

df_reserves and ft_reservesfixed updated. r_totalcurtailmentfuel added.

parent 4d996f5a
......@@ -103,6 +103,7 @@ Parameters
r_gnTotalGenShare(grid, node) "Total energy generation gn/g share"
r_gTotalGen(grid) "Total energy generation in g over the simulation (MWh)"
r_guGen(grid, unit, f, t) "Energy generation for a unit summed over nodes (MW)"
r_TotalCurtailmentFuel(flow, t) "Total curtailment per flow type (MW)"
// Approximate utilization rates
r_gnuUtilizationRate(grid, node, unit) "Approximate utilization rates of gnus over the simulation"
......
......@@ -405,11 +405,20 @@ df_central(ft(f,t))${ ord(t) > tSolveFirst + currentForecastLength - p_stepLen
// Forecast index displacement between realized and forecasted intervals, required for locking reserves ahead of (dispatch) time.
Option clear = df_reserves;
*df_reserves(node, restype, ft(f, t))
* ${ p_nReserves(node, restype, 'update_frequency')
* and p_nReserves(node, restype, 'gate_closure')
* and ord(t) <= tSolveFirst + p_nReserves(node, restype, 'gate_closure') + p_nReserves(node, restype, 'update_frequency')
* - mod(tSolveFirst - 1 + p_nReserves(node, restype, 'gate_closure') + p_nReserves(node, restype, 'update_frequency')
* - p_nReserves(node, restype, 'update_offset'), p_nReserves(node, restype, 'update_frequency'))
* }
* = sum(f_${ mf_realization(mSolve, f_) }, ord(f_) - ord(f)) + Eps; // The Eps ensures that checks to see if df_reserves exists return positive even if the displacement is zero.
df_reserves(node, restype, ft(f, t))
${ p_nReserves(node, restype, 'update_frequency')
and p_nReserves(node, restype, 'gate_closure')
and ord(t) <= tSolveFirst + p_nReserves(node, restype, 'gate_closure') + p_nReserves(node, restype, 'update_frequency')
- mod(tSolveFirst - 1 + p_nReserves(node, restype, 'gate_closure') + p_nReserves(node, restype, 'update_frequency')
- mod(tSolveFirst + p_nReserves(node, restype, 'update_frequency')
- p_nReserves(node, restype, 'update_offset'), p_nReserves(node, restype, 'update_frequency'))
}
= sum(f_${ mf_realization(mSolve, f_) }, ord(f_) - ord(f)) + Eps; // The Eps ensures that checks to see if df_reserves exists return positive even if the displacement is zero.
......@@ -421,8 +430,13 @@ ft_reservesFixed(node, restype, f_solve(f), t_active(t))
and not tSolveFirst = mSettings(mSolve, 't_start') // No reserves are locked on the first solve!
and p_nReserves(node, restype, 'update_frequency')
and p_nReserves(node, restype, 'gate_closure')
* and ord(t) <= tSolveFirst + p_nReserves(node, restype, 'gate_closure') + p_nReserves(node, restype, 'update_frequency')
* - mod(tSolveFirst - 1 + p_nReserves(node, restype, 'gate_closure') - mSettings(mSolve, 't_jump')
* + p_nReserves(node, restype, 'update_frequency') - p_nReserves(node, restype, 'update_offset'),
* p_nReserves(node, restype, 'update_frequency'))
* - mSettings(mSolve, 't_jump')
and ord(t) <= tSolveFirst + p_nReserves(node, restype, 'gate_closure') + p_nReserves(node, restype, 'update_frequency')
- mod(tSolveFirst - 1 + p_nReserves(node, restype, 'gate_closure') - mSettings(mSolve, 't_jump')
- mod(tSolveFirst - mSettings(mSolve, 't_jump')
+ p_nReserves(node, restype, 'update_frequency') - p_nReserves(node, restype, 'update_offset'),
p_nReserves(node, restype, 'update_frequency'))
- mSettings(mSolve, 't_jump')
......
$ontext
This file is part of Backbone.
Backbone is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Backbone is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Backbone. If not, see <http://www.gnu.org/licenses/>.
$offtext
* =============================================================================
* --- Recording realized parameter values -------------------------------------
* =============================================================================
* --- Result arrays required by model dynamics --------------------------------
if(tSolveFirst >= mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod') - mSettings(mSolve, 't_jump') and firstResultsOutputSolve,
firstResultsOutputSolve = 0;
r_state(gn_state(grid, node), f_solve, t) $[ord(t) = mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_state.l(grid, node, f_solve, t);
r_online(unit, f_solve, t)$[unit_online(unit) and ord(t) = mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_online_LP.l(unit, f_solve, t)$unit_online_LP(unit)
+ v_online_MIP.l(unit, f_solve, t)$unit_online_MIP(unit);
);
// Realized state history
r_state(gn_state(grid, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_state.l(grid, node, f, t)
;
// Realized state history - initial state values in samples
r_state(gn_state(grid, node), f_solve(f), t+dt(t))${ ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')
and sum(ms(mSolve, s), mst_start(mSolve, s, t))
and ft_realized(f, t)
}
= v_state.l(grid, node, f, t+dt(t))
;
// Realized unit online history
r_online(uft_online(unit, ft_realized(f, t)))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_online_LP.l(unit, f, t)${ uft_onlineLP(unit, f, t) }
+ v_online_MIP.l(unit, f, t)${ uft_onlineMIP(unit, f, t) }
;
// Unit startup and shutdown history
r_startup(unit, starttype, ft_realized(f, t))${ uft_online(unit, f, t) and [ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')] }
= v_startup.l(unit, starttype, f, t)
;
r_shutdown(uft_online(unit, ft_realized(f, t)))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_shutdown.l(unit, f, t)
;
* --- Reserve results ---------------------------------------------------------
// Loop over reserve horizon, as the reserve variables use a different ft-structure due to commitment
loop((restypeDirectionNode(restype, up_down, node), ft(f, t))
${ ord(t) <= tSolveFirst + p_nReserves(node, restype, 'reserve_length')
and ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')
},
// Reserve provisions of units
r_reserve(nuRescapable(restype, up_down, node, unit), f+df_reserves(node, restype, f, t), t)
${ not [ restypeReleasedForRealization(restype)
and ft_realized(f+df_reserves(node, restype, f, t), t)
]
}
= + v_reserve.l(restype, up_down, node, unit, f+df_reserves(node, restype, f, t), t)
+ sum(restype_$p_nuRes2Res(node, unit, restype_, up_down, restype),
+ v_reserve.l(restype_, up_down, node, unit, f+df_reserves(node, restype_, f, t), t)
* p_nuRes2Res(node, unit, restype_, up_down, restype)
);
// Reserve transfer capacity
r_resTransferRightward(restype, up_down, node, to_node, f+df_reserves(node, restype, f, t), t)
${ restypeDirectionNode(restype, up_down, to_node)
}
= v_resTransferRightward.l(restype, up_down, node, to_node, f+df_reserves(node, restype, f, t), t);
r_resTransferLeftward(restype, up_down, node, to_node, f+df_reserves(node, restype, f, t), t)
${ restypeDirectionNode(restype, up_down, to_node)
}
= v_resTransferLeftward.l(restype, up_down, node, to_node, f+df_reserves(node, restype, f, t), t);
// Dummy reserve demand changes
r_qResDemand(restype, up_down, node, f+df_reserves(node, restype, f, t), t)
= vq_resDemand.l(restype, up_down, node, f+df_reserves(node, restype, f, t), t);
r_qResMissing(restype, up_down, node, f+df_reserves(node, restype, f, t), t)
= vq_resMissing.l(restype, up_down, node, f+df_reserves(node, restype, f, t), t);
); // END loop(restypeDirectionNode, ft)
* --- Interesting results -----------------------------------------------------
// Unit generation and consumption
r_gen(gnuft(grid, node, unit, ft_realized(f, t)))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_gen.l(grid, node, unit, f, t)
;
// Fuel use of units
r_fuelUse(fuel, uft(unit_fuel, ft_realized(f, t)))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_fuelUse.l(fuel, unit_fuel, f, t)
;
// Transfer of energy between nodes
r_transfer(gn2n(grid, from_node, to_node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_transfer.l(grid, from_node, to_node, f, t)
;
// Energy spilled from nodes
r_spill(gn(grid, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_spill.l(grid, node, f, t)
;
// Total Objective function
r_totalObj
= r_totalObj + v_obj.l
;
// q_balance marginal values
r_balanceMarginal(gn(grid, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= q_balance.m(grid, node, mSolve, f, t)
;
// q_resDemand marginal values
r_resDemandMarginal(restypeDirectionNode(restype, up_down, node), ft_realized(f, t))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= q_resDemand.m(restype, up_down, node, f, t)
;
// v_stateSlack values for calculation of realized costs later on
r_stateSlack(gn_stateSlack(grid, node), slack, ft_realized(f, t))$[ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')]
= v_stateSlack.l(grid, node, slack, f, t)
;
// Unit investments
r_invest(unit)${unit_investLP(unit) or unit_investMIP(unit)}
= sum(t_invest, v_invest_LP.l(unit, t_invest) + v_invest_MIP.l(unit, t_invest))
;
// Link investments
r_investTransfer(grid, node, node_, t_invest(t))${ p_gnn(grid, node, node_, 'transferCapInvLimit')
* and t_current(t)
and ord(t) <= tSolveFirst + mSettings(mSolve, 't_jump')
}
= v_investTransfer_LP.l(grid, node, node_, t)
+ v_investTransfer_MIP.l(grid, node, node_, t) * p_gnn(grid, node, node_, 'unitSize')
;
* --- Feasibility results -----------------------------------------------------
// Dummy generation & consumption
r_qGen(inc_dec, gn(grid, node), ft_realized(f, t))
${ ord(t) > mSettings(mSolve, 't_start') + mSettings(mSolve, 't_initializationPeriod')
}
= vq_gen.l(inc_dec, grid, node, f, t)
;
* =============================================================================
* --- Diagnostics Results -----------------------------------------------------
* =============================================================================
// Capacity factors for examining forecast errors
d_capacityFactor(flowNode(flow, node), f_solve(f), t_active(t))${ sum(flowUnit(flow, unit), nu(node, unit)) }
= ts_cf_(flow, node, f, t)
+ ts_cf(flow, node, f, t)${ not ts_cf_(flow, node, f, t) }
- 1e-3${ not ts_cf_(flow, node, f, t)
and not ts_cf(flow, node, f, t)
}
;
// Temperature forecast for examining the error
d_nodeState(gn_state(grid, node), param_gnBoundaryTypes, f_solve(f), t_active(t))${ p_gnBoundaryPropertiesForStates(grid, node, param_gnBoundaryTypes, 'useTimeseries') }
= ts_node_(grid, node, param_gnBoundaryTypes, f, t)
+ ts_node(grid, node, param_gnBoundaryTypes, f, t)${ not ts_node_(grid, node, param_gnBoundaryTypes, f, t) }
- 1e-3${ not ts_node_(grid, node, param_gnBoundaryTypes, f, t)
and not ts_node_(grid, node, param_gnBoundaryTypes, f, t)
}
;
* --- Model Solve & Status ----------------------------------------------------
// Model/solve status
if (mSolve('schedule'),
r_solveStatus(tSolve,'modelStat')=schedule.modelStat;
r_solveStatus(tSolve,'solveStat')=schedule.solveStat;
r_solveStatus(tSolve,'totalTime')=schedule.etSolve;
r_solveStatus(tSolve,'iterations')=schedule.iterUsd;
r_solveStatus(tSolve,'nodes')=schedule.nodUsd;
r_solveStatus(tSolve,'numEqu')=schedule.numEqu;
r_solveStatus(tSolve,'numDVar')=schedule.numDVar;
r_solveStatus(tSolve,'numVar')=schedule.numVar;
r_solveStatus(tSolve,'numNZ')=schedule.numNZ;
r_solveStatus(tSolve,'sumInfes')=schedule.sumInfes;
r_solveStatus(tSolve,'objEst')=schedule.objEst;
r_solveStatus(tSolve,'objVal')=schedule.objVal;
);
if (mSolve('invest'),
r_solveStatus(tSolve,'modelStat')=invest.modelStat;
r_solveStatus(tSolve,'solveStat')=invest.solveStat;
r_solveStatus(tSolve,'totalTime')=invest.etSolve;
r_solveStatus(tSolve,'iterations')=invest.iterUsd;
r_solveStatus(tSolve,'nodes')=invest.nodUsd;
r_solveStatus(tSolve,'numEqu')=invest.numEqu;
r_solveStatus(tSolve,'numDVar')=invest.numDVar;
r_solveStatus(tSolve,'numVar')=invest.numVar;
r_solveStatus(tSolve,'numNZ')=invest.numNZ;
r_solveStatus(tSolve,'sumInfes')=invest.sumInfes;
r_solveStatus(tSolve,'objEst')=invest.objEst;
r_solveStatus(tSolve,'objVal')=invest.objVal;
);
......@@ -245,6 +245,21 @@ loop(m,
* sum(msft_realizedNoReset(m, s, f, t), p_msProbability(m, s))
); // END sum(ft_realizedNoReset)
r_TotalCurtailmentFuel(flow, t)
= sum(ft_realizedNoReset(f, t)$[ord(t) > mSettings(m, 't_start') + mSettings(m, 't_initializationPeriod')],
sum((grid, node, unit_flow)${ flowUnit(flow, unit_flow)
and nu(node, unit_flow) },
ts_cf_(flow, node, f, t)
* p_gnu(grid, node, unit_flow, 'maxGen')
* p_unit(unit_flow, 'availability')
- r_gen(grid, node, unit_flow, f, t)
)
); // END sum(ft_realized)
* --- Total Unit Online Results -----------------------------------------------
// Total sub-unit-hours for units over the simulation
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment