算例路径: olaFlow\tutorials\wavemakerTank
算例描述: 采用 Flap和Piston两种方式的动网格进行造波
学习目标: 了解 olaDyMFlow 的使用;理解动网格使用和参数设置,理解 dynamicMotionSolverFvMesh 参数设置;理解造波边界运动方式生成
学习体会:
(1) dynamicMotionSolverFvMesh 根据边界上的压强计算网格运动,反之它也为流体计算提供了反馈。它通过改变该边界上的速度边界条来件指定被定义物体的局部速度。
(2) 与算例9动边界(网格)消波类似,理解肤浅,逐步理解动网格 !!!
算例快照:
文件结构:
.
├── 0.org
│ ├── U
│ ├── alpha.water
│ ├── alpha.water.org
│ ├── p_rgh
│ └── pointDisplacement
├── cleanCase
├── constant
│ ├── dynamicMeshDict
│ ├── flapWaveGen.py
│ ├── g
│ ├── pistonWaveGen.py
│ ├── transportProperties
│ ├── turbulenceProperties
│ └── wavemakerMovementDict
├── runParallelCaseFlap
├── runParallelCasePiston
└── system
├── blockMeshDict
├── controlDict
├── decomposeParDict
├── fvSchemes
├── fvSolution
└── setFieldsDict
算例文件解析:
除以下解析的文件外,其他文件与 baseWaveFlume 一样。
参考 【OpenFOAM】-olaFlow-算例1- baseWaveFlume
【runParallelCasePiston】/【runParallelCaseFlap】
#!/bin/bash
mkdir 0
blockMesh > blockMesh.log
rm -fr 0
cp -r 0.org 0
setFields > setFields.log
cd constant
python pistonWaveGen.py # 创建推板运动方式
# python flapWaveGen.py # 创建摇板运动方式
cd ..
decomposePar > decomposePar.log
mpirun -np 4 olaDyMFlow -parallel > olaDyMFlow.log # 动网格造波
【0.org\U】
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
inlet
{
type movingWallVelocity; // 运动壁面的速度边界条件
value uniform (0 0 0);
}
outlet
{
type waveAbsorption2DVelocity;
absorptionDir 180;
nPaddles 10;
value uniform (0 0 0);
}
bottom
{
type fixedValue;
value uniform (0 0 0);
}
"wall."
{
type fixedValue;
value uniform (0 0 0);
}
atmosphere
{
type pressureInletOutletVelocity;
value uniform (0 0 0);
}
}
【0.org\pointDisplacement】
dimensions [0 1 0 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
inlet // 与算例9中的动网格消波相似
{
type wavemakerMovement; // 造波机运动边界条件
wavemakerDictName wavemakerMovementDict;; // 造波机运动设置字典
value uniform (0 0 0);
}
outlet
{
type fixedValue;
value uniform (0 0 0);
}
bottom
{
type fixedNormalSlip; //边界上的法向分量由用户指定;切向分量为滑移条件,即从内部场复制
n (0 0 1); // 法向方向
value uniform (0 0 0);
}
"wall."
{
//type zeroGradient;
type fixedNormalSlip; //边界上的法向分量由用户指定;切向分量为滑移条件,即从内部场复制
n (0 1 0);
value uniform (0 0 0);
}
atmosphere
{
type zeroGradient;
/*type fixedNormalSlip;
n (0 0 1);
value uniform (0 0 0);*/
}
}
【constant\dynamicMeshDict】
dynamicMotionSolverFvMesh参考 https://openfoamwiki.net/index.php/Parameter_Definitions_-_dynamicMotionSolverFvMesh#inverseDistance
dynamicFvMesh dynamicMotionSolverFvMesh;
// 应用于 FSI 领域。这种网格控制几乎专门用于涉及刚体运动的问题。
// 该求解器围绕指定的边界使网格变形,根据边界上的压强计算网格运动,反之它也为流体计算提供了反馈。它通过改变该边界上的速度边界条来件指定被定义物体的局部速度(包括平动和转动)。
motionSolverLibs ("libfvMotionSolvers.so");
solver displacementLaplacian; // 一种 fvMesh 的网格运动求解器,器原理是对运动位移进行单元中心的Laplacian 运算。(Based on solving the cell-centre Laplacian for the motion displacement.)
//参考 https://www.openfoam.com/documentation/guides/latest/api/classFoam_1_1displacementLaplacianFvMotionSolver.html
displacementLaplacianCoeffs
{
diffusivity inversePointDistance (inlet);
//eg. diffusivity quadratic inverseDistance 5.0 ( Body );
// [ Distance Type] [diffusivity model][ Distance] [Patch]
// diffusivity: 该参数控制网格运动的分布。假设一种基本情况,即一个动边界和另一组静态边界。网格运动求解器须要找到某种方式来将边界的运动扩散到域中。OpenFOAM 中有如下几种可用的方法。若不确定如何选择,可以省略改参数,程序会使用默认值。
// (1) inverseDistance
// (2) inverseFaceDistance
// (3) inversePointDistance
// (4) inverseVolume
// (5) uniform
// inversePointDistance:
}
【constant\wavemakerMovementDict】
#include "wavemakerMovement.txt" // 读取文件wavemakerMovement.txt
【constant\wavemakerMovement.txt】 for Pistion
// 运行pistonWaveGen.py生成
wavemakerType Piston; // 造波版类型
tSmooth 1.5;
genAbs 0;
timeSeries 621(
0.0
0.05
0.1
... )
paddlePosition 10(
621(
-0.008087650377905872
0.003925783549844903
0.01589620577150058
... )
621( ... ) // 每个paddle的运动
... );
paddleEta 10(
621(
0.04987574680586761
0.04997075156666095
0.0495182663162379
... )
621( ... ) ... );
【constant\wavemakerMovement.txt】 for Flap
// 运行flapWaveGen.py生成
wavemakerType Flap; // 造波版类型
tSmooth 1.5;
genAbs 0;
timeSeries 621(
0.0
0.05
0.1
... )
paddleTilt 10(
621(
-2.2802830032546137
1.1073069810089098
4.4751216177835795
... )
621( ... ) // 每个paddle的倾斜程度
... );
【constant\pistonWaveGen.py】
#!/usr/bin/python
import numpy as np
def dispersion(T, h): # 定义色散方程求解
L0 = 9.81*T**2/(2.*np.pi)
L = L0
for i in range(0,100):
Lnew = L0 * np.tanh(2.*np.pi/L*h)
if(abs(Lnew-L)<0.001):
L = Lnew
break
L = Lnew
return L
## Piston wavemaker data ##
H = 0.1
T = 3.0
h = 0.4
phase0 = 0.
direction = 15. // 斜向波 15°
nPaddles = 10
bLims = [0., 5.]
t0 = 0.
tEnd = 31.
dt = 0.05
########################
# Calculations
L = dispersion(T, h)
k = 2.*np.pi/L
w = 2.*np.pi/T
times = np.linspace(t0, tEnd, round((tEnd-t0)/dt)+1)
coords = np.linspace(bLims[0], bLims[1], nPaddles+1)
coords = coords[:-1] + np.diff(coords)/2.
HoS = 4. * np.sinh(k*h)**2. / (np.sinh(2.*k*h) + 2.*k*h)
S = H/HoS
# Export
fid = open('wavemakerMovement.txt', 'w')
fid.write('wavemakerType Piston;\n')
fid.write('tSmooth 1.5;\n')
fid.write('genAbs 0;\n\n')
fid.write('timeSeries {0}(\n'.format( len(times) ))
for t in times:
fid.write('{0}\n'.format(t))
fid.write(');\n\n'.format( len(times) ))
fid.write('paddlePosition {0}(\n'.format( nPaddles ))
for i in range(0, nPaddles):
fid.write('{0}(\n'.format( len(times) ))
for t in times:
x = S/2. * np.cos(-w*t + np.pi/2. + phase0 + 2.*np.pi*coords[i]/L*np.sin(direction*np.pi/180.) )
fid.write('{0}\n'.format(x))
fid.write(')\n')
fid.write(');\n\n')
fid.write('paddleEta {0}(\n'.format( nPaddles ))
for i in range(0, nPaddles):
fid.write('{0}(\n'.format( len(times) ))
for t in times:
x = H/2. * np.cos(-w*t + phase0 + 2.*np.pi*coords[i]/L*np.sin(direction*np.pi/180.) )
fid.write('{0}\n'.format(x))
fid.write(')\n')
fid.write(');\n\n')
fid.close()
【constant\flapWaveGen.py】
#!/usr/bin/python
import numpy as np
def dispersion(T, h):
L0 = 9.81*T**2/(2.*np.pi)
L = L0
for i in range(0,100):
Lnew = L0 * np.tanh(2.*np.pi/L*h)
if(abs(Lnew-L)<0.001):
L = Lnew
break
L = Lnew
return L
## Flap wavemaker data ##
H = 0.1
T = 3.0
h = 0.4
phase0 = 0.
direction = 15.
nPaddles = 10
bLims = [0., 5.]
t0 = 0.
tEnd = 31.
dt = 0.05
########################
# Calculations
L = dispersion(T, h)
k = 2.*np.pi/L
w = 2.*np.pi/T
times = np.linspace(t0, tEnd, round((tEnd-t0)/dt)+1)
coords = np.linspace(bLims[0], bLims[1], nPaddles+1)
coords = coords[:-1] + np.diff(coords)/2.
HoS = 4. * np.sinh(k*h)/(k*h) * (k*h*np.sinh(k*h) - np.cosh(k*h) + 1.)/(np.sinh(2.*k*h) + 2.*k*h)
S = H/HoS
# Export
fid = open('wavemakerMovement.txt', 'w')
fid.write('wavemakerType Flap;\n')
fid.write('tSmooth 1.5;\n')
fid.write('genAbs 0;\n\n')
fid.write('timeSeries {0}(\n'.format( len(times) ))
for t in times:
fid.write('{0}\n'.format(t))
fid.write(');\n\n'.format( len(times) ))
fid.write('paddleTilt {0}(\n'.format( nPaddles ))
for i in range(0, nPaddles):
fid.write('{0}(\n'.format( len(times) ))
for t in times:
x = S/2. * np.cos(-w*t + np.pi/2. + phase0 + 2.*np.pi*coords[i]/L*np.sin(direction*np.pi/180.) )
x = np.arctan(x/h)
x = x*180./np.pi
fid.write('{0}\n'.format(x))
fid.write(')\n')
fid.write(');\n')
fid.close()