diff --git a/66.Useful_Linux_commands.md b/66.Useful_Linux_commands.md new file mode 100644 index 0000000000000000000000000000000000000000..f9644db05684a02ac686dab228da17051d7f2c24 --- /dev/null +++ b/66.Useful_Linux_commands.md @@ -0,0 +1,225 @@ +# 66 有用的Linux命令 + +## 66.1 获取帮助 + +### 66.1.1 显示 -help + +几乎所有Linux命令都能显示它的作用和使用摘要。要显示此消息,必须使用以下参数之一调用该命令:`-h`,`-help`, `--help`。如果使用了错误的参数,则无论如何都会显示帮助消息,或者显示一条错误消息,其中包含了如何给定正确的参数以显示使用信息,参见代码508。 + +```sh +user@host :∼$ ls -help +ls: invalid option -- e +Try ‘ls --help ’ for more information . +user@host :∼$ +``` + +代码508:显示帮助信息。 + +显然OpenFOAM中的所有工具和求解器都显示类似的帮助信息。强烈鼓励新的Linux和OpenFOAM用户学习帮助信息以加深自己的理解。 + +### 66.1.2 man页面 + +许多Linux命令有一个额外的、更详细的文档。该文档在*man*页面中(*man*是manual的缩写)。要显示特定命令的*man*页面,是需要在`man`后面加上程序或命令的名称。代码509展示了如何显示Linux命令`cp`的*man*页面。 + +```sh +man cp +``` + +代码509:显示*man*页面。 + +*man*页面涵盖了Linux的常规命令,系统调用,C标准库的库功能等等。在某些系统上,默认情况下仅部分安装或完全不安装*man*页面。 + +## 66.2 查找文件 + +### 66.2.1 系统范围内搜索 + +可以使用命令`locate`在系统范围内搜索文件。代码510展示了搜索`icoFoam`源代码的结果。(译者注:需要先使用命令`sudo updatedb`更新文件数据库) + +```sh +user@host :∼/OpenFOAM/user-2.1.x/run/icoTurb$ locate icoFoam.C +/home/user/OpenFOAM/OpenFOAM-2.0.x/applications/solvers/incompressible/icoFoam/icoFoam.C +/home/user/OpenFOAM/OpenFOAM-2.1.x/applications/solvers/incompressible/icoFoam/icoFoam.C +``` + +代码510:查找*icoFoam.C*文件。 + +### 62.2.2 指定文件夹中搜索 + +可以在指定目录及其子目录中查找文件。代码511展示了在OpenFOAM算例目录中查找文件LESProperties。 + +```sh +find $FOAM_TUTORIALS -name LESProperties +``` + +代码511:在算例目录中查找*LESProperties*。 + +## 66.3 查找文件并扫描内容 + +*我该如何定义probes?我以前见过,但是在哪呢?* + +要回答该问题,必须查找所有定义*probes*的*controlDict*文件。此外,通过搜索返回的所有文件都必须扫描以查找*probes*的定义。因为OpenFOAM算例由许多文本文件组成,很容易使用相关命令扫描这些文件。因此,以上问题的回答是:查找所有*controlDict*文件,然后扫描它们查找其中的probe单词。 + +无需手动执行此任务,只需要在终端机中执行一行代码就解决了。代码512显示了如何查找算例目录中所有名为*controlDict*的文件并对其进行扫描以查找单词probe。 + +```sh +find $FOAM_TUTORIALS -name controlDict | xargs grep 'probes' -sl +``` + +代码512:查找并扫描文件。 + +`find`分别在指定的目录及其子目录中查找文件,文件名称由**-name**选项指定。 `xargs`将查找到的每个文件分别作为标准输入,构建并执行后面的命令。`find`的输出通过管道作为输入传递给`grep`(译者注:查找得到很多文件,经过`xargs`之后就能将这些文件分开,让`grep`依次处理每个文件)。然后`grep`扫描所有文件以查找单词probes。 + +**git以另一种形式实现** + +如果OpenFOAM是从git源代码存储库安装的,我们还可以使用git搜索模式。在这里,将根据所提供的模式搜索所有(已跟踪的)文件。使用git的原因是git以非常有效的方式跟踪文件内容。因此搜索通常会更快,尤其是当我们扫描大量文件的时候。例如如果我们想知道在源中**VGREAT**的定义。 + +在上面的示例中,我们需要切换到算例目录,然后告诉git搜索模式"probes"。这将导致整体搜索,而不仅限于controlDicts。实际上,我们还发现了一些清理脚本。 + +```sh +cd $FOAM_TUTORIALS +git grep probes +``` + +代码513:使用`git grep`扫描文件。 + +## 66.4 扫描日志文件 + +`grep`能扫描文本文件中的特定模式。在这个例子中我们想扫描求解器的输出,以匹配特定的模式。求解器twoPhaseEulerFoam在每个时间步都显示了体积分数$\alpha$的最小和最大值。由$\alpha$的物理意义可知,它的值必须在范围$0\leq \alpha \leq 1$内。 + +本例模拟崩溃了,主要怀疑有$\alpha>1$的情况。代码514展示了两行求解器输出。第一行可以发现$\alpha$的最大值是1。在某些情况下,某个区域演变到连续相消失的时候,比如在水面上,$\alpha=1$是完全合理的。第二行可以看到$\alpha$的最大值大于1。这是非物理的。 + +由于模拟通常不会立即崩溃,而包含求解器输出的日志文件的经常长达数十万行。手动寻找$\alpha$的最大值大于1是不可取的。我们需要一种能够自动为我们完成任务的命令。这时候*grep*就派上了用场。 + +```sh +Dispersed phase volume fraction = 0.194351 Min ( alpha ) = 7.52826e -42 Max ( alpha ) = 1 +Dispersed phase volume fraction = 0.060562 Min ( alpha ) = 2.30261e -52 Max ( alpha ) = 1.00003 +``` + +代码514:示例:关于体积分数的求解器输出。 + +代码515展示了用户如何以合适的模式来扫描日志文件。`grep`的第一个参数即为要搜索的模式。第二个参数是可选的,它指定了要扫描的文件从哪里读取。如果不指定文件,那么`grep`就会从标准输入读取。选项**-c**使`grep`值显示匹配到的数量。否则,`grep`会显示所有匹配到的行。某些情况下匹配到的数量可能成百上千,这时候显示所有匹配行不是明智的选择。 + +代码515的第一个命令会匹配代码514中的两行。因此模式'Max(alpha) = 1'对于确定$\alpha$是否大于1毫无帮助。代码515的第二个命令只匹配哪些$\alpha$大于1的行。因此,在代码514的两行中,只有第2行会被匹配到。 + +```sh +grep ’Max(alpha) = 1’ foamRun.log -c +grep ’Max(alpha) = 1.’ foamRun.log -c +``` + +代码515:使用`grep`扫描日志。 + +## 66.5 在脚本中运行 + +### 66.5.1 开始批量任务 + +要发挥集群的计算能力,最好让集群批量进行工作。要实现这点,这节说明如何使用脚本按顺序执行多个模拟任务。这样就能在集群上计算大量算例,而不需要用户单独地开始每个任务,尤其是需要整晚计算的时候。 + +代码516给出的脚本启动两个并行的任务,其中包含了计算域划分和重建。该脚本假设其在一个包含两个算例的目录中执行。第1组命令先切换到当前目录的一个子目录中(`cd './fullColumn_fineV01'`)。然后并行地执行任务。之后脚本会切换到第2个算例目录中(`cd '../fullColumn_fineV02'`)。 + +这是一个很基础的脚本,其中没有包含检查模型是否提前终止或者其他有用的特性。 + +```sh +#!/bin/bash +# fine 01 + +echo 'fine01' +cd './fullColumn_fineV01' + +echo 'decomposing' +decomposePar > foamDecompose.log + +mpirun -np 2 twoPhaseEulerFoam -parallel > foamRun.log + +echo 'reconstructing' +reconstructPar > foamReconstruct.log + +# fine 02 +echo 'fine02' +cd '../fullColumn_fineV02' + +echo 'decomposing' +decomposePar > foamDecompose.log + +mpirun -np 2 twoPhaseEulerFoam -parallel > foamRun.log + +echo 'reconstructing' +reconstructPar > foamReconstruct.log +``` + +代码516:使用shell脚本启动多个模拟。 + +### 66.5.2 终止正在运行的脚本 + +有时候可能需要停止脚本继续执行,而不终止当前正在进行的算例。本例中假设一个名为`runCalculations`的脚本需要被终止。首先需要知道`runCalculations`的`PID`号。在Section 12.3.2中详细地解释了如何获取`PID`号。代码516展示了如何搜索PID号,其中有两行输出。第1行表示正在运行的脚本,第2行对应正在并行计算的算例。这是因为所有并行算例都能被模式`run`匹配到(译者注:`mpirun`中包含了`run`)。因此,正在运行的`mpirun`实例也被发现了。 + +```sh +user@host :∼$ ps -el | grep run +0 S 8553 14913 14517 0 80 0 - 2687 wait pts /11 00:00:00 runCalculations +0 S 8553 14917 14913 0 80 0 - 2687 wait pts /11 00:00:00 mpirun +user@host :∼$ +``` + +代码517:使用`ps`和`grep`命令搜索`PID`号 + +**终止脚本** + +如果使用`kill`命令终止了正在运行的脚本,正在进行的模拟任务并不会受到影响。代码518展示了如何终止脚本,并且检查`mpirun`仍然在运行。 + +```sh +user@host :∼$ ps -e | grep run +14913 pts /11 00:00:00 runCalculations +14917 pts /11 00:00:00 mpirun +user@host :∼$ kill -KILL 14913 +user@host :∼$ ps -e | grep run +14917 pts /11 00:00:00 mpirun +``` + +代码518:使用`kill`来终止shell脚本 + +**终止脚本和算例** + +本例要将脚本和算例都终止。如果只是终止正在运行的算例,那么脚本会继续执行下一条命令。因此,需要首先终止脚本,然后再终止正在运行的算例。 + +## 66.6 diff 文件差异比较工具 + +`diff`是一个命令行工具,用来分析并打印出两个文件之间的差异。详细的信息可以在`diff`的*man*页面或帮助信息中查看。 + +### 66.6.1 Meld + +`Meld`是`diff`的一个图形化前端。它可以将要研究的两个文件并排比较。文件的不同部分用颜色高亮突出显示。更多关于`Meld`的信息可以参考:[http://meldmerge.org/](http://meldmerge.org/)。 + + + +## 66.7 算例设置 + +在设置算例的时候需要完成许多任务。即使是从OpenFOAM自带的算例开始,也需要先做一些乏味的工作。对于特定的任务,计算机表现比人类要好。因此,我们最好将这些乏味的任务自动化。`pyFoam`库是一个包含许多有用工具的集合。然而,有些任务需要多行命令才能完成。这就是这一节要讨论的内容。 + +### 66.7.1 文件重命名 + +当前的多相求解器使用一种命名方案,其中相的名称确定文件的扩展名。因此,气相的热物理性质存储在文件`thermophysicalProperties.air`中。在某些情况下,这导致需要重命名许多文件。比如这里我们将氩气选为气相,并且希望遵守命名OpenFOAM的命名规范。直接的办法是只将空气的性质改为氩气的,而不改变气相的名称(译者注:此时`air`只是气相的代表,不再只表示空气)。 + +在Linux中,有许多方式能够处理这类任务。对于纯文本替换,一种解决方案是基于正则表达式。代码519显示了如何使用命令`rename`来重命名包含特定文本的所有文件。 + +```sh +rename 's/air/argon/g' ./* +``` + +代码519:改变所有文件的扩展名,将air改变为argon。 + +## 66.8 其他内容(杂项) + +本节包含本文档其他位置介绍的一些有用脚本或命令的引用。 + +### 终止后台进程 + +参见Section 12.3.2。 + +### 删除processor*目录 + +如果在集群上计算了1个或多个算例,那么很自然地就会想在节点上合并求解域(译者注:执行`reconstructPar`)。否则用户在自己电脑上可能需要花费很多时间来完成这一步。在求解域合并之后,*processor\**目录仍然包含着每个时间步的数据。如果*processor\**目录在集群上就完成了合并然后删除,那么用户就可以只拷贝算例目录,而无需再关心这个转换的过程。 + +参见Section 12.5.2 查看如何处理*processor\**目录。 + +### 重定向输出 + +重定向程序输出在Section 12.1.1介绍。 \ No newline at end of file diff --git a/67.Archive_data.md b/67.Archive_data.md new file mode 100644 index 0000000000000000000000000000000000000000..b95f387cd8840fb541baec8f08727c55db6ba047 --- /dev/null +++ b/67.Archive_data.md @@ -0,0 +1,78 @@ +# 67 数据归档 + +参数研究的过程中会生成大量数据。在后处理完成后,所有文件就可以压缩一下,以节省磁盘空间。在Linux系统中`tar`归档工具是首选。`tar`的命名很有描述性,来源于`tape archive`(译者注:分别取首字母`t`和`ar`)。一个`tar`归档就是一个单独的文件,其中包含了所有被归档的文件和文件夹。归档过程仅是数据的重组,适合于顺序数据存储设备(如磁带)的使用。 + +`tar`归档的第二步是压缩。这一步有许多选择。Linux系统通常提供了`gzip`、`bzip2`或`xz`等程序。之所以要把归档和压缩分开,可能是处于历史或者实际原因。也可能是遵循了UNIX哲学:让每个程序只做好一件事。压缩程序之间的差别在于压缩算法。有一条经验法则:要压缩的数据越多,压缩所需要的时间就越长。 + +表8列出了归档并压缩一个参数研究的结果,包含21个算例、共计50 GB数据。这些数据都是以ASCII格式写入的。压缩这些数据结果能节省70+%的磁盘空间。如果归档占用磁盘空间很大的算例,一般偏向于选择运行更耗时的算法,这样能得到更好的压缩率。 + +| | 占用磁盘空间 | 压缩 | +| ------------------- | ------------ | --------------- | +| 21个未压缩的算例 | 50 GB | - | +| 压缩后:`*.tar.bz2` | 13.7 GB | 36.3 GB - 72.6% | + +## 归档日志文件 + +这个例子展示日志文件的归档。这种情况下使用相同的算法节省了更多的磁盘空间。本例说明了归档压缩率与输入数据有很强的关系。 + +| | 占用磁盘空间 | 压缩 | +| ----------------------- | ------------ | --------------- | +| 16个未压缩的磁盘空i教案 | 2.0 GB | - | +| 压缩后: `*.tar.bz2` | 154.7 MB | 1.85 GB - 92.3% | + + + +## 另一个压缩比较 + +归档OpenFOAM算例的时候在OpenFOAM前处理时(译者注:原文有误,意思不通),网格的生成可能非常复杂或耗时。因此一般会将网格与算例分开归档。这样,对于实际的算例,我们只需要直接解压之前归档的网格,而不需要困扰于网格创建。 + +这一节比较了Linux系统下3个压缩工具在压缩同一个网格时的表现。所采用的网格使用*blockMesh*命令创建,相关的文件使用二进制格式保存。 + +代码520展示了实际所使用的用于压缩网格的命令。 + +```sh +tar -cv polyMesh | gzip --best > polyMesh.tar.gz +tar -cv polyMesh | bzip2 --best > polyMesh.tar.bz +tar -cv polyMesh | lzma -9 > polyMesh.tar.xz +``` + +代码520: 用各种工具压缩网格;注意最大压缩设置。 + +```sh +user@host :∼$ du -sh polyMesh * +23M polyMesh +5,3M polyMesh.tar.bz +6,2M polyMesh.tar.gz +2,6M polyMesh.tar.xz +``` + +代码521: 比较原始网格及其不同压缩形式下磁盘的使用情况 + +代码521展示了原始以及压缩后的网格大小。所使用的压缩算法差异很大。各个工具都采用了最大压缩设置,这里没有记录每个工具的压缩耗时。但是压缩率越大,所需要的时间越多。由于是出于归档目的,磁盘空间是限制因素,因此我们往往会选择最大压缩率。 + +从代码521的比较中,我们可以看出`LZMA`压缩算法达到了最大压缩率,然后是`BZIP2`,最后是`GZIP`。这三种压缩算法都以开源实现的形式在UNIX世界中广泛使用。 + +## 网格重新编号和/或以二进制格式保存的影响 + +当使用不同的方式归档已有的网格时,可以观察到一些很有趣的现象:网格是否重新编号会影响归档文件的大小。注意这里只是归档网格,不考虑与之相关的求解数据(或场)。 + +表10中我们比较了一个全六面体、包含147262个单元的网格在归档之后文件的大小。网格本身所需要的磁盘空间只与存储格式有关,即ASCII或二进制格式。网格重新编号对网格的大小没有影响,这也很容易理解,因为重新编号并没有添加或删除信息。因此,网格所需的磁盘空间应该也不糊因为重新编号而改变。 + +然而,重新编号却对最终归档文件大小有一定影响(译者注:区别于前面的介绍,一般说的归档,应该指的是归档并压缩)。当网格以二进制格式写入磁盘时,压缩原始(as-is)网格只会产生微小的磁盘空间变化。但是最令人意外的是,当我们分别在两种情况下(ASCII和二进制)比较重新编号网格最终的归档文件大小,重新编号的网格压缩后的文件大小竟然比原始网格压缩后的文件还大。 + +| 网格 | ASCII | 二进制 | +| -------- | ----- | ------ | +| 原始 | 22 M | 16 M | +| 重新编号 | 22 M | 16 M | + +| 归档 | ASCII | 二进制 | +| -------- | ----- | ------ | +| 原始 | 17 M | 16 M | +| 重新编号 | 25 M | 20 M | + +Table 10: 比较不同条件/处理下网格归档文件的大小。这里所有的文件或文件夹的大小都使用Linux命令`du -sh FILE`确定。网格使用`LZMA`算法以最大压缩率压缩:`tar -cv constant/polyMesh | lzma -9 > polyMesh.tar.xz`。 + +从这组比较中可以得出两个结论。最明显的是,以二进制格式写入数据总是比以ASCII格式写入更好,对没有压缩的数据其占用磁盘大小的差异尤为明显。ASCII格式应该只在排查问题的时候选用。在实际作业中,应该选择二进制格式。以二进制格式写数据不仅能在存储上节省磁盘空间,也能提供最大读/写精度,因为每个数值的所有位都被保留了。相比之下,ASCII格式只是写入有限数量的有效位。(译者注:二进制读写速度也比ASCII快,计算时能节省写入数据的时间,后处理时能节省读取数据的时间) + +从以上对比可以得出的第二个结论是:不要保存重新编号后的网格。即使重新编号不会增加归档文件的大小,它也是在模拟前很容易进行的操作。重新编号所需要的时间相比于总的模拟时间来说可以忽略。因此,建议在未重新编号的状态下归档网格。除了可以节省存储空间外,这还使将来的用户可以选择是否在重新编号的网格上进行模拟。对于已经重新编号的网格,无法确定网格重新编号在模拟时间和收敛性上有何优势。只需执行必要的操作进行计算模拟,不用归档该网格。 + diff --git "a/\347\277\273\350\257\221\347\253\240\350\212\202\350\256\244\351\242\206.md" "b/\347\277\273\350\257\221\347\253\240\350\212\202\350\256\244\351\242\206.md" index 9ee79bbc69a76d9e612e2ba3f5f690c1635f1b4b..d2d5238d476f232309573e45651f91f589a6bfff 100644 --- "a/\347\277\273\350\257\221\347\253\240\350\212\202\350\256\244\351\242\206.md" +++ "b/\347\277\273\350\257\221\347\253\240\350\212\202\350\256\244\351\242\206.md" @@ -63,9 +63,9 @@ ### 51 **ParaView 273** ### 52 postProcess 280. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . skf0558 ## VII External Tools 281 -### 53 **pyFoam 281** -### 54 **swak4foam 288** -### 55 **blockMeshDG 290** +### 53 **pyFoam 281** . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xfygogo +### 54 **swak4foam 288** . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xfygogo +### 55 **blockMeshDG 290** . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xfygogo ## VIII Source Code & Programming 292 ### 56 Understanding some C and C++ 292. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .luofq ### 57 Under the hood of OpenFOAM 299.. .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .luofq