Skip to content
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

rootfind with p #125

Merged
merged 3 commits into from
Oct 16, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions src/Utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,15 @@ function find_fixpoint(nd, p, initial_guess)
return nl_res.zero
else
println("Failed to find fixpoint. Algorithm did not converge.")
println("Try running nlsolve with other options.")
end
end

export RootRhs

"""
struct RootRhs
RootRhs(of)
RootRhs(nd)

A utility function that provides a root function, to find valid initial
conditions. The operator ``M^\\dagger M - 1`` projects onto the kernel of ``M``.
Expand All @@ -191,32 +192,32 @@ struct RootRhs
rhs
mpm
end
function (rr::RootRhs)(x)
function (rr::RootRhs)(x,p)
Copy link
Member

Choose a reason for hiding this comment

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

hm commit suggestion is gone...

maybe just

function (rr:RootRhs)(x, p=nothing, t=nothing)

to achieve the old behavior? Also might be worth adding an option for t. Maybe nothing would be the better default than 0.0 since it screams a the user in case there is an explicit t dependency.

Bit off topic, but since the rhs and mpm fields are not typed the inner loop of nlsolve will be type unstable. But this might not be a problem in practice as it converges fast for small systems and for large systems the matrix multiply cost might dominate the runtime dispatch cost 🤷‍♂️

f_x = similar(x)
rr.rhs(f_x, x, nothing, 0.0)
rr.mpm * f_x .- f_x
rr.rhs(f_x, x, p, 0.0)
return rr.mpm * f_x .- f_x
end

function RootRhs(of)
mm = of.mass_matrix
function RootRhs(nd)
mm = nd.mass_matrix
@assert mm !== nothing
mpm = pinv(mm) * mm
RootRhs(of.f, mpm)
return RootRhs(nd.f, mpm)
end


export find_valid_ic


"""
find_valid_ic(of, ic_guess)
find_valid_ic(nd, ic_guess)

Try to find valid initial conditions for problems involving mass matrices.
Uses RootRhs as residual function.
"""
function find_valid_ic(of, ic_guess)
rr = RootRhs(of)
nl_res = nlsolve(rr, ic_guess)
function find_valid_ic(nd, initial_guess; p=nothing)
rr = RootRhs(nd)
nl_res = nlsolve(x -> rr(x,p), initial_guess)
if converged(nl_res) == true
return nl_res.zero
else
Expand Down