我的bilibili视频:freecad流体全过程快捷分析详细讲解https://www.bilibili.com/video/BV11NuU6iE56

这里只关心freecad的cfdof工作台里的二相流自由液面multiphase-free surface问题,其他如水轮机叶片旋转等动态网格(Dynamic Mesh)不在本笔记范畴
流体模拟工作台
https://github.com/jaheyns/CfdOF
https://wiki.freecad.org/CfdOF_Workbench

实操:
A new series of 10 tutorials about Freecad CfdOf
https://forum.freecad.org/viewtopic.php?t=68499
openfoam用户指南:第1章-关注paraview的使用
http://dyfluid.com/openfoam11-2-1.html
FreeCAD CFD 工作台,配备 OpenFOAM v2106
https://solvercube.com/sf/1nm/freecad/freecad-0-19-x-cfd-openfoam_210808/4wordpress.html

理论部分需要阅读:
openfoam用户指南第4案例-溃坝分析-二相流——关注边界
https://www.openfoam.com/documentation/tutorial-guide/4-multiphase-flow/4.1-breaking-of-a-dam
openfoam用户指南:第2章-溃坝分析,上文的翻译
http://dyfluid.com/openfoam11-2-2.html
CFD: 多相VOF算法 + 相变
http://www.dyfluid.com/interFoam.html
无痛苦N-S笔记中的6.12 OpenFOAM 中的边界条件
http://dyfluid.com/index.html
http://www.dyfluid.com/theory.pdf

西南交通DSPH计算顺序
https://github.com/DualSPHysics/DesignSPHysics
https://faculty.swjtu.edu.cn/weikai1/zh_CN/article/136968/content/2743.htm

中文视频特别少,尤其是freecad cfdof工作台的,可以下载youtube视频,上传到bilibili里,平台一般会自动生成字幕,播放时手动将字幕调成中文。要么就用抖音的剪映专业版,直接提取双语字幕。

我转载的有针对性的二相流视频:
https://www.bilibili.com/video/BV1UGu36KEuT
https://www.bilibili.com/video/BV1mGu36KEXp
cfdof论坛里搜multiphase、two phase、volume fraction等关键字

0 疑问

  1. ★问:水和空气分别怎么定义?需要指定2个区域body的“材料”属性吗?例子里怎么没有指定空气区域?
    流体力学和结构力学有限元思路不同,它有个默认场(区域)流体属性。
    FreeCAD中cfdof工作台有两个定义最是烧脑,一个是初始化field(场)——Initialise flow field;一个是初始化zone——Initialisation zone,前者定义整个分析场里某个流体占主导,后者定义某个局部区域的流体属性
    网络释义英文单词区别:“area”可指任何大小的空间或范围,“field”指视野宽的领域如足球场,“zone”指有明确边界和特定目的的功能区域
    这里涉及几个流体力学概念,多相流自由液面(multiphase-free surface)用VOF(Volume of fluid)多相流方法,FC调用openfoam开源类库模拟分析流体,openfoam里用interFoam求解器,interFoam调用了FCT算法;
    知识:VOF,考虑某一个网格单元的气液两相系统,如果此网格单元内充满了流体,则α=1(α在cfdof工作台里叫volume fraction);如果此网格单元内充满了气体,则α=0。如果α的值介于0和1之间,则此网格单元内为气液混合。——qin注:这里说的α,在cfdof里要看“主对象流体”,即fc目录树里第一个流体属性,如果第一个流体是空气,那么α=1表示全是空气,α=0表示全是水;如果第一个流体是水,那么α=1表示全是水,α=0表示全是空气。
    下列VOF公式的主体是ρ1 ρ = α 1 ρ 1 + ( 1 α 1 ) ρ 2 在二相流分析情况下,即水和空气,field和zone它们对应的volume fractions是1或0怎么设置?
  • 1.首先是设置主流体属性,选空气还是水?
    答:谁动就填谁原则?水入空气,就先设置水的属性,到下面field里只能选先设置的那个;泄流就选水为主流体。
  • 2.到Initialise flow field,只能选择上述先设置得那个流体。看区域里是什么,是本身,则volume fractions填1,如果不是本身,则volume fractions填0。
  • 3.入口是否要单独画一个zone?入口处流入的流体和周边区域(整个场的设置)设置的一致,则不用另外画一个zone,如果不一致,则要单独画。其他位置道理也一样,如果罐体里的某块流体和区域(场)不一致,就得另外画个zone。
  • 4.是画水体zone还是画空气zone?看整个区域(场)在最开始状态下占最小原则?例如溃坝,初始状态就一块水体,容易绘制zone;例如空气吹入水体中再跑到空气中,初始状态水体是固定的一块,容易画zone。——这么看来,始终是画水体zone了?有反例吗?
  • 5.举例:
    例如,空气通过管子从下方吹入罐体的水中,罐体上方开敞,先设置空气的属性,field里只能选空气——所以field这里设置空气的volume fractions填1;而入口处也是吹空气,和整个区域(场)相同,所以入口处不需要另外画一个气体包裹的zone;考虑区域(场)里都按空气,罐子里的水体需单独画一个zone,这个zone只能选择前面设置的空气,空气的volume fractions填0
    溃坝是水进入空气,所以先设置水体的属性,到field里只能选水,区域(场)里都按空气设置,所以filed里水的volume fractions填0,入口处周边对应区域设置,是空气,所以必须另外要画一个水体的zone,该水体zone对应的volume fractions是1
  1. 问:边界条件里,入口inlet什么时候设置速度,什么时候设置流速和压力?出口呢?
    入口一般是流速和大气压,出口是大气压,出口速度是未知的。

  2. 问:边界条件
    boundary文件的内容是可读的,可以使用文件编辑器打开,或使用cat工具在终端窗口中输出其内容。cat工具命令如下:
    cat constant/polyMesh/boundary
    该文件包含了五个边界,分别是:leftWall、rightWall、lowerWall、atmosphere以及defaultFaces。值得注意,关注这些边界的类型是必要的。
    首先,atmosphere是一个标准的patch,即它不具备任何特殊属性,仅仅是一个用来指定边界条件的单元。 其次,defaultFaces是由在blockMeshDict文件的boundary子字典中被省略的区所构成的,这些被省略的区块共同组成了一个patch,其相关属性在blockMeshDict文件中的defaultPatch子字典里进行了详细规定。本案例中,由于该patch的法线方向是在这个二维案例中无法求解的方向,因此默认类型设置为空。
    leftWall、rightWall和lowerWall边界均设定为wall类型。与通用的patch相似,wall类型不包含任何关于网格的几何或拓扑信息。它与标准的patch的区别仅在于,wall类型将区块标识为壁面。这对于特定模型来说是必要的,例如湍流壁函数,还有一些在计算中需要考虑距最近壁面距离的湍流模型。
    defaultFaces边界代表二维域的前后平面,与atmosphere一样,是一个空类型。特别是在VOF模拟中,表面张力模型可以模拟界面与壁面接触点之间的壁面粘附效应。壁面粘附模型可通过在alpha(α)场上应用特定的边界条件来实现,例如使用constantAlphaContactAngle边界条件,此时需要设定一个静态接触角theta0。
    本例忽略壁面与界面之间的表面张力效应。要实现这一点,一种方法是设置静态接触角,另一种方法是在壁面上对alpha应用zeroGradient条件。
    顶部边界与大气相通,因此需根据内部流动情况允许同时存在流出和流入。为了实现这一点并保持流动稳定性,需要将压力和速度的边界条件相结合。这些边界条件包括:
    prghTotalPressure 这一边界条件应用于压力场,但要减去由公式6.3给出的静水压分量;
    pressureInletOutletVelocity这一边界条件应用于速度U,该条件会对速度U的所有分量设置zeroGradient(零梯度),但在流入区域,则对切向分量应用fixedValue(固定值)条件;
    inletOutlet 这一边界条件应用于其他场,在向外流动时表现为zeroGradient条件,在向内流动时表现为fixedValue条件。
    在所有壁面边界上,fixedFluxPressure边界条件应用于压力场,并通过调整压力梯度,使边界通量与求解器(包括重力和表面张力等体力)的速度边界条件相匹配。

  3. 问:湍流模型和层流模型怎么选?
    假定流动过程没有涡旋,因此设置为层流simulationType laminar,因为二相流在fc中必须选择瞬态transient,再选择多相流-自由表面multyphase-free surface,再选择Turbulence里的层流 laminar

  4. 问:paraview里如何展示流场流线,以及对壁面的压力和负压?

  5. 问:模型比例问题,是建立1:1模型还是建立缩尺模型?

  6. 其他
    http://www.dyfluid.com/interFoam.html

1 坑

1.所有路径不包含空格和中文!!否则会报错。
所有软件、依赖安装目录、算例都不要有空格和中文
2.一定要安装好CFmesh并用它来划分网格
3.计算要取消勾选并行计算,除非你安装了MPI啥的

4.安装过程中网络要用Devsidecar对github网站加速。
5.勾选 编辑——首选项——cfdof——append document name to output directroy,否则,所有的计算都放在根目录,彼此覆盖掉。

2 安装

它这个安装相对有点运气成分
1.打开DevSidecar,安装CfdOF工作台
工具——Addon Manager——有点慢,需要等一段时间,等加载完成——搜CfdOF
2.安装好工作台后切换到CfdOF工作台,编辑——首选项 左侧点CfdOF General 开始安装依赖
按下图中顺序做,因为后面的需要知道blueCFD所在路径才行。

2.1 openfoam下载,即BlueCFD
先点击Run dependency check按钮(上图第1步)
再离线下载blueCFD
https://github.com/blueCFD/Core/releases/
因为很大,所以单独下载:
git上release里复制最后一个“香港……”地址,粘贴到https://doget.nocsdn.com/#/
里获得快速下载地址,用IDM下载。


下载后,在上图FC preference面板中指向刚才下载的文件blueCFD-Core-2024-1-win64-setup.exe(上图第2步),点击install openfoam(上图第3步)。其实和手动安装没有区别。
这里安装注意安装路径要简单,不要有空格和中文。最好像我一样,直接安排到D盘下blueCFD目录下。
安装完成后要设置指向openfoam的路径(上图第4步)。
2.2 paraview下载安装
上述blueCFD已经包含了paraview,在FC面板里设置指向所在路径即可
如果要另外安装,那么下载msi,还有带MPI的没试过

2.3 cfmesh
这个文件较小(15M),可以直接点击安装按钮。但是我出错了好多次,设置好blueCFD的路径后,多安装几次,或者先安装下面的HiSA
虽然可以用Gmesh划分网格,但是感觉这个cfmesh最适用流体吧,速度特别快,网格也好,必须要安装好。
下载的话,由于有机器人验证策略,Edge/opera浏览器都进入不了sourceforge,用firefox浏览器

2.4 HiSA
这个直接点安装。
2.5 最后再点击Run dependency check按钮,在面板最下端的Output窗口里查看有没有错误和没有安装的依赖。如果有,再解决。

3 教程

建立模型,按mm尺度建立,厚度要大于等于网格最小尺度——建立流体分析——物理分析模型设置(稳态、瞬态,单相、多相,湍流模型选择)——流体参数设置(必须先设置一个主流体,水还是空气……)——初始化流场(势流、边界流,主流场里对应刚才设置的主流体,是一致的则volume fraction填1,不一致则填0)——入口边界inlet,大气压和流速——出口边界(outlet)大气压——中间边界(wall)——网格划分,二维的要求网格小于等于模型厚度,再选择2d方向的侧面,设置网格大小——求解,并行运行——结果查看设置paraview

我们水利上常用的两相流和自由表面的例子(即泄流~),请下载下来看看边界、初始参数等怎么设置即可。
https://forum.freecad.org/viewtopic.php?t=97757

3.1 我们随便建一个模型

3.2 流体分析设置和分析

6.11节第6节吧

  1. 分析基本属性
  2. 物理模型
    选择瞬态,多相自由表面,湍流里选择层流,重力是-9810m/s^2,注意模型的方向,默认在Y方向,根据你的模型,可能要改为Z方向。
  3. 初始化流场
    选择势流,指定大气压,volume fraction即分析场和第一流体一致则填1,不一致则填0。这里第一流体是水,但场里是空气,所以填0
  4. 解算属性
    要设置5s或10s
  5. 边界条件——进口——子类型
    wall都选无滑动
  6. 边界条件——边界类型
    这里的开放open和约束没搞懂
  7. 边界条件——出口——子类型
    静压包括了速度和压力,但是速度可以不设?因为出去的速度是算出来的?
  8. 边界条件——出口——均匀流速和静压 描述

3.3 结果查看设置

6.12节里第6节吧
paraview基础用法
https://docs.paraview.org/en/latest/Tutorials/SelfDirectedTutorial/basicUsage.html
https://wiki.freecad.org/Post-Processing_of_FEM_Results_with_Paraview

3.4 动画导出

1.自带的file>save Animation,格式选择MP4即可

2.用哔哩哔哩直播姬软件录屏,注意参考这里设置分辨率,提高清晰度。再用必剪进行剪裁编辑视频后导出,另外,必剪可以识别语音为字幕

3.传统做法:
首先在 paraView中保存图片序列。点击file>save Animation,可以保存为tif, png, jpg等格式的图片序列。可以规定保存的帧数,默认是每个timestep一帧。注:图片很多的话最好建立一个新的文件夹。
其次把图片序列转换为视频或者GIF,有两种方式
第一种方式:利用OpenFOAM带的第三方后处理工具
算例文件夹下终端键入
foamCreateVedio
具体用法可以用 foamCreateVedio -help 查看
参考OpenFOAM_user_guide

3.5 残差simulation residuals

在OpenFOAM中,simulation residuals表示每个求解步骤中方程解的误差大小,用于判断数值解的收敛性。
残差的基本概念
在OpenFOAM中,残差(residual)是指当前迭代解与精确解之间的差异,通常用于衡量线性方程组或非线性方程组在每次迭代中的收敛程度。残差越小,说明数值解越接近真实解,系统越接近收敛状态。残差可以是绝对值或相对值,并且不同求解器对残差的计算方式略有不同,但一般会对向量或矩阵系统进行归一化处理,以便比较不同物理量的收敛情况。
在OpenFOAM中的显示与监控
OpenFOAM通过命令行工具和配置文件来监控残差变化:
准备residuals文件:使用foamGet residuals将模板文件拷贝到system文件夹下,并在system/residuals中指定需要监控的物理量,如速度、压力、湍动能k和耗散率ε+2。
修改controlDict:在system/controlDict文件末尾添加#includeFunc residuals,以启用残差监控功能。
运行仿真并绘制曲线:可以使用foamMonitor命令实时监控残差变化,或者结合Gnuplot绘制残差随迭代步的变化曲线,以判断收敛性。
对于非标量场(如速度向量),OpenFOAM会输出每个分量的最大残差值,以便更直观地观察收敛情况。
残差与收敛性
在RANS或其他CFD仿真中,残差是判断计算是否收敛的重要指标。通常,当残差下降到预设的容差范围(tolerance)以下时,认为方程组已经收敛,可以停止迭代或继续时间步推进。残差曲线的平稳下降或趋于稳定是收敛的标志,而残差波动或不下降可能提示网格质量、边界条件或求解器设置存在问题。

以下出错原因就是我前面提到的坑
安装错误:

网格划分错误:

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Create time

11:18:30  --> FOAM Warning :
    From function static Foam::instantList Foam::timeSelector::select0(Foam::Time&, const Foam::argList&)
11:18:30      in file db/Time/timeSelector.C at line 269
    No time specified or available, selecting 'constant'
Create polyMesh for time = constant
11:18:30
11:18:30  foamToSurface.exe :
����λ�� C:\Users\Administrator\CfdOF\meshCase\Allmesh.ps1:4 �ַ�: 5
+     & $cmd $args 2>&1 | tee log.$sol
+     ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
11:18:30
11:18:30  --> FOAM FATAL ERROR:
Cannot find file "points" in directory "polyMesh" in times "constant" down to constant
11:18:30      From function virtual Foam::IOobject Foam::fileOperation::findInstance(const Foam::IOobject&, Foam::scalar, const F
oam::word&) const
    in file global/fileOperations/fileOperation/fileOperation.C at line 869.
FOAM exiting
11:18:30  Executing: echo $WM_PROJECT_USER_DIR

分析出错

12:35:29  could not open file Map.H for source file surfaceToFMS.C due to No such file or directory
could not open file UList.H for source file surfaceToFMS.C due to No such file or directory
could not open file HashSet.H for source file surfaceToFMS.C due to No such file or directory
could not open file error.H for source file surfaceToFMS.C due to No such file or directory
could not open file token.H for source file surfaceToFMS.C due to No such file or directory
12:35:29  could not open file columnFvMesh.H for source file writeCellAndPointLevel.C due to No such file or directory
could not open file Time.H for source file writeCellAndPointLevel.C due to No such file or directory

cfdof论坛:
You initialise the pink cube as water-zone (water must be the first entry in model-tree),
the rest of the domian automatically is air.
对于二相流模式,你只需设置一个初始化参数(此处为水)——水进入空气例子。

  1. 下图2——先设置 初始化的时候,用 waterfraction=0(即等于空气)的值初始化整个区域field
  2. 下图1 初始化水体zone的时候,粉色立方体/入口,waterfraction=1,表示水体。
    下图3在 Paraview 中,alpha-water=1 表示的是水(下图3中红色部分),其余(下图3中蓝色部分)则为空气。

    https://forum.freecad.org/viewtopic.php?p=454204
    https://forum.freecad.org/viewtopic.php?t=52313
    For 2-phase you need only 1 initialization parameter (here water).
    Initialize the complete field with waterfraction=0 (==> air), then initialize the
    pink cube/inlet with waterfraction=1.
    In paraview, alpha-water=1 is water, the rest is air.
    Detailled explanation here:
    https://www.youtube.com/watch?v=gZ_TqsPwiXY

如果你添加多种流体材料,只要你在物理任务面板中选择了瞬态、不可压缩的分析类型,则会自动使用 interFoam 或多相 InterFoam(针对两种以上的流体)。现场初始化区可用于选择初始流体体积分数。目前,重力在y方向限制为-9.81 m/s^2,且无表面张力(除非案例文件被手动编辑)
If you add multiple fluid materials, then provided you choose a transient, incompressible analysis type in the physics task panel, interFoam or multiphaseInterFoam (for more than two fluids) will be used automatically. Field initialisation zones can be used to select the initial fluid volume fractions. At present gravity is restricted to -9.81 m/s^2 in the y direction and there is no surface tension (unless the case files are manually edited, of course).

https://forum.freecad.org/viewtopic.php?p=619228
这里有一个例子(水射流):
首先你定义流体(空气)被泵入充满 水域(domain,field) 的空间。——qin:动的是空气?所以初始化要设置空气吗?
第2种液体是水。对于空气,你必须定义一个初始化Zone区域,即入口处的粉色立方体。

一开始模拟器时,避免进气口处有压力。——没明白
At first you define the fluid (air) which is pumped into the waterfilled domain.
Second fluid is water. For the air you must define a initialisation zone, the pink cube.
To start with the sim avoid pressure at the inlets.

http://dyfluid.com/openfoam11-2-2.html
采用不可压缩的VoF模型求解器,求解简化的二维溃坝问题。本案例为瞬态流动,两相流体由一个明确的界面或自由表面分隔开。在incompressibleVoF中,两相算法是以流体体积(VoF)为基础的。在这种算法中,使用相传输方程来确定每个计算单元中各相的相对体积分数,或称为相分数α。根据这个相对体积分数,通过加权平均计算得出材料的物理属性。VoF方法的特性意味着相之间的界面并非显式计算得出,而是作为相分数场的一个特性显现。由于相分数的取值范围在0到1之间,因此不能精确定义相界面,而是占据应存在尖锐界面的区域体积。

仿真区域由位于水箱左侧隔膜后的一列静止水柱构成。在时间t=0s时刻,移除隔板,水柱崩塌。在崩塌过程中,水冲击水箱底部的障碍物,并产生一个复杂的流场结构,流场中包括几个空气泡。

作者:秦晓川  创建时间:2026-07-30 20:38
最后编辑:秦晓川  更新时间:2026-08-11 11:23