numerics
Loading...
Searching...
No Matches
ns_solver.hpp
Go to the documentation of this file.
1/// @file ns_solver.hpp
2/// @brief 2-D incompressible Navier-Stokes, periodic MAC grid
3///
4/// Algorithm: Chorin projection method
5/// 1. Semi-Lagrangian advection -> u*, v*
6/// 2. Build RHS: rhs = -div(u*)/dt
7/// 3. CG pressure solve: (-Delta)p = rhs (positive-definite, Backend::omp inner products)
8/// 4. Project: u = u* - dt*gradp
9///
10/// Grid (NxN cells, domain [0,1]^2):
11/// u[i,j] -- x-velocity at face (i*h, (j+1/2)*h) i,j in [0,N)
12/// v[i,j] -- y-velocity at face ((i+1/2)*h, j*h) i,j in [0,N)
13/// p[i,j] -- pressure at centre ((i+1/2)*h, (j+1/2)*h)
14///
15/// Storage: row-major, index = i*N + j.
16/// All boundaries are periodic.
17#pragma once
18
19#include "core/vector.hpp"
20#include "linalg/solvers/cg.hpp"
21
22#include <functional>
23#include <chrono>
24#include <cmath>
25
26namespace ns {
27
28using num::real;
29using num::idx;
30
31struct Stats {
32 idx cg_iters = 0;
33 real cg_residual = 0.0;
34 double advect_ms = 0.0;
35 double pressure_ms = 0.0;
36 double project_ms = 0.0;
37 double total_ms = 0.0;
38};
39
40class NSSolver {
41public:
42 /// @param N_ Grid resolution (NxN cells)
43 /// @param dt_ Time step
44 /// @param nu_ Kinematic viscosity (0 = inviscid Euler)
45 NSSolver(idx N_, real dt_, real nu_ = 0.0);
46
47 /// Double shear layer initial condition (Kelvin-Helmholtz instability).
48 /// Two counter-flowing bands at y~=0.25 and y~=0.75 seed vortex roll-up.
49 /// @param rho Shear layer thickness (default 0.05)
50 /// @param delta Perturbation amplitude (default 0.05)
51 void init_shear_layer(real rho = 0.05, real delta = 0.05);
52
53 /// Advance one time step (advect -> pressure -> project).
54 void step();
55
56 /// Vorticity omega = d_v/d_x - d_u/d_y at grid corner (i*h, j*h).
57 real vorticity(idx i, idx j) const;
58
59 /// Velocity magnitude averaged to cell centre (i,j).
60 real speed(idx i, idx j) const;
61
62 /// Interpolate x-velocity at physical point (px, py).
63 real interp_u(real px, real py) const;
64 /// Interpolate y-velocity at physical point (px, py).
65 real interp_v(real px, real py) const;
66
67 // -- Grid constants ------------------------------------------------------
68 const idx N;
69 const real h, dt, nu;
70
71 // -- State ---------------------------------------------------------------
72 num::Vector u, v, p; ///< velocity faces + cell-centre pressure, N*N each
73
75
76private:
77 num::Vector u_star, v_star, rhs;
78
79 // -- Index helpers -------------------------------------------------------
80 inline idx at (idx i, idx j) const noexcept { return i * N + j; }
81 inline idx wp1(idx i) const noexcept { return (i + 1) % N; }
82 inline idx wm1(idx i) const noexcept { return (i + N - 1) % N; }
83
84 // -- Physics sub-steps ---------------------------------------------------
85 void advect();
86 void apply_diffusion();
87 void build_rhs();
88 void solve_pressure();
89 void project();
90
91 /// CG with Backend::omp inner products -- handles periodic, singular Laplacian.
92 num::SolverResult cg_omp(
93 std::function<void(const num::Vector&, num::Vector&)> matvec,
94 const num::Vector& b, num::Vector& x,
95 real tol, idx max_iter);
96};
97
98} // namespace ns
Conjugate gradient solvers (dense and matrix-free)
num::Vector p
velocity faces + cell-centre pressure, N*N each
Definition ns_solver.hpp:72
const real h
Definition ns_solver.hpp:69
const real nu
Definition ns_solver.hpp:69
num::Vector u
Definition ns_solver.hpp:72
real vorticity(idx i, idx j) const
Vorticity omega = d_v/d_x - d_u/d_y at grid corner (i*h, j*h).
real interp_u(real px, real py) const
Interpolate x-velocity at physical point (px, py).
const idx N
Definition ns_solver.hpp:68
real interp_v(real px, real py) const
Interpolate y-velocity at physical point (px, py).
void init_shear_layer(real rho=0.05, real delta=0.05)
Definition ns_solver.cpp:27
real speed(idx i, idx j) const
Velocity magnitude averaged to cell centre (i,j).
const real dt
Definition ns_solver.hpp:69
void step()
Advance one time step (advect -> pressure -> project).
Definition ns_solver.cpp:50
num::Vector v
Definition ns_solver.hpp:72
double real
Definition types.hpp:10
std::size_t idx
Definition types.hpp:11
double total_ms
Definition ns_solver.hpp:37
double advect_ms
Definition ns_solver.hpp:34
double project_ms
Definition ns_solver.hpp:36
real cg_residual
Definition ns_solver.hpp:33
double pressure_ms
Definition ns_solver.hpp:35
Vector operations.