`EnergyModelsInvestments.EnergyModelsInvestments`

— ModuleMain module for `EnergyModelsInvestments`

.

This module implements functionalities allowing to run investment analysis.

It is in its current version extending `EnergyModelsBase`

and cannot be used as a stand-alone module.

The extension `EMIGeoExt`

includes furthermore the investment options for transmission modes as described in `EnergyModelsGeography`

.

`EnergyModelsInvestments.AbstractInvestmentModel`

— TypeAn abstract investment model type.

This abstract model type should be used when creating additional `EnergyModel`

types that should utilize investments. An example for additional types is given by the inclusion of, *e.g.*, `SDDP`

.

`EnergyModelsInvestments.BinaryInvestment`

— TypeBinary investment in given capacity with binary variables. Requires specification of `cap_start`

in `InvData`

for proper analyses.

`EnergyModelsInvestments.ContinuousInvestment`

— TypeContinuous investment between a minimum and a maximum value.

`EnergyModelsInvestments.DiscreteInvestment`

— TypeInvestment in fixed increments with integer variables.

`EnergyModelsInvestments.FixedInvestment`

— TypeForced investment in given capacity.

`EnergyModelsInvestments.InvData`

— TypeExtra data for investing in technologies.

Define the structure for the additional parameters passed to the technology structures defined in other packages. It uses the macro `Base.@kwdef`

to use keyword arguments and default values. Hence, the name of the parameters have to be specified.

**Fields**

Capital expenditure for the capacity in a strategic period.`capex_cap::TimeProfile`

Maximum possible installed capacity of the technology in a strategic period.`cap_max_inst::TimeProfile`

Maximum capacity addition in a strategic period.`cap_max_add::TimeProfile`

Minimum capacity addition in a strategic period.`cap_min_add::TimeProfile`

Type of the investment:`inv_mode::Investment = ContinuousInvestment()`

`BinaryInvestment`

,`DiscreteInvestment`

,`ContinuousInvestment`

,`SemiContinuousInvestment`

, or`FixedInvestment`

.Starting capacity in first period. If nothing is given, it is set by`cap_start::Union{Real, Nothing} = nothing`

`start_cap()`

to the capacity`cap`

of the node in the first strategic period.Capacity increment used in the case of`cap_increment::TimeProfile = FixedProfile(0)`

`DiscreteInvestment`

.Type of handling of the lifetime:`life_mode::LifetimeMode = UnlimitedLife()`

`UnlimitedLife`

,`StudyLife`

,`PeriodLife`

or`RollingLife`

Duration/lifetime of the technology invested in each period.`lifetime::TimeProfile = FixedProfile(0)`

`EnergyModelsInvestments.InvDataStorage`

— TypeExtra data for investing in storages.

Define the structure for the additional parameters passed to the technology structures defined in other packages. It uses the macro `Base.@kwdef`

to use keyword arguments and default values. Hence, the name of the parameters have to be specified.

The parameters are separated between `rate_`

and `stor_`

. The `rate_`

parameters refer to rate components (power, flow, ...) for instance, charging and discharging power of batteries, while the `stor_`

refers to a volumetric component (energy, volume, mass...), for instance storage capacity of a battery.

**Fields**

Capital expenditure for storage rate, here investment costs of the technology rate in each period.`capex_rate::TimeProfile`

Maximum possible installed rate of the technology in each period.`rate_max_inst::TimeProfile`

Maximum rate addition in a strategic period.`rate_max_add::TimeProfile`

Minimum rate addition in a strategic period.`rate_min_add::TimeProfile`

Capital expenditure, here investment costs of the technology storage volume in each strategic period.`capex_stor::TimeProfile`

Maximum possible installed storage volume of the technology in each strategic period.`stor_max_inst::TimeProfile`

Maximum storage volume addition in one period from the previous.`stor_max_add::TimeProfile`

Minimum storage volume addition in one period from the previous.`stor_min_add::TimeProfile`

Type of the investment:`inv_mode::Investment = ContinuousInvestment()`

`BinaryInvestment`

,`DiscreteInvestment`

,`ContinuousInvestment`

,`SemiContinuousInvestment`

or`FixedInvestment`

.Starting rate in first period. If`rate_start::Union{Real, Nothing} = nothing`

`nothing`

is given, it is set by`start_cap()`

to the capacity`rate_cap`

of the node in the first strategic period.Starting storage volume in first period. If`stor_start::Union{Real, Nothing} = nothing`

`nothing`

is provided, it is set by`start_cap()`

to the capacity`stor_cap`

of the node in the first strategic period.Rate increment used in the case of`rate_increment::TimeProfile = FixedProfile(0)`

`DiscreteInvestment`

Storage volume increment used in the case of`stor_increment::TimeProfile = FixedProfile(0)`

`DiscreteInvestment`

Type of handling of the lifetime:`life_mode::LifetimeMode = UnlimitedLife()`

`UnlimitedLife`

,`StudyLife`

,`PeriodLife`

, or`RollingLife`

Duration/lifetime of the technology invested in each period.`lifetime::TimeProfile = FixedProfile(0)`

`EnergyModelsInvestments.Investment`

— TypeInvestment type traits for nodes.

The investment type corresponds to the chosen investment mode.

`EnergyModelsInvestments.InvestmentData`

— TypeAbstract type for the extra data for investing in technologies.

`EnergyModelsInvestments.InvestmentModel`

— TypeA concrete basic investment model type based on the standard `OperationalModel`

as declared in `EnergyModelsBase`

. The concrete basic investment model is similar to an `OperationalModel`

, but allows for investments and additional discounting of future years.

**Fields**

are the emission caps for the different emissions types considered.`emission_limit::Dict{<:ResourceEmit, <:TimeProfile}`

are the prices for the different emissions types considered.`emission_price::Dict{<:ResourceEmit, <:TimeProfile}`

is a`co2_instance`

`ResourceEmit`

and corresponds to the type used for CO₂.is the discount rate in the investment optimization.`r`

`EnergyModelsInvestments.LifetimeMode`

— TypeAbstract lifetime mode type.

`EnergyModelsInvestments.PeriodLife`

— TypeThe investment is considered to last only for the strategic period. The excess lifetime is considered in the rest value. If the lifetime is lower than the length of the period, reinvestment is considered as well.

`EnergyModelsInvestments.RollingLife`

— TypeThe investment is rolling to the next strategic periods and it is retired at the end of its lifetime or the end of the previous strategic period if its lifetime ends between two periods.

`EnergyModelsInvestments.SemiContiInvestment`

— TypeSemi-continuous investment, either zero or between a minimum and a maximum value, involves a binary variable.

`EnergyModelsInvestments.SemiContinuousInvestment`

— TypeSemi-continuous investment where the cost is going through the origin.

`EnergyModelsInvestments.SemiContinuousOffsetInvestment`

— TypeSemi-continuous investment where the cost has an additional offset

`EnergyModelsInvestments.StudyLife`

— TypeThe investment lasts for the whole study period with adequate reinvestments at the end of the lifetime and considering the rest value.

`EnergyModelsInvestments.TransInvData`

— TypeExtra data for investing in transmission.

Define the structure for the additional parameters passed to the technology structures defined in other packages. It uses the macro `Base.@kwdef`

to use keyword arguments and default values. Hence, the name of the parameters have to be specified.

**Fields**

Capital expenditure for the transmission capacity, here investment costs of the transmission in each period.`capex_trans::TimeProfile`

Maximum possible installed transmission capacity in each period.`trans_max_inst::TimeProfile`

Maximum transmission capacity addition in one period from the previous.`trans_max_add::TimeProfile`

Minimum transmission capacity addition in one period from the previous.`trans_min_add::TimeProfile`

Type of the investment:`inv_mode::Investment = ContinuousInvestment()`

`BinaryInvestment`

,`DiscreteInvestment`

,`ContinuousInvestment`

,`SemiContinuousInvestment`

or`FixedInvestment`

.Starting transmission capacity in first period. If nothing is given, it is set by get`trans_start::Union{Real, Nothing} = nothing`

*start*cap() to the capacity`trans_cap`

of the transmission.Transmission capacity increment used in the case of`trans_increment::TimeProfile = FixedProfile(0)`

`DiscreteInvestment`

`EnergyModelsInvestments.UnlimitedLife`

— TypeThe investment's life is not limited. The investment costs do not consider any reinvestment or rest value.

`EnergyModelsBase.constraints_capacity_installed`

— Method`EMB.constraints_capacity_installed(m, n::EMB.Node, 𝒯, modeltype::AbstractInvestmentModel`

Set capacity-related constraints for nodes `𝒩`

for investment time structure `𝒯`

:

- bounds
- binary for BinaryInvestment
- link capacity variables

`EnergyModelsBase.constraints_capacity_installed`

— Method`constraints_capacity_installed(m, n::Storage, 𝒯::TimeStructure, modeltype::AbstractInvestmentModel)`

Set storage-related constraints for nodes `𝒩ˢᵗᵒʳ`

for investment time structure `𝒯`

:

- bounds
- binary for BinaryInvestment
- link storage variables

`EnergyModelsBase.objective`

— Method`EMB.objective(m, 𝒩, 𝒯, modeltype::AbstractInvestmentModel)`

Create objective function overloading the default from EMB for AbstractInvestmentModel.

Maximize Net Present Value from investments (CAPEX) and operations (OPEX and emission costs)

**TODO:**

Consider adding contributions from

- revenue (as positive variable, adding positive)
- maintenance based on usage (as positive variable, adding negative)

These variables would need to be introduced through the package `SparsVariables`

.

Both are not necessary, as it is possible to include them through the OPEX values, but it would be beneficial for a better separation and simpler calculations from the results.

`EnergyModelsBase.variables_capex`

— Method`EMB.variables_capex(m, 𝒩, 𝒯, 𝒫, modeltype::AbstractInvestmentModel)`

Create variables for the capital costs for the invesments in storage and technology nodes.

Additional variables for investment in capacity:

`:capex_cap`

- CAPEX costs for a technology`:cap_invest_b`

- binary variable whether investments in capacity are happening`:cap_remove_b`

- binary variable whether investments in capacity are removed`:cap_current`

- installed capacity for storage in each strategic period`:cap_add`

- added capacity`:cap_rem`

- removed capacity

Additional variables for investment in storage:

`:capex_stor`

- CAPEX costs for increases in the capacity of a storage`:stor_cap_invest_b`

- binary variable whether investments in capacity are happening`:stor_cap_remove_b`

- binary variable whether investments in capacity are removed`:stor_cap_current`

- installed capacity for storage in each strategic period`:stor_cap_add`

- added capacity`:stor_cap_rem`

- removed capacity

`:capex_rate`

- CAPEX costs for increases in the rate of a storage`:stor_rate_invest_b`

- binary variable whether investments in rate are happening`:stor_rate_remove_b`

- binary variable whether investments in rate are removed`:stor_rate_current`

- installed rate for storage in each strategic period`:stor_rate_add`

- added rate`:stor_rate_rem`

- removed rate

`EnergyModelsInvestments.capex`

— Method`capex(n::EMB.Node, t_inv)`

Returns the CAPEX of a node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.capex`

— Method`capex(n::EMB.Node)`

Returns the CAPEX of a node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.capex`

— Method`capex(n::Storage, t_inv)`

Returns the CAPEX of a Storage node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.capex`

— Method`capex(n::Storage)`

Returns the CAPEX of a Storage node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.capex_offset`

— Method`capex_offset(n::Node, t_inv)`

Returns the offset of the CAPEX of node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.check_data`

— Method`check_data(case, modeltype)`

Check if the case data is consistent. Use the @assert*or*log macro when testing. Currently only checking node data.

`EnergyModelsInvestments.check_investment_data`

— Method`check_investment_data(n, 𝒯)`

Performs various checks on investment data:

`min_add`

has to be less than`max_add`

in investments data.- Existing capacity can not be larger than
`max_installed`

capacity in the beginning. - TimeProfiles cannot include
`OperationalProfile`

,`RepresentativeProfile`

, or`ScenarioProfile`

`EnergyModelsInvestments.discount_rate`

— Method`discount_rate(modeltype::AbstractInvestmentModel)`

Returns the discount rate of `EnergyModel`

modeltype

`EnergyModelsInvestments.has_investment`

— Method`has_investment(n::EMB.Node)`

For a given `Node`

, checks that it contains the required investment data.

`EnergyModelsInvestments.increment`

— Method`increment(n::EMB.Node, t_inv)`

Returns the capacity increment of node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.increment`

— Method`increment(n::EMB.Node)`

Returns the capacity increment of node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.increment`

— Method`increment(n::Storage, t_inv)`

Returns the capacity increment of Storage node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.increment`

— Method`increment(n::Storage)`

Returns the capacity increment of Storage node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.investment_data`

— Method`investment_data(type)`

Return the investment data of the type `type`

.

`EnergyModelsInvestments.investment_mode`

— Method`investment_mode(type)`

Return the investment mode of the type `type`

. By default, all investments are continuous.

`EnergyModelsInvestments.lifetime`

— Method`lifetime(type, t)`

Return the lifetime of the type `type`

in period `t`

.

`EnergyModelsInvestments.lifetime`

— Method`lifetime(type)`

Return the lifetime of the type `type`

as `TimeProfile`

.

`EnergyModelsInvestments.lifetime_mode`

— Method`lifetime_mode(type)`

Return the lifetime mode of the type `type`

. By default, all investments are unlimited.

`EnergyModelsInvestments.max_add`

— Method`max_add(n::EMB.Node, t_inv)`

Returns the maximum allowed added capacity of Node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.max_add`

— Method`max_add(n::EMB.Node)`

Returns the maximum allowed added capacity of Node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.max_add`

— Method`max_add(n::Storage, t_inv)`

Returns the maximum allowed added capacity of Storage node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.max_add`

— Method`max_add(n::Storage)`

Returns the maximum allowed added capacity of Storage node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.max_installed`

— Method`max_installed(n::EMB.Node, t_inv)`

Returns the maximum allowed installed capacity of node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.max_installed`

— Method`max_installed(n::EMB.Node)`

Returns the maximum allowed installed capacity of node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.max_installed`

— Method`max_installed(n::Storage, t_inv)`

Returns the maximum allowed installed capacity of `Storage`

node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.max_installed`

— Method`max_installed(n::Storage)`

Returns the maximum allowed installed capacity of `Storage`

node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.min_add`

— Method`min_add(n::EMB.Node, t_inv)`

Returns the minimum allowed added capacity of node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.min_add`

— Method`min_add(n::EMB.Node)`

Returns the minimum allowed added capacity of node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.min_add`

— Method`min_add(n::Storage, t_inv)`

Returns the minimum allowed added capacity of Storage node `n`

in investment period `t_inv`

.

`EnergyModelsInvestments.min_add`

— Method`min_add(n::Storage)`

Returns the minimum allowed added capacity of Storage node `n`

as `TimeProfile`

.

`EnergyModelsInvestments.nodes_investment`

— Method`nodes_investment(𝒩::Vector{<:EMB.Node})`

For a given `Vector{<:Node}`

, return all `Node`

s with investments.

`EnergyModelsInvestments.set_capacity_cost`

— Method`set_capacity_cost(m, n, 𝒯, t_inv, modeltype)`

Set the capex_cost based on the technology investment cost, and strategic period length to include the needs for reinvestments and the rest value. It implements different versions of the lifetime implementation:

- UnlimitedLife: The investment life is not limited. The investment costs do not consider any reinvestment or rest value.
- StudyLife: The investment last for the whole study period with adequate reinvestments at end of lifetime and rest value.
- PeriodLife: The investment is considered to last only for the strategic period. the excess lifetime is considered in the rest value.
- RollingLife: The investment is rolling to the next strategic periods and it is retired at the end of its lifetime or the end of the previous sp if its lifetime ends between two sp.

`EnergyModelsInvestments.set_capacity_installation`

— Method`set_capacity_installation(m, n, 𝒯ᴵⁿᵛ)`

Add constraints related to capacity installation depending on investment mode of node `n`

`EnergyModelsInvestments.set_capex_value`

— Method`set_capex_value(years, lifetime, r)`

Calculate the discounted values used in the lifetime calculations, when the `LifetimeMode`

is given by `PeriodLife`

and `StudyLife`

.

**Arguments**

`years:`

: the remaining years for calculating the discounted value. The years are

depending on the considered `LifetimeMode`

, using `remaining(t_inv, 𝒯)`

for `StudyLife`

and `duration(t_inv)`

for `PeriodLife`

.

`lifetime`

: the lifetime of the node.`r`

: the discount rate.

`EnergyModelsInvestments.set_investment_properties`

— Method`set_investment_properties(n, var)`

Set investment properties for variable `var`

for type `n`

, e.g., set to binary for `BinaryInvestment`

, bounds, etc.

`EnergyModelsInvestments.set_storage_installation`

— Method`set_storage_installation(m, n, 𝒯ᴵⁿᵛ)`

Add constraints related to storage installation depending on investment mode of node `n`

`EnergyModelsInvestments.start_cap`

— Method`start_cap(m, n, t, stcap, modeltype)`

Returns the starting capacity of the node in the first investment period. If no starting capacity is provided in `InvestmentData`

(default = Nothing), then use the provided capacity from the field Cap.