-
-
Notifications
You must be signed in to change notification settings - Fork 214
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
Newmark beta method #2187
base: master
Are you sure you want to change the base?
Newmark beta method #2187
Changes from 8 commits
6dbdcd1
8e1a1e3
b3634dc
d7d479e
1380a6c
7b41813
2e65db7
9bb2401
f67ae0c
c2c7db3
68498e9
302903d
b07101b
ff5c291
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
@cache struct NewmarkBetaCache{uType, rateType, parameterType, N} <: OrdinaryDiffEqMutableCache | ||
u::uType # Current solution | ||
uprev::uType # Previous solution | ||
upred::uType # Predictor solution | ||
fsalfirst::rateType | ||
β::parameterType # newmark parameter 1 | ||
γ::parameterType # newmark parameter 2 | ||
nlsolver::N # Inner solver | ||
tmp::uType # temporary, because it is required. | ||
end | ||
|
||
function alg_cache(alg::NewmarkBeta, u, rate_prototype, ::Type{uEltypeNoUnits}, | ||
::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, | ||
dt, reltol, p, calck, | ||
::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} | ||
|
||
β = alg.β | ||
γ = alg.γ | ||
upred = zero(u) | ||
fsalfirst = zero(rate_prototype) | ||
|
||
@assert 0.0 ≤ β ≤ 0.5 | ||
@assert 0.0 ≤ γ ≤ 1.0 | ||
|
||
c = 1.0 | ||
γ̂ = ArrayPartitionNLSolveHelper(1.0,1.0) | ||
nlsolver = build_nlsolver(alg, u.x[1], uprev.x[1], p, t, dt, f.f1, rate_prototype.x[1], uEltypeNoUnits, | ||
uBottomEltypeNoUnits, tTypeNoUnits, γ̂, c, Val(true); tmp = zero(u)) | ||
|
||
tmp = zero(u) | ||
NewmarkBetaCache(u, uprev, upred, fsalfirst, β, γ, nlsolver, tmp) | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -507,6 +507,7 @@ nlsolve_f(f, alg::DAEAlgorithm) = f | |
function nlsolve_f(integrator::ODEIntegrator) | ||
nlsolve_f(integrator.f, unwrap_alg(integrator, true)) | ||
end | ||
nlsolve_f(f::DynamicalODEFunction, alg::NewmarkBeta) = f.f1 # FIXME | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm having a very hard time figuring out whether this seems obviously fine, or an incredibly bad idea. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, as you pointed out on Slack we should switch to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay the reason why I did this was that there is not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, that's weird. we have a |
||
|
||
function (integrator::ODEIntegrator)(t, ::Type{deriv} = Val{0}; | ||
idxs = nothing) where {deriv} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -303,7 +303,7 @@ end | |
# page 54. | ||
γdt = isdae ? α * invγdt : γ * dt | ||
|
||
!(W_γdt ≈ γdt) && (rmul!(dz, 2 / (1 + γdt / W_γdt))) | ||
# !(W_γdt ≈ γdt) && (rmul!(dz, 2 / (1 + γdt / W_γdt))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this random line commented out? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could not get it to work with Newmark, because here we have a comparison between a scalar |
||
relax!(dz, nlsolver, integrator, f) | ||
|
||
calculate_residuals!(atmp, dz, uprev, ustep, opts.abstol, opts.reltol, | ||
|
@@ -356,6 +356,17 @@ function compute_ustep!(ustep, tmp, γ, z, method) | |
ustep | ||
end | ||
|
||
# Dispatch for Newmark-type solvers | ||
function compute_ustep!(ustep::ArrayPartition, tmp::ArrayPartition, γ::ArrayPartitionNLSolveHelper, z, method) | ||
if method === COEFFICIENT_MULTISTEP | ||
# ustep = z | ||
@error "Multistep for second order ODEs does not work yet." | ||
else | ||
@.. ustep = ArrayPartition(tmp.x[1] + γ.γ₁ * z, tmp.x[1] + γ.γ₂ * z) | ||
end | ||
ustep | ||
end | ||
|
||
function _compute_rhs(tmp, γ, α, tstep, invγdt, method::MethodType, p, dt, f, z) | ||
mass_matrix = f.mass_matrix | ||
ustep = compute_ustep(tmp, γ, z, method) | ||
|
@@ -412,6 +423,21 @@ function _compute_rhs!(tmp, ztmp, ustep, γ, α, tstep, k, | |
return _vec(ztmp), ustep | ||
end | ||
|
||
function _compute_rhs!(tmp, ztmp, ustep, γ::ArrayPartitionNLSolveHelper, α, tstep, k, | ||
invγdt, method::MethodType, p, dt, f, z) | ||
mass_matrix = f.mass_matrix | ||
ustep = tmp + γ * z | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why isn't this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need to double check what exactly lead to this change, but I think we do not need this anymore. |
||
f(k, ustep, p, tstep) | ||
if mass_matrix === I | ||
@.. ztmp=(dt * k - z) * invγdt | ||
else | ||
update_coefficients!(mass_matrix, ustep, p, tstep) | ||
mul!(_vec(ztmp), mass_matrix, _vec(z)) | ||
@.. ztmp=(dt * k - ztmp) * invγdt | ||
end | ||
return _vec(ztmp), ustep | ||
end | ||
|
||
function _compute_rhs!(tmp::Array, ztmp::Array, ustep::Array, α, tstep, k, | ||
invγdt, p, uprev, f::TF, z) where {TF<:DAEFunction} | ||
@inbounds @simd ivdep for i in eachindex(z) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,11 +89,11 @@ end | |
|
||
abstract type AbstractNLSolver{algType, iip} end | ||
|
||
mutable struct NLSolver{algType, iip, uType, gamType, tmpType, tType, | ||
mutable struct NLSolver{algType, iip, uType, gamType, tmpType, tmp2Type, tType, | ||
C <: AbstractNLSolverCache} <: AbstractNLSolver{algType, iip} | ||
z::uType | ||
tmp::uType # DIRK and multistep methods only use tmp | ||
tmp2::tmpType # for GLM if neccssary | ||
tmp::tmpType # DIRK and multistep methods only use tmp | ||
tmp2::tmp2Type # for GLM if neccssary | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you're going to do this, I think it's probably worth refactoring to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should go into a different PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed |
||
ztmp::uType | ||
γ::gamType | ||
c::tType | ||
|
@@ -114,7 +114,7 @@ end | |
function NLSolver{iip, tType}(z, tmp, ztmp, γ, c, α, alg, κ, fast_convergence_cutoff, ηold, | ||
iter, maxiters, status, cache, method = DIRK, tmp2 = nothing, | ||
nfails::Int = 0) where {iip, tType} | ||
NLSolver{typeof(alg), iip, typeof(z), typeof(γ), typeof(tmp2), tType, typeof(cache)}(z, | ||
NLSolver{typeof(alg), iip, typeof(z), typeof(γ), typeof(tmp), typeof(tmp2), tType, typeof(cache)}(z, | ||
tmp, | ||
tmp2, | ||
ztmp, | ||
|
@@ -157,7 +157,7 @@ mutable struct NLNewtonCache{ | |
firststage::Bool | ||
firstcall::Bool | ||
W_γdt::tType | ||
du1::uType | ||
du1::rateType | ||
oscardssmith marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uf::ufType | ||
jac_config::jcType | ||
linsolve::lsType | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -42,6 +42,7 @@ get_new_W!(::AbstractNLSolverCache)::Bool = true | |||||
get_W(nlsolver::AbstractNLSolver) = get_W(nlsolver.cache) | ||||||
get_W(nlcache::Union{NLNewtonCache, NLNewtonConstantCache}) = nlcache.W | ||||||
|
||||||
set_W_γdt!(nlsolver::AbstractNLSolver, W_γdt::ArrayPartitionNLSolveHelper) = set_W_γdt!(nlsolver, W_γdt.γ₁ + W_γdt.γ₂) | ||||||
set_W_γdt!(nlsolver::AbstractNLSolver, W_γdt) = set_W_γdt!(nlsolver.cache, W_γdt) | ||||||
function set_W_γdt!(nlcache::Union{NLNewtonCache, NLNewtonConstantCache}, W_γdt) | ||||||
nlcache.W_γdt = W_γdt | ||||||
|
@@ -132,27 +133,27 @@ function build_nlsolver(alg, u, uprev, p, t, dt, f::F, rate_prototype, | |||||
::Type{uEltypeNoUnits}, | ||||||
::Type{uBottomEltypeNoUnits}, | ||||||
::Type{tTypeNoUnits}, γ, c, | ||||||
iip) where {F, uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} | ||||||
iip; tmp = zero(u)) where {F, uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} | ||||||
build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, | ||||||
uBottomEltypeNoUnits, | ||||||
tTypeNoUnits, γ, c, 1, iip) | ||||||
tTypeNoUnits, γ, c, 1, iip; tmp=tmp) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
end | ||||||
|
||||||
function build_nlsolver(alg, u, uprev, p, t, dt, f::F, rate_prototype, | ||||||
::Type{uEltypeNoUnits}, | ||||||
::Type{uBottomEltypeNoUnits}, | ||||||
::Type{tTypeNoUnits}, γ, c, α, | ||||||
iip) where {F, uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} | ||||||
iip; tmp = zero(u)) where {F, uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} | ||||||
build_nlsolver(alg, alg.nlsolve, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, | ||||||
uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, iip) | ||||||
uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, iip; tmp=tmp) | ||||||
end | ||||||
|
||||||
function build_nlsolver(alg, nlalg::Union{NLFunctional, NLAnderson, NLNewton, NonlinearSolveAlg}, | ||||||
u, uprev, p, t, dt, | ||||||
f::F, rate_prototype, ::Type{uEltypeNoUnits}, | ||||||
::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, | ||||||
γ, c, α, | ||||||
::Val{true}) where {F, uEltypeNoUnits, uBottomEltypeNoUnits, | ||||||
::Val{true}; tmp = zero(u)) where {F, uEltypeNoUnits, uBottomEltypeNoUnits, | ||||||
tTypeNoUnits} | ||||||
#TODO | ||||||
#nlalg = DiffEqBase.handle_defaults(alg, nlalg) | ||||||
|
@@ -162,7 +163,6 @@ function build_nlsolver(alg, nlalg::Union{NLFunctional, NLAnderson, NLNewton, No | |||||
|
||||||
# define fields of non-linear solver | ||||||
z = zero(u) | ||||||
tmp = zero(u) | ||||||
ztmp = zero(u) | ||||||
|
||||||
# build cache of non-linear solver | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the coefficients are part of the algorithm, can you calculate the order here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar to FBDF, you can just set this to 1 I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking a look Hendrik! Yes, I could compute them here. I will fix such stuff after I get a pendulum example working. I just opened the PR to discuss the progress and possibly better design choices for the new class of solvers.