web自学1——HTML
众所周知,web 前端主要包括 HTML+CSS+JavaScript 三部分组成,其中 HTML
是超文本标记语言,CSS 是层叠样式表,JavaScript 是脚本语言。
以下学习的内容都是静态网页而非动态网页,不涉及服务器数据库之类的知识,目标之一是了解最基本的网页知识,例如可以写出几个简单的静态网页,并且利用
Hexo+Github Pages 部署,目的之二是看懂 Hexo
搭建博客的样式配置等。参考教程:https://developer.mozilla.org
HTML 定义了网页的内容
CSS 描述了网页的布局
JavaScript 控制了网页的行为
HTML
1. 元素
一个典型的 html 元素如下:
1<p class="note">content</p>
其中<p>是开始标签,</p>是结束标签,中间的content是元素的内容,class="note"是标签的属性。
上述元素是成对的,包括开始标签和结束标签,元素可以相互嵌套,例如
1<p>My cat is <stron ...
Cpp MPI学习笔记
本文是关于并行计算的学习,根据具体的实现方式不同,并行计算主要考虑两类方式:
以 MPI
为代表的多进程,不共享内存,进程之间通过消息传递机制进行通信;
以 OpenMP 为代表的多线程,共享内存;
本文主要针对的是 MPI,使用 C++ 接口。后续还可能有关于 OpenMP 和专门的
C++ 多线程库std::thread的学习。
多进程与多线程
对于系统而言,进程是资源分配的最小单位,直接点击可执行文件一般就会开启一个进程,执行当前的应用程序,分配独立的内存空间供其使用;线程是
CPU
调度的最小单位,线程必须隶属于进程而存在,一个进程默认拥有一个线程,也可以拥有多个线程,线程之间需要共享同一个内存空间。
对于多进程的直观理解,可以类比微信多开;对于多线程的理解,例如一个带
GUI
的科学计算器程序,至少拥有两个线程,其中一个线程处于等待状态,负责接收用户的界面操作信息,给出直观的反馈,另一个线程负责执行耗时的计算,防止计算任务对整个程序的运行造成阻塞。(如果只有一个线程,则执行耗时的计算过程中,图形界面就一直是卡死的状态)
多进程的编程中,关键是如何相互传递消息,因为默认情 ...
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} + (\mathbf{u}\cdot\nabla
\math ...
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 \mathbf{u}\\
\na ...
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 \cdot
\mathbf{u}\),对动量方程求散度,得到
\[
\begin{ali ...
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}
\]
对于不可压缩流动,有流函数\(\phi\),满足:
\[
\begin{aligned}
u &= \frac{\partial \phi}{\partial y}\\
v &= -\frac{\partial \phi}{\partial x}
\end{aligned}
\]
有的材料中,流函数定义相比上文都多一个负号,这不影响算法的本质。流函数的存在性其实就直接保证了不可压缩条件的成立:
\[
\nabla \cdot \mathbf{u} =
\frac{\partial u}{\partial x} +
\frac{\partial v}{\partial y}
= \frac{\parti ...
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 语言一样,数组的长度需要在编译时确定。 ...