Documentation | Workflows | Code coverage | Quality assurance |
---|---|---|---|
This package implements energy-conserving solvers for the incompressible Navier-Stokes equations on a staggered Cartesian grid. It is based on the Matlab package INS2D/INS3D. The simulations can be run on the single/multithreaded CPUs or Nvidia GPUs.
This package also provides experimental support for neural closure models for large eddy simulation.
To install IncompressibleNavierStokes, open up a Julia-REPL, type ]
to get
into Pkg-mode, and type:
(v1.10) pkg> add IncompressibleNavierStokes
which will install the package and all dependencies to your local environment.
Note that IncompressibleNavierStokes requires Julia version 1.9
or above.
See the
Documentation
for examples of some typical workflows. More examples can be found in the
examples
directory.
See here for the source code used in the paper Discretize first, filter next: learning divergence-consistent closure models for large-eddy simulation.
The velocity and pressure fields may be visualized in a live session using
Makie. Alternatively,
ParaView may be used, after exporting individual
snapshot files using the save_vtk
function, or the full time series using the
VTKWriter
processor.
Actuator (2D) | Backward Facing Step (2D) | Decaying Turbulence (2D) | Taylor-Green Vortex (2D) |
Actuator (3D) | Backward Facing Step (3D) | Decaying Turbulence (3D) | Taylor-Green Vortex (3D) |
IncompressibleNavierStokes also supports adding a temperature equation.
iceandfire_100x100x200.mp4
The following example code using a negative body force on a small rectangle with an unsteady inflow. It simulates a wind turbine (actuator) under varying wind conditions.
Make sure to have the GLMakie
and IncompressibleNavierStokes
installed:
using Pkg
Pkg.add(["GLMakie", "IncompressibleNavierStokes"])
Then run run the following code to make a short animation:
using GLMakie
using IncompressibleNavierStokes
# A 2D grid is a Cartesian product of two vectors
n = 40
x = LinRange(0.0, 10.0, 5n + 1)
y = LinRange(-2.0, 2.0, 2n + 1)
# Boundary conditions
boundary_conditions = (
# Inlet, outlet
(
# Unsteady BC requires time derivatives
DirichletBC(
(dim, x, y, t) -> sin(π / 6 * sin(π / 6 * t) + π / 2 * (dim() == 1)),
(dim, x, y, t) ->
(π / 6)^2 *
cos(π / 6 * t) *
cos(π / 6 * sin(π / 6 * t) + π / 2 * (dim() == 1)),
),
PressureBC(),
),
# Sides
(PressureBC(), PressureBC()),
)
# Actuator body force: A thrust coefficient distributed over a thin rectangle
inside(x, y) = abs(x - 2.0) ≤ 0.055 && abs(y) ≤ 0.5
bodyforce(dim, x, y, t) = dim() == 1 && inside(x, y) ? -1.82 : 0.0
# Build setup and assemble operators
setup = Setup(x, y; Re = 100.0, boundary_conditions, bodyforce);
# Initial conditions (extend inflow)
ustart = create_initial_conditions(setup, (dim, x, y) -> dim() == 1 ? 1.0 : 0.0);
# Solve unsteady Navier-Stokes equations
solve_unsteady(;
setup, ustart, tlims = (0.0, 48.0), Δt = 0.05,
processors = (
anim = animator(; setup, path = "vorticity.mp4", nupdate = 4),
log = timelogger(),
),
)
The resulting animation is shown below.
vorticity.mp4
- WaterLily.jl Incompressible solver with immersed boundaries
- Oceananigans.jl: Ocean simulations
- ClimaCore.jl: Atmospheric simulations
- Trixi.jl: High order solvers for various hyperbolic equations
- Ferrite.jl: Finite element discretizations
- Gridap.jl: Finite element discretizations
- FourierFlows.jl: Pseudo-spectral discretizations