본문 바로가기

OpenFOAM/소스코드 파해치기

[OpenFOAM 소스코드 파해치기] 시간미분

일본어 원문링크


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


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


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

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

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

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

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

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



 

  들어가기 


시간미분함수 ddt()를 자세히 살펴보도록 하자.



  사용 버전 


OpenFOAM 1.6

 


   파일


이번에 사용파는 파일이다.(10-ddt.tar.gz).


  • Make/files
  • Make/options
  • system/controlDict
  • system/fvSchemes
  • system/fvSolution
  • constant/transportProperties
  • constant/polyMesh/blockMeshDict
  • 0/T
  • heat.C

이번의 프로그램에서 열전도를 덤으로 계산해내는 비정상열전도 프로그램을 기반으로 하고 있다.









  프로그램

 

이번에는 비정상 열전도 프로그램의 시간미분함수 ddt()의 부분을 개조시켰다.

heat.C (일부)

	...
	while(runTime.loop()){
		Info << "Time = " << runTime.timeName() << endl;


		/* ddt */
		tmp > tDdtTerm(
			new fvMatrix(
				T, T.dimensions()*dimVol/dimTime
			)
		);

		fvMatrix &ddtTerm = tDdtTerm();

		scalar dtime = runTime.deltaT().value();

		ddtTerm.diag() = mesh.V()/dtime;
		ddtTerm.source() = T.oldTime().internalField()*mesh.V()/dtime;


		solve(ddtTerm - fvm::laplacian(DT, T));
	...

원래의 코드는

	...
	while(runTime.loop()){
		Info << "Time = " << runTime.timeName() << endl;

		solve(fvm::ddt(T) - fvm::laplacian(DT, T));
	...


였으나, fvm::ddt(T)의 부분을 수정하였다. 이전에는 설명하지 않았으나 OpenFOAM에는 시간미분 ddt 나 구배 grad, 발산 div, 라플라시안 등의 유체장에 대한 연산자를 나타내는 함수가 fvm과 fvc의 2 종류 존재한다(한 종류만 존재하는 것도 있다). 각각 fvm::laplacian(T) 또는 fvc::laplacian(T)등을 참조하고 있으나 fvm가 음함수, fvc가 양함수적인 연산을 나타낸다. fvm의 연산자는 그 연산자가 적용되는 변수를 구하기 위해 사용하며 fvc는 변수에 연산자를 적용해 값을 얻어내기 위해 사용한다. 방정식의 기술에서 사용하는 경우에는 대수방정식으로 변환될 때 fvm의 결과는 좌변의 대수행렬에 들어가며 fvc의 결과는 우변의 벡터에 들어가게 된다. fvc는 직접 어떠한 값을 출력시키는 반면 fvm 은 대수방정식을 출력시킨다.


대수방정식은  fvMatrix로 표현되고 있다. solve()에 해당 오브젝트를 부여하면 방정식이 풀려 변수의 값을 구하게 된다. solve()에 의해 편미분방정식을 푸는 1행의 기술은 방정식을 나타내는 유체장의 함수집단이 fvMatrix를 구성하고 solve가 그것을 풀어내는 흐름으로 진행된다.


따라서, fvm:ddt()는 시간미분에 관한 대수방정식에 대응하는 fvMatrix를 만들고 있다. 위 프로그램은 src/finiteVolume/finiteVolume/ddtSchemes/EulerDdtSchemes/EulderDdtSchemes.C의 EulerDdtScheme::fvmDdt()를 참고로 하고 있다. fvMatrix의 오브젝트를 만들어, 대수바정식의 계수행렬에 해당하는 부분과 우변벡터에 해당하는 부분의 각각의 값을 셋업시키고 있다. 시간미분의 단순한 이산화식은 시간을 t, 변수를 T, 이전의 시간스텝의 변수를 T0,  타임스텝을 dtime으로 표현하면

dT/dt = (T - T0)/dtime


로 적을 수 있다(여기서 dT/dt 는 미분을 의미한다). 유한체적법에서는 콘트롤볼륨적분의 계념이므로 체적 V를 곱해

V*dT/dt = (V/dtime)*T - (V/dtime)*T0


dT/dt = 0 으로 생각하면면

(V/dtime)*T = (V/dtime)*T0


결국

  • 변수의 계수는 V/dtime
  • 우변의 값은  T0*V/dtime

이며, 위 프로그램과 같이 된다.


fvMatrix의 멤버함수 diag()는 계수행렬의 대각성분을 나타내고 있다(자세히 설명하면 참조를 출력한다). 행렬의 성분을 아래삼각 L, 대각 D, 윗삼각 U 로 나누었을때 D에 해당한다. 이것은  fvMatrix가 계승하는 lduMatrix(LDU행렬)의 멤버함수로, lower(), uppser()도 존재한다. source()는 소스항, 즉 우변벡터를 나타내고 있다.




  실행


컴파일하여 실행해 본다.

$ wmake $ blockMesh $ ./heat

paraFoam에서 결과를 확인해보자.




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