翻译自:CFD-online

帖子地址:http://www.cfd-online.com/Forums/openfoam/84322-difference-between-internalfield-boundaryfield.html

Rusty Velo

亲爱的Ofoamer们

作为一个OpenFOAM的新手,我可能有一个非常简单的问题..但是我没有从OF的案例中找到合适的答案并且我变得越来越困惑(我尝试做了一个"尝试性和错误性的计算")。

比如说在U文件下的'internalField'描述的什么?'internalField' 和 'boundaryField'之间有什么区别(细节上)?

先谢过了

felix

nimasam

考虑压力(p),它被定义为volScalarField

意味着它定义在计算域每个单元的中心。计算域有两部分:内容域(internalField)和域周边(boundaryField)。

p.boundaryField()让你获取边界上的值,边界上的值就是面中心的值。当你需要一个边界值最大值,最小值或者平均值时,这个是非常有用的。

p.internalField()返回一个scalarField(我不确定,检查一下),这对于你想要处理内部值和保持边界条件不变是有用的。

351Cleveland

你好,felix

我是一个OpenFOAM的菜鸟,但是我能给一点internalField边界条件的解释。

对于速度U,这internalField的特点是用来确定计算域内部流场流体的性质。比如,如果流体是静止的并且在任何方向都没有速度,这个值将为(0
0 0),反之,如果我们有动能(标量)并且初始条件表明存在一些速度,这个值将为uniform
x。

简而言之,据我所知,(希望是正确的),这个边界条件很简单的设置流体的初始特性而不依赖任何边界。

希望有帮助

Dom

nimasam

如果你刚才问的是0目录下的U文件。

你想要解偏微分方程,你需要设置边界条件和初始条件,internalField可以定义均匀的或者非均匀的初始边界条件同时boundaryField定义如下的数学边界条件:fixedValue(边界上的平均值被定义)或者zeroGradient(变量在边界上的梯度为0),更多的请参与用户手册。

Rusty Velo

你好,Nima,你好,Dominic

感谢你的快速回复!这些正是我遗失的信息。

Nima:现在我只有一些老的算例来知道所有设置的可能的不同。但是可以肯定的是,我将进一步阅读用户手册!

祝好

Felix

mm.abdollahzadeh

Quote:

Originally
Posted by nimasam 'internalField' 和'boundaryField'的区别?【翻译】-LMLPHP和'boundaryField'的区别?【翻译】">

consider
pressure (p), it is defined as volScalarField

means it defines in center of each cell in domain. domain has two
parts : domain content (internalField) and domain surrounding
(boundaryField).



p.boundaryField() give you access to value in boundary, value in
boundary would be surface center value. its helpful when you need
the maximum, min, sum or average the value of a patch, so it
returns a surfaceScalarField.

p.internalField() returns a scalarField (im not sure, check
it 'internalField' 和'boundaryField'的区别?【翻译】-LMLPHP和'boundaryField'的区别?【翻译】"> ) , so it can be useful when you want to deal with
internal value and keep boundary conditions
unchanged.

亲爱的nima

感谢你清楚的描述。

你能进一步解释一下dimensionedInternalField()和InternalField()的不同吗?

我有如下方程。但是当我用InternalField()替代dimensionedInternalField()时,报出这样的错误(这里没有dimensionedboundaryField())。

  1. dimensionedInternalField()=min(scalar(0),B.dimen
    sionedInternalField());
    A.boundaryField()=min(scalar(0),B.boundaryField()) ;

祝好

Mahdi

nimasam

你知道变量是有量纲的,比如速度量纲是{m/s}

OpenFOAM同时保存变量的值和它的量纲

因此dimensionedInternalField()的值是除了InternalField()以外的值,它也是有量纲的!

这个错误显示你想要和一个具有量纲的变量进行比较。

这是不允许的,你应该定义你的为0!作为一个有合适量纲的dimensionedScalar

mm.abdollahzadeh

Quote:

Originally
Posted by nimasam 'internalField' 和'boundaryField'的区别?【翻译】-LMLPHP和'boundaryField'的区别?【翻译】">

you know
variable has dimension, for example velocity dimension is
{m/s}

OpenFOAM saves both variable values and its dimension,

so dimensionedInternalField() has
besides value of InternalField(), its
dimension too!



the error returns that you are going to compare a
dimensionedvarible with a scalar, 

it is not allowed, you should define your zero! as a
dimensionedScalar with appropriate dimension

感谢nima

但是这意味着这个公式是正确的!

Code:

A.dimensionedInternalField()=min(scalar(0),B.dimen
sionedInternalField());

但是这一个是不正确的

Code:

A.InternalField()=min(scalar(0),B.InternalField());

nimasam

什么错误?

把错误贴出来

CHARLES

我知道这是一个老帖子但是我有一个与主题相关的问题

我尝试编写一个循环,不管我怎么编码,我总是会得到错误。

我尝试这样编码:

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!

dkxls

你正在除以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] =
...

}

}

CHARLES

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

在编制索引时,我尝试包含"()" 到nu()

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

dkxls

Quote:

Originally
Posted by CHARLES 'internalField' 和'boundaryField'的区别?【翻译】-LMLPHP和'boundaryField'的区别?【翻译】">

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()不是一个场。我没有检查源代码我也不常处理不可压缩的代码。

不知道你的代码错在什么地方。你确定这个错误是和你最初贴出来的代码有关吗?或许你应该重新检查错误信息所在行和源代码。

CHARLES

非常感谢,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]

dkxls

Quote:

Originally
Posted by CHARLES 'internalField' 和'boundaryField'的区别?【翻译】-LMLPHP和'boundaryField'的区别?【翻译】">

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.



Does that make sense?

不对,它没有任何意义。

f1可能是一个场,但是你可以很好的设置一个'double'值到一个单元。事实上,当你进行如下操作时,

Code:

f1Cells[cellI]
= 3.141592;

你就设置了一个'double'到一个单元上。

好的,解决你问题的方法是平分你的代码。意思是,从赋'double'值开始(比如3.141592)给你的单元,看是否能编译。如果能运行,然后一步一步添加更多的步骤,看哪里开始出错。

祝好运!

dkxls

Quote:

Originally
Posted by CHARLES 'internalField' 和'boundaryField'的区别?【翻译】-LMLPHP和'boundaryField'的区别?【翻译】">

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()。能编译吗?

CHARLES

Armin

这个代码是湍流模型的一部分(LRR)。

我正在尝试

Code:

f1Cells[cellI]=3.141564

并且这个代码可以编译

我移除nu() 并用一个数值代替它。它能编译并且运行!因此这所有的问题都是nu()造成的。

怎样才能得到nu的值并且使现在的模拟会采用循环的数值?

我困惑的原因是每当它外循环的时候我都能获得nu的值。

例如,如果我有

Code:

f1=exp(-0.5*xn*utau/nu());

就没问题

问题出现在nu()在循环中使用

dkxls

Quote:

Originally
Posted by CHARLES 'internalField' 和'boundaryField'的区别?【翻译】-LMLPHP和'boundaryField'的区别?【翻译】">

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().

...

For example, if I have

Code:

f1=exp(-0.5*xn*utau/nu());

there is no
problem. 

The problem arises when nu() is used in the loop...

这又把我带回我的第一个方程

Quote:

Originally
Posted by dkxls 'internalField' 和'boundaryField'的区别?【翻译】-LMLPHP和'boundaryField'的区别?【翻译】">

What is
nu()? Is it a field?

查看nu()的返回值然后你将会有你问题的解决方法。随机测试只是浪费你的时间,我的猜测是它是一个临时场...

dkxls

Quote:

Originally
Posted by CHARLES 'internalField' 和'boundaryField'的区别?【翻译】-LMLPHP和'boundaryField'的区别?【翻译】">

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

http://www.cfd-online.com/Forums/openfoam-programming-development/71912-tmp-stands-true-macro-pain.html

应该像这样修复你的问题:

Code:

const
scalarField& nuCells =
nu()().internalField();

在循环的时候你能像平常获取单元值那样:

Code:

f1Cells[cellI]
= 3.141564*nuCells[cellI];

CHARLES

非常感谢,Armin!你解决了我的问题。

05-26 04:08