Skip to content

Implemented QDEIM and ODEIM algorithms #88

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

smallpondtom
Copy link

Checklist

  • Appropriate tests were added
  • Any code changes were done in a way that does not break public API
  • All documentation related to code changes were updated
  • The new code follows the
    contributor guidelines, in particular the SciML Style Guide and
    COLPRAC.
  • Any new documentation only uses public API

Additional context

I implemented the QDEIM algorithm (Drmac and Gugercin, 2016) and ODEIM algorithm (Peherstorfer, Drmac, and Gugercin, 2020). I used the FHN model to verify my results which you can reproduce with the following code:

using ModelingToolkit, MethodOfLines, DifferentialEquations, ModelOrderReduction
using CairoMakie

## firstly construct a ModelingToolkit.PDESystem for the FitzHugh-Nagumo model
@variables x t v(..) w(..)
Dx = Differential(x)
Dxx = Dx^2
Dt = Differential(t)
const L = 1.0
const ε = 0.015
const b = 0.5
const γ = 2.0
const c = 0.05
f(v) = v * (v - 0.1) * (1.0 - v)
i₀(t) = 50000.0t^3 * exp(-15.0t)
eqs = [ε * Dt(v(x, t)) ~ ε^2 * Dxx(v(x, t)) + f(v(x, t)) - w(x, t) + c,
    Dt(w(x, t)) ~ b * v(x, t) - γ * w(x, t) + c]
bcs = [v(x, 0.0) ~ 0.0, w(x, 0) ~ 0.0, Dx(v(0, t)) ~ -i₀(t), Dx(v(L, t)) ~ 0.0]
domains = [x ∈ (0.0, L), t ∈ (0.0, 14.0)]
ivs = [x, t]
dvs = [v(x, t), w(x, t)]
pde_sys = PDESystem(eqs, bcs, domains, ivs, dvs; name = Symbol("FitzHugh-Nagumo"))

## transfer to a ModelingToolkit.ODESystem by automated discretization via MethodOfLines
N = 15 # equidistant discretization intervals
dx = (L - 0.0) / N
dxs = [x => dx]
discretization = MOLFiniteDifference(dxs, t)
ode_sys, tspan = symbolic_discretize(pde_sys, discretization)
simp_sys = structural_simplify(ode_sys)
ode_prob = ODEProblem(simp_sys, nothing, tspan)

## solve the full-order model to get snapshots
sol = solve(ode_prob, Tsit5())
snapshot_simpsys = Array(sol.original_sol)

## set POD and DEIM dimensions
# apply POD-DEIM to obtain the reduced-order model
pod_dim = deim_dim = 5
deim_sys = deim(simp_sys, snapshot_simpsys, pod_dim; deim_dim = deim_dim, interpolation_algo=:deim)
deim_prob = ODEProblem(deim_sys, nothing, tspan)
deim_sol = solve(deim_prob, Tsit5())

## retrieve the approximate solution of the original full-order model
sol_deim_x = deim_sol[x]
sol_deim_v = deim_sol[v(x, t)]
sol_deim_w = deim_sol[w(x, t)]

## apply POD-QDEIM to obtain the reduced-order model
deim_sys = deim(simp_sys, snapshot_simpsys, pod_dim; deim_dim = deim_dim, interpolation_algo=:qdeim)
deim_prob = ODEProblem(deim_sys, nothing, tspan)
deim_sol = solve(deim_prob, Tsit5())

## retrieve the approximate solution of the original full-order model
sol_qdeim_x = deim_sol[x]
sol_qdeim_v = deim_sol[v(x, t)]
sol_qdeim_w = deim_sol[w(x, t)]

## apply POD-ODEIM to obtain the reduced-order model
deim_sys = deim(simp_sys, snapshot_simpsys, pod_dim; deim_dim = deim_dim, interpolation_algo=:odeim, odeim_dim=8)
deim_prob = ODEProblem(deim_sys, nothing, tspan)
deim_sol = solve(deim_prob, Tsit5())

## retrieve the approximate solution of the original full-order model
sol_odeim_x = deim_sol[x]
sol_odeim_v = deim_sol[v(x, t)]
sol_odeim_w = deim_sol[w(x, t)]

## Plot
with_theme(theme_latexfonts()) do
    fig = Figure()
    ax = Axis3(fig[1, 1], xlabel="x", ylabel="v(x,t)", zlabel="w(x,t)", 
               title="FHN model comparison of full and reduced systems",
               xlabelsize=16, ylabelsize=16, zlabelsize=16)
    scatter!(ax, sol[x], sol[v(x, t)], sol[w(x, t)], label="Full32", markersize=8)
    scatter!(ax, sol_deim_x, sol_deim_v, sol_deim_w, label="POD5-DEIM5", markersize=8)
    scatter!(ax, sol_qdeim_x, sol_qdeim_v, sol_qdeim_w, label="POD5-QDEIM5", markersize=6)
    scatter!(ax, sol_odeim_x, sol_odeim_v, sol_odeim_w, label="POD5-ODEIM8", markersize=5)
    axislegend(ax, position=:rt, nbanks=2)
    display(fig)
end

The final results will look as follows:
download

Testing issue:
The test file test/deim.jl seems to fail due to something within the package itself that I couldn't quite identify. But, I did verify that the new algorithms are bug-free. Please let me know if you need further information before merging this PR!

@ChrisRackauckas ChrisRackauckas requested a review from bowenszhu June 5, 2024 04:59
@bowenszhu
Copy link
Member

Thank you! I will review this after I complete

@smallpondtom
Copy link
Author

@bowenszhu Any updates on this?

@bowenszhu
Copy link
Member

Apologies for the delay. I haven't forgotten about this PR, and I'll take a look as soon as I can.

@smallpondtom
Copy link
Author

Gotcha. No worries. Thanks for the response

@smallpondtom
Copy link
Author

Hi @bowenszhu! It's been a while but I happened to remember I made this pull request. Would it be possible to merge it? Thanks!

@bowenszhu bowenszhu closed this Mar 4, 2025
@bowenszhu bowenszhu reopened this Mar 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants