#!/usr/bin/env python # coding: utf-8 # # Relax and hold steady # ## Stokes flow # This notebook presents the coding assignment for **Module 5** of the course [*"Practical Numerical Methods with Python.*](https://github.com/numerical-mooc/numerical-mooc) Your mission is to solve Stokes flow in a square cavity, using the vorticity-streamfunction formulation. # # Stokes flow, also known as *creeping flow*, refers to flows that are dominated by viscous forces and not by the advective/convective forces. The Stokes-flow assumption works well for flows that have very low Reynolds number, much smaller than 1: very slow, highly viscous or flows at microscopic length scales. # # Stokes flow allows us to simplify the Navier-Stokes equations, eliminating the non-linearity. Let's run through a quick derivation of the vorticity-transport equation with Stokes-flow assumptions. # ### Vorticity # We start with the Navier-Stokes equations for incompressible flow: # # $$ # \begin{equation} # \frac{\partial u}{\partial t} + u \cdot \nabla u = -\frac{1}{\rho}\nabla p + \nu\nabla^2 u # \end{equation} # $$ # # If we scale Equation $(1)$ to make it non-dimensional, we can rewrite it as # # $$ # \begin{equation} # Re \left(\frac{\partial u^*}{\partial t} + u^* \cdot \nabla u^* \right) = -\nabla p^* + \nabla^2 u^* # \end{equation} # $$ # # Where $u^*$ and $p^*$ are the non-dimensional velocity and pressure, respectively. # # To obtain Stokes flow, we assume that the Reynolds number approaches zero. Applying that assumption to Equation $(2)$ and dropping the stars, yields # # $$ # \begin{equation} # 0 = - \nabla p + \nabla^2 u # \end{equation} # $$ # # That simplified things! Now, we apply the curl operator on both sides of the equation: # # $$ # \begin{equation} # \nabla \times 0 = \nabla \times \left( - \nabla p + \nabla^2 u\right) # \end{equation} # $$ # # The left-hand side remains zero, while the first term on the right-hand side is # # $$ # \begin{equation} # \nabla \times - \nabla p = 0 # \end{equation} # $$ # # because $\nabla \times \nabla \phi = 0$ where $\phi$ is a scalar. # # Finally, # # $$ # \begin{equation} # \nabla \times \nabla^2 u =\nabla^2\omega # \end{equation} # $$ # # where $\nabla \times u = \omega$ is the vorticity. # # Combining all of these equations, we arrive at the simplified vorticity transport equation for Stokes flow: # # $$ # \begin{equation} # \nabla ^2 \omega = 0 # \end{equation} # $$ # # Look familiar? # ### Stream function # Define the stream function $\psi$, such that # # $$ # \begin{equation} # u = \frac{\partial \psi}{\partial y} \text{ and } v = - \frac{\partial \psi}{\partial x} # \end{equation} # $$ # # In 2D, we can write out the vorticity as # # $$ # \begin{equation} # \omega = \frac{\partial v}{\partial x} - \frac{\partial u}{\partial y} # \end{equation} # $$ # # which, combined with the previous equation yields another familiar looking equation: # # $$ # \begin{equation} # \nabla^2 \psi = -\omega # \end{equation} # $$ # # We have a system of two coupled equations that can describe the fluid flow in a lid-driven cavity at very low Reynolds numbers. # # $$ # \begin{equation} # \nabla^2 \omega = 0 # \end{equation} # $$ # # $$ # \begin{equation} # \nabla^2 \psi = -\omega # \end{equation} # $$ # # Note that by substituting Equation $(12)$ into $(11)$, we arrive at a new equation: the *biharmonic equation*: # # $$ # \begin{equation} # \nabla^4 \psi= 0 # \end{equation} # $$ # ### Solving the biharmonic equation # Is it possible to discretize a 4th-order partial differential equation? Of course! Are we going to? No! # # There's nothing wrong with a 4th-order equation, but in this course module we learned about the Poisson equation and that's what we're going to use. # ## Cavity flow # You will solve a problem called *lid-driven cavity flow*. This is a common test problem for Navier-Stokes solvers—we'll be using it to examine Stokes flow. # # Assume that the lid of a square cavity moves at a constant velocity of $u=1$, with no fluid leaking out past the moving lid. We we want to visualize what the flow field inside the cavity looks like at steady state. # # All of the surfaces, including the lid, are assumed to have no-slip boundary conditions. The boundary conditions are all specified in terms of the streamfunction $\psi$, as shown below in Figure $(1)$. # # #### Figure 1. Lid-driven Cavity Flow # ### Boundary conditions # One of the major hurdles with the vorticity-streamfunction formulation is the treatment of boundary conditions. # # The boundary conditions are all specified in terms of $\psi$ and its derivatives, but the Laplace equation # # $$ # \nabla \omega^2 = 0 # $$ # # has no $\psi$ value. Instead, we need a way to represent the boundary conditions for $\omega$ in terms of $\psi$. # # Consider the equation $\nabla ^2 \psi = -\omega$ along the top surface of the cavity (the moving surface). The streamfunction $\psi$ along $x$-direction is a zero constant, so $\frac{\partial ^2 \psi}{\partial x^2}$ goes to zero and the equation simplifies to # # $$ # \begin{equation} # \frac{\partial ^2 \psi}{\partial y^2} = -\omega # \end{equation} # $$ # A 2nd-order central difference discretization gives # # $$ # \begin{equation} # \omega_j = - \left(\frac{\psi_{j+1} - 2\psi_j + \psi_{j-1}}{\Delta y^2}\right) # \end{equation} # $$ # # but the value $\psi_{j+1}$ is outside of the domain. Now take a 3rd-order discretization of $\frac{\partial \psi}{\partial y}$ evaluated along the top edge. # # $$ # \begin{equation} # \left.\frac{\partial \psi}{\partial y}\right|_j = \frac{2\psi_{j+1} + 3\psi_j - 6\psi_{j-1} + \psi_{j-2}}{6 \Delta y} # \end{equation} # $$ # # $\frac{\partial \psi}{\partial y}$ is a given boundary value in the problem along the top edge # # $$ # \begin{equation} # \left.\frac{\partial \psi}{\partial y}\right|_j = u_j # \end{equation} # $$ # # which leaves us with a value for $\psi_{j+1}$ that consists only of points within the domain. # # $$ # \begin{equation} # \psi_{j+1} = \frac{6\Delta y u_j - 3\psi_j + 6 \psi_{j-1} - \psi_{j-2}}{2} # \end{equation} # $$ # # Plug in that result into the initial discretization from Equation $(15)$ and we have a boundary condition for $\omega$ along the top surface in terms of $\psi$: # # $$ # \begin{equation} # \omega_{i,j} = -\frac{1}{2 \Delta y^2} (8\psi_{i, j-1} - \psi_{i, j-2}) - \frac{3u_j}{\Delta y} + \mathcal{O}(\Delta y^2) # \end{equation} # $$ # ### Coding assignment # Solve Stokes flow in a lid-driven cavity using the parameters given below. # # You should iteratively solve for both $\omega$ and $\psi$ until the L1 norm of the difference between successive iterations is less than $1$$\tt{E}$$^-6$ for **both** quantities. # In[1]: import numpy # In[2]: # Set parameters. nx, ny = 41, 41 # number of points in each direction L = 1.0 # length of the square cavity dx = L / (nx - 1) # grid spacing in the x direction dy = L / (ny - 1) # grid spacing in the y direction # In[3]: def l1_norm(u, u_ref): """ Computes and returns the L1-norm of the difference between a solution u and a reference solution u_ref. Parameters ---------- u : numpy.ndarray The solution as an array of floats. u_ref : numpy.ndarray The reference solution as an array of floats. Returns ------- diff : float The L2-norm of the difference. """ diff = numpy.sum(numpy.abs(u - u_ref)) return diff # The final result should resemble the plot shown in Figure $(2)$. # ##### Hint # The boundary conditions for $\omega$ depend upon the current value of $\psi$. The two equations are *coupled*. If you try to solve them in a *uncoupled* way, things will go poorly. # # #### Figure 2. Contour plot of streamfunction at steady state # ### References # * Fletcher, C. A. (1988). Computational Techniques for Fluid Dynamics: Volume 2: Specific Techniques for Different Flow Categories. # # * Ghia, U. K. N. G., Ghia, K. N., & Shin, C. T. (1982). High-Re solutions for incompressible flow using the Navier-Stokes equations and a multigrid method. Journal of computational physics, 48(3), 387-411. # # * Greenspan, D. (1974). Discrete numerical methods in physics and engineering (Vol. 312). New York: Academic Press. # # * Heil, Matthias (2007). [Viscous Fluid Flow Vorticity Handout (pdf)](http://www.maths.manchester.ac.uk/~mheil/Lectures/Fluids/Material_2007/Vorticity.pdf) # # * Non-dimensionalization and scaling of the Navier Stokes equations. (n.d.). In *Wikipedia*. Retrieved January 30, 2015 [http://en.wikipedia.org/w/index.php?title=Non-dimensionalization_and_scaling_of_the_Navier-Stokes_equations](http://en.wikipedia.org/w/index.php?title=Non-dimensionalization_and_scaling_of_the_Navier%E2%80%93Stokes_equations&oldid=641860920) # --- # ###### The cell below loads the style of this notebook. # In[4]: from IPython.core.display import HTML css_file = '../../styles/numericalmoocstyle.css' HTML(open(css_file, 'r').read())