trixi-framework / Trixi.jl

Trixi.jl: Adaptive high-order numerical simulations of conservation laws in Julia
https://trixi-framework.github.io/Trixi.jl
MIT License
527 stars 105 forks source link

Plotting at different saved times (movies etc.) #842

Open jlchan opened 3 years ago

jlchan commented 3 years ago

OrdinaryDiffEq.jl provides a nice saveat kwarg to specify times at which to save solution snapshots. This seems like it would be useful for visualizing dynamic behavior or creating movies, but would require modification of current plot recipes.

ranocha commented 3 years ago

We have to discuss what kind of approach to reach these times we want to use, see also https://github.com/trixi-framework/Trixi.jl/issues/769#issuecomment-899454244. The default of DiffEq is to interpolate (unless you also set tstops accordingly).

jlchan commented 3 years ago

For callbacks, I think the specific approach can be pretty important. However, for visualization, interpolation seems like it would be easier to implement and sufficiently accurate (given that our timesteps tend to be fairly small).

ranocha commented 3 years ago

Well, a possible problem with interpolation might be to reach unphysical states (say, negative density) when using certain methods. Thus, one might wonder what the hell is going on when plotting this... Otherwise, I agree with you.

ranocha commented 3 years ago

Right now, the save solution callback is basically an indirect visualization callback (via VTK). Thus, I think we should probably unify the handling of these two.

jlchan commented 3 years ago

That's a good idea - thanks. I'll take a look at that callback.

ranocha commented 3 years ago

Oh, sorry, I wasn't saying that this callback is good right now - in contrast, it only implements output based on a fixed step number frequency and shall be updated (https://github.com/trixi-framework/Trixi.jl/issues/19).

ranocha commented 3 years ago

One thing to keep in mind: Using saveat means that we store the full solution state in RAM (which is feasible for appropriate scales). Thus, visualization using them is definitely possible (I did this in some presentations of Trixi.jl) but will not work with AMR (where we change the mesh). Thus, we should decide whether we want to use this approach or whether we would like to use a dedicated movie or continuous visualization callback, which processes the solution at desired times and saves the resulting visualization to disk without storing the numerical solution itself.

jlchan commented 3 years ago

Ah, that's a really good point. I completely forgot that AMR would break this feature...

jlchan commented 3 years ago

I guess the question would be whether or not we wish to standardize plotting features across solver types. We have a few solvers/meshes which don't yet support AMR (DGMulti, StructuredMesh2D, UnstructuredMesh2D), so we could potentially have a visualization feature which is specific only to certain solvers.

The downside is that even if documented, this would increase the mental burden for visualization to have to remember which solvers allow for what forms of visualization...

jlchan commented 3 years ago

One other way around this might be allowing the user to pass in a solution array, e.g., something like plot(PlotData2D(u, semi)) where u is an array of solution values which is consistent with the underlying storage of the scheme.

Then, plotting a different solution at another saveat time would just require plot(PlotData2D(sol.u[index], semi)). This would also work for AMR if one could extract an array of the solution at different simulation times. What do you think of something like this, @ranocha?

ranocha commented 3 years ago

We have a few solvers/meshes which don't yet support AMR (DGMulti, StructuredMesh2D, UnstructuredMesh2D), so we could potentially have a visualization feature which is specific only to certain solvers.

That's okay with me in general. However, I would of course prefer something that leaves the door open.

ranocha commented 3 years ago

Then, plotting a different solution at another saveat time would just require plot(PlotData2D(sol.u[index], semi)). What do you think of something like this, @ranocha?

Don't we already allow something like this? At least I have used something like plot(ui, semi) for ui in sol.u.

ranocha commented 3 years ago

This would also work for AMR if one could extract an array of the solution at different simulation times.

No, it doesn't, since we would need to also store the mesh at the same times.

jlchan commented 3 years ago

Don't we already allow something like this? At least I have used something like plot(ui, semi) for ui in sol.u.

Interesting, I wasn't aware of a feature like this. Do you know if this is still available and, if so, where it's located?

ranocha commented 3 years ago

An example is contained in https://nbviewer.jupyter.org/github/trixi-framework/talk-2021-juliacon/blob/main/demo.ipynb (directly before the heading https://nbviewer.jupyter.org/github/trixi-framework/talk-2021-juliacon/blob/main/demo.ipynb#Adaptive-mesh-refinement). It works due to recipes such as https://github.com/trixi-framework/Trixi.jl/blob/edfa693b4c2ee9c586a5483c105c0ca54443d3b9/src/visualization/recipes_plots.jl#L197 I don't remember whether we have something similar for Makie.

jlchan commented 3 years ago

That's perfect - thanks! This should also work for Makie then through plot(PlotData2D(u, semi)).

jlchan commented 3 years ago

Since the original idea would be inconsistent with AMR and since there's a pretty easy workaround, I'm closing this.

ranocha commented 3 years ago

Let's re-open this and call it "movie callback"