작성일 : 2009년 12월 5일
번역일 : 2016년 2월 9일
크롬 브라우저로 보시는 것을 권장해 드립니다.
------------------------------------------------------------
----- OpenFOAM 소스코드를 다루는 문법 기본 -----
------------------------------------------------------------
들어가기 |
격자 클래스 fvMesh를 사용해 본다.
사용 버전 |
OpenFOAM 1.6
파일 |
이전과 같이 소스디렉토리식을 작성해보자. 데릭토리를 만들고 안에 아래와 같이 준비한다.(04-mesh.tar.gz)
- Make/files
- Make/options
- system/controlDict
- system/fvSchemes
- system/fvSolution
- constant/polyMesh/boundary
- constant/polyMesh/faces
- constant/polyMesh/neighbour
- constant/polyMesh/owner
- constant/polyMesh/points
- mesh.C
Make 하위는 이전과 같다.
이전과 같이, Time 클래스를 필요로 하는 OpenFOAM 설정용 딕셔너리 파일 controlDict를 준비하여야 한다. 더불어, 이번의 fvMesh는 fvSchemes과 fvSolution를 요구한다. 해당 파일들을 튜토리얼(예를들면 icoFoam; tutorials/incompressible/icoFoam)의 icoFoam/cavity/system에서 system폴더 내의 것을 복사하도록 한다.
격자파일 |
이번에는 격자를 다루므로, 격자파일을 준비하여야 한다.
- constant/polyMesh/boundary
- constant/polyMesh/faces
- constant/polyMesh/neighbour
- constant/polyMesh/owner
- constant/polyMesh/points
여기서 다루는 격자는 단순화를 위해 1개의 셀만 가지는 격자를 사용한다.
boundary
FoamFile
{
version 2.0;
format ascii;
root "/home/cfd/kasuga/tankentai/04-mesh"
case "04-mesh";
instance "constant";
local "polyMesh";
class polyBoundaryMesh;
object boundary;
}
(
left
{
type patch;
nFaces 1;
startFace 0;
physicalType wall;
}
bottom
{
type patch;
nFaces 1;
startFace 1;
physicalType wall;
}
right
{
type patch;
nFaces 1;
startFace 2;
physicalType wall;
}
top
{
type patch;
nFaces 1;
startFace 3;
physicalType wall;
}
)
위는 경계정보를 가지는 파일이다. 제일 위의 "FoamFile {...}"는 형식상 이미 결정되어있는 내용이다. 그 이하의 "(...)"가 경계의 정보에 해당한다. "경계명 {...}"라는 형식으로 적혀져 있따. 각 항목은 아래와 같다.
- type : 경계 타입
- nFaces : 페이스(면) 수
- startFace : 시작 페이스(면) 번호
- physicalType : 물리적 타입
같은 경계의 페이스(면) 번호는 순차적으로 정의되어있어야 하는것 같다.
faces (일부)
...
4
(
2(0 1)
2(1 2)
2(2 3)
2(3 0)
)
위는 페이스의 정의이다. "(...)"의 위가 페이스 수, "(...)" 내의 각행이 페이스 절점수와 절점번호리스트이다.
neighbour (일부)
...
(
)
위는 내부경계가 접하는 옆 셀의 정보이다. 이번에는 1개 셀만 가지고 있으므로 아무것도 적혀이지 않다.
owner (일부)
...
4
(
0
0
0
0
)
페이스를 소유하는 셀의 정보이다. neighbour, owner에서 페이스는 2개의 셀과 접해있는 상황에 대해 2개 셀이 페이스에 대해 서로 소유자이면서 접하는 셀이 되는것이 아닌, 어느 한 쪽이 소유자이고 어느한쪽이 접하는 셀로 구성하게 된다.
points (일부)
...
4
(
(0 0 0)
(1 0 0)
(1 1 0)
(0 1 0)
)
절점에 대한 정보이다.
프로그램 |
자 이번엔 프로그램에 대한 설명이다.
mesh.C (일부)
#include "fvCFD.H"
#include "IOmanip.H"
...
Info << "default region: " << fvMesh::defaultRegion << endl;
Info << "mesh sub dir: " << fvMesh::meshSubDir << endl;
fvMesh mesh(
IOobject(
fvMesh::defaultRegion,
runTime.timeName(), runTime,
IOobject::MUST_READ
)
);
Info << "mesh dir: " << mesh.meshDir() << endl;
const pointField &p = mesh.points();
Info << "num points: " << p.size() << endl;
for(int i = 0; i < p.size(); i++){
Info << "(";
Info << setf(ios_base::scientific)
<< setw(15) << setprecision(3)
<< p[i][0];
Info << ", ";
Info << setf(ios_base::scientific)
<< setw(15) << setprecision(3)
<< p[i][1];
Info << ", ";
Info << setf(ios_base::scientific)
<< setw(15) << setprecision(3)
<< p[i][2];
Info << ")" << endl;
}
const faceList &f = mesh.faces();
Info << "num faces: " << f.size() << endl;
forAll(f, i){
Info << "(";
Info << setw(3) << f[i][0];
Info << setw(3) << f[i][1];
Info << ")" << endl;
}
const labelList &fo = mesh.faceOwner();
Info << "num face owner: " << fo.size() << endl;
forAll(fo, i){
Info << setw(3) << fo[i] << endl;
}
const labelList &fn = mesh.faceNeighbour();
Info << "num face neighbour: " << fn.size() << endl;
forAll(fn, i){
Info << setw(3) << fn[i] << endl;
}
const polyBoundaryMesh &bm = mesh.boundaryMesh();
Info << "boundary mesh: " << bm.size() << endl;
forAll(bm, i){
const polyPatch &patch = bm[i];
Info << "(";
Info << patch.name() << ", ";
Info << patch.type() << ", ";
Info << patch.physicalType();
Info << ")" << endl;
}
...
fvMesh의 상세한 정의를 확인해보자. 해당하는 소스코드 fvMesh.H는 src의 하위에서 직접 찾아보도록 하자(Eclipse에 포팅하였따면 "Search"를 사용하면 편리하다).
fvMesh 오브젝트의 정의는, createMesh.H (src/openFOAM/include/createMesh.H)를 참고하도록 하자.
절점이나 페이스 등의 정보를 참조를 얻어 각각을 표시하고 있다. 절점표시에서는 for문, 그 외에서는 forAll문을 사용하고 있으나 어느쪽돈 같다. forAll은 OpenFOAM에서 이미 정의되어있는 문법이다.
forAll(p, i){
...
}
는
for(int i = 0; i < p.size(); i++){
...
}
으로 적은것과 동일하다.
처음에 인클루드한 IOmanip.H는 C++ 표준입출력스트림용의 입출력방식과 같은 것을 Info 명령어에 사용하고 있기 때문이다. setw()를 사용하기때문에 인클루드되어있다.
컴파일 |
소스디렉토리내에서(Make내부가 아니다!), wmake를 실행시킨다.
$ wmake
$ ./mesh
추가정보 |
기존의 프로그램을 약간 수정해보자(04-mesh2.tar.gz). 변경한 부분은 아래와 같다.
mesh.C (일부)
...
Info << "mesh dir: " << mesh.meshDir() << endl;
// move point
pointField pnew(mesh.points());
pnew[0][0] = 0.01;
mesh.movePoints(pnew);
const pointField &p = mesh.points();
...
mesh.write();
return 0;
}
절점정보에서부터 pointField 오브젝트를 만들어 절점위치를 변경하고(0번의 절점의 x좌표를 0.01으로 설정), movePoints()로 해당 변화를 격자에 적용시키고 있다. 실행경과는 paraFoam을 통해 볼수 있듯이, 절점의 위치가 변경되어 있다.
'OpenFOAM > 소스코드 파해치기' 카테고리의 다른 글
[OpenFOAM 소스코드 파해치기] 이동격자 (2) | 2016.02.09 |
---|---|
[OpenFOAM 소스코드 파해치기] blockMesh (0) | 2016.02.09 |
[OpenFOAM 소스코드 파해치기] 시간 (3) | 2016.02.06 |
[OpenFOAM 소스코드 파해치기] 인수 리스트 (0) | 2016.02.06 |
[OpenFOAM 소스코드 파해치기] 단순 프로그램 (0) | 2016.02.06 |