Add emissions to generators
This how-to shows how to attach EmissionsData supplemental attributes to generators. For background on emissions metadata, see Emissions metadata.
Prerequisites
using PowerSystems
using PowerSystemCaseBuilder
sys = build_system(PSITestSystems, "c_sys5_uc")
thermals = collect(get_components(ThermalStandard, sys))5-element Vector{ThermalStandard}:
ThermalStandard(Solitude, true, true, ACBus(3, nodeC, true, ACBusTypes.PV = 2, 0.0, 1.0, (min = 0.9, max = 1.05), 230.0, nothing, nothing, Dict{String, Any}()), 2.7, 0.0, 5.2, (min = 1.0, max = 5.2), (min = -3.9, max = 3.9), (up = 0.00624, down = 0.00624), ThermalGenerationCost(CostCurve{QuadraticCurve}(QuadraticCurve(0.0, 30.0, 0.0), UnitSystem.NATURAL_UNITS = 2, LinearCurve(0.0, 0.0)), 0.0, 3.0, 1.5), 100.0, (up = 5.0, down = 3.0), false, PrimeMovers.ST = 20, ThermalFuels.COAL = 1, Service[], 10000.0, nothing, Dict{String, Any}())
ThermalStandard(Park City, true, false, ACBus(1, nodeA, true, ACBusTypes.PV = 2, 0.0, 1.0, (min = 0.9, max = 1.05), 230.0, nothing, nothing, Dict{String, Any}()), 0.0, 0.0, 2.2125, (min = 0.65, max = 1.7), (min = -1.275, max = 1.275), (up = 0.04425, down = 0.04425), ThermalGenerationCost(CostCurve{QuadraticCurve}(QuadraticCurve(0.0, 15.0, 0.0), UnitSystem.NATURAL_UNITS = 2, LinearCurve(0.0, 0.0)), 0.0, 1.5, 0.75), 100.0, (up = 0.0, down = 0.0), false, PrimeMovers.ST = 20, ThermalFuels.COAL = 1, Service[], 10000.0, nothing, Dict{String, Any}())
ThermalStandard(Alta, true, false, ACBus(1, nodeA, true, ACBusTypes.PV = 2, 0.0, 1.0, (min = 0.9, max = 1.05), 230.0, nothing, nothing, Dict{String, Any}()), 0.0, 0.0, 0.5, (min = 0.2, max = 0.4), (min = -0.3, max = 0.3), (up = 0.4, down = 0.4), ThermalGenerationCost(CostCurve{LinearCurve}(LinearCurve(14.0, 0.0), UnitSystem.NATURAL_UNITS = 2, LinearCurve(0.0, 0.0)), 0.0, 4.0, 2.0), 100.0, (up = 0.0, down = 0.0), false, PrimeMovers.ST = 20, ThermalFuels.COAL = 1, Service[], 10000.0, nothing, Dict{String, Any}())
ThermalStandard(Brighton, true, true, ACBus(5, nodeE, true, ACBusTypes.PV = 2, 0.0, 1.0, (min = 0.9, max = 1.05), 230.0, nothing, nothing, Dict{String, Any}()), 6.0, 0.0, 7.5, (min = 3.0, max = 6.0), (min = -4.5, max = 4.5), (up = 0.01125, down = 0.01125), ThermalGenerationCost(CostCurve{QuadraticCurve}(QuadraticCurve(0.0, 10.0, 0.0), UnitSystem.NATURAL_UNITS = 2, LinearCurve(0.0, 0.0)), 0.0, 1.5, 0.75), 100.0, (up = 5.0, down = 3.0), false, PrimeMovers.ST = 20, ThermalFuels.COAL = 1, Service[], 10000.0, nothing, Dict{String, Any}())
ThermalStandard(Sundance, true, false, ACBus(4, nodeD, true, ACBusTypes.REF = 3, 0.0, 1.0, (min = 0.9, max = 1.05), 230.0, nothing, nothing, Dict{String, Any}()), 0.0, 0.0, 2.5, (min = 1.0, max = 2.0), (min = -1.5, max = 1.5), (up = 0.0375, down = 0.0375), ThermalGenerationCost(CostCurve{QuadraticCurve}(QuadraticCurve(0.0, 40.0, 0.0), UnitSystem.NATURAL_UNITS = 2, LinearCurve(0.0, 0.0)), 0.0, 4.0, 2.0), 100.0, (up = 2.0, down = 1.0), false, PrimeMovers.ST = 20, ThermalFuels.COAL = 1, Service[], 10000.0, nothing, Dict{String, Any}())Create a constant-rate emissions attribute
A scalar emission_rate is automatically wrapped in a constant-rate IncrementalCurve:
co2 = EmissionsData(;
name = "co2_ccgt",
pollutant = PollutantType.CO2,
emission_rate = 117.6,
basis = EmissionBasis.FUEL_INPUT,
energy_unit = EnergyUnit.MMBTU,
)EmissionsData: 280e2f49-d82e-478d-a405-e83382772de9:
name: co2_ccgt
pollutant: PollutantType.CO2 = 1
emission_rate: IncrementalCurve{LinearFunctionData}(LinearFunctionData(0.0, 117.6), nothing, nothing)
basis: EmissionBasis.FUEL_INPUT = 1
start_up_adder: 0.0
mass_unit: MassUnit.KG = 1
energy_unit: EnergyUnit.MMBTU = 1
gwp: 1.0
available: true
ext: Dict{String, Any}()
has_time_series: falseCreate a varying-rate emissions attribute
Pass a ValueCurve directly for nonlinear or piecewise relationships:
nox = EmissionsData(;
name = "nox_ccgt",
pollutant = PollutantType.NOX,
emission_rate = IncrementalCurve(LinearFunctionData(0.001, 0.01), nothing, nothing),
basis = EmissionBasis.FUEL_INPUT,
energy_unit = EnergyUnit.MMBTU,
start_up_adder = 5.0,
)EmissionsData: 62a1747d-9130-4463-a07d-88275dae9b7d:
name: nox_ccgt
pollutant: PollutantType.NOX = 10
emission_rate: IncrementalCurve{LinearFunctionData}(LinearFunctionData(0.001, 0.01), nothing, nothing)
basis: EmissionBasis.FUEL_INPUT = 1
start_up_adder: 5.0
mass_unit: MassUnit.KG = 1
energy_unit: EnergyUnit.MMBTU = 1
gwp: 1.0
available: true
ext: Dict{String, Any}()
has_time_series: falseAttach to generators
Attach attributes with add_supplemental_attribute!. The same EmissionsData instance can be shared across multiple units:
add_supplemental_attribute!(sys, thermals[1], co2)
add_supplemental_attribute!(sys, thermals[2], co2)
add_supplemental_attribute!(sys, thermals[1], nox)Verify attachments with get_component_supplemental_attribute_pairs:
pairs = collect(
get_component_supplemental_attribute_pairs(ThermalStandard, EmissionsData, sys),
)
length(pairs)3See also
- Emissions metadata — emission rate, basis, and start-up adder concepts
- Attach supplemental data to components — general attachment pattern
ValueCurveOptions — curve types foremission_rate