我的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边界条件应用于压力场,并通过调整压力梯度,使边界通量与求解器(包括重力和表面张力等体力)的速度边界条件相匹配。

压力入口边界条件(Pressure Inlet)是Fluent中用于模拟”压力已知但流量未知”场景的核心工具。与直觉相反,它并非简单地”施加一个压力”,而是建立了一个允许流体根据系统阻力自动调节的物理机制。
典型误用场景分析:
储罐排放模拟错误地使用速度入口,导致流量计算结果偏离实际30%以上
自然通风系统错误指定入口速度,破坏了温度驱动的自然对流平衡
多分支管道系统各入口强行设置相同速度,造成流量分配严重失真
压力入口的物理本质可通过一个简单实验理解:想象连接气球和管道的系统。当气球内压力(Pressure Inlet)和外部环境压力(Pressure Outlet)存在差值时,气流速度会自然形成,而无需人为指定——这正是压力入口要模拟的物理过程。

关键判断标准:

1. 是否知道入口处的**绝对压力值**?(如压力表读数、设计压力值)
2. 流量是否应由**系统阻力决定**?(如管道摩擦、阀门开度等)
3. 是否存在**回流可能性**?(如脉动流、瞬态工况)

当以上任一问题答案为”是”时,压力入口通常是更物理准确的选择。下表对比了三种主要入口边界条件的适用场景:

边界类型 已知条件 适用场景 收敛难度
Pressure Inlet 总压/静压 压力驱动系统、多分支管路 中等
Velocity Inlet 速度分布 实验数据充分、低速内流
Mass Flow Inlet 质量流量 精确流量控制、燃烧器
  1. 问:湍流模型和层流模型怎么选?
    假定流动过程没有涡旋,因此设置为层流simulationType laminar,因为二相流在fc中必须选择瞬态transient,再选择多相流-自由表面multyphase-free surface,再选择Turbulence里的层流 laminar

  2. 问:paraview里如何展示流场流线,以及对壁面的压力和负压?
    流线图
    http://dyfluid.com/openfoam11-2-1.html#id16

  3. 问:模型比例问题,是建立1:1模型还是建立缩尺模型?
    现实中1m长,在模型里建1000mm。

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

3 二相流分析教程

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

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

3.1 建模

建模挺讲究的,我们做自由液面二相流,实际上是建立空气和墙来模拟边界,也就是除了边界,其他地方都是空气。如果其他地方有预先存有水体,例如消力池里的存水,那要另外建立一个体body,把它设置为zone。
在二维分析里,可以建立一个面进行拉伸很薄的高度,面就是空气,面的周围就是默认边界——也有不定义边界的,好像默认就是封闭边界。
在三维里,就稍微烧脑了,边界得先建立一个body,空气另外建立一个body,两个body在part里进行boolean fragements

举三个例子

  1. 管道向水池中注水要建几个body?一个即可,这个body整体作为空气,外表面可以作为wall边界
  2. 如果水池中间有一个三角堰,建2个body比较方便,整个水池范围一个大立方体,堰单独一个body,两个body做part工作台里的boolean fragements,这样,堰的上方也会被空气包裹。原理是第一个body都是空气,body的外表面可以定义为wall,但是堰body嵌入到第一个body里,这个堰body必须把第一个body切割,并集的bool运算吧。
    技巧:那么,如何将嵌入第一个body中的三角堰表面选中定义为wall呢?用FreeCAD里view菜单下的修剪视图,把模型割开,就可以选到内部三角堰的表面了。
  3. 旋流消能井
    只需要建立里面的旋流滑梯body,另外建立一个空气圆筒body,圆筒直径等于滑梯外径,2个body做boolean fragements后,空气圆筒的外表面就直接作为边界了,相当于井的内壁了。

    4.主管和支管,支管顶端有空气,可以这样模拟。

3.2 流体分析设置和分析

6.11节第6节吧

  1. 分析基本属性——默认即可
  2. 物理模型
    选择瞬态,多相自由表面,湍流里选择层流,重力是-9810m/s^2,注意模型的方向,默认在Y方向,根据你的模型,可能要改为Z方向。
  3. 初始化分析场
    选择势流,指定大气压,volume fraction,如果分析场和第一流体一致则填1,不一致则填0。这里分析场空间是空气,而第一流体是水,所以填0
  4. 解算属性
    要设置5s或10s……
  5. 边界条件——进口——子类型
    wall都选无滑动
    技巧:那么,如何将嵌入在body内部的另一个body表面选中呢?用FreeCAD里view菜单下的修剪视图,把模型割开显示,就可以选到内部三角堰的表面了。

    选取技巧
  6. 边界条件——边界类型
    这里的开放open和约束没搞懂
  7. 边界条件——出口——子类型
    静压包括了速度和压力,出口速度可以不设,因为出去的速度是算出来的。
  8. 边界条件——出口——均匀流速和静压 描述
  9. 分析
    并行分析,选择CPU数量,如何查看CPU,看下图

    先点击write,程序会将解算分解到上面设置的并行计算数量。计算过程中会出现残差过程窗口

    10.网格
    记得如果是boolean fragement,那要选中boolean fragement后,再点击网格按钮。
    总体网格大小假如是200mm,那么支管要设置refinement,细分网格大小是总体网格的0.25
    特别注意,如果主网格尺寸大于某个面的尺寸,则会发生失败。

3.3 结果查看设置

  1. 分析完成后点击paraview按钮
  2. 动作一:选中openfoamreader1,勾选group/wall,点击apply按钮
  3. 动作二:view菜单下勾选multiblock inspector,右侧出现对应面板。在openfoamreader1处于选中并且可见状态下,取消勾选右侧面板中的internalMesh。这个internalMesh只有上述动作一中点击apply后才会出现的。
    不显示内在的网格,就只出现墙体,方便观察
  4. 动作三:第二行工具条中,切换到alpha.water,这是二相流独有的;左侧面板向下滚动到coloring——Editor——右侧面板color map editor里,下滚到color dicretization……将数字256改为2。这个是气液二相流分离显示的关键!
  5. 动作四:添加流线,左侧面膜seeds里选择seed type为point cloud;取消勾选show sphere;Number of points改为2000,会加密流线密度

6.12节里第6节
openfoam用户指南:第1章
http://dyfluid.com/openfoam11-2-1.html
矢量图
http://dyfluid.com/openfoam11-2-1.html#id13
流线图
http://dyfluid.com/openfoam11-2-1.html#id16
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.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-09-22 21:46