【诠释版】12 steps to Navier-Stokes —— Introduction and Step 1【待修改】

来源:互联网 发布:电影故事板软件 编辑:程序博客网 时间:2024/05/09 20:51

Preface

现在计划将LorenaABarba的《12 steps to Navier-Stokes》系列做一个诠释版。不做完全翻译版的目的是感觉现阶段我的翻译水平并不能完全驾驭作者想要表达的。为了不改变经典的原貌,只做部分注释。在这个过程中大家共同进步。

Introductions

Hello! Welcome to the 12 steps to Navier-Stokes. This is a practical module that is used in the beginning of an interactive Computational Fluid Dynamics (CFD) course taught by Prof. Lorena Barba since Spring 2009 at Boston University. The course assumes only basic programming knowledge (in any language) and of course some foundation in partial differential equations(偏微分方程)and fluid mechanics(流体力学). The practical module was inspired by the ideas of Dr. Rio Yokota, who was a post-doc in Barba’s lab, and has been refined by Prof. Barba and her students over several semesters teaching the course. The course is taught entirely using Python and students who don’t know Python just learn as we work through the module.

This IPython notebook will lead you through the first step of programming your own Navier-Stokes solver in Python from the ground up(从头开始). We’re going to dive right in. Don’t worry if you don’t understand everything that’s happening at first, we’ll cover it in detail as we move forward and you can support your learning with the videos of Prof. Barba’s lectures on YouTube.(需要翻墙,视频中包含详细的推导过程)

For best results, after you follow this notebook, prepare your own code for Step 1, either as a Python script or in a clean IPython notebook.

To execute this Notebook, we assume you have invoked the notebook server using: ipython notebook.(原作者采用IPython,笔者采用Anaconda来替代,版本为Anaconda3,其中Python版本为3.5.1)


Step 1: 1-D Linear Convection

The 1-D Linear Convection equation(对流方程) is the simplest, most basic model that can be used to learn something about CFD. It is surprising that this little equation can teach us so much! Here it is:

ut+cux=0

With given initial conditions (understood as a wave), the equation represents the propagation of that initial wave with speed c, without change of shape. Let the initial condition be u(x,0)=u0(x). Then the exact solution of the equation is i=0 to N, and stepping in discrete time intervals of size Δt.

From the definition of a derivative(导数的定义) (and simply removing the limit), we know that:(或者通过泰勒展开)

uxu(x+Δx)u(x)Δx

Our discrete equation, then, is:
un+1i=unicΔtΔx(uniuni1)

Now let’s try implementing this in Python.

We’ll start by importing a few libraries to help us out.

  • numpyis a library that provides a bunch of useful matrix operations akin to MATLAB
  • matplotlib is a 2D plotting library that we will use to plot our results
  • time andsys provide basic timing functions that we’ll use to slow down animations for viewing

Now let’s define a few variables; we want to define an evenly spaced grid of points within a spatial domain that is 2 units of length wide, i.e., xi(0,2). We’ll define a variable nx, which will be the number of grid points we want and dx will be the distance between any pair of adjacent grid points.

We also need to set up our initial conditions. The initial velocity u0is given as u=2 in the interval 0.5x1 and u=1 everywhere else in (0,2) (i.e., a hat function).(你会看到下面代表初始条件的函数形如帽子)

Here, we use the function ones()defining a numpy array which is nx elements long with every value equal to 1.

Now let’s take a look at those initial conditions using a Matplotlib plot. We’ve imported the matplotlib plotting library pyplot and the plotting function is called plot, so we’ll call pyplot.plot. To learn about the myriad possibilities of Matplotlib, explore the Gallery of example plots.

Here, we use the syntax for a simple 2D plot: plot(x,y), where the x values are evenly distributed grid points:

Why doesn’t the hat function have perfectly straight sides? Think for a bit.

Now it’s time to implement the discretization of the convection equation using a finite-difference scheme.

For every element of our array u, we need to perform the operation

un+1i=unicΔtΔx(uniuni1)

We’ll store the result in a new (temporary) array un, which will be the solution u for the next time-step. We will repeat this operation for as many time-steps as we specify and then we can see how far the wave has convected.

We first initialize our placeholder array un to hold the values we calculate for the n+1 timestep, using once again the NumPy function ones().

import numpy                       from matplotlib import pyplot      nx = 41     #节点数               dx = 2/(nx-1)   #网格单元的尺度      nt = 25     #时间步数     dt = 0.025    #时间步长c = 1   #波的传播速度u = numpy.ones(nx)u[0.5/dx : 1/dx+1] = 2print(u)    #数组中写入了初始条件pyplot.plot(numpy.linspace(0,2,nx), u)    #初始条件图像un = numpy.ones(nx)     #un是一个临时数组 for n in range(nt):      un = u.copy()     for i in range(1,nx):        u[i] = un[i]-c*dt/dx*(un[i]-un[i-1])pyplot.plot(numpy.linspace(0,2,nx),u)   #计算结果图像

这里写图片描述

Then, we may think we have two iterative operations: one in space and one in time (we’ll learn differently later), so we’ll start by nesting one loop inside the other. Note the use of the nifty range() function. When we write: for i in range(1,nx) we will iterate through the u array, but we’ll be skipping the first element (the zero-th element). Why?

Note—We will learn later that the code as written above is quite inefficient, and there are better ways to write this, Python-style. But let’s carry on.

Now let’s try plotting our u array after advancing in time.

OK! So our hat function has definitely moved to the right, but it’s no longer a hat. What’s going on?


Last but not least

Remember to rewrite Step 1 as a fresh Python script or in your own IPython notebook and then experiment by changing the discretization parameters. Once you have done this, you will be ready for Step 2.

1 0
原创粉丝点击