外残差: 对于方程f(x,t)=0在t_0时刻有收敛解x_0, 则f(x_0,t=t_0)=0; 当用t0时刻的结果代入到t1时刻的方程时,通常并不能满足方程,即 f(x_0, t = t_1) = r !=0; 这里的残差r称为外残差。
内残差:在cfd计算中通常将方程转化为代数方程Ax=b;当得到某个解A*x_0-b = r1; 这里的r1 ->0时,认为Ax=b收敛。 这里的r1为内残差。
对于稳态问题:只有当r->0时,才被认为收敛,也就是(x_1 - x_0)->0. 也就是我们在cfd计算中通常见到的那个残差,fluent及其pyFoam输出残差图就是这个r。r常被作为收敛判据。 对于非稳态问题,下一时刻的求解结果用于和当前的求解结果不一样(时变的,也就是非稳态),这时候r并不是很小,对于特定的问题,这个r永远不可能很小(因为是非稳态问题),所以对于非稳态问题外残差r不能作为收敛判据。
无论是稳态还是非稳态,都必须是代数方程Ax=b收敛,r1->0 时,是必须满足的。但是在稳态计算中,由于某一个迭代的结构没有意义,这时候为了减少计算量通常给定一定的迭代次数,而并不是设定r1必须满足一定的限制。这是fluent采用的一种手段。而对于非稳态问题,由于我们关心某一个时刻的值,这时候必须是r1->0,使得求解的代数方程收敛,因此r1才是作为非稳态问题的收敛判据。
在openfoam中两个残差都有,外残差就是你在迭代过程中的输出屏幕上看到的那个initial residual,而内残差就是求解某一个方程迭代一定后的那个残差,内残差r1,可以通过在fvSolution里面的代数方程求解器中设定,relTol(相对残差)tol(绝对残差)。两者的区别不用说了吧。 外残差只对稳态的求解器有,就是fvSolution下的Simple字典下的convergence,可以通过下面方法设置 Simple {
convergence 1e-6; }
当所有方程残差外残差小于1e-6时,认为收敛,求解器停止计算。
OpenFOAM中非均匀初始场的设定
采纳网友的建议,这次讨论OpenFOAM中非均匀初始场设置问题。 对于openfoam非均匀场初始化现成程序有两个: 1)OpenFOAM自带功能setFields 2)社区中的funkySetFields. 下面介绍一下两者的使用。 1 setFields的使用
使用setFields只需要将system文件夹中建立setFieldsDict,然后在其中设置相应的参数,设置完后,在case根目录下利用控制台输入setFields就可以了。下面介绍一下interFoam算例中的setFieldsDict.该字典位置在
OpenFOAM-1.6/tutorials/multiphase/interFoam/laminar/damBreak/system/setFieldsDict,文件中的内容为
FoamFile //文件头 {
version 2.0; format ascii; class dictionary; location \ object setFieldsDict; }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // defaultFieldValues //用来设定场的默认值 (
volScalarFieldValue alpha1 0 // 设置场alpha1的默认值 );
regions //设置alpha1不为0 的区域 (
boxToCell // 方形区域内的cell
{
box (0 0 -1) (0.1461 0.292 1); //方形区域的边界,两点xyz最小点和xyz最大点 fieldValues //用来指定定值 (
volScalarFieldValue alpha1 1 //用来alpha1场在上面box区域内的值的大小 ); } );
setFields对于规则区域定值使用比较方便,但是很难实现比较复杂内部场的设置,比如满足某种关系式的内部场设置。 2 funkySetFields的使用
用来设定比较复杂的内部场。 可以指定满足一定条件的关系式的初始场。 2.1 软件的获取
funkySetFields在官方或者dev版本里面都没有该功能,可以通过下面命令获取。运行下面的命令需要你的电脑安装svn。 svn
checkout
https://openfoam-extend.svn.sourceforge.net/svnroot/openfoam-extend/trunk/Breeder_1.6/utilities/postProcessing/FunkySetFields/
2.2 软件的安装
该软件安装比较简单,直接进入该文件夹,并运行Allwmake ./Allwmake 2.3 使用 2.3.1 常用关键字 field //用来指定要修改的场
expression_r //用来指定表达式
condition //用来指定上述表达式应当满足的条件
keepPatches //用来说明是否保持原来边界条件,最好加上,不加的话,funkySetField会给所有边界为0梯度
create //用来说明是否是新建场
valuePatches //用来指定那些定值边界由临近内部节点值给定
dimension //用来指定新建立场的单位 time //用来指定funkySetField所指定的时间点
应当指出,上述关键字可以直接在控制台上输,也可以写在名字为funkySetFieldsDict(类
似于setFieldsDict)中。 2.3.2 使用方法
方法1 直接在控制台输入
直接进入你要初始话的case中,输入类似于下面的命令。如上面的setField也可以通过下面的funkySetFields命令来实现
funkySetFields -time 0 -keepPatches -field alpha1 -expression_r \\
注意比较长的式子用单引号或者双引号隔开。 上述关键字没有次序要求。 方法2 使用funkySetFieldsDict字典
方法和上面setFields差不多,在system文件夹中建立funkySetFieldsDict字典文件,对于上面表达式可以通过下面字典文件实现。 expression_rs //设置复杂内部边界入口 (
alpha // 设置alpha1,名字任意 {
field alpha1; //操作的场 expression_r \ //表达式
condition \执行上述表达式的条件 keepPatches true; //是否保持以前边界 }
pressure1 //设置压力,名字任意 {
field p; //指定操作场
expression_r \; //执行表达式子,无条件 } pressure2
{
field p; 指定表达式
expression_r \; //表达式子
condition \; //条件 } );
从上面可以看出,使用funkySetFieldsDict可以实现更为复杂内部场,且可以同时对多个场进行操作
2.3.3 表达式中的常用支持
也许你已经注意到,上面例子中condition和expression_r使用了表达式,funkySetFields中你可以使用下列常用的操作符或者函数
1) C++基本操作符
+,-,*,/,%, <,>,<=,>=,!=,==, &&,||,? : 2)OpenFOAM定义的向量操作符 &,^
3)圆周率常量 pi
4)标量函数
pow,log,exp,sqr,sqrt,sin,cos,tan 5)OpenFOAM中的一些函数 mag:求模 grad :求标量梯度 curl :求向量旋度 snGrad:表面法向剃度 div :向量场散度
laplaction :求一个场的laplacian项目 min,max :标量场的最值 pos :网格中心位置矢量 fpos :面中心位置矢量