RasmahRasmah

Moving Domains: the Arbitrary Lagrangian–Eulerian (ALE) Formulation

using Rasmah

Overview

When the domain itself moves — a piston, a flapping foil, a deforming container — the flow equations must be written on the moving mesh. The Arbitrary Lagrangian–Eulerian (ALE) formulation replaces the convection velocity by the relative velocity u − w, where w is the mesh velocity:

\[\rho\big((u-w)\cdot\nabla\big)u = \nabla\cdot(\mu\nabla u) - \nabla p + f\]

Rasmah implements ale_navier_stokes_operator with an optional mesh-velocity field w_fn(x).

The two limits

The ALE formulation interpolates between the two classical frames:

  • Eulerian (w = 0): a fixed mesh; this is the ordinary Navier–Stokes operator.
  • Lagrangian (w = u): the mesh follows the fluid, so the relative velocity u − w = 0 and the convection vanishes.

Rasmah’s ale_navier_stokes_operator with w = 0 reproduces the plain Navier–Stokes operator exactly:

using LinearAlgebra
function channel(nx, ny)
    nv = (nx + 1) * (ny + 1)
    verts = Matrix{Float64}(undef, 3, nv)
    for j in 0:ny, i in 0:nx
        idx = i + j * (nx + 1) + 1
        verts[1, idx] = i / nx; verts[2, idx] = j / ny
    end
    faces = Matrix{Int}(undef, 3, 2nx * ny)
    k = 0
    for j in 0:(ny - 1), i in 0:(nx - 1)
        a = i + j * (nx + 1) + 1; b = a + 1; c = a + nx + 1; d = c + 1
        k += 1; faces[:, k] = [a, b, c]
        k += 1; faces[:, k] = [b, d, c]
    end
    TriangleMesh(verts, faces)
end

m = channel(4, 4)
U = FESpace(m, ReferenceFE(2, 2); valuetype = VectorValue{2})
P = FESpace(m, ReferenceFE(2, 1))
opALE = ale_navier_stokes_operator(U, P, 0.1, 1.0, nothing)   # w = 0
opNS  = navier_stokes_operator(U, P, 0.1, 1.0)
n = ndofs(U) + ndofs(P)
w = 0.1 .* rand(n)
println("|residual_ALE − residual_NS| = ",
        maximum(abs.(assemble_residual(opALE, w) .- assemble_residual(opNS, w))))
|residual_ALE − residual_NS| = 0.0

The residual difference is zero (the Eulerian limit is exact).

Next steps