翻譯自:CFD-onlinephp
帖子地址:http://www.cfd-online.com/Forums/openfoam/84322-difference-between-internalfield-boundaryfield.htmlhtml
Rusty Velo:linux
親愛的Ofoamer們 編程
做爲一個OpenFOAM的新手,我可能有一個很是簡單的問題..可是我沒有從OF的案例中找到合適的答案而且我變得愈來愈困惑(我嘗試作了一個"嘗試性和錯誤性的計算")。 app
好比說在U文件下的'internalField'描述的什麼?'internalField' 和 'boundaryField'之間有什麼區別(細節上)? less
先謝過了 dom
felixide
nimasam:oop
考慮壓力(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
祝好
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!你解決了個人問題。