INSE学习笔记——6. SIMPLE算法
SIMPLE 算法全称是压力耦合方程组的半隐式方法(Semi-Implicit Method for Pressure Linked Equations), 作为经典的压力修正算法在 Fluent 等工业软件中被广泛应用。 SIMPLE 算法介绍 考虑无量纲化的二维不可压缩方程组 \[ \begin{aligned} \frac{\partial \mathbf{u}}{\partial t} + (\mathbf{u}\cdot \nabla) \mathbf{u} &= -\nabla p + \frac{1}{Re} \nabla^2 \mathbf{u}\\ \nabla \cdot \mathbf{u} &= 0\\ \end{aligned} \] 现在我们已有 \(\mathbf{u}^n\),希望下一步的 \(\mathbf{u}^{n+1},p^{n+1}\) 满足 \[ \begin{aligned} \frac{\mathbf{u}^{n+1}-\mathbf{u}^n}{\Delta t} +...
INSE学习笔记——5. 投影法
投影法也称为时间分裂法,分步法,按照思路分为两类: 第一类基于 N-S 方程组的半离散格式,基于 Helmholtz 分解定理; 第二类基于 N-S 方程组的全离散格式,采用近似算子分裂/近似矩阵分裂。 下文只包括第一类投影法。 Helmholtz 分解定理 对于任意光滑的向量场\(V\)可以唯一分解为一个无源场 \(V^d\) 和一个无旋场 \(\nabla \phi\) 之和。 \[ V = V^d + \nabla \phi \] 满足 \(\nabla \cdot V^d = 0\), 和 \(\nabla \times \nabla \phi=0\)。 这一说法是不严谨的,因为唯一性需要向量场满足一定的边界条件,暂时略过边界的考虑 投影法简介 考虑无量纲化的二维不可压缩方程组 \[ \begin{aligned} \frac{\partial \mathbf{u}}{\partial t} + (\mathbf{u}\cdot \nabla) \mathbf{u} &= -\nabla p + \frac{1}{Re} \nabla^2...
INSE学习笔记——4. MAC方法
标记网格法(Marker-and-Cell method,MAC),是一种求解压力 Poisson 方程算法,最初被设计用于求解含自由面的不可压缩流动,下文的算法并不涉及自由面,只是关注对不可压缩条件的处理。 求解压力 Poisson 方程算法 求解压力 Poisson 方程算法是一大类 N-S 方程的求解算法,它的特点是:通过求解一个 Poisson 方程获取压强 \(p\),并且使得速度散度为零间接地得到满足。(张德良,计算流体力学教程) 考虑无量纲化的二维不可压缩方程组 \[ \begin{aligned} \frac{\partial \mathbf{u}}{\partial t} + (\mathbf{u}\cdot \nabla) \mathbf{u} &= -\nabla p + \frac{1}{Re} \nabla^2 \mathbf{u}\\ \nabla \cdot \mathbf{u} &= 0\\ \end{aligned} \] 记 \(D = \nabla...
INSE学习笔记——3. 人工压缩性方法(ACM)
人工压缩性方法(ACM),主要用于求解不可压缩定常流问题。 人工压缩性方程 考虑无量纲化的二维不可压缩方程组 \[ \begin{aligned} \frac{\partial \mathbf{u}}{\partial t} + (\mathbf{u}\cdot \nabla) \mathbf{u} &= -\nabla p + \frac{1}{Re} \nabla^2 \mathbf{u}\\ \nabla \cdot \mathbf{u} &= 0\\ \end{aligned} \] 由于缺少 \(\frac{\partial p}{\partial t}\),难以计算压强,因此引入人工压缩性因子 \(\beta >0\),使得连续性方程替换为人工压缩性方程: \[ \frac{\partial p}{\partial t} + \beta \nabla \cdot \mathbf{u} = 0 \] 这里的人工压缩性因子 \(\beta\) 相当于声速的平方 \(c^2\),也可以从物理的角度进行理解,在 \(\beta >0\)...
INSE学习笔记——2. 涡量流函数法
通过把原始变量(速度,压强)转化为导出变量(涡量,流函数)的方程组,可以避开处理压强时的困难,称为涡量流函数方法。 涡量和流函数 对于二维的流动,记速度 \(\mathbf{u}=(u,v)^T\),则涡量 \(w\) 只是一个标量,定义为 \[ w = \frac{\partial u}{\partial y}-\frac{\partial v}{\partial x} \] 对于不可压缩流动,有流函数 \(\varphi\),满足: \[ \begin{aligned} u &= \frac{\partial \varphi}{\partial y}\\ v &= -\frac{\partial \varphi}{\partial x} \end{aligned} \] 有的材料中,流函数定义相比上文都多一个负号,这不影响算法的本质。流函数的存在性其实就直接保证了不可压缩条件的成立: \[ \nabla \cdot \mathbf{u} = \frac{\partial u}{\partial x} + \frac{\partial v}{\partial...
INSE学习笔记——1. 概述
1 N-S 方程 无量纲化的不可压 N-S 方程组如下: \[ \begin{aligned} \frac{\partial \mathbf{u}}{\partial t} + (\mathbf{u}\cdot \nabla) \mathbf{u} &= -\nabla p + \frac{1}{Re} \nabla^2 \mathbf{u}\\ \nabla \cdot \mathbf{u} &= 0\\ \end{aligned} \] 下文将不可压 N-S 方程组简写为 INSE。与可压缩流动相比,不可压缩流动有如下特点: INSE 的压强:只出现在动量方程中,从数学上只是起到了一个 Lagrange 乘子的作用,失去了热力学意义; INSE 不含压强的时间导数项 \(p_t\) ,压强 \(p\) 的显式计算比较困难,往往需要求解一个全局的 Poisson...
Fortran学习笔记——5.其他
一些琐碎的小部分,放在最后。 自定义类型 Fortran 90 支持自定义类型,相当于 c 语言的结构体。 12345678910111213141516program main implicit none type :: person integer :: age integer :: height integer :: weight end type person type(person) :: a ! 声明a是一个person类型的变量 ! %用于提取结构体的分量 read(*,*) a%age, a%height, a%weight write(*,*) a%age, a%height, a%weight stopend program main 字符/字符串 在前面的基本数据类型的笔记中,我们特意完全忽略了字符和字符串的部分,只是在 write 语句中使用了字符串常量。 注:Fortran 对于字符串的处理效率比较慢,谨慎使用——数值计算其实也没什么字符串处理的需求。 与 c...
Fortran学习笔记——4.数组,指针与数值计算
在前三篇笔记,学习了 Fortran 作为一个编程语言,最基本的内容:变量,输入输出,流程控制和程序结构。接下来是 Fortran 的数组以及基于数组的数值计算,我认为这是 Fortran 语言最有价值的精华部分,因此特意放在了学习笔记靠后的部分,在学习了基本的语法和子程序等之后。注意,Fortran 的字符集不包括中括号[],因此与 c 语言的风格不同,Fortran 对数组分量的操作全都是使用小括号()的。 因为这部分内容比较重要,不像前几篇对 Fortran 77 的上古语法大部分进行了忽略,这一篇对于 Fortran 77 的语法也进行介绍。 一维数组 最基本的一维数组声明如下 123integer :: nums(10)integer, parameter :: len = 20real :: datas(len) 一维数组的类型可以是 integer, real, complex, logical 四种基本类型,(也可以是字符或者自定义类型,暂时不管)一维数组的长度可以是字面值常量,也可以是声明为 parameter 的整数——和 c...
Fortran学习笔记——3.子程序, 函数与模块
与 c 语言只有函数不同,Fortran 提供了子程序 subroutine,函数 function,模块 module 等多种结构。 子程序 subroutine 首先,回顾之前的 HelloWorld 1234program main implicit none write(*,*) "hello,world!"end program main 其中使用了名称为 main 的主程序 program,一个可执行程序只允许有一个 program,为了分离和复用某个功能,可以使用子程序 subroutine。 123456789101112program main implicit none write(*,*) "hello,world!" call hello() ! call 调用子程序end program mainsubroutine hello() implicit none write(*,*) "hello,subroutine!"end subroutine...
Fortran学习笔记——2.流程控制
第一部分基本内容包括了变量的声明,输入输出语句,接下来是条件语句和循环语句等运算的流程控制。 if 条件语句 无需多言,例子即可: 1234567891011121314151617if(a > 10) then ! do somethingend ifif(a > 10) then ! do 1else ! do 2end ifif(a > 10) then ! do 1else if(a > 5) then ! do 2else ! do 3end if 在 if 后面必须接 then,if 和 end if 构成一个标准的条件结构。支持 if 结构的嵌套。可以使用简单的单行 if,不需要 end 和 then。 1if(a>10) b=a 逻辑语句和逻辑运算 在 if 语句之后,顺便介绍逻辑类型和运算。逻辑类型:.true.,.false.。0 被视作 false,1 被视作 true。 12logical varvar = (a>10) 逻辑运算: Fortran...