OpenFOAM中自带的自适应加密只支持三维的,这里分两种情况,一种是三维的自适应加密,一种是二维的自适应加密
本文参考https://www.jianshu.com/p/b67bcaf3a440
和github上的https://github.com/krajit/dynamicRefine2DFvMesh
因为我做这个的目的是想算一个稳态问题,而且加密区域不需要改变,所以用这样的办法来获得一个有特定区域加密的网格。
结果
一、三维情况
1.1 更改求解器
OpenFOAM版本:openfoam-v2012
瞬态不可压求解器有pisoFOAM和pimpleFOAM,其中只有pimpleFOAM添加了动网格和自适应网格模块,所以采用pimpleFOAM求解器进行更改。
复制一个pimpleFOAM到另外位置,新建一个.H文件calculate_S.H
打开createFields.H文件,在其中添加
Info << "Reading field s\n" << endl;
volScalarField s
(
IOobject
(
"s",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
这代表了要加密的区域,s是一个没有单位的标量,运行的时候只需要在“0”文件夹中复制一个“p”文件进行边界条件的定义,这里先按下不表。
打开之前新建立的文件calculate_S.H,在里边添加上
scalar distance = 1000,x_ ,y_;
forAll(mesh.C(), i)//mesh.C()网格坐标点
{
x_ = mesh.C()[i].x();
y_ = mesh.C()[i].y();
distance = my_abs(Foam::sqrt(x_*x_ + y_ * y_) - 0.5);
if (distance < 0.5)
{
if (distance <0.001)
s.field()[i] = 1000;
else
s.field()[i] = 1 / distance;
}
}
这里边的**s.field()[i]**指的是之前新定义的一个标量场在第i个单元中的值,上边简单的代码可以看出来,s的大小取决于距离圆心在(0,0)半径为0.5的圆边界的距离,距离越近,s的值越大,但是s不是无限大和无限小的,只有当distance小于0.5时,s才会被赋值,s的最大值是1000。
打开pimpleFoam.C文件,在runTime.write();之前添加上#include “calculate_S.H”,具体哪个位置我也不好说,我的理解是只要在时间循环内和pimple循环外就是了。
最后打开Make/files,修改EXE = $(FOAM_USER_APPBIN)/dynamic_2,最后保存并回到终端wmake就行了。
算例
修改的部分就只是在0文件夹和constant文件夹下,复制p,并修改
我的p文件是这样
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
"(inlet|updown)"
{
type zeroGradient;
}
outlet
{
type fixedValue;
value uniform 0;
}
frontAndBackPlanes
{
type empty;
}
}
// ************************************************************************* //
修改成s文件是这样
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object s;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 0 0 0 0];
internalField uniform 0;
boundaryField
{
"(inlet|updown)"
{
type fixedValue;
value uniform 0;
}
outlet
{
type fixedValue;
value uniform 0;
}
frontAndBackPlanes
{
type empty;
}
}
// ************************************************************************* //
至于constant文件夹下的修改,要添加dynamicMeshDict
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object dynamicMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dynamicFvMesh dynamicRefineFvMesh;
dynamicRefineFvMeshCoeffs
{
// How often to refine
refineInterval 1;
// Field to base refinement on
field s;//***修改的地方就是在这里,把场换成我们自己定义的s***
// Refine field inbetween lower..upper
lowerRefineLevel 2; //然后把最大最小值改一下
upperRefineLevel 1000;//
// If value < unrefineLevel unrefine
unrefineLevel 0.1;
// Have slower than 2:1 refinement
nBufferLayers 1;
// Refine cells only up to maxRefinement levels
maxRefinement 4;
// Stop refinement if maxCells reached
maxCells 2000000;
// Flux field and corresponding velocity field. Fluxes on changed
// faces get recalculated by interpolating the velocity. Use 'none'
// on surfaceScalarFields that do not need to be reinterpolated.
correctFluxes
(
(phi none)
(nHatf none)
(rhoPhi none)
(ghf none)
(alphaPhi none)
(alphaPhiUn none)
(alphaPhi0.water none)
);
// Write the refinement level as a volScalarField
dumpLevel true;
}
// ************************************************************************* //
其他地方的意思可以参照这篇文章https://www.jianshu.com/p/b67bcaf3a440
然后运行dynamic_2就能看到特定区域的加密
不过这样的加密是三维的,如果是二维的加密看下边
参照github上的这个代码
https://github.com/krajit/dynamicRefine2DFvMesh
不过是在openfoam8中wmake没有报错,在v2012中报错了
因为我做这个的目的是想算一个瞬态问题,而且加密区域不需要改变,所以用这样的办法来获得一个有特定区域加密的网格。