个人信息Personal Information


教师英文名称:Kai Wei

学历:博士研究生毕业

学位:工学博士学位

办公地点:西南交通大学土木馆1218室

在职信息:在岗

毕业院校:同济大学

学科:土木水利. 桥梁与隧道工程

所在单位:土木工程学院

教师博客

当前位置: 中文主页 >> 教师博客

SPH命令流指南

发布时间:2026-01-16  

SPH命令流指南

c++文件编程指南

对执行文本.xml的研究,为了方便没有编程基础的同学,小节——“生成.xml 文件”是展示从freeCAD软件上直接生成.xml 文件的操作步骤,可以在调通模型之后快速获取代码,若需跑多个代码可以将其文件中的参数进行修改。

生成.xml 文件

为了方便没有学过编程的同学,本小节内容是在生成一个可以运行文档。

  1. 先使用浮体章节建立freeCAD构建模型和运行参数。

  2. 在此补充一下定义浮体的操作,需要使用如下的选项。

  3. 点击 gencase 即可生成****_Def.xml文件。本文之后****代表自定义的算例名称。比如我的算例命名为standard,那么文件夹里面会有一个standard_Def.xml的文件。这个文件就是gencase生成的。

⚠️ 注意:

只需要生成这一个.xml文件,因为给出的bat命令会包含前处理,运行,后处理等环节,自动生成其他.xml文件

代码参数注释

xml文件参数注释

以上述模型为例,其中代码的comment部分就是注释,所以不在另外写说明。

<!-- Case name: standard-1 -->
<?xml version="1.0" encoding="UTF-8" ?>
<case app="DesignSPHysics v0.8.1" date="18-10-2025 18:19:46"> <!-- 根节点:案例元信息,仅供记录 -->

  <casedef> <!-- GenCase 预处理部分:几何、mk 标签、浮体与运动的定义 -->

    <constantsdef> <!-- SPH 全局常量(单相):重力、参考密度、声速等 -->
      <gravity x="0" y="0" z="-9.81" comment="Gravitational acceleration" units_comment="m/s^2" />
      <rhop0 value="1000" comment="Reference density of the fluid" units_comment="kg/m^3" />
      <rhopgradient value="2" comment="Initial density gradient" units_comment="-" />
      <hswl value="0" auto="true" comment="Maximum still water level" units_comment="metres (m)" />
      <gamma value="7" comment="Polytropic constant for water" />
      <speedsystem value="0" auto="true" comment="Maximum system speed" />
      <coefsound value="20" comment="Coefficient to multiply speedsystem" />
      <speedsound value="0" auto="true" comment="Speed of sound" />
      <coefh value="1.2" comment="Coefficient to calculate the smoothing length" />
      <cflnumber value="0.2" comment="Coefficient to multiply dt" />
      <h value="0" auto="true" units_comment="metres (m)" />
      <b value="0" auto="true" units_comment="Pascal (Pa)" />
      <massbound value="0" auto="true" units_comment="kg" />
      <massfluid value="0" auto="true" units_comment="kg" />
    </constantsdef>

    <mkconfig boundcount="241" fluidcount="9">
    </mkconfig>

    <geometry> <!-- 几何与粒子生成(GenCase) -->
      <definition dp="0.1" comment="Initial inter-particle distance" units_comment="metres (m)">
        <pointref x="0" y="0" z="0" />
        <pointmin x="-0.2" y="-0.2" z="-0.2" />
        <pointmax x="15.8" y="2.2" z="2.2" />
      </definition>
      
      <commands>
        <mainlist>
          <setshapemode>actual | dp | bound</setshapemode>
          <setmkbound mk="3"/>
          <setdrawmode mode="face"/>
          <drawbox objname="flume">
            <boxfill>front | back | bottom | left | right</boxfill>
            <layers vdp="" />
            <point x="0.0" y="0.0" z="0.0" />
            <size x="15.4" y="2.0" z="2.0" />
          </drawbox>
          
          <setmkbound mk="1"/>
          <setdrawmode mode="full"/>
          <drawbox objname="piston">
            <boxfill>solid</boxfill>
            <layers vdp="" />
            <point x="0.4" y="0.0" z="0.0" />
            <size x="0.01" y="2.0" z="2.0" />
          </drawbox>

          <move x="0.4" y="0.0" z="0.0" />

          <setmkfluid mk="0"/>
          <fillbox x="0.6" y="1.0" z="0.3" objname="FillBox">
            <modefill>void</modefill>
            <point x="0" y="0" z="0" />
            <size x="15.0" y="2.0" z="0.6" />
          </fillbox>

          <matrixreset />

          <setmkbound mk="2"/>
          <setdrawmode mode="full"/>
          <drawcylinder radius="0.5" objname="floating">
            <layers vdp="" />
            <point x="5.0" y="1.0" z="0.5" />
            <point x="5.0" y="1.0" z="0.8" />
          </drawcylinder>

          <shapeout file="" />
        </mainlist>
      </commands>
    </geometry>

    <floatings>
      <floating mkbound="2" rhopbody="700.0" property="">
      </floating>
    </floatings>

    <motion>
      <objreal ref="1">
        <begin mov="1" start="0"/>
        <mvnull id="1" />
      </objreal>
    </motion>

  </casedef>

  <execution>
    <special>
      <initialize></initialize>
      <wavepaddles active="true">
        <piston>
          <mkbound value="1" />
          <start value="0" />
          <duration value="0.0" />
          <depth value="0.6" />
          <pistondir x="1.0" y="0.0" z="0.0" />
          <waveorder value="2" />
          <waveheight value="0.1" />
          <waveperiod value="1.0" />
          <gainstroke value="1.0" />
          <phase value="0.0" />
          <ramp value="0.0" />
          <savemotion periods="24" periodstep>
        </piston>
      </wavepaddles>
    </special>
  </execution>
</case>

从官方示例迁移到自建模型时建议检查的项目

当从 DualSPHysics 官方示例迁移到自己的几何模型时,可以按下面的顺序逐项检查:

  • [ ] 几何尺度与坐标系:确认水槽尺寸、构件位置与目标实验/工程场景一致。

  • [ ] 粒径与粒子数:根据几何最小特征尺度和显存限制选择粒径,预估粒子总数是否在可接受范围。

  • [ ] 物性参数:水的密度、黏度、重力加速度等是否保持一致。

  • [ ] 时间步长与总时长:是否满足稳定性要求,并且覆盖了目标物理过程的完整时间区间。

  • [ ] 输出频率:兼顾结果精度与存储压力,确保对自由面、压力和刚体姿态的记录足够密。

ℹ️ 注意:

在搭建命令流时,容易出现一些重复踩的坑,可以优先检查下面几类问题:

  • mk 号使用错误:
    水槽、构件、造波板使用了同一个 mk,导致边界条件混乱或刚体属性异常。出现这种问题时,通常会在前处理或仿真初始阶段报出边界相关错误,或者刚体自由下沉/漂移不符合预期。

  • 几何缺面或漏箱:
    fillbox 范围与实际几何不一致,导致流体粒子逸出计算域或局部区域没有粒子。遇到这种情况,优先检查 shapeout 生成的几何可视化文件,确认几何是否闭合。

  • 坐标变换遗漏:
    使用 matrixreset 或旋转、平移命令后,没有在预期位置得到物体。建议在每次坐标变换后输出 shapeout 文件,先在几何层面确认位置正确,再进入正式计算。

  • 输出目录和文件名不统一:
    不同案例使用了不同的输出路径和前缀,后处理中难以批量读取。建议在命令流中统一设置输出目录和命名规则,并在批量脚本里保持一致。

bash命令行注释

1. 开头环境配置部分

@echo off
setlocal EnableDelayedExpansion
rem Don't remove the two jump line after than the next line [set NL=^]
set NL=^
  • @echo off:关掉命令行里每一行命令的回显,不然屏幕上会刷一堆命令本身。

  • setlocal EnableDelayedExpansion:开启“延迟变量展开”,为了后面用 !option! 这种写法读用户输入。

  • set NL=^ + 后面两行空行:这是一个批处理的老骚操作,用来在字符串里插入“换行符”。

2. 根据目录名字自动生成案例名 + 输出目录

rem "name" and "dirout" are named according to the testcase
for %%I in ("%~dp0.") do set "name=%%~nxI"
set dirout=%name%_out
set diroutdata=%dirout%\data
  • for %%I in ("%~dp0.") do set "name=%%~nxI"

    这行的意思是:取当前脚本所在文件夹的名字,赋值给变量 name。所以如果你的案例目录叫 case_0,那 name=case_0

  • set dirout=%name%_out

    输出目录变量,比如 case_0_out

  • set diroutdata=%dirout%\data

    数据子目录,比如 case_0_out\data,后面所有 .bi4 / .csv 之类的东西都从这里读。

3. 可执行程序路径设置

rem "executables" are renamed and called from their directory

set dirbin=C:\Users\win10\AppData\Roaming\FreeCAD\Mod\DesignSPHysics\dualsphysics\bin
set gencase="%dirbin%/GenCase_win64.exe"
set dualsphysicscpu="%dirbin%/DualSPHysics5.4CPU_win64.exe"
set dualsphysicsgpu="%dirbin%/DualSPHysics5.4_win64.exe"
set boundaryvtk="%dirbin%/BoundaryVTK_win64.exe"
set partvtk="%dirbin%/PartVTK_win64.exe"
set partvtkout="%dirbin%/PartVTKOut_win64.exe"
set measuretool="%dirbin%/MeasureTool_win64.exe"
set computeforces="%dirbin%/ComputeForces_win64.exe"
set isosurface="%dirbin%/IsoSurface_win64.exe"
set flowtool="%dirbin%/FlowTool_win64.exe"
set floatinginfo="%dirbin%/FloatingInfo_win64.exe"
  • dirbin:所有 DualSPHysics / DesignSPHysics 工具的安装目录。

ℹ️ 注意:

每个电脑的安装位置不同,一定要修改,否则会报错。

  • 每个 set xxx="..." 就是给这些程序起个变量名,方便后面调用:

    • gencase:生成粒子布置、边界等 (GenCase)

    • dualsphysicscpu / gpu:CPU/GPU 的主程序

    • boundaryvtk:把边界导成 VTK

    • partvtk:把粒子数据导成 VTK

    • computeforces:计算力

    • floatinginfo:专门用于提取浮体运动信息

要改 EXE 路径,就在这里动手,建议直接改 dirbin

4. 菜单逻辑:目录已存在怎么办

:menu
if exist %dirout% (
    set /p option="The folder "%dirout%" already exists. Choose...L!  [2]- Execute post-processing.!NL!  [3]- Abort and exit.!NL!"
    if "!option!" == "1" goto run else (
        if "!option!" == "2" goto postprocessing else (
            if "!option!" == "3" goto fail else (
                goto menu
            )
        )
    )
)
  • :menu 是一个跳转点。

  • if exist %dirout%:如果输出文件夹已经存在,就弹菜单问你:

    • [1] 重新跑一遍

    • [2] 只做后处理

    • [3] 退出

5. 主计算阶段 :run

:run
rem "dirout" to store results is removed if it already exists
if exist %dirout% rd /s /q %dirout%

rem CODES are executed according the selected parameters of execution in this testcase

%gencase% %name%_Def %dirout%/%name% -save:all
if not "%ERRORLEVEL%" == "0" goto fail

%dualsphysicsgpu% -gpu %dirout%/%name% %dirout% -dirdataout data -svres
if not "%ERRORLEVEL%" == "0" goto fail
  • if exist ... rd /s /q:如果目录存在,递归删除。

  • 运行 GenCase:用定义文件生成案例。

  • 运行 DualSPHysics (GPU版):

    • -gpu:使用显卡计算。

    • -svres:保存结果。

  • if not "%ERRORLEVEL%" == "0" goto fail:如果有错误码,直接跳转到 fail。

6. 后处理阶段 :postprocessing

:postprocessing
set dirout2=%dirout%\particles
%partvtk% -dirin %diroutdata% -savevtk %dirout2%/PartMoving -onlytype:-all,+moving -vars:+idp,+vel,+rhop,+press
if not "%ERRORLEVEL%" == "0" goto fail

%partvtk% -dirin %diroutdata% -savevtk %dirout2%/PartFloating -onlytype:-all,+floating
if not "%ERRORLEVEL%" == "0" goto fail

%partvtk% -dirin %diroutdata% -savevtk %dirout2%/PartFluid -onlytype:-all,+fluid -vars:+idp,+vel,+rhop,+press
if not "%ERRORLEVEL%" == "0" goto fail

%partvtkout% -dirin %diroutdata% -savevtk %dirout2%/PartFluidOut -SaveResume %dirout2%/_ResumeFluidOut
if not "%ERRORLEVEL%" == "0" goto fail

这一块基本都是“把不同类型粒子导出成 VTK 文件”:

  • PartMoving:只导出移动粒子。

  • PartFloating:只导出浮体粒子。

  • PartFluid:只导出流体粒子,附带速度、密度、压强变量。

  • PartFluidOut:域外流体粒子(用于Debug边界泄漏)。

力的计算

set dirout2=%dirout%\forces
%computeforces% -dirin %diroutdata% -onlymk:012 -savecsv %dirout2%/_FloatingForce -savevtk %dirout2%/FloatingForce
if not "%ERRORLEVEL%" == "0" goto fail
  • onlymk:012:只对 mk=012 (浮体) 计算受力。

  • 保存结果为 CSV 和 VTK。

浮体运动信息

set dirout2=%dirout%\floatinginfo
%floatinginfo% -dirin %diroutdata% -onlymk:012 -savedata %dirout2%/FloatingMotion012
if not "%ERRORLEVEL%" == "0" goto fail
  • 注意: 这个命令一次性帮你导出了 mk=012 浮体的运动时程数据(CSV)。

7. 结束逻辑

:success
echo All done
goto end

:fail
echo Execution aborted.

:end
pause
  • :success:顺利跑完输出 "All done"。

  • :fail:出错跳到这里。

  • :end:执行 pause 暂停窗口。

⚠️ 注意:

  1. bat运行文件为注释版,如果在txt文件中复制粘贴,最好更改编码为 ANSI 编码,否则中文有显示错误。

  2. 在首次运行完成之后,默认进行后处理,建议直接关闭输出vtk,因为所有运行结果保存在 data 中,vtk产生图片信息基本和data重合,并且占用的储存空间较大。