Commit 82c47085 authored by Niina Helistö's avatar Niina Helistö
Browse files

Update to startup cost calculation and v_online limits

parent 72a7f322
......@@ -87,7 +87,7 @@ Sets //Reserve type sets
/
;
Sets //Startup type sets
Sets //Startup related sets
starttype "Startup types"
/ hot "Hot start"
warm "Warm start"
......@@ -95,6 +95,10 @@ Sets //Startup type sets
/
starttypeConstrained(starttype) "Startup types with constrained maximum non-opearational time"
/ hot, warm /
cost_consumption "Startup cost or startup fuel consumption"
/ cost, consumption /
unit_capacity "Unit or capacity based parameter"
/ unit, capacity /
;
* Numeric parameters
......
......@@ -55,6 +55,7 @@ Parameters
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"
p_uNonoperational(unit, starttype, min_max) "Non-operational time after being shut down before start up"
p_uStartup(unit, starttype, cost_consumption, unit_capacity) "Startup cost and fuel consumption"
// 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"
......
......@@ -115,6 +115,18 @@ p_uNonoperational(unit, 'hot', 'min') = 0;
p_uNonoperational(unit, 'hot', 'max') = p_unit(unit, 'startWarm');
p_uNonoperational(unit, 'warm', 'min') = p_unit(unit, 'startWarm');
p_uNonoperational(unit, 'warm', 'max') = p_unit(unit, 'startCold');
p_uStartup(unit, 'hot', 'cost', 'unit') = p_unit(unit, 'startCost');
p_uStartup(unit, 'hot', 'cost', 'capacity') = p_unit(unit, 'startCost_MW');
p_uStartup(unit, 'hot', 'consumption', 'unit') = p_unit(unit, 'startFuelCons');
p_uStartup(unit, 'hot', 'consumption', 'capacity') = p_unit(unit, 'startFuelCons_MW');
p_uStartup(unit, 'warm', 'cost', 'unit') = p_unit(unit, 'startCostWarm');
p_uStartup(unit, 'warm', 'cost', 'capacity') = p_unit(unit, 'startCostWarm_MW');
p_uStartup(unit, 'warm', 'consumption', 'unit') = p_unit(unit, 'startFuelConsWarm');
p_uStartup(unit, 'warm', 'consumption', 'capacity') = p_unit(unit, 'startFuelConsWarm_MW');
p_uStartup(unit, 'cold', 'cost', 'unit') = p_unit(unit, 'startCostCold');
p_uStartup(unit, 'cold', 'cost', 'capacity') = p_unit(unit, 'startCostCold_MW');
p_uStartup(unit, 'cold', 'consumption', 'unit') = p_unit(unit, 'startFuelConsCold');
p_uStartup(unit, 'cold', 'consumption', 'capacity') = p_unit(unit, 'startFuelConsCold_MW');
p_gnu(grid, node, unit, 'unitSizeGen')$(p_gnu(grid, node, unit, 'maxGen') and p_unit(unit, 'unitCount')) = p_gnu(grid, node, unit, 'maxGen')/p_unit(unit, 'unitCount'); // If maxGen and unitCount are given, calculate unitSizeGen based on them.
p_gnu(grid, node, unit, 'unitSizeCons')$(p_gnu(grid, node, unit, 'maxCons') and p_unit(unit, 'unitCount')) = p_gnu(grid, node, unit, 'maxCons')/p_unit(unit, 'unitCount'); // If maxCons and unitCount are given, calculate unitSizeCons based on them.
* 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.
......
......@@ -88,66 +88,28 @@ q_obj ..
)
// Start-up costs
+ sum(uft_online(unit, f, t),
+ {
+ v_startup(unit, 'hot', f, t) // Cost of starting up
}
* {
// Startup variable costs
+ p_unit(unit, 'startCost')${not unit_investLP(unit)}
+ p_unit(unit, 'startCost_MW')$unit_investLP(unit)
// Start-up fuel and emission costs
+ sum(uFuel(unit, 'startup', fuel)$unit_fuel(unit),
(
+ p_unit(unit, 'startFuelCons')${not unit_investLP(unit)}
+ p_unit(unit, 'startFuelCons_MW')$unit_investLP(unit)
+ sum(starttype,
+ {
+ v_startup(unit, starttype, f, t) // Cost of starting up
}
* {
// Startup variable costs
+ p_uStartup(unit, starttype, 'cost', 'unit')${not unit_investLP(unit)}
+ p_uStartup(unit, starttype, 'cost', 'capacity')$unit_investLP(unit)
// Start-up fuel and emission costs
+ sum(uFuel(unit, 'startup', fuel)$unit_fuel(unit),
(
+ p_uStartup(unit, starttype, 'consumption', 'unit')${not unit_investLP(unit)}
+ p_uStartup(unit, starttype, 'consumption', 'capacity')$unit_investLP(unit)
)
* ( + sum{tFuel$[ord(tFuel) <= ord(t)],
ts_fuelPriceChange(fuel, tFuel) } // Fuel costs for start-up fuel use
+ sum(emission, // Emission taxes of startup fuel use
p_unitFuelEmissionCost(unit, fuel, emission) )
)
)
* ( + sum{tFuel$[ord(tFuel) <= ord(t)],
ts_fuelPriceChange(fuel, tFuel) } // Fuel costs for start-up fuel use
+ sum(emission, // Emission taxes of startup fuel use
p_unitFuelEmissionCost(unit, fuel, emission) )
)
)
}
+ {
+ v_startup(unit, 'warm', f, t) // Cost of starting up
}
* {
// Startup variable costs
+ p_unit(unit, 'startCostWarm')${not unit_investLP(unit)}
+ p_unit(unit, 'startCostWarm_MW')$unit_investLP(unit)
// Start-up fuel and emission costs
+ sum(uFuel(unit, 'startup', fuel)$unit_fuel(unit),
(
+ p_unit(unit, 'startFuelConsWarm')${not unit_investLP(unit)}
+ p_unit(unit, 'startFuelConsWarm_MW')$unit_investLP(unit)
)
* ( + sum{tFuel$[ord(tFuel) <= ord(t)],
ts_fuelPriceChange(fuel, tFuel) } // Fuel costs for start-up fuel use
+ sum(emission, // Emission taxes of startup fuel use
p_unitFuelEmissionCost(unit, fuel, emission) )
)
)
}
+ {
+ v_startup(unit, 'cold', f, t) // Cost of starting up
}
* {
// Startup variable costs
+ p_unit(unit, 'startCostCold')${not unit_investLP(unit)}
+ p_unit(unit, 'startCostCold_MW')$unit_investLP(unit)
// Start-up fuel and emission costs
+ sum(uFuel(unit, 'startup', fuel)$unit_fuel(unit),
(
+ p_unit(unit, 'startFuelConsCold')${not unit_investLP(unit)}
+ p_unit(unit, 'startFuelConsCold_MW')$unit_investLP(unit)
)
* ( + sum{tFuel$[ord(tFuel) <= ord(t)],
ts_fuelPriceChange(fuel, tFuel) } // Fuel costs for start-up fuel use
+ sum(emission, // Emission taxes of startup fuel use
p_unitFuelEmissionCost(unit, fuel, emission) )
)
)
}
}
)
)
// Ramping costs
+ sum(gnuft_ramp(grid, node, unit, f, t)${ p_gnu(grid, node, unit, 'rampUpCost') OR p_gnu(grid, node, unit, 'rampDownCost') },
......@@ -946,35 +908,17 @@ q_emissioncap(grid, node, emission)${p_gnPolicy(grid, node, 'emissionCap', emiss
)
// Start-up emissions
+ sum(uft_online(unit, f, t),
+ {
+ v_startup(unit, 'hot', f, t)
}
* {
+ sum(uFuel(unit, 'startup', fuel)$unit_fuel(unit),
(
+ p_unit(unit, 'startFuelCons')${not unit_investLP(unit)}
+ p_unit(unit, 'startFuelCons_MW')$unit_investLP(unit)
)
* (
p_fuelEmission(fuel, emission) / 1e3
* (p_gnu(grid, node, unit, 'maxGen')
+ p_gnu(grid, node, unit, 'unitSizeGen')$(not p_gnu(grid, node, unit, 'maxGen'))
) // Weighted emissions from different output energy types
/ sum(gnu_output(grid_, node_, unit), p_gnu(grid_, node_, unit, 'maxGen')
+ p_gnu(grid_, node_, unit, 'unitSizeGen')$(not p_gnu(grid_, node_, unit, 'maxGen'))
)
)
)
}
+ {
+ v_startup(unit, 'warm', f, t)
}
* {
+ sum(uFuel(unit, 'startup', fuel)$unit_fuel(unit),
(
+ p_unit(unit, 'startFuelConsWarm')${not unit_investLP(unit)}
+ p_unit(unit, 'startFuelConsWarm_MW')$unit_investLP(unit)
)
+ sum(starttype,
+ {
+ v_startup(unit, starttype, f, t) // Cost of starting up
}
* {
// Start-up fuel and emission costs
+ sum(uFuel(unit, 'startup', fuel)$unit_fuel(unit),
(
+ p_uStartup(unit, starttype, 'consumption', 'unit')${not unit_investLP(unit)}
+ p_uStartup(unit, starttype, 'consumption', 'capacity')$unit_investLP(unit)
)
* (
p_fuelEmission(fuel, emission) / 1e3
* (p_gnu(grid, node, unit, 'maxGen')
......@@ -984,29 +928,9 @@ q_emissioncap(grid, node, emission)${p_gnPolicy(grid, node, 'emissionCap', emiss
+ p_gnu(grid_, node_, unit, 'unitSizeGen')$(not p_gnu(grid_, node_, unit, 'maxGen'))
)
)
)
}
+ {
+ v_startup(unit, 'cold', f, t)
}
* {
+ sum(uFuel(unit, 'startup', fuel)$unit_fuel(unit),
(
+ p_unit(unit, 'startFuelConsCold')${not unit_investLP(unit)}
+ p_unit(unit, 'startFuelConsCold_MW')$unit_investLP(unit)
)
* (
p_fuelEmission(fuel, emission) / 1e3
* (p_gnu(grid, node, unit, 'maxGen')
+ p_gnu(grid, node, unit, 'unitSizeGen')$(not p_gnu(grid, node, unit, 'maxGen'))
) // Weighted emissions from different output energy types
/ sum(gnu_output(grid_, node_, unit), p_gnu(grid_, node_, unit, 'maxGen')
+ p_gnu(grid_, node_, unit, 'unitSizeGen')$(not p_gnu(grid_, node_, unit, 'maxGen'))
)
)
)
}
}
)
)
)
)
......
......@@ -59,17 +59,25 @@ v_gen.up(gnu(grid, node, unit), ft(f,t))${p_gnu(grid, node, unit, 'maxGen') < 0
} = 0;
// v_online cannot exceed unit count
v_online.up(uft_online(unit, ft_dynamic(f,t)))${not unit_investMIP(unit)
v_online.up(uft_online(unit, ft(f,t)))${not unit_investMIP(unit)
} = p_unit(unit, 'unitCount');
// Restrict v_online also in the last dynamic time step
v_online.up(uft_online(unit, ft_dynamic(f,t)))${mftLastSteps(mSolve, f, t)
and not unit_investMIP(unit)
} = p_unit(unit, 'unitCount');
// v_online is zero for units with continuous online variable
v_online.fx(uft_online(unit, ft_dynamic(f,t)))${unit_investLP(unit)
v_online.fx(uft_online(unit, ft(f,t)))${unit_investLP(unit)
} = 0;
// v_onlineLP is zero for units without continuous online variable
v_online_LP.fx(uft_online(unit, ft_dynamic(f,t)))${not unit_investLP(unit)
// Restrict v_online also in the last dynamic time step
v_online.fx(uft_online(unit, ft_dynamic(f,t)))${mftLastSteps(mSolve, f, t)
and unit_investLP(unit)
} = 0;
// v_online_LP is zero for units without continuous online variable
v_online_LP.fx(uft_online(unit, ft(f,t)))${not unit_investLP(unit)
} = 0;
// Restrict v_online_LP also in the last dynamic time step
v_online_LP.fx(uft_online(unit, ft_dynamic(f,t)))${mftLastSteps(mSolve, f, t)
and not unit_investLP(unit)
} = 0;
// Possible constraints for generator ramping speeds
......
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