티스토리 뷰

일본어 원문링크


작성일 : 2009년 12월   5일
번역일 : 2016년  2월    9일


크롬 브라우저로 보시는 것을 권장해 드립니다.


 ------ OpenFOAM 소스코드 파해치기 시리즈 ------

OpenFOAM 소스코드 파해치기 목차로 이동

 ------------------------------------------------------------

 ----- OpenFOAM 소스코드를 다루는 문법 기본 -----

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 소스코드 파해치기 목차로 이동



댓글
공지사항
글 보관함
링크
«   2018/12   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Total
102,142
Today
42
Yesterday
71