Skip to content
Snippets Groups Projects
Commit b1002b95 authored by Brian Groenke's avatar Brian Groenke
Browse files

Fix CGEuler not respecting dtmax and dtmin

parent 4b65f405
No related branches found
No related tags found
No related merge requests found
name = "CryoGrid" name = "CryoGrid"
uuid = "a535b82e-5f3d-4d97-8b0b-d6483f5bebd5" uuid = "a535b82e-5f3d-4d97-8b0b-d6483f5bebd5"
authors = ["Brian Groenke <brian.groenke@awi.de>", "Jan Nitzbon <jan.nitzbon@awi.de>", "Moritz Langer <moritz.langer@awi.de>"] authors = ["Brian Groenke <brian.groenke@awi.de>", "Jan Nitzbon <jan.nitzbon@awi.de>", "Moritz Langer <moritz.langer@awi.de>"]
version = "0.23.1" version = "0.23.2"
[deps] [deps]
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
......
...@@ -38,7 +38,7 @@ tile = Tile(strat, modelgrid, forcings, ssinit); ...@@ -38,7 +38,7 @@ tile = Tile(strat, modelgrid, forcings, ssinit);
tspan = (DateTime(2000,10,1), DateTime(2002,10,1)) tspan = (DateTime(2000,10,1), DateTime(2002,10,1))
u0, du0 = initialcondition!(tile, tspan); u0, du0 = initialcondition!(tile, tspan);
prob = CryoGridProblem(tile, u0, tspan, saveat=24*3600, savevars=(:T,:θw,:∂H∂T), step_limiter=nothing) prob = CryoGridProblem(tile, u0, tspan, saveat=24*3600, savevars=(:T,:θw,:∂H∂T), step_limiter=nothing)
integrator = init(prob, ImplicitEuler(autodiff=false)) integrator = init(prob, ImplicitEuler())
# test one step # test one step
@time step!(integrator) @time step!(integrator)
last_t = integrator.t last_t = integrator.t
......
...@@ -22,7 +22,16 @@ struct LiteImplicitEulerCache{Tu,TA} <: SciMLBase.DECache ...@@ -22,7 +22,16 @@ struct LiteImplicitEulerCache{Tu,TA} <: SciMLBase.DECache
D::TA D::TA
end end
function DiffEqBase.__init(prob::CryoGridProblem, alg::LiteImplicitEuler, args...; dt=24*3600.0, saveat=dt, kwargs...) function DiffEqBase.__init(
prob::CryoGridProblem,
alg::LiteImplicitEuler,
args...;
dt=24*3600.0,
dtmax=dt,
dtmin=1.0,
saveat=dt,
kwargs...
)
tile = Tile(prob.f) tile = Tile(prob.f)
grid = tile.grid grid = tile.grid
u0 = copy(prob.u0) u0 = copy(prob.u0)
...@@ -54,6 +63,6 @@ function DiffEqBase.__init(prob::CryoGridProblem, alg::LiteImplicitEuler, args.. ...@@ -54,6 +63,6 @@ function DiffEqBase.__init(prob::CryoGridProblem, alg::LiteImplicitEuler, args..
similar(u0, eltype(u0), length(prob.u0.H)), similar(u0, eltype(u0), length(prob.u0.H)),
) )
p = isnothing(prob.p) ? prob.p : collect(prob.p) p = isnothing(prob.p) ? prob.p : collect(prob.p)
opts = CryoGridIntegratorOptions(; dtmax=dt, saveat=CryoGrid.expandtstep(saveat, prob.tspan), kwargs...) opts = CryoGridIntegratorOptions(; saveat=CryoGrid.expandtstep(saveat, prob.tspan), dtmax, dtmin, kwargs...)
return CryoGridIntegrator(alg, cache, opts, sol, copy(u0), p, t0, convert(eltype(prob.tspan), dt), 1, 1) return CryoGridIntegrator(alg, cache, opts, sol, copy(u0), p, t0, convert(eltype(prob.tspan), dt), 1, 1)
end end
...@@ -74,6 +74,6 @@ function perform_step!(integrator::CryoGridIntegrator{CGEuler}) ...@@ -74,6 +74,6 @@ function perform_step!(integrator::CryoGridIntegrator{CGEuler})
# set next dt # set next dt
# compute maximum timestep # compute maximum timestep
dtmax = CryoGrid.timestep(tile, du, u, p, t₀) dtmax = CryoGrid.timestep(tile, du, u, p, t₀)
integrator.dt = dtmax integrator.dt = max(min(dtmax, integrator.opts.dtmax), integrator.opts.dtmin)
return nothing return nothing
end end
...@@ -52,7 +52,7 @@ function DiffEqBase.sensitivity_solution(sol::CryoGridSolution, u, t) ...@@ -52,7 +52,7 @@ function DiffEqBase.sensitivity_solution(sol::CryoGridSolution, u, t)
end end
Base.@kwdef mutable struct CryoGridIntegratorOptions{Tt,Tsaveat,Ttstops} Base.@kwdef mutable struct CryoGridIntegratorOptions{Tt,Tsaveat,Ttstops}
dtmax::Tt = 24*3600.0 dtmax::Tt = 3600.0
dtmin::Tt = one(typeof(dtmax)) dtmin::Tt = one(typeof(dtmax))
saveat::Tsaveat = typeof(dtmax)[] saveat::Tsaveat = typeof(dtmax)[]
tstops::Ttstops = SortedSet{typeof(dtmin)}() tstops::Ttstops = SortedSet{typeof(dtmin)}()
......
...@@ -47,7 +47,8 @@ Constructor for `CryoGridProblem` that automatically generates all necessary cal ...@@ -47,7 +47,8 @@ Constructor for `CryoGridProblem` that automatically generates all necessary cal
function CryoGridProblem( function CryoGridProblem(
tile::Tile, tile::Tile,
u0::ComponentVector, u0::ComponentVector,
tspan::NTuple{2,Float64}; tspan::NTuple{2,Float64},
p::Union{Nothing,AbstractVector}=nothing;
diagnostic_stepsize=3600.0, diagnostic_stepsize=3600.0,
saveat=3600.0, saveat=3600.0,
savevars=(), savevars=(),
...@@ -68,7 +69,7 @@ function CryoGridProblem( ...@@ -68,7 +69,7 @@ function CryoGridProblem(
# strip all "fixed" parameters # strip all "fixed" parameters
tile = stripparams(FixedParam, tile) tile = stripparams(FixedParam, tile)
# retrieve variable parameters # retrieve variable parameters
p = length(ModelParameters.params(tile)) > 0 ? parameters(tile) : nothing tilepara = length(ModelParameters.params(tile)) > 0 ? parameters(tile) : nothing
du0 = zero(u0) du0 = zero(u0)
# remove units # remove units
tile = stripunits(tile) tile = stripunits(tile)
...@@ -95,6 +96,8 @@ function CryoGridProblem( ...@@ -95,6 +96,8 @@ function CryoGridProblem(
tile.data.outputs = savevals tile.data.outputs = savevals
# build mass matrix # build mass matrix
mass_matrix = Numerics.build_mass_matrix(tile.state) mass_matrix = Numerics.build_mass_matrix(tile.state)
# get params
p = isnothing(p) && !isnothing(tilepara) ? ustrip.(vec(tilepara)) : p
func = odefunction(tile, u0, p, tspan; mass_matrix, specialization, function_kwargs...) func = odefunction(tile, u0, p, tspan; mass_matrix, specialization, function_kwargs...)
return CryoGridProblem{true}(func, u0, tspan, p, callbacks, saveat, getsavestate, isoutofdomain, prob_kwargs) return CryoGridProblem{true}(func, u0, tspan, p, callbacks, saveat, getsavestate, isoutofdomain, prob_kwargs)
end end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment