작성일 : 2012년 5월 19일
번역일 : 2016년 3월 29일
크롬 브라우저로 보시는 것을 권장해 드립니다.
------------------------------------------------------------
----- OpenFOAM 소스코드를 다루는 문법 기본 -----
------------------------------------------------------------
들어가기 |
autoPtr과 tmp에 대해 살펴보자.
사용 버전 |
OpenFOAM 2.1.0
autoPtr |
보통 사용되지는 않지만 "자동변수" 라는 용어가 있다. 이것은 C 언어에서 함수 내의 static 변수에 해당하는 개념이다. 자동변수는 정의된 함수에서 나오면 메모리에서 자동적으로 삭제된다. 한편, static 변수는 함수에서 나와도 메모리에서 지워지지 않는다. 예를 들 면 아래와 같은 함수를 생각할 수 있다.
void f1() { int a = 0; a++; printf("%d\n", a); } void f2() { static int a = 0; a++; printf("%d\n", a); }
f1() 의 출력은, 언제나 "1"이지만 f2()는 실행할때마다 "1", "2", "3",... 으로 값이 증가하게 된다. f2()의 경우 변수 a가 메모리에 그대로 존재하기 때문이다.
void f() { int *a; a = malloc(sizeof(int)*N);
...free(a); }
매번 수행하기에 귀찮은 작업이기에 "자동포인터"라는 개념이 탄생했다. C++의 오브젝트에서는 만들어질때 생성자, 삭제할때 소멸자를 자동적으로 호출한다. 자동포인터는 그러한 특성을 이용하여 생성자를 통해 메모리의 주소를 받고, 소멸자를 통해 그 메모리를 해방시킨다. 이렇게 하면 오브젝트가 삭제될때 포인터가 가르키는 메모리가 해제되게되어 메모리 관리에 용의하다.
template<class T>
inline Foam::autoPtr<T> ::autoPtr(T* p) : ptr_(p) {} ... template<class T> inline Foam::autoPtr<T> ::~autoPtr() { clear(); }
생성자 autoPtr()로 포인터를 저장, 소멸자 ~autoPtr()로 clear()를 호출하고 있다. clear()는 아래와 같다.
template<class T>
inline void Foam::autoPtr<T> ::reset(T* p) { if (ptr_) { delete ptr_; } ptr_ = p; } template<class T> inline void Foam::autoPtr<T> ::clear() { reset(0); }
포인터가 어떤곳을 가르키고 있다면 메모리를 삭제하고, 삭제한 메모리가 잘못 사용되지 않도록 0을 설정하고 있다.
일시적으로 메모리를 확보하고 싶다면 자동포인터를 사용하면 편리하다. 이렇게 기능을 강화한 포인터를 "스마트포인터"라고 부르기도 한다.
tmp |
tmp는, 이름으로부터 스마트 포인터의 한 종류로 보인다. 실제 메모리를 자동적으로 제거하는 점에서 autoPtr과 닮아있으나 더 높은 차원의 기능을 수행한다. tmp는 쓰레기 수집기이다.
tmpI.H
template<class T>
class tmp { // Private data //- Flag for whether object is a temporary or a constant object bool isTmp_; //- Pointer to temporary object mutable T* ptr_; //- Const reference to constant object const T& ref_; ...
ref_ 가 참조카운터에 해당한다. 형태가 "const T&" 로 되어 있는데 이것은 Field 의 정의를 보면 이유를 알 수 있다.
template<class Type>
class Field
:
public refCount,
public List<Type>
즉 tmp 는, 참조 카운터클래스 refCount를 계승하고 있는 Field 의 하위 클래스 (GeometricField 등)을 템플릿 클래스로 상정하고 있다.
refCont의 조작은 어느정도 예상가능하다. tmp 의 코드를 살펴보자
tmpI.H.
template<class T>
inline Foam::tmp<T> ::tmp(T* tPtr) : isTmp_(true), ptr_(tPtr), ref_(*tPtr) {} ... template<class T> inline Foam::tmp<T> ::tmp(const tmp<T> & t) : isTmp_(t.isTmp_), ptr_(t.ptr_), ref_(t.ref_) { if (isTmp_) { if (ptr_) { ptr_->operator++(); } else { FatalErrorIn("Foam::tmp<T> ::tmp(const tmp<T> &)") << "attempted copy of a deallocated temporary" << abort(FatalError); } } } template<class T> inline Foam::tmp<T> ::~tmp() { if (isTmp_ && ptr_) { if (ptr_->okToDelete()) { delete ptr_; ptr_ = 0; } else { ptr_->operator--(); } } }
일반적 포인터를 받을 때는 그것을 설정, tmp 를 받을때는 참조카운터를 증가시킨다. 오브젝트를 제거할때는 참조카운터를 줄이며 메모리를 삭제할수 있는 상태이면 삭제한다.
대입연산자는 다음과 같다.
template<class T>
inline void Foam::tmp<T> ::operator=(const tmp <T> & t)
{ if (isTmp_ && ptr_) { if (ptr_->okToDelete()) { delete ptr_; ptr_ = 0; } else { ptr_->operator--(); } } if (t.isTmp_) { isTmp_ = true; ptr_ = t.ptr_; if (ptr_) { ptr_->operator++(); } else { FatalErrorIn("Foam::tmp <T> ::operator=(const tmp <T> &)")
<< "attempted copy of a deallocated temporary" << abort(FatalError); } } else { FatalErrorIn("Foam::tmp <T> ::operator=(const tmp <T> &)")
<< "attempted to assign to a const reference to constant object" << abort(FatalError); } }
대입되는 쪽은 참조카운터를 줄이거나, 메모리를 삭제한다. 대입하는 데이터를 설정하고 참조카운터를 증가시키고 있다.
이 방식은 불필요한 메모리 할당(메모리 리크) 을 방지함과 동시에 메모리를 가능한 복제하지 않고 여러곳에서 사용할 수 있어 효율성이 증대된다.
tmp<fvVectorMatrix>
UEqn ( fvm::div(phi, U) + turbulence->divDevReff(U) == sources(U) );
pEqn.H
{ p.boundaryField().updateCoeffs(); volScalarField rAU(1.0/UEqn().A()); U = rAU*UEqn().H(); UEqn.clear(); phi = fvc::interpolate(U, "interpolate(HbyA)") & mesh.Sf(); adjustPhi(phi, U, p); // Non-orthogonal pressure corrector loop while (simple.correctNonOrthogonal()) { fvScalarMatrix pEqn ( fvm::laplacian(rAU, p) == fvc::div(phi) ); ...
'OpenFOAM > 소스코드 파해치기' 카테고리의 다른 글
[OpenFOAM 소스코드 파해치기] 경계조건 (0) | 2016.04.04 |
---|---|
[OpenFOAM 소스코드 파해치기] 벽함수 (Wall function) (0) | 2016.03.30 |
[OpenFOAM 소스코드 파해치기] 다공질체 (porous media) (0) | 2016.03.29 |
[OpenFOAM 소스코드 파해치기]수송특성 추가 (0) | 2016.03.29 |
[OpenFOAM 소스코드 파해치기]입출력오브젝트 (0) | 2016.03.29 |