작성일 : 2012년 4월 30일
번역일 : 2016년 3월 29일
크롬 브라우저로 보시는 것을 권장해 드립니다.
------------------------------------------------------------
----- OpenFOAM 소스코드를 다루는 문법 기본 -----
------------------------------------------------------------
들어가기 |
다공질체 (porous media) 를 다루는 코드를 살펴보자.
사용 버전 |
OpenFOAM 2.1.0
파일 |
소스코드 조사 |
다공질체를 다루는 솔버로 porousSimpleFoam이 있다. 이것의 UEqn.H 을 살펴보자. 아래와 같은 코드를 통해 다공질체의 저항을 적용한다.
pZones.addResistance(UEqn(), tTU());
pZones는 createPorousZones.H 에서 아래와 같이 정의된다.
porousZones pZones(mesh);
그렇다면, porousZones의 addResistance()를 찾아보자.
$FOAM_SRC/finiteVolume/cfdTools/general/porousMedia/porousZones.H
void Foam::porousZone::addResistance(fvVectorMatrix& UEqn) const { ... const scalarField& V = mesh_.V(); scalarField& Udiag = UEqn.diag(); vectorField& Usource = UEqn.source(); const vectorField& U = UEqn.psi(); .... addViscousInertialResistance ( Udiag, Usource, V, geometricOneField(), mesh_.lookupObject<volScalarField>
("nu"), U ); ... }
addViscousInertialResistance() 등으로 실제 저항을 부여하고 있다.
$FOAM_SRC/finiteVolume/cfdTools/general/porousMedia/porousZoneTemplate.H
template<class RhoFIeldType>
void Foam::porousZone::addViscousInertialResistance ( scalarField& Udiag, vectorField& Usource, const scalarField& V, const RhoFieldType& rho, const scalarField& mu, const vectorField& U ) const { const tensor& D = D_.value(); const tensor& F = F_.value(); forAll(cellZoneIds_, zoneI) { const labelList& cells = mesh_.cellZones()[cellZoneIds_[zoneI]]; forAll(cells, i) { const tensor dragCoeff = mu[cells[i]]*D + (rho[cells[i]]*mag(U[cells[i]]))*F; const scalar isoDragCoeff = tr(dragCoeff); Udiag[cells[i]] += V[cells[i]]*isoDragCoeff; Usource[cells[i]] -= V[cells[i]]*((dragCoeff - I*isoDragCoeff) & U[cells[i]]); } } }
다공질체의 저항은 보통 운동량방정식의 소스항으로 다루어진다. 위의 코드에서는 U 의 소스 Usource 와 U 의 계수행렬의 대각성분의 값을 설정하고 있다. Usource 에는 저항의 식이 설정되고 있다. Udiag 의 설정은 안정화를 위한 것이다.
소스항에 의한 장애물이 표현 |
위에서 살펴본 바와 같이 소스항에 의한 장애물의 표현을 테스트해보자. 운동량방정식에서 속도를 고정하는 단순한 표현은 아래와 같다.
UEqn = A*(U - U0)
A는 큰 값, U0는 고정한 속도이다. A가 충분히 클때, 양변에서 A 를 빼면 U-U0 = 0 즉 U = U0 가 되는 방식이다.
이때, 소스항은 U에 의존하고 있으므로 비선형이며, 불안정할 수 밖에 없다. 따라서, 안정화를 위해 소스항을 다음과 같이 표현한다.
UEqn = dS*U + S0
dS 는 S(U) 의 U 에 의한 미분계수, S0 는 U 의 함수로 볼 수 있다. 이렇게 표현하면, 우변의 첫번째항을 좌변으로 넘길 수 있고, 불안정성이 감소된다. 안정화를 위해 dS는 음수로 하는것이 좋다는 것을 알 수 있다.
위에서 살펴본 것을 바탕으로, 장애물을 다음과 같이 표현할 수 있다.
UEqn = -A*U + A*U0
장애물을 설정하는 코드를 icoFoam에 추가해보자. 먼저, U의 방정식 UEqn에서 계수행렬의 대각성분과 소스항을 취득한다.
scalarField& Udiag = UEqn.diag();
vectorField& Usource = UEqn.source();
A를 설정한다. 여기의 값은 대충 넣어도 된다. 또한, 장애물을 설정하는 영역을 "c0" 라는 셀존으로부터 받도록 한다.
scalar A = 1e8;
sonst labelList& cells = mesh.cellZone()["c0"];
소스항을 설정한다.
forAll(cells, i)
{
Udiag[cells[i]] += A;
}
이때, U0 = 0 이므로, 소스항은 -A*U, 이것을 좌변에 이동시켜 계수행렬에 포함시키므로 위와 같이 표현하게 된다.
영역의 중앙에 셀존 c0을 설정하여, 왼쪽부터 오른쪽으로의 흐름을 만들면 다음과 같이 된다.
U0 에 0 이외의 값을 설정하는 경우, 다음과 같이 할 수 있다.
forAll(cells, i)
{
Udiag[cells[i]] += A;
Usource[cells[i]] += A*vector(0., 1., 0.);
}
'OpenFOAM > 소스코드 파해치기' 카테고리의 다른 글
[OpenFOAM 소스코드 파해치기] 벽함수 (Wall function) (0) | 2016.03.30 |
---|---|
[OpenFOAM 소스코드 파해치기] autoPtr과 tmp (0) | 2016.03.30 |
[OpenFOAM 소스코드 파해치기]수송특성 추가 (0) | 2016.03.29 |
[OpenFOAM 소스코드 파해치기]입출력오브젝트 (0) | 2016.03.29 |
[OpenFOAM 소스코드 파해치기] 열물성 다루기 (0) | 2016.03.28 |