Skip to content

Commit

Permalink
Merge pull request #100 from fund-model/puls
Browse files Browse the repository at this point in the history
Add pulse size docs
  • Loading branch information
lrennels authored Jun 15, 2021
2 parents 2584ece + 8b6e822 commit 33d0f32
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 31 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,17 @@ result.mm # returns the Mimi MarginalModel
marginal_temp = result.mm[:climatedynamics, :temp] # marginal results from the marginal model can be accessed like this
```

### Pulse Size Details

By default, MimiFUND will calculate the SC using a marginal emissions pulse of 10 GtCO2 spread over ten years, or 1 GtCO2 (or Gt other gas) per year for ten years. The SC will be always be returned in units of dollars per ton because it is normalized by the pulse size. This choice of pulse size and duration is a decision made based on experiments with stability of results and moving from continuous to discretized equations, and can be found described further in the literature around FUND.

If you wish to alter this pulse size, it is an optional keyword argument to the `compute_sc` function where `pulse_size` controls the size of the marginal emission pulse. For a deeper dive into the machinery of this function, see the forum conversation [here](https://forum.mimiframework.org/t/mimifund-emissions-pulse/153/9) and the docstrings in `new_marginaldamage.jl`.

## Versions and academic use policy

Released versions of FUND have a git tag in this repository *and* the ``master`` branch either points to that version, or a newer version. In general we increase at least the minor part of the version (the versions follow the ``major.minor.patch`` pattern) whenever we change any of the equations or calibrations. All versions with a git tag that is at least as new as the git tag that ``master`` points to have been used in at least one publication and we welcome if other researchers use those versions for their own work and in their publications.

The ``master`` branch in this repository always points to the latest released versions, i.e. it will always point to a version that has a git tag and is released.

The ``next`` branch (and any git tags that are newer than the git tag that ``master`` points to) contains work in progress. In general you should not assume that the ``next`` branch is ready for use for anything. It often is in an intermediate state between released versions, where we have started changes that are not finished etc. While the code on the ``next`` branch is technically licensed under the MIT license, we kindly ask other researchers to not publish papers based on versions that they can see in the ``next`` branch. The versions in that branch represent ongoing work by us that we haven't gotten academic credit for because we have not yet published something with these versions, and we therefore ask other researchers to not use those versions on their own. You can of course always approach us about joint work when it comes to the version on the ``next`` branch and then we can discuss how we handle that.

96 changes: 65 additions & 31 deletions src/new_marginaldamages.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Mimi.compinstance

"""
compute_scc(m::Model=get_model(); year::Int = nothing, gas::Symbol = :CO2, last_year::Int = 3000, equity_weights::Bool = false, eta::Float64 = 1.45, prtp::Float64 = 0.015, equity_weights_normalization_region::Int=0)
compute_scc(m::Model=get_model(); year::Union{Int, Nothing} = nothing,
gas::Symbol = :CO2, last_year::Int = 3000, equity_weights::Bool = false,
eta::Float64 = 1.45, prtp::Float64 = 0.015, equity_weights_normalization_region::Int=0)
Deprecated function for calculating the social cost of carbon for a MimiFUND model. Use `compute_sc` or gas-specific functions `compute_scco2`, `compute_scch4`, `compute_scn2o`, or `compute_scsf6` instead.
"""
Expand All @@ -12,23 +14,28 @@ function compute_scc(m::Model=get_model(); year::Union{Int, Nothing} = nothing,
end

"""
compute_scco2(m::Model=get_model();
compute_scco2(
m::Model=get_model();
year::Union{Int, Nothing} = nothing,
eta::Float64 = 1.45,
prtp::Float64 = 0.015,
equity_weights::Bool = false,
equity_weights_normalization_region::Int = 0,
equity_weights_normalization_region::Int=0,
last_year::Int = 3000,
pulse_size::Float64 = 1e7,
return_mm::Bool = false,
n::Union{Int, Nothing} = nothing,
trials_output_filename::Union{String, Nothing} = nothing,
pulse_size::Float64 = 1e7)
return_mm::Bool = false,
n::Union{Int, Nothing} = nothing,
trials_output_filename::Union{String, Nothing} = nothing,
seed::Union{Int, Nothing} = nothing)
Returns the Social Cost of CO2 for the specified `year` for the provided MimiFUND model `m`.
If no model is provided, the default model from MimiFUND.get_model() is used.
Units of the returned value are 1995\$ per metric tonne of CO2.
The size of the marginal emission pulse can be modified with the `pulse_size` keyword argument, in metric
tonnes of the specified gas (this does not change the units of the returned value, which is always normalized
by the `pulse_size` used).
This is a wrapper function that calls the generic social cost function `compute_sc(m, gas = :CO2, args...)`. See docstring for
`compute_sc` for a full description of the available keyword arguments.
"""
Expand All @@ -46,18 +53,22 @@ end
eta::Float64 = 1.45,
prtp::Float64 = 0.015,
equity_weights::Bool = false,
equity_weights_normalization_region::Int=0,
last_year::Int = 3000,
pulse_size::Float64 = 1e7,
return_mm::Bool = false,
n::Union{Int, Nothing} = nothing,
trials_output_filename::Union{String, Nothing} = nothing,
seed::Union{Int, Nothing} = nothing)
pulse_size::Float64 = 1e7) ,
return_mm::Bool = false,
n::Union{Int, Nothing} = nothing,
trials_output_filename::Union{String, Nothing} = nothing,
seed::Union{Int, Nothing} = nothing,
equity_weights_normalization_region::Int=0)
Returns the Social Cost of CH4 for the specified `year` for the provided MimiFUND model `m`.
If no model is provided, the default model from MimiFUND.get_model() is used.
Units of the returned value are 1995\$ per metric tonne of CH4.
The size of the marginal emission pulse can be modified with the `pulse_size` keyword argument, in metric
tonnes of the specified gas (this does not change the units of the returned value, which is always normalized
by the `pulse_size` used).
This is a wrapper function that calls the generic social cost function `compute_sc(m, gas = :CH4, args...)`. See docstring for
`compute_sc` for a full description of the available keyword arguments.
"""
Expand All @@ -70,23 +81,27 @@ function compute_scch4(m::Model=get_model(); year::Union{Int, Nothing} = nothing
end

"""
compute_scn2o(m::Model=get_model();
compute_scn2o(
m::Model=get_model();
year::Union{Int, Nothing} = nothing,
eta::Float64 = 1.45,
prtp::Float64 = 0.015,
eta::Float64 = 1.45, prtp::Float64 = 0.015,
equity_weights::Bool = false,
equity_weights_normalization_region::Int = 0,
last_year::Int = 3000,
pulse_size::Float64 = 1e7,
return_mm::Bool = false,
n::Union{Int, Nothing} = nothing,
trials_output_filename::Union{String, Nothing} = nothing,
seed::Union{Int, Nothing} = nothing)
return_mm::Bool = false,
n::Union{Int, Nothing} = nothing,
trials_output_filename::Union{String, Nothing} = nothing,
seed::Union{Int, Nothing} = nothing,
equity_weights_normalization_region::Int=0)
Returns the Social Cost of N2O for the specified `year` for the provided MimiFUND model `m`.
If no model is provided, the default model from MimiFUND.get_model() is used.
Units of the returned value are 1995\$ per metric tonne of N2O.
The size of the marginal emission pulse can be modified with the `pulse_size` keyword argument, in metric
tonnes of the specified gas (this does not change the units of the returned value, which is always normalized
by the `pulse_size` used).
This is a wrapper function that calls the generic social cost function `compute_sc(m, gas = :N2O, args...)`. See docstring for
`compute_sc` for a full description of the available keyword arguments.
"""
Expand All @@ -99,23 +114,28 @@ function compute_scn2o(m::Model=get_model(); year::Union{Int, Nothing} = nothing
end

"""
compute_scsf6(m::Model=get_model();
compute_scsf6(
m::Model=get_model();
year::Union{Int, Nothing} = nothing,
eta::Float64 = 1.45,
prtp::Float64 = 0.015,
equity_weights::Bool = false,
equity_weights_normalization_region::Int = 0,
last_year::Int = 3000,
pulse_size::Float64 = 1e7,
return_mm::Bool = false,
n::Union{Int, Nothing} = nothing,
trials_output_filename::Union{String, Nothing} = nothing,
seed::Union{Int, Nothing} = nothing)
return_mm::Bool = false,
n::Union{Int, Nothing} = nothing,
trials_output_filename::Union{String, Nothing} = nothing,
seed::Union{Int, Nothing} = nothing,
equity_weights_normalization_region::Int=0)
Returns the Social Cost of SF6 for the specified `year` for the provided MimiFUND model `m`.
If no model is provided, the default model from MimiFUND.get_model() is used.
Units of the returned value are 1995\$ per metric tonne of SF6.
The size of the marginal emission pulse can be modified with the `pulse_size` keyword argument, in metric
tonnes of the specified gas (this does not change the units of the returned value, which is always normalized
by the `pulse_size` used).
This is a wrapper function that calls the generic social cost function `compute_sc(m, gas = :SF6, args...)`. See docstring for
`compute_sc` for a full description of the available keyword arguments.
"""
Expand Down Expand Up @@ -185,6 +205,8 @@ function compute_sc(m::Model=get_model();
!(last_year in 1950:3000) ? error("Invlaid value for `last_year`: $last_year. `last_year` must be within the model's time index 1950:3000.") : nothing
!(year in 1950:last_year) ? error("Invalid value for `year`: $year. `year` must be within the model's time index 1950:$last_year.") : nothing

# note use of `pulse_size` as the `delta` in the creation of a marginal model,
# which allows for normalization to $ per ton
mm = get_marginal_model(m; year = year, gas = gas, pulse_size = pulse_size)

ntimesteps = getindexfromyear(last_year)
Expand Down Expand Up @@ -255,19 +277,23 @@ end
Creates a Mimi MarginalModel where the provided m is the base model, and the marginal model has additional emissions of gas `gas` in year `year`.
If no year is provided, the marginal emissions component will be added without an additional pulse.
If no Model m is provided, the default model from MimiFUND.get_model() is used as the base model.
The size of the marginal emission pulse can be modified with the `pulse_size` keyword argument, in metric tonnes.
The size of the marginal emission pulse can be modified with the `pulse_size` keyword argument,
in metric tonnes (this does not change the units of the returned value, which is always normalized
by the `pulse_size` used).
"""
function get_marginal_model(m::Model = get_model(); gas::Symbol = :CO2, year::Union{Int, Nothing} = nothing, pulse_size::Float64 = 1e7)
year !== nothing && !(year in 1950:3000) ? error("Cannot add marginal emissions in $year, year must be within the model's time index 1950:3000.") : nothing

# note use of `pulse_size` as the `delta` in the creation of a marginal model,
# which allows for normalization to $ per ton
mm = create_marginal_model(m, pulse_size)
add_marginal_emissions!(mm.modified, year; gas = gas, pulse_size = pulse_size)

return mm
end

# A component for an emissions pulse to be used in social cost calculations. Computes the `output` vector by adding
# `add` to `input`. This is similar to the Mimi.adder component, except that it allows missing values to be passed through.
# add` to `input`. This is similar to the Mimi.adder component, except that it allows missing values to be passed through.
@defcomp emissionspulse begin
add = Parameter(index=[time])
input = Parameter(index=[time])
Expand All @@ -280,7 +306,9 @@ end

"""
Adds an emissionspulse component to `m`, and sets the additional emissions if a year is specified.
The size of the marginal emission pulse can be modified with the `pulse_size` keyword argument, in metric tonnes.
The size of the marginal emission pulse can be modified with the `pulse_size` keyword argument, in metric
tonnes of the specified gas (this does not change the units of the returned value, which is always normalized
by the `pulse_size` used).
"""
function add_marginal_emissions!(m, year::Union{Int, Nothing} = nothing; gas::Symbol = :CO2, pulse_size::Float64 = 1e7)

Expand All @@ -289,7 +317,10 @@ function add_marginal_emissions!(m, year::Union{Int, Nothing} = nothing; gas::Sy
nyears = length(Mimi.time_labels(m))
addem = zeros(nyears)
if year != nothing
# pulse is spread over ten years, and emissions components is in Mt so divide by 1e7, and convert from CO2 to C if gas==:CO2 because emissions component is in MtC
# pulse is spread over ten years, and emissions components is in Mt so
# divide by 1e7, and convert from CO2 to C if gas==:CO2 because emissions
# component is in MtC; also use 12/44 to convert from GtCO2 to GtC for CO2 since the
# emissions component expects GtC not GtCO2 but pulse is in CO2
addem[getindexfromyear(year):getindexfromyear(year) + 9] .= pulse_size / 1e7 * (gas == :CO2 ? 12/44 : 1)
end
set_param!(m, :emissionspulse, :add, addem)
Expand Down Expand Up @@ -336,6 +367,9 @@ function getmarginaldamages(; year=2020, parameters = nothing, gas = :CO2, pulse

# Get marginal model
m = get_model(params = parameters)

# note use of `pulse_size` as the `delta` in the creation of a marginal model,
# which allows for normalization to $ per ton
mm = get_marginal_model(m, year = year, gas = gas, pulse_size = pulse_size)
run(mm)

Expand Down

0 comments on commit 33d0f32

Please sign in to comment.