'internalField' 和'boundaryField'的區別?【翻譯】

翻譯自:CFD-onlinephp

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

Rusty Velolinux

親愛的Ofoamer 編程

做爲一個OpenFOAM的新手,我可能有一個很是簡單的問題..可是我沒有從OF的案例中找到合適的答案而且我變得愈來愈困惑(我嘗試作了一個"嘗試性和錯誤性的計算")。 app

好比說在U文件下的'internalField'描述的什麼?'internalField' 'boundaryField'之間有什麼區別(細節上)? less

先謝過了 dom

felixide

nimasamoop

考慮壓力(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 

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  ) , 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 

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()代替xnutau上的[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,f1xn

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你好

我認爲nuconstant > 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 

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 

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 

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 

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 

What is nu()? Is it a field?

查看nu()的返回值而後你將會有你問題的解決方法。隨機測試只是浪費你的時間,個人猜想是它是一個臨時場...

dkxls

Quote:

Originally Posted by CHARLES 

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!你解決了個人問題。

相關文章
相關標籤/搜索