-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consistent and correct methods for changing the timestep on the fly. #26
Comments
Quoting @fonsp again
|
Following up on @fonsp's discussion, I think it will be fairly common to use baseline emissions that do not have the ramp shape (e.g. we do this in the Belaia et al. DICE+SG example). Would it make more sense to just handle all input timeseries in a |
Yes, that's a good idea! But the problem is: This restriction is fine, (and I can't think of an easy solution that still supports JSON exports), but:
|
But maybe it's okay to drop JSON support. In that case, JSON is great to share models, but the restriction to values and arrays is limiting. I think that this will become a larger issue if we make ClimateMARGO more extensible. Since the package will probably be used in an interactive environment, and never outside of Julia, you might as well share Julia code! You can just send someone the code to set up a model: ClimateModelParameters(Physics(...), Economics(...)) But rather than sending snippets of code, you can send someone an entire notebook, which includes the code to set up the model parameters. I think that it will be common to share MARGO setups using notebooks, rather than JSON-blobs, because you can also include your findings and text. In fact, if you used a JSON-formatted model, then you would need to send 2 files, and make sure that the paths are correct. |
So my suggestion is to drop JSON support, and change the type of time-series parameters from function ramp_emissions(q0::Float64, n::Float64, t1::Float64, t2::Float64)::Function
return function(t)
t0 = t[1]
Δt0 = t1 - t0
Δt1 = t2 - t1
q = zeros(size(t))
increase_idx = (t .<= t1)
decrease_idx = ((t .> t1) .& (t .<= t2))
q[increase_idx] .= q0 * (1. .+ (n-1) .*(t[increase_idx] .- t0)/Δt0)
q[decrease_idx] .= n * q0 * (t2 .- t[decrease_idx])/Δt1
q[t .> t2] .= 0.
return q
end
end |
I understand the idea and it seems appealing, but how would this look in practice? Let's say I want to load in the default MARGO parameters, change the feedback parameter, and re-optimize. Would I just call m = ClimateModelParameters(Physics(...), Economics(...)) and then I can just modify m.Physics.B -= 0.5
optimize_controls!(m) It just seems like this could get messy in many use cases. What if I wanted to load 10 different MARGO configurations from different users and compare them, but their various notebooks have shared / conflicting variable assignments, for example? |
Default parametersI think the defaults should be created using a function inside the ClimateMARGO module. You would use it like: m = ClimateMARGO.default_parameters()
m.Physics.B -= 0.5
... It's good that you mention modifying it - if the default params are a simple variable ( m = ClimateMARGO.ClimateModelParameters()
...
|
I've started a huge overhaul of the code base in #45 (see the corresponding issue #44; please let me know what you think!) and am trying to include some of these ideas there so that we can swap out the I took your advice and set the type of the emissions functions as a julia struct RampingEmissions <: EmissionsParams
func::Function
end in the restructed economics structure mutable struct Economics
emissions::EmissionsParams
growth::GrowthParams
discounting::DiscountingParams
controlcosts::ControlCostParams
damages::DamageParams
end In principle, this means that we should now be able to change the timestep on the fly just like any other parameter since the diagnostics just call the emissions function: emissions(q, M) = q .* (1. .- M)
function emissions(m::ClimateModel; M=false)
return emissions(
m.economics.emissions.func(t(m)),
m.controls.deployed["M"] .* (1. .- .~future_mask(m) * ~M)
)
end |
Quoting @fonsp
I was looking at the new IO functions, I really like the feature of sharing your configuration!
However, I found that the new Economics struct contain baseline_emissions and extra_CO2, which are time series, so they depend on the Domain. This means that:
This also means that the MargoAPI can only use dt=5, but I found that dt=20 has representative results with better performance.
Some ideas:
Storing a time series:
Domain
should be an immutable struct, because changing it will either error, or lead to invisibly false results.Alternatives to storing a time series:
Store the parameters describing these series, so for baseline_emissions, that would be the parameters for ramp_emissions.
(I'm not sure what the plans are for extra_CO2)
but this would limit what you can use for these parameters
Store the function itself. So:
mutable struct Economics
...
baseline_emissions::Function
extra_CO₂::Function
end
The problem now is that JSON2 can't convert Functions. So instead, you could store the string:
mutable struct Economics
...
end
and use eval(Meta.parse(code)) to get a Julia function from the code. But this is obviously quite messy.
Let me know what you think!
For the API, I will just reconstruct these two timeseries from a different dt :)
The text was updated successfully, but these errors were encountered: