Operators

All discrete operators are built using KernelAbstractions.jl and Cartesian indices, similar to WaterLily.jl. This allows for dimension- and backend-agnostic code. See this blog post for how to write kernels. IncompressibleNavierStokes previously relied on assembling sparse operators to perform the same operations. While being very efficient and also compatible with CUDA (CUSPARSE), storing these matrices in memory is expensive for large 3D problems.

IncompressibleNavierStokes.Qfield!Function
Qfield!(Q, u, setup)

Compute $Q$-field [10] given by

\[Q = - \frac{1}{2} \sum_{α, β} \frac{\partial u^α}{\partial x^β} \frac{\partial u^β}{\partial x^α}.\]

source
IncompressibleNavierStokes.kinetic_energy!Function
kinetic_energy!(k, u, setup; interpolate_first = false)

Compute kinetic energy field $k$ (in-place version). If interpolate_first is true, it is given by

\[e_I = \frac{1}{8} \sum_\alpha (u^\alpha_{I + \delta(\alpha) / 2} + u^\alpha_{I - \delta(\alpha) / 2})^2.\]

Otherwise, it is given by

\[e_I = \frac{1}{4} \sum_\alpha (u^\alpha_{I + \delta(\alpha) / 2}^2 + u^\alpha_{I - \delta(\alpha) / 2}^2),\]

as in [11].

source
IncompressibleNavierStokes.tensorbasis!Function
tensorbasis!(B, V, u, setup)

Compute symmetry tensor basis B[1]-B[11] and invariants V[1]-V[5], as specified in [12] in equations (9) and (11). Note that B[1] corresponds to $T_0$ in the paper, and V to $I$.

source