8000 [WIP] Better staggered implementation by cmhyett · Pull Request #285 · SciML/MethodOfLines.jl · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

[WIP] Better staggered implementation #285

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

Merged
merged 39 commits into from
Nov 28, 2023

Conversation

cmhyett
Copy link
Contributor
@cmhyett cmhyett commented Jun 21, 2023

Working to solve #255. Previous work found a way to perform time staggering - now we want to perform space staggering as well. The first thing I did was encapsulate functionality to more easily identify component parts (and perhaps overwrite them if need be).

Currently, Iaxies & Igrid members of DiscreteSpace are not utilized (at least as best as I can tell), but hold the potential to provide for a mapping between independent and dependent grids.

By default, it's a bijective map, but in general it doesn't need to be. However, since they aren't currently used, it'll take a bit of work to identify correct locations to use them instead of the dependent variable axies & grids. As a basic example, suppose we have u(x,t) => u[1](t) = u(x[1],t), u[2](t) = u(x[3],t), u[3](t) = u(x[5],t) and v(x,t) => v[1](t) = v(x[2],t), v[2](t) = v(x[4],t), v[3](t) = v(x[6],t), and using centered in space finite differences to update ~ du[2] = (v[2] - v[1])/(2*dx) notice that this is actually second-order centered because of the staggering.

This would change the differential operator based on the grid type.....may or may not be viable.

@xtalax @ChrisRackauckas, let me know if you forsee issues here.

@cmhyett cmhyett changed the title Better staggered implementation [WIP] Better staggered implementation Jun 21, 2023
@cmhyett
Copy link
Contributor Author
cmhyett commented Jun 22, 2023

Having thought about it overnight, I think doing a simple variable transformation as described in the attached image achieves the same effect, with the benefit of having an explicit mapping between the variables.

Still open to utilization of Igrid and Iaxies (should be equivalent, but unsure of side-effects), if @xtalax has ideas.

This is particularly nice because I only have to map the second-order space discrete differential to the first order forward space differential.

unnamed

cmhyett added 2 commits June 22, 2023 11:03
…retize, but this shouldn't be necessary in general) to get spatial staggering working. very close now, just need to tease out the details of the discretized differential operators now.
@codecov
Copy link
codecov bot commented Jun 28, 2023

Codecov Report

Attention: 156 lines in your changes are missing coverage. Please review.

Comparison is base (a04e094) 83.02% compared to head (0694c0d) 79.62%.

Files Patch % Lines
...schemes/centered_difference/centered_difference.jl 0.00% 80 Missing ⚠️
src/discretization/generate_bc_eqs.jl 0.00% 32 Missing ⚠️
src/discretization/staggered_discretize.jl 0.00% 30 Missing ⚠️
...discretization/generate_finite_difference_rules.jl 0.00% 11 Missing ⚠️
src/interface/solution/timedep.jl 60.00% 2 Missing ⚠️
src/interface/MOLFiniteDifference.jl 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #285      +/-   ##
==========================================
- Coverage   83.02%   79.62%   -3.40%     
==========================================
  Files          40       41       +1     
  Lines        1756     1944     +188     
==========================================
+ Hits         1458     1548      +90     
- Misses        298      396      +98     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@cmhyett
Copy link
Contributor Author
cmhyett commented Jul 13, 2023

Following up on the commits yesterday, we should be able to combine this and the time-staggering hack to get a stable wave equation method. VelocityVerlet complains unfortunately, so I used another method that I'm unfamiliar with, I don't think it is the issue..

The results are that we obtain some advection, (not the correct advection in both directions unfortunately), with instability. There seems to be an off-by-one error in the flux that I can't quite track down.
wave_eq

@cmhyett
Copy link
Contributor Author
cmhyett commented Jul 13, 2023

We have wave equation looking results! I implemented my own simple leapfrog update - there is a strange bit about how the symbolic tracing modifies the du variables - check this placeholder in calc_du!

There is also a preference to leftward advection; I think this must be due to an off-by-one error, and I suspect the boundary substitution to be the issue.

For reference, I put the code here including all the hacks necessary to do the time staggering.

using OrdinaryDiffEq, ModelingToolkit, MethodOfLines, DomainSets, Plots;

@parameters t x
@variables ρ(..) ϕ(..)
Dt = Differential(t);
Dx = Differential(x);

a = 1.0;#1.0/2.0;
L = 8.0;
dx = 0.0625;
dt = dx/a;

initialFunction(x) = exp(-(x-dx)^2);
eq = [Dt(ρ(t,x)) + Dx(ϕ(t,x)) ~ 0,
      Dt(ϕ(t,x)) + a^2 * Dx(ρ(t,x)) ~ 0]
bcs = [ρ(0,x) ~ initialFunction(x),
       ϕ(0.0,x) ~ 0.0,
       ρ(t,-L) ~ ρ(t,L),
       ϕ(t,-L) ~ ϕ(t,L)];

domains = [t in Interval(0.0, 10.0),
           x in Interval(-L, L)];

@named pdesys = PDESystem(eq, bcs, domains, [t,x], [ρ(t,x), ϕ(t,x)]);

#discretization = MOLFiniteDifference([x=>dx], t, grid_align=MethodOfLines.CenterAlignedGrid());
discretization = MOLFiniteDifference([x=>dx], t, grid_align=MethodOfLines.StaggeredGrid());

prob = discretize(pdesys, discretization);

len = floor(Int, length(prob.u0)/2);
@variables rho[1:len] phi[1:len]
drho = (prob.f([collect(rho); collect(phi)], nothing, 0.0)[1:len]);
dphi = (prob.f([collect(rho); collect(phi)], nothing, 0.0)[len+1:end]);

gen_drho = eval(Symbolics.build_function(drho, collect(rho), collect(phi))[2]);
gen_dphi = eval(Symbolics.build_function(dphi, collect(rho), collect(phi))[2]);

dynamical_f1(_drho,u,p,t) = gen_drho(_drho, u[1:len], u[len+1:end]);
dynamical_f2(_dphi,u,p,t) = gen_dphi(_dphi, u[1:len], u[len+1:end]);
u0 = [prob.u0[1:len]; prob.u0[len+1:end]];
prob = DynamicalODEProblem(dynamical_f1, dynamical_f2, u0[1:len], u0[len+1:end], (0.0,1.0))
tsteps = 0.0:dt:10.0
#sol = solve(prob, IRKN3(), dt=dt, saveat=tsteps);

function calc_du!(du, u, p, t)
    placeholder = copy(du);
    dynamical_f1(du, u, p, t);
    dynamical_f2(placeholder, [(u[1:len] + dt*du[1:len]); u[len+1:end]], p, t);
    du[len+1:end] .= placeholder[1:len];
    return;
end

function update(u, p, t)
    du = zeros(length(u));
    calc_du!(du, u, p, t);
    return u .+ du*dt;
end

sol = zeros(length(u0), length(tsteps));
sol[:,1] .= u0;
for i in 2:length(tsteps)
    sol[:,i] = update(sol[:,i-1], 0, 0);
end

function plot_sol(sol)
    p_rho = plot();
    p_phi = plot();
    for i in 1:5:20;#length(sol)
        plot!(p_phi, sol[1:len,i], legend=false);
        plot!(p_rho, sol[len+1:end,i], legend=false)
    end
    return plot(p_rho, p_phi);
end

plot_sol(sol)

wave_eq

@cmhyett
Copy link
Contributor Author
cmhyett commented Aug 10, 2023

@xtalax , looking in the last commit, in staggered_discretize.jl symbolic_trace(), can you help me construct the findall statements?

I want to look for all the same variables, i.e., collect all the \rho in u1 and all the \phi in u2 but I can't figure out how to do the comparison

@cmhyett
Copy link
Contributor Author
cmhyett commented Sep 1, 2023

In addition to the included tests, a few words about the final commits:

  1. @xtalax and I made the symbolic tracing more robust
  2. We now output a SplitODEProblem which can be solved using standard (RK4) or specialized (CNLF2) solvers
  3. Along with Dirichlet and Neumann BCs, time-derivatives in the boundary equations work - in our tests we implement transparent BCs.

In the attached pictures we show stability of transparent and reflecting boundary conditions - these cases are codified in the tests.
transparent_bcs
reflecting_bcs

@xtalax
Copy link
Member
xtalax commented Sep 4, 2023

2 things, We need to get tests passing, and we need a docs page detailing how this is used with an example

@cmhyett
Copy link
Contributor Author
cmhyett commented Sep 4, 2023

@xtalax , do you understand these errors? The offending lines of code (these get_index calls) are not code that I modified...Errors are in generate_grid for EdgeAlignedGrid

Perhaps I clobbered an include in src/MethodOfLines.jl?

@xtalax
Copy link
Member
xtalax commented Sep 4, 2023

Somehow, you've broken the default construct_discrete_space, or changed the behaviour of MOLFiniteDifference, I suggest you look at master and compare

@xtalax xtalax closed this Oct 31, 2023
@xtalax xtalax reopened this Oct 31, 2023
@cmhyett
Copy link
Contributor Author
cmhyett commented Nov 7, 2023

Integration tests failed due to an upstream failure addressed in:
SciML/SimpleNonlinearSolve.jl#96

@xtalax PR tests are ready to be re-run.

@xtalax xtalax closed this Nov 8, 2023
@xtalax xtalax reopened this Nov 8, 2023
const center_align=CenterAlignedGrid()
const edge_align=EdgeAlignedGrid()
const stagger_align=StaggeredGrid()
Copy link
Member

Choose a reason for hiding this comment

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

please make this staggered_grid

@@ -0,0 +1,37 @@
using OrdinaryDiffEq, ModelingToolkit, MethodOfLines, DomainSets, Plots;
Copy link
Member

Choose a reason for hiding this comment

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

you should add these to PDESystemLibrary.jl, and tag them appropriately so that you can retrieve them, rather than in a folder here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you commented on an old file? This has been moved to docs/staggered.md and it follows the same template as is found in e.g. heatss.md

Can you clarify?

end
othervars = filter(v -> (length(arguments(v)) != 1) && any(isequal(x_), arguments(depvar(v, s))), othervars)

depvarderivbcmaps = [(Differential(x_)^d)(u_) => central_difference(derivweights, II, s, [], (x2i(s, u, x_), x_), u, ufunc, d) for d in derivweights.orders[x_]];
Copy link
Member

Choose a reason for hiding this comment

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

remember the depvar/derivbcmaps are different for variables on the other grid

@@ -1,7 +1,7 @@
# Steady State Heat Equation - No Time Dependence - NonlinearProblem

Occasionally, it is desirable to solve an equation that has no time evolution, such as the steady state heat equation:
```@example heatss
```
Copy link
Member

Choose a reason for hiding this comment

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

need to change this back

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It works now?

@@ -23,7 +23,7 @@ using DomainSets
end

# Laplace's Equation, same as above but with MOL discretization
@testset "1D Laplace - constant solution" begin
@test_skip begin #@testset "1D Laplace - constant solution" begin
Copy link
Member

Choose a reason for hiding this comment

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

change all these back

@xtalax xtalax merged commit a3810a0 into SciML:master Nov 28, 2023
@cmhyett cmhyett deleted the better_staggered_implementation branch December 4, 2023 16:06
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
0