Generation

Generation builders create dispatchable, nuclear, intermittent, and hydro sources. Costed electricity sources attach annualised investment and decommissioning costs, fixed operation and maintenance, and the applicable variable costs.

See Component Builders for shared naming, workbook, capacity, and port conventions, and Tags And Post-Processing for tagging and reporting. Each section's diagram follows the conventions in Reading The Port Diagrams.

Dispatchable Generation

makedispatchable creates a source named "$name $(elec.name)". Its principal port is electricity output, and its investment, connection, fixed O&M, decommissioning, variable O&M, and direct fuel costs are attached there.

In tech_mode=:excel, common technical and economic defaults come from the technology column named by tech_column in sheet dispatchable. In tech_mode=:arguments, additive costs and emissions default to zero, linked fuel defaults to lossless efficiency, and unit sizing and ramping default to disabled. Capital lifetime and profiles are required only when their associated cost is active. A numeric cap fixes output capacity; a JuMP variable or affine expression reuses an external capacity decision; nothing creates a new decision; and an extracted snapshot inherits the matching component's capacity. mincap and maxcap bound either variable form. Numeric cap=0 builds a zero-capacity component. capacity_multiplier can impose a time-varying availability on output.

If fuel_node is absent, fuel_cost is a variable cost on electricity output. If a fuel node is supplied, the builder instead creates a fuel input equal to electricity output divided by efficiency. Non-zero co2_emission adds a linked co2 output and requires co2_node; co2_price prices that flow. Zero-emission generation needs no CO2 node.

Ports of a dispatchable generation component

Setting uc=true adds unit commitment, no-load cost, and start-up cost. Passing an extracted snapshot as uc instead replays the commitment schedule already solved for that component, and then requires a fixed cap. integer_uc selects continuous or integer commitment. The minimum power, up-time, down-time, start-up duration, and shut-down duration default to rows in the same workbook column. When unit_size is positive, non-zero ramp_up and ramp_down values add ramp limits after multiplication by the unit size.

Tags: :tech => tech, :zone => elec.name, and the function tags generation and dispatchable.

See the Dispatchable Generation example for a complete model using this builder.

Posy2.makedispatchable — Function
makedispatchable(name::String, elec::Node, s::Snapshot;
    tech::String=name, tech_column::String=tech,
    cap=nothing, mincap=nothing, maxcap=nothing, capacity_multiplier=nothing,
    integer_uc=false, uc=false, fuel_node=nothing, co2_node=nothing,
    co2_price=co2_price(s),
    overnight_cost, om_fixed_cost, decommissioning, lifetime,
    construction_profile, decommissioning_profile, connection_cost,
    om_var_cost, fuel_cost, no_load_cost, startup_cost, co2_emission,
    efficiency, unit_size, ramp_up, ramp_down, min_power, min_uptime,
    min_downtime, startup_duration, shutdown_duration,
)

Build, connect and return a dispatchable component.

Arguments:

  • name: component name prefix.

  • tech: technology label used for reporting and component queries; defaults to name.

  • tech_column: technology column name in the dispatchable tech data sheet; defaults to tech.

  • elec: Electricity node connected to component output flow.

  • s: Target snapshot where the component and behaviors are registered.

  • cap: Output capacity in MW. A number fixes capacity, a JuMP VariableRef or AffExpr reuses that expression, nothing creates a capacity decision, and an extracted Snapshot inherits the capacity of "<name> <node name>" in it. Numeric 0 builds a zero-capacity component.

  • mincap: Lower capacity bound in MW; checked as an assertion against a fixed or inherited one.

  • maxcap: Upper capacity bound in MW; checked as an assertion against a fixed or inherited one.

  • capacity_multiplier: Dimensionless time-varying multiplier on output capacity.

  • integer_uc: If true, newly constructed UC commitment variables are integer; used only when uc=true.

  • uc: Enables UC constraints and UC linked costs (no_load_cost, startup_cost). An extracted Snapshot instead replays the commitment schedule already solved for the matching component, and then requires a fixed cap.

  • fuel_node: If provided, fuel is modeled as an input flow linked by efficiency. If nothing, fuel is modeled as a variable cost on output energy (fuel_cost).

  • co2_node: CO2 node connected when co2_emission is nonzero. It is required in that case and otherwise defaults to nothing.

  • co2_price: Carbon price in currency/tCO2, used only when co2_emission != 0.

  • overnight_cost: Overnight CAPEX in currency/kW of output capacity.

  • om_fixed_cost: Fixed O&M in currency/kW/year of output capacity.

  • decommissioning: Decommissioning cost as a fraction of overnight CAPEX.

  • lifetime: Asset lifetime in years (> 0, integer-valued).

  • construction_profile: Dimensionless yearly construction-cost shares.

  • decommissioning_profile: Dimensionless yearly decommissioning-cost shares.

  • connection_cost: Connection cost as a fraction of annualized investment.

  • om_var_cost: Variable O&M in currency/MWh of output.

  • fuel_cost: Fuel cost in currency/MWh of output, used only without fuel_node.

  • no_load_cost: No-load cost in currency/committed-unit/hour, used with UC.

  • startup_cost: Startup cost in currency/unit-start, used with UC.

  • co2_emission: Emission factor in kgCO2/MWh of output; converted to tCO2.

  • efficiency: Output per unit of fuel input (dimensionless when both carriers use MWh), used only with fuel_node.

  • unit_size: Generating-unit size in MW. 0 disables unit sizing; a positive value is required with UC.

  • ramp_up, ramp_down: Maximum ramp fractions of unit capacity per hour; nonzero values require a positive unit_size.

  • min_power: Minimum committed output as a fraction of unit capacity, used only when uc=true.

  • min_uptime, min_downtime, startup_duration, shutdown_duration: Durations in hours, used only when uc=true.

With nothing, economic arguments use workbook values in :excel mode. In :arguments mode, costs default to zero; nonzero overnight cost requires lifetime and construction_profile, plus decommissioning_profile when decommissioning is nonzero.

source

Nuclear Generation

makenuclear uses the same dispatchable sheet and the same principal electricity, fuel, and CO2 ports. It adds waste_cost, supports integer capacity with integer_cap, and accepts warm_start for a capacity decision. Ramping follows makedispatchable: non-zero ramp_up and ramp_down values are multiplied by unit_size. They default to inactive in :arguments mode; in :excel mode, omitted values come from the technology column.

Ports of a nuclear generation component

Fresh unit commitment may include planned refuelling outages. Refuelling is active only when refuel=true, uc=true, refuel_fraction_per_year is positive, and refuel_duration is positive. Set refuel=false to disable it without reading or validating the other refuelling arguments. When active, refuel_slot_spacing must be supplied by the caller as a positive Integer. It spaces, in hours, the grid at which an outage may start, so 8760 leaves a single allowed start and 730 leaves about twelve. The grid is mapped onto the time mesh, so a mesh coarser than the spacing opens fewer starts than the grid holds. In :excel mode, refuel fraction and duration default to the dispatchable technology column. In :arguments mode they default to zero, disabling refuelling outages; refuel_slot_spacing has no workbook default. Supplying refuelling arguments with uc=false emits a warning and does not add refuelling constraints. A replayed UC schedule retains the outages it was solved with; explicit refuelling arguments emit a warning and are ignored. Economic terms and emissions also default to zero in :arguments mode.

Capacity follows the common numeric, external-expression, nothing, and inherited-from-a-snapshot semantics. For an external expression, mincap and maxcap constrain that expression. Nosy does not allow warm_start with an external expression. With integer_cap=true, a VariableRef is made integer, whereas an AffExpr is rejected. In particular, unit_size does not make an external variable a number-of-units variable; represent that explicitly as unit_size * integer_units when unit-block integrality is required.

Refuelling constraints do not depend on tech_column. Like every builder they require an 8,760-hour horizon, but they are built by walking the time mesh, so they hold on an aggregated or sub-hourly mesh as well as on the hourly one.

Tags: :tech => tech, :zone => elec.name, and the function tags generation and dispatchable. Direct emissions are controlled by co2_emission; the builder does not infer a carbonfree tag from the technology name.

See the Nuclear example for models using this builder with forced and flexible refuelling schedules.

Posy2.makenuclear — Function
makenuclear(name::String, elec::Node, s::Snapshot;
    tech::String=name, tech_column::String=tech,
    cap=nothing, mincap=nothing, maxcap=nothing, integer_cap=false, warm_start=nothing,
    uc=false, integer_uc=false, startup_mask=nothing, shutdown_mask=nothing,
    refuel::Bool=true, refuel_duration::Union{Nothing,Real}=nothing,
    refuel_slot_spacing::Union{Nothing,Integer}=nothing, refuel_fraction_per_year::Union{Nothing,Real}=nothing,
    fuel_node=nothing, co2_node=nothing, co2_price=co2_price(s),
    overnight_cost::Union{Nothing,Real}=nothing, om_fixed_cost::Union{Nothing,Real}=nothing,
    decommissioning::Union{Nothing,Real}=nothing, lifetime::Union{Nothing,Real}=nothing, construction_profile=nothing, decommissioning_profile=nothing,
    connection_cost::Union{Nothing,Real}=nothing, om_var_cost::Union{Nothing,Real}=nothing, fuel_cost::Union{Nothing,Real}=nothing,
    waste_cost::Union{Nothing,Real}=nothing, no_load_cost::Union{Nothing,Real}=nothing, startup_cost::Union{Nothing,Real}=nothing,
    co2_emission::Union{Nothing,Real}=nothing, efficiency::Union{Nothing,Real}=nothing, unit_size::Union{Nothing,Real}=nothing,
    ramp_up::Union{Nothing,Real}=nothing, ramp_down::Union{Nothing,Real}=nothing,
    min_power::Union{Nothing,Real}=nothing, min_uptime::Union{Nothing,Real}=nothing, min_downtime::Union{Nothing,Real}=nothing,
    startup_duration::Union{Nothing,Real}=nothing, shutdown_duration::Union{Nothing,Real}=nothing,
)

Build, connect and return a nuclear reactor component.

Arguments:

  • name: component name prefix.

  • tech: technology label used for reporting and component queries; defaults to name.

  • tech_column: technology column name in the dispatchable tech data sheet; defaults to tech.

  • elec: electricity node to connect the component to.

  • s: snapshot to register the component in.

  • cap: Output capacity in MW. A number fixes capacity, a JuMP VariableRef or AffExpr reuses that expression, nothing creates a capacity decision, and an extracted Snapshot inherits the capacity of "<name> <node name>" in it.

  • mincap: Lower capacity bound in MW; checked as an assertion against a fixed or inherited one.

  • maxcap: Upper capacity bound in MW; checked as an assertion against a fixed or inherited one.

  • integer_cap: Integer flag for variable capacity; ignored for fixed or inherited capacity.

  • warm_start: Variable-capacity warm start in MW; ignored for fixed or inherited capacity.

  • uc: Enables UC constraints and UC linked costs. An extracted Snapshot instead replays the commitment schedule already solved for the matching component and requires a fixed cap. Fresh refuelling constraints are built only when uc=true; with uc=false they are ignored, and a replayed schedule retains its solved refuelling decisions.

  • integer_uc: Integer UC commitment variables, used only when uc=true.

  • startup_mask: Startup availability mask, used only when uc=true.

  • shutdown_mask: Shutdown availability mask, used only when uc=true.

  • refuel: Enables planned refuelling constraints. Set to false to disable refuelling regardless of the other refuelling arguments.

  • refuel_duration: Planned refuelling outage in hours. A positive value enables refuelling constraints when refuel_fraction_per_year > 0. If nothing, use the workbook value in :excel mode and zero in :arguments mode.

  • refuel_slot_spacing: Spacing, in hours, of the grid at which a refuelling outage may start: 8760 leaves a single allowed start, 730 leaves about twelve. Must be positive. Required when refuelling is enabled, and not read from the workbook. The grid is mapped onto the time mesh, so a mesh coarser than the spacing opens fewer starts than the grid holds.

  • refuel_fraction_per_year: Minimum refuelling events per unit/year. If nothing, use the workbook value in :excel mode and zero in :arguments mode.

  • fuel_node: If provided, fuel is represented as linked input flow using efficiency. If nothing, fuel_cost is applied as output variable cost.

  • co2_node: CO2 node connected when co2_emission is nonzero. It is required in that case and otherwise defaults to nothing.

  • co2_price: Carbon price in currency/tCO2, used only when co2_emission != 0.

  • overnight_cost: Overnight CAPEX in currency/kW of output capacity.

  • om_fixed_cost: Fixed O&M in currency/kW/year of output capacity.

  • decommissioning: Decommissioning cost as a fraction of overnight CAPEX.

  • lifetime: Asset lifetime in years (> 0, integer-valued).

  • construction_profile: Dimensionless yearly construction-cost shares.

  • decommissioning_profile: Dimensionless yearly decommissioning-cost shares.

  • connection_cost: Connection cost as a fraction of annualized investment.

  • om_var_cost, fuel_cost, waste_cost: Costs in currency/MWh of output; fuel_cost is used directly only without fuel_node.

  • no_load_cost: No-load cost in currency/committed-unit/hour, used with UC.

  • startup_cost: Startup cost in currency/unit-start, used with UC.

  • co2_emission: Emission factor in kgCO2/MWh of output; converted to tCO2.

  • efficiency: Output per unit of fuel input (dimensionless when both carriers use MWh), used only with fuel_node.

  • unit_size: Reactor-unit size in MW. 0 disables unit sizing; a positive value is required with UC.

  • ramp_up, ramp_down: Maximum ramp fractions of unit capacity per hour; nonzero values require a positive unit_size.

  • min_power: Minimum committed output as a fraction of unit capacity, used only when uc=true.

  • min_uptime, min_downtime, startup_duration, shutdown_duration: Durations in hours, used only when uc=true.

With nothing, economic arguments use workbook values in :excel mode. In :arguments mode, costs default to zero; nonzero overnight cost requires lifetime and construction_profile, plus decommissioning_profile when decommissioning is nonzero.

source

Intermittent Generation

makeintermittentsource creates a profile source. It reads availability from sheet profiles_<weather_year>, column <tech_column>_<electricity-node-name>. The profile multiplies the output capacity. Workbook lookup requires an explicit weather_year; the keyword defaults to nothing and is unused when profile is supplied directly.

Ports of an intermittent generation component

Numeric cap fixes capacity; a JuMP variable or affine expression reuses an external capacity decision; nothing creates a new decision; and a solved snapshot inherits the named component's capacity. mincap and maxcap bound either variable form. In :excel mode, technical and cost defaults come from the technology column named by tech_column in sheet intermittent. In :arguments mode, costs and emissions default to zero and inactive capital data are not required. The production profile remains structural whenever capacity is active. Non-zero emissions create the same linked CO2 flow as for dispatchable generation.

Tags: :tech => tech, :zone => elec.name, and the function tags generation and intermittent. The component also receives the function tag carbonfree when co2_emission is zero.

See the Dispatchable Generation example for a model that co-optimises intermittent and dispatchable capacity.

Posy2.makeintermittentsource — Function
makeintermittentsource(name::String, elec::Node, s::Snapshot;
    tech::String=name, tech_column::String=tech,
    cap=nothing, mincap=nothing, maxcap=nothing,
    weather_year=nothing, profile=nothing,
    co2_node=nothing, co2_price=co2_price(s),
    overnight_cost::Union{Nothing,Real}=nothing, om_fixed_cost::Union{Nothing,Real}=nothing,
    decommissioning::Union{Nothing,Real}=nothing, lifetime::Union{Nothing,Real}=nothing, construction_profile=nothing, decommissioning_profile=nothing,
    connection_cost::Union{Nothing,Real}=nothing, om_var_cost::Union{Nothing,Real}=nothing,
    fuel_cost::Union{Nothing,Real}=nothing, co2_emission::Union{Nothing,Real}=nothing,
)

Build, connect and return an intermittent source component.

Arguments:

  • name: component name prefix.

  • tech: technology label used for reporting and component queries; defaults to name.

  • tech_column: technology column name in the intermittent tech data sheet; defaults to tech.

  • elec: electricity node to connect the component to.

  • s: snapshot to register the component in.

  • cap: Output capacity in MW. A number fixes capacity, a JuMP VariableRef or AffExpr reuses that expression, nothing creates a capacity decision, and an extracted Snapshot inherits the capacity of "<name> <node name>" in it.

  • mincap: Lower capacity bound in MW; checked as an assertion against a fixed or inherited one.

  • maxcap: Upper capacity bound in MW; checked as an assertion against a fixed or inherited one.

  • weather_year: Year suffix used to select profile series profiles_<year>. Required for workbook lookup; unused when profile is supplied explicitly.

  • profile: Dimensionless hourly capacity-factor vector or scalar in [0, 1]. If nothing, read the <tech_column>_<node> workbook column. With numeric cap == 0, an omitted profile is replaced by zero without a workbook or weather-year lookup.

  • co2_price: Carbon price in currency/tCO2, used only when co2_emission != 0.

  • co2_node: CO2 node connected when co2_emission is nonzero. It is required in that case and otherwise defaults to nothing.

  • overnight_cost: Overnight CAPEX in currency/kW of output capacity.

  • om_fixed_cost: Fixed O&M in currency/kW/year of output capacity.

  • decommissioning: Decommissioning cost as a fraction of overnight CAPEX.

  • lifetime: Asset lifetime in years (> 0, integer-valued).

  • construction_profile: Dimensionless yearly construction-cost shares.

  • decommissioning_profile: Dimensionless yearly decommissioning-cost shares.

  • connection_cost: Connection cost as a fraction of annualized investment.

  • om_var_cost, fuel_cost: Costs in currency/MWh of output.

  • co2_emission: Emission factor in kgCO2/MWh of output; converted to tCO2.

With nothing, economic arguments use workbook values in :excel mode. In :arguments mode, costs default to zero; nonzero overnight cost requires lifetime and construction_profile, plus decommissioning_profile when decommissioning is nonzero.

source

Run-of-river Hydro

makehydroror reads an intake shape from sheet hydro_ror_<weather_year>, column <zone>. The builder normalizes the shape to sum to one, distributes intake over it, and limits hourly output by both that intake envelope and installed capacity. Workbook lookup requires an explicit weather_year; the keyword defaults to nothing and is unused when intake_profile is supplied directly.

Ports of a run-of-river hydro component

In :excel mode, cost defaults come from the technology column named by tech_column in sheet intermittent; the default column name is Hydro ror. In :arguments mode costs default to zero and inactive capital data are not required. A numeric cap fixes output capacity; cap=nothing creates a new capacity decision; and a JuMP variable or affine expression reuses an external decision. mincap and maxcap bound either variable form. The intake profile remains independent of capacity.

Tags: :tech => tech, :zone => elec.name, and the function tags generation, intermittent, and carbonfree.

Posy2.makehydroror — Function
makehydroror(name::String, zone::String, elec::Node, s::Snapshot;
    tech::String=name, cap=nothing, mincap=nothing, maxcap=nothing,
    tech_column::String="Hydro ror", weather_year=nothing,
    intake, intake_profile=nothing,
    overnight_cost::Union{Nothing,Real}=nothing, om_fixed_cost::Union{Nothing,Real}=nothing, om_var_cost::Union{Nothing,Real}=nothing,
    decommissioning::Union{Nothing,Real}=nothing, lifetime::Union{Nothing,Real}=nothing, construction_profile=nothing, decommissioning_profile=nothing,
)

Build, connect and return a run of river hydro component.

Arguments:

  • name: component name prefix.

  • tech: technology label used for reporting and component queries; defaults to name.

  • zone: Time series zone used to read the hydro intake profile.

  • elec: electricity node to connect the component to.

  • s: snapshot to register the component in.

  • cap: Output capacity in MW. A number fixes capacity, nothing creates a new capacity decision, a JuMP variable or affine expression reuses that external decision, and an extracted Snapshot inherits the capacity of "<name> <node name>" in it.

  • mincap: Lower capacity bound in MW; checked as an assertion against a fixed or inherited one.

  • maxcap: Upper capacity bound in MW; checked as an assertion against a fixed or inherited one.

  • tech_column: technology column name in the intermittent tech data sheet; defaults to "Hydro ror".

  • weather_year: Year suffix used to select intake series hydro_ror_<year>. Required for workbook lookup; unused when intake_profile is supplied explicitly.

  • intake_profile: Dimensionless hourly run-of-river intake shape or scalar, nonnegative with a strictly positive sum. The profile is normalized to sum to one before the total intake is applied. If nothing, read zone from the selected workbook sheet.

  • intake: Total yearly intake in MWh, spread over the normalized profile. 0 disables intake and skips the zone, profile, and weather-year lookup.

  • overnight_cost: Overnight CAPEX in currency/kW of output capacity.

  • om_fixed_cost: Fixed O&M in currency/kW/year of output capacity.

  • om_var_cost: Variable O&M in currency/MWh of output.

  • decommissioning: Decommissioning cost as a fraction of overnight CAPEX.

  • lifetime: Asset lifetime in years (> 0, integer-valued).

  • construction_profile: Dimensionless yearly construction-cost shares.

  • decommissioning_profile: Dimensionless yearly decommissioning-cost shares.

With nothing, economic arguments use workbook values in :excel mode. In :arguments mode, costs default to zero; nonzero overnight cost requires lifetime and construction_profile, plus decommissioning_profile when decommissioning is nonzero.

source

Note On Capacity And Unit Commitment

unit_size is the output of one physical unit. Unit commitment uses it to express commitment, startup, and shutdown in numbers of units, so every enabled UC formulation requires a positive unit_size. A fixed capacity used with integer_uc=true must be an integer multiple of unit_size.

The uc and integer_uc combinations have these effects:

ArgumentsFormulation
uc=falseNo UC equations or UC costs; integer_uc and UC operating arguments have no effect
uc=true, integer_uc=falseFresh UC equations with continuous, relaxed commitment variables
uc=true, integer_uc=trueFresh UC equations with integer commitment, startup, and shutdown variables
uc=<extracted snapshot>Replays the solved commitment schedule and requires cap to be fixed by a number or snapshot

integer_cap is supported by makenuclear. With cap=nothing, a positive unit_size makes the new capacity decision a number of units and integer_cap=true makes that count integer. With an external VariableRef, the supplied variable itself is made integer; unit_size does not reinterpret or scale it. An external AffExpr cannot be made integer and is rejected. To share unit-block capacity, create an integer unit-count variable and pass unit_size * integer_units explicitly. Fixed and inherited capacities contain no capacity decision, so integer_cap and warm_start have no effect on them. warm_start applies only to a new capacity decision and is rejected for an external expression.

integer_cap and integer_uc are independent. If both are enabled for a new nuclear capacity with fresh UC, both the capacity unit count and the hourly UC variables are integer; Posy2 does not drop either integrality condition as a simplification.

For fresh uc=true, min_power, min_uptime, min_downtime, startup_duration, and shutdown_duration configure the UC equations. Nuclear startup_mask and shutdown_mask also apply only to fresh UC. A replayed schedule already contains those choices, so these operating arguments and integer_uc do not alter it. no_load_cost and startup_cost are attached whenever UC is enabled, including replayed UC. For makedispatchable and makenuclear, ramping is separate from UC: non-zero ramp_up or ramp_down adds a limit whenever unit_size is positive, even with uc=false. After workbook defaults and explicit overrides are resolved, zero or nothing omits that limit.