Skip to content

Commit

Permalink
Merge pull request #28 from PALEOtoolkit/split_dae
Browse files Browse the repository at this point in the history
SteadyState.steadystate_ptc_splitdae solver with inner Newton solve for algebraic constraints
  • Loading branch information
sjdaines authored Sep 13, 2022
2 parents 46180f5 + 68c9570 commit 4487d4c
Show file tree
Hide file tree
Showing 8 changed files with 774 additions and 98 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PALEOmodel"
uuid = "bf7b4fbe-ccb1-42c5-83c2-e6e9378b660c"
authors = ["Stuart Daines <[email protected]>"]
version = "0.15.10"
version = "0.15.11"

[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Expand Down
51 changes: 26 additions & 25 deletions docs/src/PALEOmodelSolvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,32 @@ print_sol_stats
calc_output_sol!
```

## Steady-state solvers (Julia [`NLsolve`](https://github.com/JuliaNLSolvers/NLsolve.jl) based)
```@meta
CurrentModule = PALEOmodel.SteadyState
```
```@docs
steadystate
steadystate_ptc
steadystate_ptc_splitdae
```

## Steady-state solvers (Sundials Kinsol based):
```@meta
CurrentModule = PALEOmodel.SteadyStateKinsol
```
```@docs
steadystate_ptc
```
```@meta
CurrentModule = PALEOmodel
```
```@docs
Kinsol
Kinsol.kin_create
Kinsol.kin_solve
```

## Fixed timestep solvers
```@meta
CurrentModule = PALEOmodel.ODEfixed
Expand Down Expand Up @@ -83,31 +109,6 @@ ThreadBarrierAtomic
ThreadBarrierCond
```

## Steady-state solvers (Julia [`NLsolve`](https://github.com/JuliaNLSolvers/NLsolve.jl) based)
```@meta
CurrentModule = PALEOmodel.SteadyState
```
```@docs
steadystate
steadystate_ptc
```

## Steady-state solvers (Sundials Kinsol based):
```@meta
CurrentModule = PALEOmodel.SteadyStateKinsol
```
```@docs
steadystate_ptc
```
```@meta
CurrentModule = PALEOmodel
```
```@docs
Kinsol
Kinsol.kin_create
Kinsol.kin_solve
```

## Variable aggregation
```@meta
CurrentModule = PALEOmodel
Expand Down
7 changes: 4 additions & 3 deletions src/JacobianAD.jl
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ end
####################################################################

"""
jac_transfer_variables(model, modeldata_ad, modeldata) -> (transfer_data_arrays_ad, transfer_data_arrays)
jac_transfer_variables(model, modeldata_ad, modeldata; extra_vars=[]) -> (transfer_data_arrays_ad, transfer_data_arrays)
Build Vectors of data arrays that need to be copied from `modeldata` to `modeldata_ad` before calculating Jacobian.
(looks for Variables with :transfer_jacobian attribute set). Only needed if the Jacobian calculation is optimised
Expand All @@ -333,11 +333,12 @@ The copy needed is then:
d_ad .= d
end
"""
function jac_transfer_variables(model, modeldata_ad, modeldata)
function jac_transfer_variables(model, modeldata_ad, modeldata; extra_vars=[])

# get list of Variables with attribute :transfer_jacobian = true
transfer_vars = []
# get list of Variables with attribute :transfer_jacobian = true
for dom in model.domains
append!(transfer_vars, PB.get_variables(dom, v -> v.name in extra_vars))
append!(transfer_vars, PB.get_variables(dom, v -> PB.get_attribute(v, :transfer_jacobian, false)))
end

Expand Down
27 changes: 21 additions & 6 deletions src/NonLinearNewton.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,62 @@ import LinearAlgebra
solve(
func, jac, u0::AbstractVector;
reltol=1e-5,
miniters=0,
maxiters=100,
verbose=0,
jac_constant::Bool=false,
u_min=-Inf,
) -> (u, Lnorm_2, Lnorm_inf, niter)
Minimal naive Newton solver for nonlinear function `func(u)` with jacobian `jac(u)`, starting at `u0`.
Stopping criteria is `norm(func(u), Inf) < reltol`.
Non-allocating if `u0` and hence `u` and `func(u)` are `StaticArrays.SVector`s.
Set `verbose` to 1, 2, 3 for increasing levels of output.
Set `verbose` to 1, 2, 3, 4 for increasing levels of output.
"""
function solve(
func,
jac,
u0::AbstractVector;
reltol=1e-5,
miniters::Integer=0,
maxiters::Integer=100,
verbose::Integer=0,
jac_constant::Bool=false,
u_min=-Inf,
)

u = copy(u0)
residual = func(u0)
Lnorm_2 = LinearAlgebra.norm(residual, 2)
Lnorm_inf = LinearAlgebra.norm(residual, Inf)
iters = 0
while Lnorm_inf > reltol && iters < maxiters
jacobian = jac(u)
verbose >= 1 && @info "iters $iters Lnorm_2 $Lnorm_2 Lnorm_inf $Lnorm_inf u $u residual $residual"

while (Lnorm_inf > reltol || iters < miniters) && iters < maxiters
if !jac_constant || iters == 0
global jacobian = jac(u)
end
verbose >= 4 && @info "iters $iters jac:" jacobian
u = u - jacobian \ residual
if u_min != -Inf
u = max.(u, u_min)
end
iters += 1
residual = func(u)
Lnorm_2 = LinearAlgebra.norm(residual, 2)
Lnorm_inf = LinearAlgebra.norm(residual, Inf)

verbose >= 2 && @info "iters $iters Lnorm_2 $Lnorm_2 Lnorm_inf $Lnorm_inf"
verbose >= 3 && @info "u $u residual $residual"
verbose >= 3 && @info " u $u residual $residual"
end

iters < maxiters || @warn "maxiters $maxiters reached"
verbose >= 1 && @info "iters $iters Lnorm_2 $Lnorm_2 Lnorm_inf $Lnorm_inf u $u residual $residual"

verbose >= 1 && @info "iters $iters Lnorm_2 $Lnorm_2 Lnorm_inf $Lnorm_inf"
iters < maxiters || throw(ErrorException("NonLinearNewton.solve: maxiters $maxiters reached"))

return (u, Lnorm_2, Lnorm_inf, iters)
end
Expand Down
15 changes: 15 additions & 0 deletions src/ODE.jl
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,21 @@ function calc_output_sol!(outputwriter, model::PB.Model, tsoln, soln, modeldata
return nothing
end

function calc_output_sol!(outputwriter, model::PB.Model, tsoln, soln, modelode, modeldata)

PALEOmodel.OutputWriters.initialize!(outputwriter, model, modeldata, length(tsoln))

# call model to (re)calculate
du = similar(first(soln)) # not used
for i in eachindex(tsoln)
tmodel = tsoln[i]
modelode(du, soln[i], nothing, tmodel)
PALEOmodel.OutputWriters.add_record!(outputwriter, model, modeldata, tmodel)
end

return nothing
end

"""
print_sol_stats(sol::SciMLBase.ODESolution)
print_sol_stats(sol::SciMLBase.DAESolution)
Expand Down
2 changes: 2 additions & 0 deletions src/PALEOmodel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ include("ODELocalIMEX.jl")

include("Kinsol.jl")

include("SplitDAE.jl")

include("SteadyState.jl")

include("SteadyStateKinsol.jl")
Expand Down
Loading

2 comments on commit 4487d4c

@sjdaines
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/68213

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.15.11 -m "<description of version>" 4487d4c5f29bd5b57f2de7292ff605177b4ee233
git push origin v0.15.11

Please sign in to comment.