|
| 1 | +# 2D Channel Flow with a Cylinder |
| 2 | + |
| 3 | +This example solves the two-dimensional incompressible Navier-Stokes equations in a channel using MOLE mimetic operators and a projection (pressure-correction) method. |
| 4 | + |
| 5 | +The cylinder obstacle is introduced as a masked no-slip region inside the channel. To make things easy, the current implementation uses an axis-aligned masked block of cells rather than a fitted curved boundary. The purpose of this example is to show how MOLE operators can be combined to build a transient incompressible flow solver in a direct and compact way. |
| 6 | + |
| 7 | +## Governing Equations |
| 8 | + |
| 9 | +We solve the incompressible Navier-Stokes equations |
| 10 | + |
| 11 | +$$ |
| 12 | +\frac{\partial \mathbf{u}}{\partial t} |
| 13 | ++ (\mathbf{u}\cdot\nabla)\mathbf{u} |
| 14 | += -\frac{1}{\rho}\nabla p + \nu \nabla^2 \mathbf{u} |
| 15 | +$$ |
| 16 | + |
| 17 | +$$ |
| 18 | +\nabla \cdot \mathbf{u} = 0 |
| 19 | +$$ |
| 20 | + |
| 21 | +where $\mathbf{u} = (u,v)$ is the velocity field, $p$ is the pressure, $\rho$ is the density, and $\nu$ is the kinematic viscosity. |
| 22 | + |
| 23 | +## Spatial Domain |
| 24 | + |
| 25 | +The computational domain is |
| 26 | + |
| 27 | +$$ |
| 28 | +x \in [0,8], \qquad y \in [-1,1] |
| 29 | +$$ |
| 30 | + |
| 31 | +The default grid is |
| 32 | + |
| 33 | +- $m = 481$ cells in the $x$-direction |
| 34 | +- $n = 121$ cells in the $y$-direction |
| 35 | + |
| 36 | +The Reynolds number is defined through |
| 37 | + |
| 38 | +$$ |
| 39 | +\nu = \frac{U_{\mathrm{init}} D_0}{Re} |
| 40 | +$$ |
| 41 | + |
| 42 | +with the default values |
| 43 | + |
| 44 | +- $Re = 200$ |
| 45 | +- $U_{\mathrm{init}} = 1$ |
| 46 | + |
| 47 | +## Initial and Boundary Conditions |
| 48 | + |
| 49 | +### Initial Conditions |
| 50 | + |
| 51 | +At $t = 0$, |
| 52 | + |
| 53 | +$$ |
| 54 | +u = U_{\mathrm{init}}, \qquad v = 0 |
| 55 | +$$ |
| 56 | + |
| 57 | +in the fluid region, and the masked obstacle region is initialized with |
| 58 | + |
| 59 | +$$ |
| 60 | +u = 0, \qquad v = 0 |
| 61 | +$$ |
| 62 | + |
| 63 | +### Velocity Boundary Conditions |
| 64 | + |
| 65 | +- **Inlet (left):** Dirichlet inflow |
| 66 | + |
| 67 | + $$ |
| 68 | + u = U_{\mathrm{init}}, \qquad v = 0 |
| 69 | + $$ |
| 70 | + |
| 71 | +- **Outlet (right):** zero streamwise gradient |
| 72 | + |
| 73 | + $$ |
| 74 | + \frac{\partial u}{\partial x} = 0, \qquad \frac{\partial v}{\partial x} = 0 |
| 75 | + $$ |
| 76 | + |
| 77 | +- **Top and bottom walls:** no-slip |
| 78 | + |
| 79 | + $$ |
| 80 | + u = 0, \qquad v = 0 |
| 81 | + $$ |
| 82 | + |
| 83 | +- **Obstacle mask:** no-slip |
| 84 | + |
| 85 | + $$ |
| 86 | + u = 0, \qquad v = 0 |
| 87 | + $$ |
| 88 | + |
| 89 | +### Pressure Boundary Conditions |
| 90 | + |
| 91 | +During the pressure Poisson step, |
| 92 | + |
| 93 | +- **Outlet (right):** reference pressure |
| 94 | + |
| 95 | + $$ |
| 96 | + p = 0 |
| 97 | + $$ |
| 98 | + |
| 99 | +- **All other boundaries:** homogeneous Neumann |
| 100 | + |
| 101 | + $$ |
| 102 | + \frac{\partial p}{\partial n} = 0 |
| 103 | + $$ |
| 104 | + |
| 105 | +## Numerical Method |
| 106 | + |
| 107 | +A projection method is used to enforce incompressibility. |
| 108 | + |
| 109 | +This is the same overall time-stepping strategy used in both the MATLAB/Octave and C++ implementations. |
| 110 | + |
| 111 | +### Time Integration |
| 112 | + |
| 113 | +The momentum equation is advanced with a mixed time discretization: |
| 114 | + |
| 115 | +- the **convective term** is treated explicitly with **AB2** (Adams-Bashforth 2) |
| 116 | +- the **first time step** uses **AB1** |
| 117 | +- the **diffusive term** is treated implicitly with **Crank-Nicolson** |
| 118 | + |
| 119 | +The convective term is nonlinear, so an explicit AB2 treatment keeps the method simple and avoids solving a nonlinear system at each time step. The diffusive term is linear and is treated with Crank-Nicolson to obtain a stable and second-order accurate semi-implicit update. |
| 120 | + |
| 121 | +As a result, the intermediate velocity solve uses the matrices |
| 122 | + |
| 123 | +$$ |
| 124 | +M = I - \frac{1}{2}\Delta t \, \nu L, |
| 125 | +\qquad |
| 126 | +M_p = I + \frac{1}{2}\Delta t \, \nu L |
| 127 | +$$ |
| 128 | + |
| 129 | +which are the Crank-Nicolson diffusion matrices used in the Helmholtz-type solves for $u^*$ and $v^*$. |
| 130 | + |
| 131 | +### Intermediate Velocity |
| 132 | + |
| 133 | +An intermediate velocity $\mathbf{u}^*$ is computed first from the momentum equation using the explicit convective update and the semi-implicit diffusive update. |
| 134 | + |
| 135 | +### Pressure Poisson Equation |
| 136 | + |
| 137 | +The pressure is then obtained from |
| 138 | + |
| 139 | +$$ |
| 140 | +\nabla^2 p^{n+1} |
| 141 | += |
| 142 | +\frac{\rho}{\Delta t}\nabla \cdot \mathbf{u}^* |
| 143 | +$$ |
| 144 | + |
| 145 | +### Velocity Correction |
| 146 | + |
| 147 | +The velocity is corrected by |
| 148 | + |
| 149 | +$$ |
| 150 | +\mathbf{u}^{n+1} |
| 151 | += |
| 152 | +\mathbf{u}^* |
| 153 | +- |
| 154 | +\frac{\Delta t}{\rho}\nabla p^{n+1} |
| 155 | +$$ |
| 156 | + |
| 157 | +### Re-application of Velocity Boundary Conditions and Mask |
| 158 | + |
| 159 | +After the pressure correction step, the code re-applies the velocity boundary values and the obstacle mask. |
| 160 | + |
| 161 | +This is done because the projection step updates the full cell-centered velocity field. Re-applying these values ensures that the final updated velocity satisfies the intended inlet, wall, outlet, corner, and masked-region constraints exactly. |
| 162 | + |
| 163 | +## Role of the MOLE Operators |
| 164 | + |
| 165 | +This example is intended to highlight how MOLE operators are used in an incompressible flow solver. |
| 166 | + |
| 167 | +The main operators are |
| 168 | + |
| 169 | +- **Laplacian $L$:** used for viscous diffusion |
| 170 | +- **Divergence $D$:** used in the convective flux form and in the pressure Poisson right-hand side |
| 171 | +- **Gradient $G$:** used in the pressure correction step |
| 172 | +- **Interpolation operators:** used to map between cell-centered values and face-based quantities for flux evaluation and projection |
| 173 | + |
| 174 | +These operators are combined to build |
| 175 | + |
| 176 | +- the Crank-Nicolson diffusion operators |
| 177 | +- the pressure Poisson operator |
| 178 | +- the interpolation maps needed for face fluxes and pressure-gradient correction |
| 179 | + |
| 180 | + |
| 181 | +## Running the Example |
| 182 | + |
| 183 | +After building the C++ examples, run |
| 184 | + |
| 185 | +```bash |
| 186 | +cd <mole-repo>/examples/cpp |
| 187 | +../../build/examples/cpp/cylinder_flow_2D |
| 188 | +``` |
| 189 | + |
| 190 | +## MATLAB and C++ Versions |
| 191 | + |
| 192 | +MATLAB/Octave and C++ versions of this example are provided with the same problem setup and the same overall projection-method structure. In particular, both versions use |
| 193 | + |
| 194 | +- AB2 for the convective term |
| 195 | +- AB1 at the first step |
| 196 | +- Crank-Nicolson for the diffusive term |
| 197 | +- a pressure Poisson solve followed by velocity correction |
| 198 | + |
| 199 | +This makes it easier to compare the two implementations and to see how the same MOLE operators are used in each language. |
| 200 | + |
| 201 | +## Results |
| 202 | + |
| 203 | +### C++ result |
| 204 | + |
| 205 | + |
| 206 | + |
| 207 | +### MATLAB result |
| 208 | + |
| 209 | + |
0 commit comments