본문 바로가기

OpenFOAM/소스코드 파해치기

[OpenFOAM 소스코드 파해치기] 이동격자

일본어 원문링크


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


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


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

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

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

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

OpenFOAM 소스코드를 다루는 문법 기본으로 이동

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



 

  들어가기 


단순한 이동격자 기능을 사용해보자.



  사용 버전 


OpenFOAM 1.6

 


   파일


이번에 사용파는 파일이다.(06-dynesh.tar.gz).


  • Make/files
  • Make/options
  • system/controlDict
  • system/fvSchemes
  • system/fvSolution
  • constant/polyMesh/blockMeshDict
  • constant/dynamicMeshDict
  • 0/cellMotionUx
  • 0/pointMotionUx
  • dynmesh.C

이번엔 조금은 특별한 조작을 하므로, Make/options를 수정할 필요가 있다.


Make/options

EXE_INC  = -I$(LIB_SRC)/finiteVolume/lnInclude \
	   -I$(LIB_SRC)/dynamicFvMesh/lnInclude
EXE_LIBS = -lfiniteVolume \
	   -l dynamicFvMesh


이동격자용의 설정을 추가한다.

격자는 이전과 같이 blockMesh로 작성한다.



  이동격자의 설정


이동격자의 기능을 설정하는데는 dynamicMeshDict 파일(constant/dynamicMeshDict)에서 이루어진다. 이 파일은 tutorials/incompressible/pimpleDyMFoam/movingCone의 constant에 있다.


dynamicMeshDict (일부)

...
dynamicFvMesh   dynamicMotionSolverFvMesh;

motionSolverLibs ( "libfvMotionSolvers.so" );

solver          velocityComponentLaplacian x;

diffusivity     directional ( 1 200 0 );
...


여기서 "x 방향으로 어떤 속도를 가지고 격자가 이동한다"라는 기능을 사용하고 있다.


격자의 이동속도에 대한 설정은 경계조건 파일 0/cellMotionUx, 0/pointMotionUx에서 이루어진다.


cellMotionUx

FoamFile
{
    version     2.0;
    format      ascii;
    class       volScalarField;
    object      motionU;
}

dimensions      [0 1 -1 0 0 0 0];

internalField   uniform 0;

boundaryField
{
    left
    {
        type            fixedValue;
        value           uniform 1;
    }
    right
    {
        type            fixedValue;
        value           uniform 0;
    }
    top
    {
        type            slip;
    }
    bottom
    {
        type            slip;
    }
    frontAndBack
    {
        type            slip;
    }
}


경계조건의 설정은 이동격자에만 해당하는 것이아니라 전부 상기 형식으로 적혀져 있다.


dimensions는 단위에 대한 설정이다. 숫자의 열의 각각 [kg, m, s, K, mol, A Cd]의 지수를 의미하고 있다(이것은 src/OpenFOAM/dimensionSet/dimensionSet.H에서 확인가능하다). [0 1 -1 0 0 0 0]는 m/s, 즉, 속도의 단위를 의미한다.


internalField는 내부경계영역전체에 대한 설정이다. "uniform 0"라고 하는 것은, 0 이라는 일정한 값을 전체에 설정한다는 의미이다.



boudnary이하는, 경계 각각에 대한 설정이다. "경계이름 {...}"의 형식으로 type이 경계타입, value가 그 곳의 값, 그 외에도 경계 타입에 따라 다양한 키워드가 사용된다. 여기서는 "type fixedValue"는 고정값경계, "value uniform 1"는 1 m/s 일정치를 설정한다는 의미이다. 또한 "type slip"은, 여기는 미끄러져간다(slip 경계조건)는 의미이다.



pointMotionUx도 동일하다.



  fvSchemes과 fvSolution


이전에도 사용하였던 system 폴더 내의 fvSchemes과 fvSolution이라는 파일은 방정식을 푸는 방법에 대한 설정에 해당한다. 이전까지는 방정식을 풀지 않았으므로 해당 내용을 불러들여도 사용하지 않았었다. 이번의 경우, 이동격자에서 방정식을 풀어야 하므로, 그에 해당하는 설정이 필요하다. 이번 케이스에서는 dynamicMeshDict파일과 동일하게, tutorials/incompressible/pimpleDyMFoam/movingCone의 system에서부터 fvSchemes, fvSolution을 복사하도록 한다.


fvSchemes (일부)

...
laplacianSchemes
{
    default         none;
    laplacian(nu,U) Gauss linear corrected;
    laplacian(rAU,pcorr) Gauss linear corrected;
    laplacian(rAU,p) Gauss linear corrected;
    laplacian(diffusivity,cellMotionU) Gauss linear uncorrected;
    laplacian(nuEff,U) Gauss linear uncorrected;
}
...

fvSchemes에는 이산화 스캠의 설정이 적혀 있다. 이번에 사용하는 이동격자기능에서는 라플라스방정식을 풀어야 하므로, 라플라시안의 이산화스킴의 설정을 필요로 한다. 해당부분은 아래와 같다.


laplacian(diffusivity,cellMotionU) Gauss linear uncorrected;


방정식의 "laplacian(diffusivity,cellMotionU)"에, 가우스의 발산정리에 의한 이산화를 사용하도록 정의한다.


fvSolution (일부)

...
solvers
{
    ...
    cellMotionUx
    {
        solver          PCG;
        preconditioner  DIC;
        tolerance       1e-08;
        relTol          0;
    }
}
...

fvSolution은 편미분방정식의 이산화하여 나타나는 대수방정식을 풀기위한 설정에 해당한다. 위에서 cellMotionUx 변수에 대한 방정식의 솔버 설정을 나타내고 있다. 솔버에 PCG (전처리를 포함하는 병역분배법)을 사용하도록 설정되어있다. 여기서 전처리는 불완전 콜레스키분해를 의미하는듯 하다.









  프로그램

 

이번에 사용하는 프로그램이다.

dynmesh.C

#include "fvCFD.H"
#include "dynamicFvMesh.H"

	...
	autoPtr meshPtr(
		dynamicFvMesh::New(
			IOobject(
				fvMesh::defaultRegion,
				runTime.timeName(),
				runTime
			)
		)
	);

	dynamicFvMesh &mesh = meshPtr();

	while(runTime.loop()){
		Info << "Time: " << runTime.timeName() << endl;
		mesh.update();
		runTime.write();
	}
	...

처음에 인클루드하는 "dynamicFvMesh.H"는 dynamicFvMesh 클래스를 사용할 수 있도록 한다. 


dynamicFvMesh 오브젝트의 정의는 특수하다. (참조: src/dynamicFvMesh/include/createDynamicFvMesh.H) dynamicFvMesh의 오브젝트를 직접 생성자로 만들지 않고 멤버함수 New()를 사용하여 포인터로 얻는다. 이런 방식을 채택한 이유는 dynamicFvMesh 클래스는 추상적 클래스이며 실체는 별도의 클래스를 가지기 때문이다.  dynamicFvMesh는 창문에 불과하며 실체는 dynamicMeshDict의 설정에 의해 변화한다( 여기서는 dynamicMotionSolverFvMesh가 그 정체). 이러한 구조로 OpenFOAM은 다른 클래스도 사용가능하게 되어 있다.


"mesh = meshPtr()"의 부분은, 단순히 이름을 바꾸고 있을 뿐이다. 이동격자 이외에도 격자는 mesh를 참조하고 있으므로, 이렇게 놓으면 병행 표기가 되어 중복사용 가능하다.


계산 루프 내의 mesh.update()에서 격자를 이동시키고 있다.



  실행


컴파일하여 실행해 본다.

$ wmake
$ blockMesh
$ ./dynmesh

paraFoam에서 결과를 확인해보면 격자가 이동하고 있음을 알 수 있다.







  추가정보

 

dynamicFvMesh에서는  motionSolver라는 것이 사용되고 있으며 이것이 실제 격자를 이동시키고 있다. 이번에 사용되고 있는 velocityComponenetLaplaican은 fvMotionSolver를 계승하고 있으며 fvMotionSolver는 motionSolver를 계승하고 있다. 

dynmaicMOtionSolverFvMesh는 이 motionSolver를 통해 velocityComponentLaplacian을 사용하여 격자를 이동시키고 있다. 위에서 보는 프로그램은 dynamicFvMesh를 통해 이 dynamicMotionSolverFvMesh의 격자이동을 호출하고 있는 것이다.


따라서, 이러한 내부의 복잡한 상황 때문에 dynamicFvMesh가 창문의 개념으로 적용된다. 즉, dynamicFvMesh 이하의 내부형체가 다른것으로 변경되어도 dynamicFvMesh의 유저는 알 수 없으며, 알 필요도 없다. 이렇게 함으로써, dynamicMeshDict에서 지정된 격자이동용 솔버의 종류에 상관없이 프로그래밍이 가능하다.


그렇다면, dynamicFvMesh를 사용하지 않고, motionSolver를 사용해 격자를 이동시키는 프로그램을 작성해 보자(06-dynmesh2.tar.gz).


dynmesh.C (일부)


#include "fvCFD.H"
#include "motionSolver.H"

	...

	fvMesh mesh(
		IOobject(
			fvMesh::defaultRegion,
			runTime.timeName(), runTime,
			IOobject::MUST_READ
		)
	);

	autoPtr motionPtr = motionSolver::New(mesh);

	while(runTime.loop()){
		Info << "Time: " << runTime.timeName() << endl;
		mesh.movePoints(motionPtr->newPoints());
		runTime.write();
	}
	...


이것에 의해, 격자를 실제로 이동시키는 것은 fvDynamicMesh가 아닌 motionSolver임을 확인 할 수 있다.


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