Skip to article frontmatterSkip to article content

In this part, we will implement a naive finite volume scheme to solve the one-dimensional inviscid Burgers equation. While this implementation is straightforward, we will see in later sections how to improve it to handle multi-resolution meshes correctly. We will use the Burgers equation as a demonstration. This equation is a fundamental partial differential equation that models various physical phenomena, including fluid dynamics and traffic flow. The inviscid Burgers equation is given by:

ut+12u2x=0.\frac{\partial u}{\partial t} + \frac{1}{2} \frac{\partial u^2}{\partial x} = 0.

Finite volume scheme

We will use the simplest finite volume scheme to solve the Burgers equation. The domain is discretized into control volumes (cells), and the solution is approximated by its average value within each cell. The update formula for the cell average uiu_i at time step n+1n+1 is given by:

uin+1=uinΔtΔx(F(ui+1/2n)F(ui1/2n)),u_i^{n+1} = u_i^n - \frac{\Delta t}{\Delta x} \left( F(u_{i+1/2}^n) - F(u_{i-1/2}^n) \right),

where uinu_i^n represents the cell average of uu in the cell ii at time step nn, Δt\Delta t is the time step size, and Δx\Delta x is the cell size. We use a Forward Euler method here to discretize time for simplicity. However, more complex time schemes can be used, as we will show at the end of this practical session. F(ui+1/2n)F(u_{i+1/2}^n) is the numerical flux function, which we will define using the upwind flux. For simplicity, we will assume that the velocity is always positive (upwind scheme). The flux at the right interface of cell ii is determined by the left state:

F(ui+1/2)=12ui2F(u_{i+1/2}) = \frac{1}{2} u_i^2

Mesh adaptation

It is time to adapt the mesh according to the solution. We will use the multi-resolution capabilities of samurai to do so. We will not go into the theoretical details of multi-resolution here, but you can refer to Thomas Bellotti’s thesis in chapter 2 for more information.

Adding the adaptation step performed by the multi-resolution framework of samurai is straightforward. You simply need to follow these steps:

#include <samurai/mr/adapt.hpp>
auto MRadaptation = samurai::make_MRAdapt(u);
auto mra_config   = samurai::mra_config().epsilon(1e-3).relative_detail(false);
MRadaptation(mra_config);
unp1.resize();

You can visualize the adapted mesh and the solution evolution over time using the same command as before. If you add the command-line option --save-debug-fields when running your program, samurai will save additional fields that can help you understand how the mesh is adapted over time, such as levels and coordinates.

If you want to visualize these additional fields, you can use the following command:

python /path/to/read_mesh.py burgers_1d_ --field levels u --start 0 --end 340 --wait 10

Conclusion

In this part, you implemented a naive finite volume scheme for the inviscid Burgers equation using samurai. You learned how to set up the problem, implement the finite volume update, and adapt the mesh using samurai’s multi-resolution capabilities.

However, this naive implementation has several issues. Most notably, we do not compute the flux correctly at interfaces between cells of different refinement levels. To understand why this is problematic, consider the conservation property of finite volume schemes.

In a proper finite volume scheme, conservation requires that the flux leaving one cell exactly equals the flux entering its neighbor. This ensures that mass (or any conserved quantity) is neither created nor destroyed at cell interfaces. Mathematically, for two adjacent cells sharing an interface, the flux balance must satisfy:

Fleft=Fright.F_{\text{left}} = - F_{\text{right}}.
Flux conservation problem

At multi-resolution interfaces, the naive approach breaks down because it uses ghost cells to compute fluxes. Consider the diagram above:

The problem is that these two fluxes are computed at the same physical interface (shown by the red vertical line), but using different cell and ghost values.

The ghost values are constructed differently on each side, leading to inconsistent flux evaluations. This breaks conservation and can cause numerical errors, spurious oscillations, or even instabilities.

In the next section, we will address this by implementing samurai’s flux mechanism, which properly accounts for the multi-resolution mesh structure and ensures conservation at all interfaces.