'internalField' 和'boundaryField'的区别?【翻译】
翻译自:CFD-online
帖子地址:http://www.cfd-online.com/Forums/openfoam/84322-difference-between-internalfield-boundaryfield.html
亲爱的Ofoamer们
作为一个OpenFOAM的新手,我可能有一个非常简单的问题..但是我没有从OF的案例中找到合适的答案并且我变得越来越困惑(我尝试做了一个"尝试性和错误性的计算")。
比如说在U文件下的'internalField'描述的什么?'internalField' 和 'boundaryField'之间有什么区别(细节上)?
先谢过了
felix
考虑压力(p),它被定义为volScalarField
意味着它定义在计算域每个单元的中心。计算域有两部分:内容域(internalField)和域周边(boundaryField)。
p.boundaryField()让你获取边界上的值,边界上的值就是面中心的值。当你需要一个边界值最大值,最小值或者平均值时,这个是非常有用的。
p.internalField()返回一个scalarField(我不确定,检查一下),这对于你想要处理内部值和保持边界条件不变是有用的。
你好,felix
我是一个OpenFOAM的菜鸟,但是我能给一点internalField边界条件的解释。
对于速度U,这internalField的特点是用来确定计算域内部流场流体的性质。比如,如果流体是静止的并且在任何方向都没有速度,这个值将为(0 0 0),反之,如果我们有动能(标量)并且初始条件表明存在一些速度,这个值将为uniform x。
简而言之,据我所知,(希望是正确的),这个边界条件很简单的设置流体的初始特性而不依赖任何边界。
希望有帮助
Dom
如果你刚才问的是0目录下的U文件。
你想要解偏微分方程,你需要设置边界条件和初始条件,internalField可以定义均匀的或者非均匀的初始边界条件同时boundaryField定义如下的数学边界条件:fixedValue(边界上的平均值被定义)或者zeroGradient(变量在边界上的梯度为0),更多的请参与用户手册。
你好,Nima,你好,Dominic
感谢你的快速回复!这些正是我遗失的信息。
Nima:现在我只有一些老的算例来知道所有设置的可能的不同。但是可以肯定的是,我将进一步阅读用户手册!
祝好
Felix
Quote:
consider
pressure (p), it is defined as volScalarField |
亲爱的nima
感谢你清楚的描述。
你能进一步解释一下dimensionedInternalField
我有如下方程。但是当我用InternalField()替代dimensionedInternalField
- dimensionedInternalField
()=min(scalar(0),B.dimen sionedInternalField()); A.boundaryField()=min(scalar(0),B.boundaryField()) ;
祝好
Mahdi
你知道变量是有量纲的,比如速度量纲是{m/s}
OpenFOAM同时保存变量的值和它的量纲
因此dimensionedInternalField
这个错误显示你想要和一个具有量纲的变量进行比较。
这是不允许的,你应该定义你的为0!作为一个有合适量纲的dimensionedScalar
Quote:
you know
variable has dimension, for example velocity dimension is
{m/s} |
感谢nima
但是这意味着这个公式是正确的!
Code:
A.dimensionedInternalField
但是这一个是不正确的
Code:
A.InternalField()=min(scalar(0),B.InternalField());
什么错误?
把错误贴出来
我知道这是一个老帖子但是我有一个与主题相关的问题
我尝试编写一个循环,不管我怎么编码,我总是会得到错误。
我尝试这样编码:
Code:
forAll(f1,celli)
{
if (utau[celli] == 0.0)
{
f1[celli] = exp(-0.5*xn[celli]*utau[celli]/nu());
}else
{ f1[celli]= 0.0;
}
}
但是显示如下错误:
Code:
error: cannot convert 'Foam::tmp<Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> >' to 'double' in assignment
make: *** [Make/linux64GccDPOpt/SPLRRIP.o] Error 1
我尝试了许多.internalField()和.dimensionedInternalField
我理解f1是有量纲的,因此我尝试使用.value()代替xn和utau上的[celli]但是当我这样做的时候,我得到如下的错误:
Code:
SPLRRIP.C: In member function 'virtual void Foam::incompressible::RASModels::SPLRRIP::correct()':
SPLRRIP.C:458:26: error: 'Foam::volScalarField' has no member named 'value'
SPLRRIP.C:458:39: error: 'Foam::volScalarField' has no member named 'value'
make: *** [Make/linux64GccDPOpt/SPLRRIP.o] Error 1
我做错了什么吗?
这里是我如何定义utau,f1和xn
Code:
xn
(
IOobject
(
"xn",
runTime_.timeName(),
mesh_,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh_,
dimensionedScalar("xn", dimLength, SMALL)
),
utau
(
IOobject
(
"utau",
runTime_.timeName(),
mesh_,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh_,
dimensionedScalar("utau", U_.dimensions(), 0.0)
),
f1
(
IOobject
(
"f1",
runTime_.timeName(),
mesh_,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh_,
dimensionedScalar("f1", dimless, 0.0)
)
xn = wallDist(mesh_).y(); //Normal distance to wall
const fvPatchList& Boundaries = mesh_.boundary();
forAll(Boundaries, patchi) //loops through boundaries, patchi is the index
{
const fvPatch& currPatch = Boundaries[patchi]; //indexed boundary definition (current patch)
if (isType<wallFvPatch>(currPatch))
{
utauw.boundaryField()[patchi] =
sqrt
(
nu()*mag(U_.boundaryField()[patchi].snGrad())
);
forAll(currPatch, facei)
{
label faceCelli = currPatch.faceCells()[facei]; //indexed face in current patch
// Assign utau[on indexed cell face] value from utauw[on boundary][at each boundary face]
utau[faceCelli] = utauw.boundaryField()[patchi][facei];
forAll(utau, celli) //assigns value of utau[at face] to utau[cells]
{
utau[celli] = utau[faceCelli];
}
}
}
}
Thanks!
你正在除以nu()。什么是nu()?是一个场吗?,如果是这样,你也需要获取单元中的nu()值。
总之,获取一个internal/boundary场的参考值并且循环他们。就像这样的:
Code:
scalarField& f1Cells = f1.internalField();
forAll(f1Cells, cellI)
{
f1Cells[cellI] = ...
}
forAll(f1.boundaryField(), patchI)
{
fvPatchScalarField& pf1 = f1.boundaryField()[patchI];
forAll(pf1, faceI)
{
pf1[faceI] = ...
}
}
Armin你好
我认为nu是constant > transportProperties下定义的运动粘度。我正在运行不可压模拟,我假设nu()是一个常识,这也是为什么我要获取每个独特单元的值
然而,我尝试对nu()编制索引:
Code:
scalarField& f1Cells = f1.internalField();
forAll(f1Cells,celli)
{
if (utau[celli] == 0.0)
{
f1Cells[celli] = exp(-0.5*xn[celli]*utau[celli]/nu[celli]);
}else
{ f1Cells[celli]= 0.0;
}
}
我得到一个错误:
Code:
SPLRRIP.C:459:58: error: invalid types '<unresolved overloaded function type>[Foam::label {aka int}]' for array subscript
make: *** [Make/linux64GccDPOpt/SPLRRIP.o] Error 1
在编制索引时,我尝试包含"()"
Code:
forAll(f1Cells,celli)
{
if (utau[celli] == 0.0)
{
f1Cells[celli] = exp(-0.5*xn[celli]*utau[celli]/nu()[celli]);
}else
{ f1Cells[celli]= 0.0;
}
}
我得到:
Code:
SPLRRIP.C:459:60: error: no match for 'operator[]' in 'Foam::incompressible::turbulenceModel::nu() const()[celli]'
make: *** [Make/linux64GccDPOpt/SPLRRIP.o] Error 1
Quote:
Code: SPLRRIP.C:459:60: error: no match for 'operator[]' in 'Foam::incompressible::turbulenceModel::nu() const()[celli]' make: ***
[Make/linux64GccDPOpt/SPLRRIP.o] Error 1 |
显然,nu()不是一个场。我没有检查源代码我也不常处理不可压缩的代码。
不知道你的代码错在什么地方。你确定这个错误是和你最初贴出来的代码有关吗?或许你应该重新检查错误信息所在行和源代码。
非常感谢,Armin!
我知道我的错误是因为对f1赋值造成的。
OpenFOAM不喜欢f1[celli]=exp(...)
这个原因(根据我的理解)是f1是一个场,但是这个exp(...)返回一个双精度的值。因此,我尝试在一个场的内部设置一个'double'。
我想我可能相处一个结局初始化问题的办法了...现在我有另外一个问题。
用下面的方式编码编译(我应该创建一个标签但是我正在测试)
Code:
forAll(f1,celli)
{
if (utau[celli] == 0.0)
{
f1.internalField() = exp(-0.5*xn[celli]*utau[celli]/nu());
}else
{ f1.internalField()= scalar(0.0);
}
}
现在的问题是模拟第一步将伴随这个错误停止:
Code:
Starting time loop
Time = 1e-05
DILUPBiCG: Solving for Ux, Initial residual = 1, Final residual = 1.36617e-07, No Iterations 1
DILUPBiCG: Solving for Uy, Initial residual = 1, Final residual = 1.36614e-07, No Iterations 1
DICPCG: Solving for p, Initial residual = 0.999805, Final residual = 9.67079e-07, No Iterations 531
time step continuity errors : sum local = 3.21009e-14, global = 1.1476e-17, cumulative = 1.1476e-17
[0]
[0]
[0] --> FOAM FATAL ERROR:
[0] Argument of trancendental function not dimensionless
[0]
[0] From function trans(const dimensionSet&)
[0] in file dimensionSet/dimensionSet.C at line 424.
[0]
FOAM parallel run aborting
[0]
Quote:
The reason
(as far as I understand it) is that f1 is a field, but exp(...)
returns a double. So, I'm trying to assign a 'double' to a cell
within a field. |
不对,它没有任何意义。
f1可能是一个场,但是你可以很好的设置一个'double'值到一个单元。事实上,当你进行如下操作时,
Code:
f1Cells[cellI] = 3.141592;
你就设置了一个'double'到一个单元上。
好的,解决你问题的方法是平分你的代码。意思是,从赋'double'值开始(比如3.141592)给你的单元,看是否能编译。如果能运行,然后一步一步添加更多的步骤,看哪里开始出错。
祝好运!
Quote:
Code: forAll(f1,celli) { if (utau[celli] == 0.0) { f1.internalField() = exp(-0.5*xn[celli]*utau[celli]/nu()); }else { f1.internalField()= scalar(0.0); } } |
这个看起来是错误的!
代码在哪里?在求解器或者链接库?
可能你需要跳转回我带有内部场参考值初始化的例子同时移除nu()。能编译吗?
Armin
这个代码是湍流模型的一部分(LRR)。
我正在尝试
Code:
f1Cells[cellI]=3.141564
并且这个代码可以编译
我移除nu()
怎样才能得到nu的值并且使现在的模拟会采用循环的数值?
我困惑的原因是每当它外循环的时候我都能获得nu的值。
例如,如果我有
Code:
f1=exp(-0.5*xn*utau/nu());
就没问题
问题出现在nu()在循环中使用
Quote:
I removed
nu() and substituted it with it's numerical value and it compiled
and ran! So the whole problem was being caused by nu(). Code: f1=exp(-0.5*xn*utau/nu()); there is no
problem. |
这又把我带回我的第一个方程
Quote:
查看nu()的返回值然后你将会有你问题的解决方法。随机测试只是浪费你的时间,我的猜测是它是一个临时场...
Quote:
I don't understand why nu() can be accessed in a non-loop way but not from within a loop. |
当你接触OpenFOAM高级编程时,会知道"tmp"
http://openfoamwiki.net/index.php/OpenFOAM_guide/tmp
应该像这样修复你的问题:
Code:
const scalarField& nuCells = nu()().internalField();
在循环的时候你能像平常获取单元值那样:
Code:
f1Cells[cellI] = 3.141564*nuCells[cellI];
非常感谢,Armin!你解决了我的问题。