Commit cb666391 authored by Niina Helistö's avatar Niina Helistö
Browse files

Testing investment parameters and variables

parent 989be5c1
......@@ -179,6 +179,8 @@ param_gnn "Set of possible data parameters for grid, node, node (nodal interconn
diffCoeff "Coefficients for energy diffusion between nodes"
boundStateOffset "Offset parameter for relatively bound node states"
boundStateMaxDiff "Maximum difference of node state pairs"
transferCapInvLimit "Capacity limit for investments"
invCost "Investment cost (€/MW)"
/
param_gnu "Set of possible data parameters for grid, node, unit" /
......@@ -190,6 +192,8 @@ param_gnu "Set of possible data parameters for grid, node, unit" /
maxRampDown "Speed to ramp down (p.u. / min)"
rampUpCost "Wear and tear cost of ramping up (€/MW)"
rampDownCost "Wear and tear cost of ramping up (€/MW)"
maxGenCap "Maximum output capacity investment (MW)"
maxConsCap "Maximum loading capacity investment (MW)"
/
param_unit "Set of possible data parameters for units" /
......@@ -217,6 +221,7 @@ param_unit "Set of possible data parameters for units" /
level1 * level9 "Level of simplification in the part-load efficiency representation"
useTimeseries "Uses time series form input for unit parameters whenever possible"
section "Possibility to define a no load fuel use for units with zero minimum output"
invCosts "Investment costs (€/MW)"
/
param_fuel "Parameters for fuels" /
......@@ -236,5 +241,9 @@ param_policy "Set of possible data parameters for grid, node, regulation" /
gate_closure "???"
/
param_gnugnu "Set of possible data parameters for grid, node, unit, grid, node, unit" /
capacityRatio "Fixed ratio of the capacity of the first unit to the second"
/
; // End parameter set declarations
......@@ -52,6 +52,7 @@ Parameters
p_uFuel(unit, param_fuel, fuel, param_unitFuel) "Parameters interacting between units and fuels"
p_effUnit(effSelector, unit, effSelector, *) "Data for piece-wise linear efficiency blocks"
p_effGroupUnit(effSelector, unit, *) "Unit data specific to a efficiency group (e.g. left border of the unit)"
p_gnugnu(grid, node, unit, grid, node, unit, param_gnugnu) "Data connecting units in nodes and grids"
// Time dependent unit & fuel parameters
ts_unit(unit, *, f, t) "Time dependent unit data, where energy type doesn't matter"
ts_effUnit(effSelector, unit, effSelector, *, f, t) "Time dependent data for piece-wise linear efficiency blocks"
......
......@@ -46,6 +46,7 @@ $loaddc ts_cf
$loaddc ts_fuelPriceChange
$loaddc ts_influx
$loaddc ts_nodeState
$loaddc p_gnugnu
$gdxin
$ontext
......@@ -73,6 +74,9 @@ p_gnu(grid, node, unit_aggregate(unit), 'maxCons') = sum(unit_$unitUnit_aggregat
gnu(grid, node, unit)$(p_gnu(grid, node, unit, 'maxGen') or p_gnu(grid, node, unit, 'maxCons')) = yes;
gnu_output(grid, node, unit)$p_gnu(grid, node, unit, 'maxGen') = yes;
gnu_input(grid, node, unit)$p_gnu(grid, node, unit, 'maxCons') = yes;
gnu(grid, node, unit)$(p_gnu(grid, node, unit, 'maxGenCap') or p_gnu(grid, node, unit, 'maxConsCap')) = yes;
gnu_output(grid, node, unit)$p_gnu(grid, node, unit, 'maxGenCap') = yes;
gnu_output(grid, node, unit)$p_gnu(grid, node, unit, 'maxConsCap') = yes;
gn2gnu(grid_, node_input, grid, node, unit)$(gnu_input(grid_, node_input, unit) and gnu_output(grid, node, unit)) = yes;
nu(node, unit)$sum(grid, gnu(grid, node, unit)) = yes;
nuRescapable(restype, up_down, node, unit)$p_nuReserves(node, unit, restype, up_down) = yes;
......@@ -81,6 +85,8 @@ unit_flow(unit)$sum(flow, flowUnit(flow, unit)) = yes;
unit_fuel(unit)$sum[ (fuel, node)$sum(t, ts_fuelPriceChangenode(fuel, node, t)), uFuel(unit, 'main', fuel) ] = yes;
unit_elec(unit)$sum(gnu(grid, node, unit), p_gnu('elec', node, unit, 'maxGen')) = yes;
unit_elec(unit)$sum(gnu(grid, node, unit), p_gnu('elec', node, unit, 'maxCons')) = yes;
unit_elec(unit)$sum(gnu(grid, node, unit), p_gnu('elec', node, unit, 'maxGenCap')) = yes;
unit_elec(unit)$sum(gnu(grid, node, unit), p_gnu('elec', node, unit, 'maxConsCap')) = yes;
* Assume values for critical unit related parameters, if not provided by input data
p_unit(unit, 'eff00')$(not p_unit(unit, 'eff00')) = 1; // If the unit does not have efficiency set, it is 1
......@@ -90,6 +96,7 @@ p_unit(unit, 'outputCapacityTotal')$(not p_unit(unit, 'outputCapacityTotal')) =
* Generate node related sets based on input data // NOTE! These will need to change if p_gnn is required to work with only one row per link.
gn2n(grid, from_node, to_node)${p_gnn(grid, from_node, to_node, 'transferCap') OR p_gnn(grid, from_node, to_node, 'transferLoss')} = yes;
gn2n(grid, from_node, to_node)${p_gnn(grid, from_node, to_node, 'transferCapBidirectional') OR p_gnn(grid, to_node, from_node, 'transferCapBidirectional')} = yes;
gn2n(grid, from_node, to_node)$p_gnn(grid, from_node, to_node, 'transferCapInvLimit') = yes;
gnn_boundState(grid, node, node_)$(p_gnn(grid, node, node_, 'boundStateOffset')) = yes;
gnn_state(grid, node, node_)$(p_gnn(grid, node, node_, 'diffCoeff') or gnn_boundState(grid, node, node_)) = yes;
gn_stateSlack(grid, node)$(sum((upwardSlack, useConstantOrTimeSeries), p_gnBoundaryPropertiesForStates(grid, node, upwardSlack, useConstantOrTimeSeries))) = yes;
......
......@@ -36,6 +36,8 @@ Positive variables
v_transfer(grid, node, node, f, t) "Average electricity transmission level from node to node during time period/slice (MW)"
v_resTransfer(restype, up_down, node, node, f, t) "Electricity transmission capacity from node to node reserved for providing reserves (MW)"
v_reserve(restype, up_down, node, unit, f, t) "Unit capacity reserved for providing reserve of specific type (MW)"
v_gnn(grid, node, node) "Invested transfer capacity (MW)"
v_gnu(grid, node, unit) "Invested energy generation capacity (MW)"
;
* --- Feasibility control -----------------------------------------------------
......
......@@ -38,6 +38,8 @@ equations
q_boundStateMaxDiff(grid, node, node, mType, f, t) "Node state variables bounded by other nodes (maximum state difference)"
q_boundCyclic(grid, node, mType, f, t, t_) "Cyclic bound for the first and the last state"
q_bidirectionalTransfer(grid, node, node, f, t) "Possible common transfer capacity constraint for interconnected transfer variables"
q_fixedGenCap
q_symmetricTransferCap
;
......@@ -100,8 +102,9 @@ q_obj ..
p_fuelEmission(fuel, emission) / 1e3
* p_gnPolicy(grid, node, 'emissionTax', emission) // Sum emission costs from different output energy types
)
) / p_gnu(grid, node, unit, 'maxGen') // Calculate these in relation to maximum output ratios between multiple outputs
) / (p_gnu(grid, node, unit, 'maxGen')$p_gnu(grid, node, unit, 'maxGen') + 1$(not p_gnu(grid, node, unit, 'maxGen'))) // Calculate these in relation to maximum output ratios between multiple outputs
) * sum(gnu_output(grid, node, unit), p_gnu(grid, node, unit, 'maxGen')) // see line above
* Check the calculation of emissions when maxGen = 0
)
}
)
......@@ -154,6 +157,12 @@ q_obj ..
)
)
)
+ sum(gnu(grid, node, unit),
v_gnu(grid, node, unit) * p_unit(unit, 'invCosts')
)
+ sum(gn2n(grid, from_node, to_node),
v_gnn(grid, from_node, to_node) * p_gnn(grid, from_node, to_node, 'invCost')
)
;
* -----------------------------------------------------------------------------
......@@ -248,6 +257,7 @@ q_resTransfer(gn2n(grid, from_node, to_node), ft(f, t))${ sum(restypeDirection(r
)
=L=
+ p_gnn(grid, from_node, to_node, 'transferCap')
+ v_gnn(grid, from_node, to_node)
;
* -----------------------------------------------------------------------------
q_maxDownward(gnuft(grid, node, unit, f, t))${ [ ord(t) < tSolveFirst + settings('t_reserveLength') // Unit is either providing
......@@ -274,9 +284,11 @@ q_maxDownward(gnuft(grid, node, unit, f, t))${ [ ord(t) < tSolveFirst + sett
+ (p_effGroupUnit(effGroup, unit, 'lb')${not ts_effGroupUnit(effGroup, unit, 'lb', f, t)} + ts_effGroupUnit(effGroup, unit, 'lb', f, t))
)
+ v_gen.lo(grid, node, unit, f, t)$p_gnu(grid, node, unit, 'maxCons') // notice: v_gen.lo for consuming units is negative
+ v_gnu(grid, node, unit)$p_gnu(grid, node, unit, 'maxConsCap') // notice: v_gnu for consuming units is negative
- v_online(unit, f, t)${uft_online(unit, f, t) and p_gnu(grid, node, unit, 'maxCons')} // Online variables should only be generated for units with restrictions
/ p_unit(unit, 'unitCount')
* p_gnu(grid, node, unit, 'maxGen')
* Check what needs to be done for investment options and check why there is maxGen in the row above
;
* -----------------------------------------------------------------------------
q_maxUpward(gnuft(grid, node, unit, f, t))${ [ ord(t) < tSolveFirst + settings('t_reserveLength') // Unit is either providing
......@@ -303,9 +315,16 @@ q_maxUpward(gnuft(grid, node, unit, f, t))${ [ ord(t) < tSolveFirst + settin
+ (p_effGroupUnit(effGroup, unit, 'lb')${not ts_effGroupUnit(effGroup, unit, 'lb', f, t)} + ts_effGroupUnit(effGroup, unit, 'lb', f, t))
)
+ v_gen.up(grid, node, unit, f, t)${not uft_online(unit, f, t) and p_gnu(grid, node, unit, 'maxGen')} // Generation units are restricted by their (online) capacity
+ (v_gnu(grid, node, unit) * p_unit(unit, 'availability'))${not uft_online(unit, f, t) and not unit_flow(unit) and p_gnu(grid, node, unit, 'maxGenCap')}
+ sum(flow$(flowUnit(flow, unit) and nu(node, unit) and unit_flow(unit) and p_gnu(grid, node, unit, 'maxGenCap')),
ts_cf_(flow, node, f, t) *
v_gnu(grid, node, unit) *
p_unit(unit, 'availability')
)
+ v_online(unit, f, t)${uft_online(unit, f, t) and p_gnu(grid, node, unit, 'maxGen')} // Consuming units are restricted by their min. load (consuming is negative)
/ p_unit(unit, 'unitCount')
* p_gnu(grid, node, unit, 'maxGen')
* Check what needs to be done for investment options
;
* -----------------------------------------------------------------------------
q_startup(uft_online(unit, ft_dynamic(f, t))) ..
......@@ -574,4 +593,18 @@ q_bidirectionalTransfer(gn2n_bidirectional(grid, node, node_), ft(f, t))${p_gnn(
=L=
p_gnn(grid, node, node_, 'transferCapBidirectional')
;
*-----------------------------------------------------------------------------
q_fixedGenCap(grid, node, unit, grid_, node_, unit_)$(p_gnugnu(grid, node, unit, grid_, node_, unit_, 'capacityRatio')) ..
+ v_gnu(grid, node, unit)
=E=
+ v_gnu(grid_, node_, unit_)
* p_gnugnu(grid, node, unit, grid_, node_, unit_, 'capacityRatio')
;
*-----------------------------------------------------------------------------
q_symmetricTransferCap(gn2n(grid, from_node, to_node)) ..
+ v_gnn(grid, from_node, to_node)
=E=
+ v_gnn(grid, to_node, from_node)
;
......@@ -28,8 +28,8 @@ v_state.fx(gn_state(grid, node), ft_limits(f, t))$(p_gn(grid, node, 'boundAll')
* Other time dependent parameters and variable limits
// Max. energy generation
v_gen.up(gnu(grid, node, unit), ft_limits(f,t))$(not unit_flow(unit)) = p_gnu(grid, node, unit, 'maxGen') * p_unit(unit, 'availability');
v_gen.up(gnu(grid, node, unit_flow), ft_limits(f,t)) // Should only be about variable generation
v_gen.up(gnu(grid, node, unit), ft_limits(f,t))$(not unit_flow(unit) and not p_gnu(grid, node, unit, 'maxGenCap')) = p_gnu(grid, node, unit, 'maxGen') * p_unit(unit, 'availability');
v_gen.up(gnu(grid, node, unit_flow), ft_limits(f,t))$(not p_gnu(grid, node, unit_flow, 'maxGenCap')) // Should only be about variable generation
= sum(flow$(flowUnit(flow, unit_flow) and nu(node, unit_flow)),
ts_cf_(flow, node, f, t) *
p_gnu(grid, node, unit_flow, 'maxGen') *
......@@ -37,9 +37,9 @@ v_gen.up(gnu(grid, node, unit_flow), ft_limits(f,t)) // Should only be abou
);
// Min. generation to zero for units without consumption
v_gen.lo(gnu(grid, node, unit), ft_limits(f,t))$(not p_gnu(grid, node, unit, 'maxCons')) = 0;
v_gen.lo(gnu(grid, node, unit), ft_limits(f,t))$(not p_gnu(grid, node, unit, 'maxCons') and not p_gnu(grid, node, unit, 'maxConsCap')) = 0;
// Max. consumption capacity
v_gen.lo(gnu(grid, node, unit), ft_limits(f,t))$gnu_input(grid, node, unit) = -p_gnu(grid, node, unit, 'maxCons');
v_gen.lo(gnu(grid, node, unit), ft_limits(f,t))$(gnu_input(grid, node, unit) and not p_gnu(grid, node, unit, 'maxConsCap')) = -p_gnu(grid, node, unit, 'maxCons');
// In the case of negative generation (currently only used for cooling equipment)
v_gen.lo(gnu(grid, node, unit), ft_limits(f,t))${p_gnu(grid, node, unit, 'maxGen') < 0} = p_gnu(grid, node, unit, 'maxGen');
......@@ -65,9 +65,9 @@ v_spill.up(gn(grid, node), ft_limits(f, t))$p_gnBoundaryPropertiesForStates(grid
= ts_nodeState_(grid, node, 'maxSpill', f, t) * p_gnBoundaryPropertiesForStates(grid, node, 'maxSpill', 'multiplier') * p_stepLength(mSolve, f, t);
// Restrictions on transferring energy between nodes
v_transfer.up(gn2n(grid, from_node, to_node), ft_limits(f, t))
v_transfer.up(gn2n(grid, from_node, to_node), ft_limits(f, t))$(not p_gnn(grid, from_node, to_node, 'transferCapInvLimit'))
= p_gnn(grid, from_node, to_node, 'transferCap');
v_resTransfer.up(restype, 'up', from_node, to_node, ft_limits(f, t))$(restypeDirectionNode(restype, 'up', from_node) and restypeDirectionNode(restype, 'up', to_node))
v_resTransfer.up(restype, 'up', from_node, to_node, ft_limits(f, t))$(restypeDirectionNode(restype, 'up', from_node) and restypeDirectionNode(restype, 'up', to_node) and not p_gnn('elec', from_node, to_node, 'transferCapInvLimit'))
= p_gnn('elec', from_node, to_node, 'transferCap');
// Reserve provision limits based on resXX_range (or possibly available generation in case of unit_flow)
......@@ -80,6 +80,14 @@ v_reserve.up(nuRescapable(restype, 'down', node, unit_elec), ft_limits(f, t))$nu
v_gen.up('elec', node, unit_elec, f, t) - v_gen.lo('elec', node, unit_elec, f, t) // Generator + consuming unit available unit_elec. output delta
};
// Max capacity investment
v_gnu.up(gnu(grid, node, unit)) = INF;
v_gnu.up(gnu(grid, node, unit))$(p_gnu(grid, node, unit, 'maxGenCap') > 0) = p_gnu(grid, node, unit, 'maxGenCap');
v_gnu.up(gnu(grid, node, unit))$(p_gnu(grid, node, unit, 'maxConsCap') > 0) = p_gnu(grid, node, unit, 'maxConsCap');
v_gnu.fx(gnu(grid, node, unit))${not p_gnu(grid, node, unit, 'maxGenCap') and not p_gnu(grid, node, unit, 'maxConsCap')} = 0;
v_gnn.up(gn2n(grid, from_node, to_node)) = INF;
v_gnn.up(gn2n(grid, from_node, to_node)) = p_gnn(grid, from_node, to_node, 'transferCapInvLimit');
* --- Bounds overwritten for the first solve -----------------------------------
loop(ft_limits(f, tSolve),
// First solve, state variables (only if boundStart flag is true)
......
......@@ -88,3 +88,7 @@ $offtext
* solve building using mip minimizing v_obj;
* ); // END IF BUILDING
* if (mSolve('storage'), solve storage using lp minimizing v_obj; );
if (mSolve('invest'),
settings(mSetting) = mSettings(mSolve, mSetting);
solve invest using mip minimizing v_obj;
);
......@@ -75,7 +75,7 @@ $offtext
p_fuelEmission(fuel, emission) / 1e3
* p_gnPolicy(grid, node, 'emissionTax', emission) // Sum emission costs from different output energy types
)
) / p_gnu(grid, node, unit, 'maxGen') // Calculate these in relation to maximum output ratios between multiple outputs
) / (p_gnu(grid, node, unit, 'maxGen')$p_gnu(grid, node, unit, 'maxGen') + 1$(not p_gnu(grid, node, unit, 'maxGen'))) // Calculate these in relation to maximum output ratios between multiple outputs
) * sum(gnu_output(grid, node, unit), p_gnu(grid, node, unit, 'maxGen')) // see line above
)
}
......
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