API Reference
This page groups every public binding exported by Posy2. For a narrative guide to the constructors, see Component Builders. Nosy types and lower-level modelling operations are documented in the Nosy API reference.
Package
Configuration And Input Data
Posy2.Posy2Options — Type
Posy2Options(; data_dir=joinpath(pwd(), "data"),
techdata_file="tech_data.xlsx", timeseries_file="time_series.xlsx",
tech_mode=:arguments, timeseries_mode=:arguments,
discount_rate=0.05, co2_price=0.0)Configure Posy2 input workbooks and economic assumptions. Pass the resulting object to a Nosy snapshot as Snapshot(sim, Dict(:posy => options)). A snapshot carrying no :posy entry is read as Posy2Options(), which is workbook-free.
Fields:
data_dir: directory containing the input workbooks. It defaults tojoinpath(pwd(), "data"), which follows the process working directory.techdata_file: technology-parameter workbook filename.timeseries_file: hourly time-series workbook filename.tech_mode::arguments(default) to use documented neutral defaults and require structural values explicitly, or:excelto fill omitted technology arguments from the workbook.timeseries_mode::arguments(default) to use documented neutral profiles and require structural profiles explicitly, or:excelto fill omitted profiles from the workbook.discount_rate: real discount rate used to annualise investment and decommissioning costs.co2_price: carbon price applied by emitting component builders.
DC power flow is not configured here: call applydcopf! on the snapshot when a study needs KVL constraints.
Posy2.posy_options — Function
posy_options(s::Snapshot)Return the Posy2Options stored in s.options[:posy], or the workbook-free Posy2Options() when the snapshot carries no :posy entry.
Throw an ArgumentError when the entry is present but is not a Posy2Options object.
Posy2.discount_rate — Function
discount_rate(s::Snapshot)Return the discount rate configured in the snapshot's Posy2Options.
Posy2.co2_price — Function
co2_price(s::Snapshot)Return the carbon price configured in the snapshot's Posy2Options.
Posy2.tech_mode — Function
Return the configured technology-input mode (:excel or :arguments).
Posy2.timeseries_mode — Function
Return the configured time-series-input mode (:excel or :arguments).
Posy2.readtechdata — Function
readtechdata(filename="tech_data.xlsx"; data_dir=joinpath(pwd(), "data"))Open and return the Posy2 technology-parameter workbook at joinpath(data_dir, filename).
The workbook is cached by path, filename, and modification time. If another application has locked the file, Posy2 reads a temporary copy when possible.
Posy2.gettechparam — Function
gettechparam(xl, tech_column::String, param::String, sheetname::String, digits::Int)
gettechparam(s::Snapshot, tech_column::String, param::String, sheetname::String;
digits=6)Read one technology parameter from sheetname. Technology sheets use a tech column for parameter names and one column per technology; tech_column selects the technology column and param selects the row.
The snapshot method resolves the workbook through Posy2Options when tech_mode=:excel; :arguments rejects direct snapshot lookups. Numeric values are rounded to digits. Cells of a *_profile row hold the yearly cost shares as a semicolon-separated string and are returned as a Vector{Float64}; other strings are returned unchanged. Missing sheets, columns, rows, or values raise ArgumentError with workbook context.
Posy2.readtimeseries — Function
readtimeseries(filename="time_series.xlsx";
data_dir=joinpath(pwd(), "data"))Open and return the Posy2 hourly time-series workbook at joinpath(data_dir, filename).
The workbook is cached by path, filename, and modification time. If another application has locked the file, Posy2 reads a temporary copy when possible.
Posy2.gettimeseries — Function
gettimeseries(xl, title::String, sheetname::String, digits::Int)
gettimeseries(s::Snapshot, title::String, sheetname::String; digits=6)Read and return the complete column title from sheetname in a Posy2 time-series workbook.
The snapshot method resolves the workbook through Posy2Options when timeseries_mode=:excel; :arguments rejects direct snapshot lookups. Values are rounded to digits. Missing sheets or columns, and columns containing missing, non-numeric, or non-finite values raise ArgumentError with workbook context.
Demand And Flexibility
Posy2.makedemand — Function
makedemand(name::String, zone::String, n::Node, s::Snapshot;
tech::String=name, profile=nothing, profile_multiplier=1.0, profile_shift_hours::Int=0,
annual_flat_demand::Real=0., grid_losses=0.,
)Build, connect and return a component based on the Demand template.
Arguments:
name: component name prefix.tech: technology label used for reporting and component queries; defaults toname.zone: time series name in the time series workbook (demandsheet).n: demand node to connect the component to.s: snapshot to register the component in.profile: Hourly demand in MW, or a scalar expanded across the simulation mesh. Ifnothing, readzonefrom thedemandsheet.profile_multiplier: Dimensionless multiplier applied to the profile demand.0disables it and skips thezone,profile, andprofile_shift_hoursinputs.profile_shift_hours: Circular profile shift in hours (e.g. align the first day to Monday).annual_flat_demand: Flat demand in MWh/year, distributed over 8760 hours (annual_flat_demand >= 0).grid_losses: Proportional grid-loss fraction on demand input (0 <= grid_losses < 1).
Posy2.makeflathydrogendemand — Function
makeflathydrogendemand(name::String, n::Node, annual_demand::Real, s::Snapshot;
tech::String=name)Build, connect and return a flat hydrogen demand component.
Arguments:
name: component name prefix.tech: technology label used for reporting and component queries; defaults toname.n: hydrogen demand node to connect the component to.annual_demand: Total hydrogen demand in MWh/year. Must satisfyannual_demand >= 0.s: snapshot to register the component in.
Posy2.makeflexhydrogendemand — Function
makeflexhydrogendemand(name::String, n::Node, annual_demand::Real, s::Snapshot;
tech::String=name)Build, connect and return a flexible hydrogen demand component.
Arguments:
name: component name prefix.tech: technology label used for reporting and component queries; defaults toname.n: hydrogen demand node to connect the component to.annual_demand: Total hydrogen demand in MWh/year, enforced throughYearlySum("input", annual_demand, :equal). Must satisfyannual_demand >= 0.s: snapshot to register the component in.
Posy2.makedemandresponse — Function
makedemandresponse(name::String, elec::Node, cap, cost::Real, s::Snapshot;
tech::String=name, type::Symbol=:volDR)Build, connect and return a demand response component represented as negative consumption.
The positive output is an unconnected accounting flow used for capacity, cost, and reporting. The connected negative consumption input is -(1 - elec.losses) * output; when node losses are zero, it is exactly -output. Consequently, activation enters the nodal balance on the demand side without modifying existing demand components.
Arguments:
name: component name prefix.tech: technology label used for reporting and component queries; defaults toname.elec: electricity node to connect the component to.cap: Response capacity in MW. A number fixes capacity, a JuMPVariableReforAffExprreuses that expression,nothingcreates a capacity decision, andInfleaves output unlimited.nothingemits a warning to distinguish it from unlimited capacity.cost: Activation cost in currency/MWh.s: snapshot to register the component in.type: variable cost label used for reporting (default:volDR).
Electric Vehicles
Posy2.makeEV — Function
makeEV(name::String, elec::Node, s::Snapshot;
tech::String=name,
fixed_profile::Bool=true, smart_charging::Bool=false, vehicle_to_grid::Bool=false,
annual_consumption=nothing, offhours1=nothing, offhours2=nothing, minratio=nothing, days_threshold::Integer=104,
number_ev=nothing, initial_connected_share=nothing,
zone::Union{Nothing,String}=nothing, tech_column::String="EV",
compensation::Real=0., grid_losses=0.,
departures=nothing, arrivals=nothing,
departure_soc=nothing, arrival_soc=nothing,
charging_eff::Union{Nothing,Real}=nothing, self_discharge::Union{Nothing,Real}=nothing,
max_charging_power_per_ev::Union{Nothing,Real}=nothing, max_dispatch_power_per_ev::Union{Nothing,Real}=nothing,
battery_capacity_per_ev::Union{Nothing,Real}=nothing,
)Build, connect and return an EV component.
Arguments:
name: Component name prefix.tech: technology label used for reporting and component queries; defaults toname.elec: Electricity node to connect EV charging/discharging flows.s: Target snapshot where the EV component and behaviors are registered.fixed_profile: Enable fixed-profile EV demand mode (deterministic hourly charging profile).smart_charging: Enable flexible charging mode (charging only, no discharge to grid).vehicle_to_grid: Enable flexible charging + grid discharge (V2G) mode. Exactly one offixed_profile,smart_charging,vehicle_to_gridmust betrue.annual_consumption: Yearly EV electricity consumption in fixed-profile mode (MWh/year). Must be non-negative and is rejected in flexible modes.offhours1: Winter off-hour indices (0-23, no duplicates). Required whenfixed_profile=true; ignored otherwise.offhours2: Summer off-hour indices (0-23, no duplicates). Required whenfixed_profile=true; ignored otherwise.minratio: Dimensionless charging level during off-hours (0 <= minratio <= 1). Required whenfixed_profile=true; ignored otherwise. The hourly profile is normalized so that it sums toannual_consumption; a schedule that leaves no charging hour at all (every hour an off-hour withminratio=0) is rejected.days_threshold: Number of first winter days before summer segment in fixed-profile assembly (0 <= days_threshold <= 183, used only whenfixed_profile=true).
The fleet, mobility-profile, charging-efficiency, and battery-limit arguments below are used only in flexible/V2G modes unless stated otherwise.
number_ev: Number of vehicles in the fleet (> 0). Scales per-vehicle power and battery limits.initial_connected_share: Share of the fleet connected immediately before the first model timestep (0 <= initial_connected_share <= 1).zone: Zone key used to read omitted EV time series in:excelmode.departures: Hourly number of vehicles departing the connected fleet, scalar or vector, nonnegative. Ifnothing, read it from the configured time-series workbook (EV_departure).arrivals: Hourly number of vehicles arriving to the connected fleet, scalar or vector, nonnegative. Ifnothing, read it from the configured time-series workbook (EV_arrival).departure_soc: Mean SOC of departing vehicles in[0, 1], scalar or vector. Ifnothing, read it fromEV_departure_socin:excelmode.arrival_soc: Mean SOC of arriving vehicles in[0, 1], scalar or vector. Ifnothing, read it fromEV_arrival_socin:excelmode.tech_column: Technology column name in thestoragetech data sheet for EV parameters, used in flexible/V2G modes; defaults to"EV".compensation: V2G compensation in currency/MWh of grid discharge (ignored in non-V2G modes).grid_losses: Proportional grid-loss fraction on EV input in fixed-profile mode (0 <= grid_losses < 1).charging_eff: Dimensionless charging efficiency in flexible/V2G modes (0 < charging_eff <= 1); defaults to one in:argumentsmode.self_discharge: Self-discharge fraction per hour in flexible/V2G modes (0 <= self_discharge < 1); defaults to zero in:argumentsmode.max_charging_power_per_ev: Maximum charging power in MW/vehicle (> 0), required explicitly in:argumentsmode.max_dispatch_power_per_ev: Maximum V2G power in MW/vehicle (>= 0), required explicitly for V2G in:argumentsmode and ignored otherwise.battery_capacity_per_ev: Battery capacity in MWh/vehicle (> 0), required explicitly in:argumentsmode.
Generation
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 toname.tech_column: technology column name in thedispatchabletech data sheet; defaults totech.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 JuMPVariableReforAffExprreuses that expression,nothingcreates a capacity decision, and an extractedSnapshotinherits the capacity of"<name> <node name>"in it. Numeric0builds 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: Iftrue, newly constructed UC commitment variables are integer; used only whenuc=true.uc: Enables UC constraints and UC linked costs (no_load_cost,startup_cost). An extractedSnapshotinstead replays the commitment schedule already solved for the matching component, and then requires a fixedcap.fuel_node: If provided, fuel is modeled as an input flow linked by efficiency. Ifnothing, fuel is modeled as a variable cost on output energy (fuel_cost).co2_node: CO2 node connected whenco2_emissionis nonzero. It is required in that case and otherwise defaults tonothing.co2_price: Carbon price in currency/tCO2, used only whenco2_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 withoutfuel_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 withfuel_node.unit_size: Generating-unit size in MW.0disables 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 positiveunit_size.min_power: Minimum committed output as a fraction of unit capacity, used only whenuc=true.min_uptime,min_downtime,startup_duration,shutdown_duration: Durations in hours, used only whenuc=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.
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 toname.tech_column: technology column name in thedispatchabletech data sheet; defaults totech.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 JuMPVariableReforAffExprreuses that expression,nothingcreates a capacity decision, and an extractedSnapshotinherits 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 extractedSnapshotinstead replays the commitment schedule already solved for the matching component and requires a fixedcap. Fresh refuelling constraints are built only whenuc=true; withuc=falsethey are ignored, and a replayed schedule retains its solved refuelling decisions.integer_uc: Integer UC commitment variables, used only whenuc=true.startup_mask: Startup availability mask, used only whenuc=true.shutdown_mask: Shutdown availability mask, used only whenuc=true.refuel: Enables planned refuelling constraints. Set tofalseto disable refuelling regardless of the other refuelling arguments.refuel_duration: Planned refuelling outage in hours. A positive value enables refuelling constraints whenrefuel_fraction_per_year > 0. Ifnothing, use the workbook value in:excelmode and zero in:argumentsmode.refuel_slot_spacing: Spacing, in hours, of the grid at which a refuelling outage may start:8760leaves a single allowed start,730leaves 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. Ifnothing, use the workbook value in:excelmode and zero in:argumentsmode.fuel_node: If provided, fuel is represented as linked input flow usingefficiency. Ifnothing,fuel_costis applied as output variable cost.co2_node: CO2 node connected whenco2_emissionis nonzero. It is required in that case and otherwise defaults tonothing.co2_price: Carbon price in currency/tCO2, used only whenco2_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_costis used directly only withoutfuel_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 withfuel_node.unit_size: Reactor-unit size in MW.0disables 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 positiveunit_size.min_power: Minimum committed output as a fraction of unit capacity, used only whenuc=true.min_uptime,min_downtime,startup_duration,shutdown_duration: Durations in hours, used only whenuc=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.
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 toname.tech_column: technology column name in theintermittenttech data sheet; defaults totech.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 JuMPVariableReforAffExprreuses that expression,nothingcreates a capacity decision, and an extractedSnapshotinherits 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 seriesprofiles_<year>. Required for workbook lookup; unused whenprofileis supplied explicitly.profile: Dimensionless hourly capacity-factor vector or scalar in[0, 1]. Ifnothing, read the<tech_column>_<node>workbook column. With numericcap == 0, an omitted profile is replaced by zero without a workbook or weather-year lookup.co2_price: Carbon price in currency/tCO2, used only whenco2_emission != 0.co2_node: CO2 node connected whenco2_emissionis nonzero. It is required in that case and otherwise defaults tonothing.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.
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 toname.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,nothingcreates a new capacity decision, a JuMP variable or affine expression reuses that external decision, and an extractedSnapshotinherits 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 theintermittenttech data sheet; defaults to"Hydro ror".weather_year: Year suffix used to select intake serieshydro_ror_<year>. Required for workbook lookup; unused whenintake_profileis 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. Ifnothing, readzonefrom the selected workbook sheet.intake: Total yearly intake in MWh, spread over the normalized profile.0disables 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.
Hydrogen
Posy2.makeflathydrogenpurchase — Function
makeflathydrogenpurchase(name::String, n::Node, annual_supply::Real, s::Snapshot;
tech::String=name)Build, connect and return a flat hydrogen purchase component.
Arguments:
name: component name prefix.tech: technology label used for reporting and component queries; defaults toname.n: hydrogen node to connect the component to.annual_supply: Purchased hydrogen in MWh/year, converted internally to a flat hourly flow (annual_supply / 8760).s: snapshot to register the component in.
Storage And Conversion
Posy2.makehydroreservoir — Function
makehydroreservoir(name::String, zone::String, elec::Node, s::Snapshot;
tech::String=name, tech_column::String=tech,
discharge_cap, charge_cap, intake, energy_cap=Inf, spillage=false,
weather_year=nothing, grid_losses=0., simplified=false,
intake_profile=nothing,
roundtrip_eff::Union{Nothing,Real}=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 hydro reservoir component.
This builder does not cover endogenous capacity expansion of the reservoir. discharge_cap, charge_cap and energy_cap are exogenous: unlike the other builders they accept neither nothing nor a JuMP expression, and so are never capacity decisions. A model-sized reservoir would be built free of charge, because CAPEX and fixed O&M are applied to discharging capacity alone. Costs still apply to the fixed capacities, so an existing fleet reports its annualized cost.
If you need an expandable reservoir, please write a dedicated component builder for it. It needs a cost basis for each expanded dimension, which the shared storage technology sheet does not carry.
Arguments:
name: component name prefix.tech: technology label used for reporting and component queries; defaults toname.tech_column: technology column name in thestoragetech data sheet; defaults totech.zone: Zone used for reservoir intake time series lookup.elec: electricity node to connect the component to.s: snapshot to register the component in.discharge_cap: Discharging capacity in MW. A number fixes it, and an extractedSnapshotinherits the capacity of"<name> <node name>"in it.charge_cap: Charging capacity in MW with the same choices. Theinputport is always created; numeric0gives it a zero capacity, so a turbine-only reservoir still reports a charging flow of zero.intake: Total yearly natural intake in MWh, spread over the normalized profile.0disables natural intake.energy_cap: Storage level capacity in MWh, with the same choices asdischarge_cap, plusInf(the default) which leaves the level unlimited by adding no level capacity behavior.spillage: Add an unconnected, unlimitedspilloutput that lets the reservoir release stored energy without generating. It defaults tofalse, which forces all natural intake to eventually become generation.weather_year: Year suffix used to select the intake series stored inreservoir_inflow_<year>. Required whenintake_profileis read from the time-series workbook; unused when a profile is supplied explicitly or natural intake is disabled.grid_losses: Proportional charging-loss fraction (0 <= grid_losses < 1).simplified: Passed toLazyStorage(..., simplified=...).intake_profile: Dimensionless hourly natural-intake shape or scalar, nonnegative with a strictly positive sum. It is normalized to sum to one beforeintakeis applied. Ifnothing, readzonefromreservoir_inflow_<weather_year>.roundtrip_eff: Dimensionless round-trip charging efficiency.overnight_cost: Overnight CAPEX in currency/kW of discharging capacity.om_fixed_cost: Fixed O&M in currency/kW/year of discharging capacity.om_var_cost: Variable O&M in currency/MWh discharged.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.
Posy2.makebatterystorage — Function
makebatterystorage(name::String, elec::Node, s::Snapshot;
tech::String=name, tech_column::String=tech,
power_cap=nothing, power_mincap=nothing, power_maxcap=nothing,
simplified=false, grid_losses=0.,
roundtrip_eff::Union{Nothing,Real}=nothing, duration::Union{Nothing,Real}=nothing,
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,
)Build, connect and return a battery storage component.
Arguments:
name: component name prefix.tech: technology label used for reporting and component queries; defaults toname.tech_column: technology column name in thestoragetech data sheet; defaults totech.elec: electricity node to connect the component to.s: snapshot to register the component in.power_cap: Power capacity in MW. It bounds charging and discharging alike, and the stored level atpower_cap * duration. A number fixes capacity, a JuMPVariableReforAffExprreuses that expression,nothingcreates a capacity decision, and an extractedSnapshotinherits the capacity of"<name> <node name>"in it.power_mincap: Lower power-capacity bound in MW; checked as an assertion against a fixed or inherited one.power_maxcap: Upper power-capacity bound in MW; checked as an assertion against a fixed or inherited one.simplified: Passed toBasicStorage(..., simplified=...).grid_losses: Proportional charging-loss fraction (0 <= grid_losses < 1).roundtrip_eff: Dimensionless round-trip storage efficiency.duration: Storage duration in hours (duration > 0); required in:argumentsmode and otherwise read from the workbook whennothing.overnight_cost: Overnight CAPEX in currency/kW of charging capacity.om_fixed_cost: Fixed O&M in currency/kW/year of charging 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 charged.
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.
Posy2.makehydrogenstorage — Function
makehydrogenstorage(name::String, h2::Node, s::Snapshot;
tech::String=name, tech_column::String=tech,
energy_cap=nothing, energy_mincap=nothing, energy_maxcap=nothing,
roundtrip_eff::Union{Nothing,Real}=nothing,
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,
)Build, connect and return a hydrogen storage component.
Arguments:
name: component name prefix.tech: technology label used for reporting and component queries; defaults toname.tech_column: technology column name in thestoragetech data sheet; defaults totech.h2: hydrogen node to connect the component to.s: snapshot to register the component in.energy_cap: Stored-energy capacity in MWh. Charging and discharging power are left unlimited. A number fixes capacity, a JuMPVariableReforAffExprreuses that expression,nothingcreates a capacity decision, and an extractedSnapshotinherits the capacity of"<name> <node name>"in it.energy_mincap: Lower energy-capacity bound in MWh; checked as an assertion against a fixed or inherited one.energy_maxcap: Upper energy-capacity bound in MWh; checked as an assertion against a fixed or inherited one.roundtrip_eff: Dimensionless round-trip storage efficiency. Ifnothing, read it from the workbook in:excelmode and use one in:argumentsmode.overnight_cost: Overnight CAPEX in currency/kWh of storage capacity.om_fixed_cost: Fixed O&M in currency/kWh/year of storage 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.
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.
Posy2.makeelectrolyser — Function
makeelectrolyser(name::String, elec::Node, h2::Node, s::Snapshot;
tech::String=name, tech_column::String=tech,
cap=nothing, mincap=nothing, maxcap=nothing,
grid_losses=0.,
efficiency::Union{Nothing,Real}=nothing,
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,
om_var_cost::Union{Nothing,Real}=nothing,
)Build, connect and return an electrolyser component.
Arguments:
name: component name prefix.tech: technology label used for reporting and component queries; defaults toname.tech_column: technology column name in theelectrolysistech data sheet; defaults totech.elec: electricity node to connect the component to.h2: hydrogen node to connect the component to.s: snapshot to register the component in.cap: Electricity input capacity in MW. A number fixes capacity, a JuMPVariableReforAffExprreuses that expression,nothingcreates a capacity decision, and an extractedSnapshotinherits 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.grid_losses: Proportional electricity-loss fraction (0 <= grid_losses < 1).efficiency: Hydrogen output per unit of electricity input (dimensionless when both carriers use MWh). Ifnothing, read it from the workbook in:excelmode and use one in:argumentsmode.overnight_cost: Overnight CAPEX in currency/kW of electricity input capacity.om_fixed_cost: Fixed O&M in currency/kW/year of electricity input 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.om_var_cost: Variable O&M in currency/MWh of electricity input.
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.
Interconnections
Posy2.makepricelink — Function
makepricelink(name::String, elec::Node, s::Snapshot;
neighbor::String=name, neighbor_column::String=neighbor,
import_cap=nothing, import_mincap=nothing, import_maxcap=nothing,
export_cap=nothing, export_mincap=nothing, export_maxcap=nothing,
exclusive_direction::Bool=false, neighbor_is_foreign::Bool=true,
transaction_cost::Real=0.,
spot_price=nothing, import_availability=nothing, export_availability=nothing,
)Build, connect and return an interconnection component named "<name>_<elec.name>", trading with a neighbouring market represented by an exogenous price series instead of an explicit node. If exclusive_direction is true, apply a one direction at a time constraint at every timestep.
Arguments:
name: interconnector name prefix.elec: local electricity node to connect the interconnector to.s: snapshot to register the component in.neighbor: counterparty market, reported as the:neighbortag and as the remote endpoint of directed flows. Defaults toname.neighbor_column: name the workbook columns are built from. Defaults toneighbor.import_cap: Import capacity in MW, following the common capacity contract: a number fixes it, a JuMPVariableReforAffExprreuses that expression,nothingcreates a capacity decision, and an extractedSnapshotinherits the"output"capacity of"<name>_<elec.name>"in it. Numeric0disables imports.import_mincap: Lower import capacity bound in MW; checked as an assertion against a fixed or inherited one.import_maxcap: Upper import capacity bound in MW; checked as an assertion against a fixed or inherited one.export_cap: Export capacity in MW, with the same contract; an extractedSnapshotinherits the"input"capacity. Numeric0disables exports.export_mincap: Lower export capacity bound in MW.export_maxcap: Upper export capacity bound in MW.exclusive_direction: iftrue, apply SOS1 one direction at a time flow constraint.neighbor_is_foreign: iftrue, the neighbouring market lies outside the modelled system and the component is tagged:foreign. A price interconnection carries this on itself because its remote endpoint is not a node that could hold a:foreigntag, unlikemaketransmissionlink. Set it to false when the price series represents another internal zone.transaction_cost: Transaction adder in currency/MWh on both directions.spot_price: Foreign spot price in currency/MWh, as an hourly vector or scalar.import_availability: Dimensionless hourly multiplier for the foreign-to-local direction, each value in[0, 1], read from column"<neighbor_column>><elec.name>".export_availability: Dimensionless hourly multiplier for the local-to-foreign direction, with the same[0, 1]domain, read from column"<elec.name>><neighbor_column>". Availability is resolved for every direction except a numeric zero one. When omitted, it comes from the workbook in:excelmode and defaults to one in:argumentsmode.spot_priceis required whenever either direction has active capacity, and is read from column"<neighbor_column>". When both capacities are numeric zeros the corridor is disabled: no spot price is read and the reported exogenous price is an hourly series of zeros.
Neither direction carries an investment cost, so bound an optimized capacity with import_maxcap or export_maxcap.
Posy2.maketransmissionlink — Function
maketransmissionlink(name::String, a::Node, b::Node, s::Snapshot;
cap=nothing, mincap=nothing, maxcap=nothing,
exclusive_direction::Bool=false, dc::Bool=false,
transaction_cost::Real=0., loss_factor::Real=0.,
susceptance::Union{Nothing,Real}=nothing,
a_to_b_availability=nothing, b_to_a_availability=nothing,
overnight_cost=nothing, om_fixed_cost=nothing,
lifetime=nothing, construction_profile=nothing,
)Build, connect and return an interconnection component linking two nodes. Whether the link crosses the self-system boundary is derived at reporting time from the connected nodes' :foreign tags; there is no component-level flag.
Arguments:
name: interconnector name prefix.a: first node linked by the interconnector.b: distinct second node linked by the interconnector; self-connections are rejected before model construction.s: snapshot to register the component in.cap: Installed capacity in MW. A number fixes capacity, a JuMPVariableReforAffExprreuses that expression,nothingcreates a capacity decision, and an extractedSnapshotinherits the capacity of"<name>_<a.name>_<b.name>"in it. Numeric0builds 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.exclusive_direction: apply an SOS1 one direction at a time flow constraint.dc: iftrue, tag as:DC; otherwise tag as:AC.transaction_cost: Transaction adder in currency/MWh on each direction.loss_factor: Dimensionless proportional loss; must be finite and satisfy0 <= loss_factor < 1.susceptance: AC series susceptance in model power units/rad (MW/rad under the standard convention; must be negative), used only whendc=false; stored inSnapshot.options[:ic_susceptance](required for KVL whenapplydcopf!is called).a_to_b_availability: Dimensionless hourlya -> bmultiplier vector or scalar, each value in[0, 1].b_to_a_availability: Dimensionless hourlyb -> amultiplier vector or scalar, with the same[0, 1]domain. These directional multipliers represent asymmetric available transfer capacity against the shared installed capacity. A nonzero fixed or optimized capacity reads both workbook columns in:excelmode when omitted, and defaults both to one in:argumentsmode. Numeric zero does not resolve either availability series.overnight_cost: Overnight CAPEX in currency/kW of shared capacity. Defaults to zero.om_fixed_cost: Fixed O&M in currency/kW/year of shared capacity. Defaults to zero.lifetime: Asset lifetime in years, used to annualize nonzero overnight cost (> 0, integer-valued).construction_profile: Dimensionless yearly construction-cost shares, required whenovernight_costis nonzero.
In :excel mode both directional multipliers are read from the sheet that matches the link type: transfer_capacities_AC when dc=false, transfer_capacities_DC when dc=true. Columns are named From>To after the node names. An AC and a DC link on the same node pair therefore carry their own availability series, and neither reads transfer_capacities, which belongs to makepricelink.
Node interconnections cannot be added after applydcopf! has run on the snapshot; build the full topology first.
Exactly one AC and one DC may share the same unordered node pair (either, both, or neither is fine). A second AC or a second DC on that pair raises an error. Component-name collisions are also rejected before model construction. Aggregate equivalent parallel circuits before calling this builder.
Economics And Optimisation
Posy2.eac — Function
eac(overnight_cost::Real, discount_rate::Real, lifetime, construction_profile)Return the annualized investment cost in function of the overnight cost, the discount rate, the lifetime and the construction profile. The effects are the following:
- total cost (financing taking construction time into account + overnight cost)
- annualization via corrected CRF (so that operation starts right after construction, no white year)
Units: overnight_cost is a cost per unit of capacity and the result is that cost per unit of capacity per year. Builders take overnight_cost in currency per kW and multiply it by 1000 before calling eac, so a direct call takes currency per MW and returns currency per MW per year. discount_rate is a fraction per year, lifetime is a number of years, and construction_profile is a number or a vector of yearly shares summing to 1.
Posy2.applydcopf! — Function
applydcopf!(s::Snapshot)Add KVL (DC power flow) constraints at snapshot level, so that cycles in the AC network are enforced globally. For each independent cycle, constrain sum(flow_ij / B_ij) = 0, where flow_ij is the net midpoint flow and B_ij the susceptance registered by maketransmissionlink. DC interconnections are excluded. Warns when there is no AC loop to constrain.
Call it before Nosy.optimize! in the studies that need DC power flow, and leave it out of the others: there is no snapshot option to switch it off.
It may be called only once per snapshot, and no node interconnection may be added afterwards: the constraints are built from the topology present at the call, so a second call would stack duplicates and a later interconnection would leave them describing a different network. Both raise an ArgumentError.
Post-processing And Export
Posy2.selfcost — Function
selfcost(s::Snapshot)Return the self total cost associated with Snapshot s. This includes:
- all non-interconnection components in
selfnodes - no non-interconnection components in
foreignnodes - import costs and export revenues for interconnections connected to
selfnodes - congestion rent for interconnections connected to
selfnodes
Posy2.losses — Function
losses(s::Snapshot; collapse=true, categories=LOSSCATEGORIES, by=nothing)Return a DataFrame of the electricity losses of Snapshot s, with one row per (loss source, node) pair and the columns:
| column | content |
|---|---|
node | electricity node the loss is charged to |
source | component causing the loss, or the node name for :node losses |
tech | technology label of the source |
category | one of (:node, :component, :interconnection, :storage, :selfdischarge) |
losses | MWhe value, or hourly MWhe series when collapse=false |
Lossless sources are omitted, so an empty table means a lossless system.
categories restricts the reported categories:
:node: nodal losses ofNode(losses=...), a ratio of the node inflow:component: proportionalgrid lossesflow of a single component:interconnection: transfer losses of a node interconnection:storage: charging conversion loss of a storage or EV,input * (1 - eff):selfdischarge: stored energy lost over a timestep
Only (:node, :component, :interconnection) are flows of the nodal balance; :storage and :selfdischarge are internal to their component and are already included in its charging flow.
Every row is attributed to a single node, and a component spanning several electricity nodes (a node interconnection) splits its loss equally between them. Therefore sum(df.losses) is the system total, grouping by node gives nodal losses and grouping by source gives whole-component losses.
by aggregates the table over one or more of :node, :source, :tech and :category, keeping the losses column:
losses(result) # every loss source
losses(result; by=:node) # losses of each node
losses(result; by=(:tech, :category)) # losses of each technology, split by cause
losses(result; by=:source, categories=(:interconnection,)) # losses of each interconnectionLosses of non-electricity nodes (e.g. hydrogen storage) are out of scope, and so are carrier conversion losses (electrolysis, fuel to power): their output is a product on another carrier rather than a loss of the electricity system.
Posy2.write_results — Function
write_results(s::Snapshot{Float64}, path::String; overwrite::Bool=false)Write the standard Posy2 workbook report of the extracted snapshot s to path and return path. Missing parent directories are created.
path is taken as given, extension included; nothing is prepended to it. An existing file is never touched unless overwrite=true is passed, in which case it is replaced.