Policy
E4ST.Policy
— Typeabstract type Policy <: Modification
This is a subtype of Modification that represents a policy to be modeled.
Basic Policy Types are used when defining standard policies in E4ST. They are specified as mods in the config file with a type
field.
There are currently six basic policy types. Novel policy types can also be added as needed.
Policies (Policy subtypes)
Tax Credits
ITC
E4ST.ITC
— Typestruct ITC <: Policy
Investment Tax Credit - A tax incentive that is a percentage of capital cost given to generators that meet the qualifications.
Keyword Arguments
name
: policy namevalues
: the credit level, stored as an OrderedDict with year and value(:y2020=>0.3)
. Credit level refers to the percentage of the capex that will be rebated to the investorgen_filters
: filters for qualifying generators, stored as an OrderedDict with gen table columns and values (:emis_co2=>"<=0.1"
for co2 emission rate less than or equal to 0.1)
E4ST.modify_setup_data!
— MethodE4ST.modify_setup_data!(pol::ITC, config, data)
Creates a column in the gen table with the ITC value in each simulation year for the qualifying generators.
ITC values are only calculated when the year is the year_on.
E4ST.modify_model!
— Methodfunction E4ST.modify_model!(pol::ITC, config, data, model)
Subtracts the ITC price * Capacity in that year from the objective function using add_obj_term!(data, model, PerMWCap(), pol.name, oper = -)
E4ST.ITCStorage
— Typestruct ITCStorage <: Policy
Investment Tax Credit - A tax incentive that is a percentage of capital cost given to storage units that meet the qualifications.
Keyword Arguments
name
: policy namevalues
: the credit level, stored as an OrderedDict with year and value(:y2020=>0.3)
. Credit level refers to the percentage of the capex that will be rebated to the investorstorage_filters
: filters for qualifying storage, stored as an OrderedDict with gen table columns and values
E4ST.modify_setup_data!
— MethodE4ST.modify_setup_data!(pol::ITCStorage, config, data)
Creates a column in the gen table with the ITCStorage value in each simulation year for the qualifying generators.
ITCStorage values are calculated based on capex_obj
so ITCStorage values only apply in year_on
for a generator.
E4ST.modify_model!
— Methodfunction E4ST.modify_model!(pol::ITCStorage, config, data, model)
Subtracts the ITCStorage price * Capacity in that year from the objective function using add_obj_term!(data, model, PerMWCap(), pol.name, oper = -)
PTC
E4ST.PTC
— Typestruct PTC <: Policy
Production Tax Credit - A $/MWh tax incentive for the generation of specific technology or under specific conditions.
Keyword Arguments
name
: policy namevalues
: $/MWh values of the PTC, stored as an OrderedDict with years and the value(:y2020=>10)
, noteyear
is aSymbol
years_after_ref_min
: Min (inclusive) number of years the sim year can be after gen reference year (ie. yearon, yearretrofit). If ref year is year_on then this would be equivaled to min gen age.years_after_ref_max
: Max (inclusive) number of years the sim year can be after gen reference year (ie. yearon, yearretrofit). If ref year is year_on then this would be equivaled to max gen age.ref_year_col
: Column name to use as reference year for min and max above. Must be a year column. If this is :yearon, then the yearsafterref filters will filter gen age. If this is :yearretrofit, the the yearsafterref filters will filter by time since retrofit.gen_filters
: filters for qualifying generators, stored as an OrderedDict with gen table columns and values (:emis_co2=>"<=0.1"
for co2 emission rate less than or equal to 0.1)
E4ST.modify_setup_data!
— MethodE4ST.modify_setup_data!(pol::PTC, config, data)
Creates a column in the gen table with the PTC value in each simulation year for the qualifying generators.
E4ST.modify_model!
— Methodfunction E4ST.modify_model!(pol::PTC, config, data, model)
Subtracts the PTC price * generation in that year from the objective function using add_obj_term!(data, model, PerMWhGen(), pol.name, oper = -)
Derivation of the PTC capex adjustment First, find the adjusted PTC value $x$ if it were a constant cash flow over entire econ lifetime $l$.
Start by setting the NPV of the actual PTC (per MW capacity) $p$ and the adjusted PTC (per MW capacity) $x$.
$m$ is the minimum age of the generator to qualify for the PTC
$n$ is the maximum age of the generator to qualify for the PTC
\[\sum_{i=1}^l x / \left(1+r \right)^i = \sum_{i=m}^n p / \left(1+r \right)^i\]
$
x \left( \frac{1- \left(\frac{1}{1+r}\right)^l}{1 - \left(\frac{1}{1+r}\right)}\right) = p \left( \frac{1- \left(\frac{1}{1+r}\right)^n}{1 - \left(\frac{1}{1+r}\right)^{m+1}}\right) $
$
x = p \frac{\left(1- \left(\frac{1}{1+r}\right)^n\right)\left(1 - \left(\frac{1}{1+r}\right)\right)}{\left(1- \left(\frac{1}{1+r}\right)^l\right)\left(1 - \left(\frac{1}{1+r}\right)^{m+1}\right)} $
To get the adjustement to capex $capex\_ adj$ we can start with $ capex + capex_ adj + p = capex + x $ so $ capex_ adj = p - x $
$
capex_ adj = p \left(1 - \left(\frac{\left(1- \left(\frac{1}{1+r}\right)^n\right)\left(1 - \left(\frac{1}{1+r}\right)\right)}{\left(1- \left(\frac{1}{1+r}\right)^l\right)\left(1 - \left(\frac{1}{1+r}\right)^{m+1}\right)}\right)\right) $
The value of the PTC per MW capacity $p$ is equal to the PTC in per MWh terms $PTC$ * capacity factor $cf$. We can substitute this in to get the final formula
$
capex_ adjust = PTC*cf\left(1 - \left(\frac{\left(1- \left(\frac{1}{1+r}\right)^n\right)\left(1 - \left(\frac{1}{1+r}\right)\right)}{\left(1- \left(\frac{1}{1+r}\right)^l\right)\left(1 - \left(\frac{1}{1+r}\right)^{m+1}\right)}\right)\right) $
GenerationStandard
GenerationStandard is a type used for policies that give some generators certain credits and constrain generation to a certain target. The primary examples are CESs, RPSs, and state carveouts.
E4ST.GenerationStandard
— Typestruct GenerationStandard{T} <: Policy
A generation standard (also refered to as a portfolio standard) is a constraint on generation where a portion of generation from certain generators must meet the a portion of the load in a specified region. This encompasses RPSs, CESs, and technology carveouts. To assign the credit (the portion of generation that can contribute) to generators, the Crediting
type is used.
name
- Name of the policygen_filters
- Filters on which generation qualifies to fulfill the GS. Sometimes qualifying generators may be outside of the GS load region if they supply power to it.crediting
- the crediting structure and related fieldsload_targets
- OrderedDict containing key-value pairs where each key is the name of a requirement (not currently used), and each value is an OrderedDict with the following keys:filters
- Filters on which buses fall into the GS load region. The GS will be applied to the load from these buses.targets
- The yearly percent targets of the qualifying load that must be covered by the qualifying generation.
E4ST.modify_setup_data!
— Methodmodify_setup_data!(pol::GenerationStandard, config, data)
Adds column to the gen table with the credit level of the generation standard. Adds the name and type of the policy to the gspollist in data.
E4ST.modify_model!
— Methodmodify_model!(pol::GenerationStandard, config, data, model)
Creates the expression :pgsbus, the load that generation standards are applied to, if it hasn't been created already. Creates a constraint that takes the general form: sum(gs_egen * credit) <= gs_value * sum(gs_load)
Crediting
E4ST.Crediting
— Typeabstract type Crediting
Crediting is used to set the credit levels of generators for policies. It is primarily used for GenerationStandard
s and ReserveRequirement
s (RPS, CES, carveouts, etc).
Setup inside config yaml
Crediting is specified in the yaml file. A type key must be specified, along with the approriate keys for the credit type you specified. Two examples are shown in the config below.
base_out_path: "../out/3bus_rps"
mods:
example_rps:
type: "RPS"
crediting:
type: "StandardRPSCrediting"
gen_filters:
bus_nation: "archenland"
load_targets:
stormness_rps:
filters:
state: stormness
targets:
y2035: 0.85
y2040: 0.9
example_rps_gentype:
type: "RPS"
crediting:
type: "CreditByGentype"
credits:
solar: 0.8
wind: 1.0
oswind: 1.0
gen_filters:
bus_nation: "narnia"
load_targets:
narnia_rps:
targets:
y2030: 0.7
y2035: 0.8
y2040: 0.9
filters:
nation: "narnia"
stor:
type: Storage
file: "../data/3bus/storage.csv"
Standard Crediting subtypes include:
Interfaces Implements
get_credit(c::Crediting, data, gen_row::DataFrameRow)
- gets the appropriate credit level for the generator row for the given Crediting subtype.
E4ST.get_credit
— Functionget_credit(c::Crediting, data, gen_row::DataFrame) ->
Return the credit value for the given generator and crediting type.
get_credit(c::CreditByGentype, data, gen_row::DataFrameRow)
Returns the credit level specified for the gentype in c.credits. If no credit is specified for that gentype, it defaults to 0.
get_credit(c::CreditByBenchmark, data, gen_row::DataFrameRow) ->
Returns the credit level based on the formula max(1.0 - (gen_row[gen_col] / c.benchmark), 0.0)
.
E4ST.StandardRPSCrediting
— Typestruct StandardRPSCrediting <: Crediting
Standard RPS crediting structure. Anything included in the RPS gentypes recieves a credit of 1. Creates a CreditByGentype
["solar", "dist_solar", "wind", "oswind", "geothermal", "hcc_new", "hcc_ret"]
E4ST.CreditByGentype
— TypeCreditByGentype(;credits::OrderedDict{String, Float64})
Crediting method where credit levels are specified by gentypes.
E4ST.CreditByBenchmark
— TypeCreditByBenchmark(;gen_col, benchmark)
Awards credit of each generator based on how that generator's gen_col
compares to benchmark
, using the following formula.
max(1.0 - (gen_row[gen_col] / benchmark), 0.0)
gen_col::Symbol
- the column of thegen
table to compare againstbenchmark::Float64
- the benchmark rate to compare with, in the same units as thegen_col
.
E4ST.AvailabilityFactorCrediting
— TypeAvailabilityFactorCrediting <: Crediting
Returns the availability factor of the generator.
E4ST.StandardStorageReserveCrediting
— Typestruct StandardStorageReserveCrediting <: Crediting
Awards crediting to storage facilities based on their discharge duration and capacity. The values were retrieved from NYISO at the following website, page 31:
CES
CES is an alias for GenerationStandard. Modifying functions called on a CES will use the GenerationStandard method.
E4ST.CES
— Typeconst CES = GenerationStandard{:CES}
Clean Energy Standard - A policy in which the load serving entity must purchase a certain ampount of clean energy credits. The number of credits for a type of generation typically depends on it's emission rates relative to a benchmark.
CES is defined as an alias of GenerationStandard
.
No default crediting is specified although the standard crediting will be CreditByBenchmark
where the benchmark should be specified in the config.
Fields
name
- Name of the policytargets
- The yearly targets for the CEScrediting
- the crediting structure and related fields. CES crediting is oftenCreditByBenchmark
.gen_filters
- Filters on which generation qualifies to fulfill the CES. Sometimes qualifying generators may be outside of the RPS load region if they supply power to it.load_bus_filters
- Filters on which buses fall into the load region. The CES will be applied to the load from these buses.
RPS
RPS is an alias for GenerationStandard. Modifying functions called on an RPS will use the GenerationStandard method.
E4ST.RPS
— Typeconst RPS = GenerationStandard{:RPS}
Renewable Portfolio Standard - A policy that constrains a certain amount of load from a region to be supplied by qualifying clean/renewable energy.
RPS is defined as an alias of GenerationStandard where the default crediting type is StandardRPSCrediting. mod_rank for RPS will be 1.0 because that is the rank of GenerationStandards
Fields
name
- Name of the policytargets
- The yearly targets for the RPScrediting
- the crediting structure and related fields. Standard CES crediting is CreditingByBenchmark.gen_filters
- Filters on which generation qualifies to fulfill the RPS. Sometimes qualifying generators may be outside of the RPS load region if they supply power to it.load_bus_filters
- Filters on which buses fall into the RPS load region. The RPS will be applied to the load from these buses.
GenerationConstraint
GenerationConstraint is a type used for constraining generation from some generators to a certain max or min amount. The max and min can also be defined in terms of another column in the gen table such as emissions. A GenerationConstraint is defined when creating an EmissionCap but can be used for more general modifications beyond policies as well.
E4ST.GenerationConstraint
— Typestruct GenerationConstraint <: Modification
Generation Constraint - A Modification that applies a constraint based on (yearly generation) * (a column from the gen table).
name
: modification namecol
: gen table columnmax_values
: maximum values for a year (defaults as an empty OrderedDict if no maxs)min_values
: minimum values for a year (defaults as an empty OrderedDict if no mins)gen_filters
: OrderedDict of the generator filters
E4ST.modify_model!
— Methodmodify_model!(cons::GenerationConstraint, config, data, model)
Creates upper and lower bound constraints on the generators. See also GenerationConstraint
for more details
EmissionCap
E4ST.EmissionCap
— Typestruct EmissionCap <: Policy
Emission Cap - A limit on a certain emission for a given set of generators.
name
: name of the policy (Symbol)emis_col
: name of the emission rate column in the gen table (ie. emis_co2) (Symbol)targets
: OrderedDict of cap targets by yeargen_filters
: OrderedDict of generator filtersgen_cons
: GenerationConstraint Modification created on instantiation of the EmissionCap (not specified in config). It sets the cap targets as the max_targets of the GenerationConstraint and passes on other fields.
E4ST.modify_model!
— MethodE4ST.modify_model!(pol::EmissionCap, config, data, model)
Calls modify_model!(cons::GenerationConstraint, config, data, model)
EmissionPrice
E4ST.EmissionPrice
— Typestruct EmissionPrice <: Policy
Emission Price - A price on a certain emission for a given set of generators.
name
: name of the policy (Symbol)emis_col
: name of the emission rate column in the gen table (ie. emis_co2) (Symbol)prices
: OrderedDict of prices by year. Given as price per unit of emissions (ie. $/short ton)years_after_ref_min
: Min (inclusive) number of years the sim year can be after gen reference year (ie. yearon, yearretrofit). If ref year is year_on then this would be equivaled to min gen age. This is rarely used in real policy, so be careful if changing from default valueyears_after_ref_max
: Max (inclusive) number of years the sim year can be after gen reference year (ie. yearon, yearretrofit). If ref year is year_on then this would be equivaled to max gen age. This is rarely used in real policy, so be careful if changing from default valueref_year_col
: Column name to use as reference year for min and max above. Must be a year column. If this is :yearon, then the yearsafterref filters will filter gen age. If this is :yearretrofit, the the yearsafterref filters will filter by time since retrofit. This is rarely used in real policy, so be careful if changing from default valuegen_filters
: OrderedDict of generator filtershour_filters
: OrderedDict of hour filters
E4ST.modify_model!
— MethodE4ST.modify_model!(pol::EmissionPrice, config, data, model)
Adds a column to the gen table containing the emission price as a per MWh value (gen emission rate * emission price). Adds this as a PerMWhGen
price to the objective function using add_obj_term!