본문 바로가기

물리학/물리연구를 위한 컴퓨팅

Geant4: a toolkit for the simulation of the passage of particles through matter

Geant4 란 매질 내부를 지나가는 입자들에 대한 시뮬레이션 툴로서 http://geant4.cern.ch 에서 제공하는 공짜프로그램이다.

이번 방학중 매일 오후 1시부터 3시까지 연구실에서 박사님들께 이놈을 쓰는 방법을 배우고 있는데, 숙제를 배당받은 김에 공부한 내용을 기록으로 남길겸 포스팅을 해본다.

내가 배정받은 숙제는 납판떼기를 향해 나아가는 감마의 운명에 대한 시뮬레이션이다.

일단 Geant4 로 작성하게 되는 가장 간단한 프로젝트(C 언어 처음 배울 때의 hello, world 쯤으로 생각하면 된다.)의 기본 구조는 다음과 같다.

/projectmain
/include
PhysicsList.hh
DetectorConstruction.hh
PrimaryGeneratorAction.hh
/src
DetectorConstruction.cc
PrimaryGeneratorAction.cc
PhysicsList.cc
GNUmakefile
maincode.cc

기본적으로 이러한 구조하에 maincode.cc 및 src/ 및 include/ 에 작성한 코드들로 인해 프로그램이 돌아가게 된다.

일단 include/PhysicsList.hh 와 src/PhysicsList.cc 는 우리가 시뮬레이션하고자 하는 상황에서 고려하고자 하는 물리학적 현상들에 관한 코드로서, 대부분 Geant4 에서 제공하는 라이브러리에서 어떤 phenomena 를 갖다 쓸것인가에 의해 코드 내용이 좌우되게 되며, 자기 입맛에 맞도록 physical phenomena 를 정의해서 쓸 수도 있다.

include/DetectorConstruction.hh 와 src/DetectorConstruction.cc 는 실험이 이루어지는 공간을 정의하고, 매질의 조성이나 형태에 관해 정의하는 내용이 들어가게 된다.

include/PrimaryGeneratorAction.hh 와 src/PrimaryGeneratorAction.cc 에서는 시뮬레이션 동안 어떠한 action 들이 수행될 것인지가 결정된다. 이를테면 어느 위치에다 particle gun 을 위치시키고 얼마의 에너지로 어떤 방향으로 발사할 것인가, 몇 번 발사할 것인가, 어떤 에너지 분포로 랜덤하게 발사할 것인가 등등 시뮬레이션 동안 이루어지는 activity에 관한 셋팅을 하는 곳이다.

과제를 위해 작성한 DetectorConstruction.cc 의 내용은 아래와 같다.

#include "leadTest_DetectorConstruction.hh" // Geant4 library 로부터 DetectorConstruction 에 관한 기능들을 가져오는 내용이 들어있는 파일인데 인클루드하자. 

#include "G4Material.hh" // 여러가지 매질들을 이용하기 위한 method 들을 포함하는 library header 이다.
#include "G4Box.hh" // Box 형 검출기를 구현하기 위한 library header.
#include "G4LogicalVolume.hh" // Geant4 에서는 PhysicalVolume 과 LogicalVolume 을 구분하는데 나중에 설명하자.
#include "G4ThreeVector.hh" // 3차원 벡터의 이용에 관한 헤더.
#include "G4PVPlacement.hh" // PhysicalVolume 에 관한 헤더.
#include "globals.hh" // 기본적으로 include 하는 파일. (stdio.h 같은 녀석)

leadTest_DetectorConstruction::leadTest_DetectorConstruction()
:       experimentalHall_log(0),
        calorimeterPanel_log(0),
        experimentalHall_phys(0),
        calorimeterPanel_phys(0)
{;}

leadTest_DetectorConstruction::~leadTest_DetectorConstruction()
{
}

G4VPhysicalVolume *leadTest_DetectorConstruction::Construct()
{
        // Material
        G4double a;    // Atomic mass        
        G4double z;    // Atomic number
        G4double density;

         // 아르곤을 정의
        G4Material *Ar = new G4Material("ArgonGas", z = 18., a = 39.95*g/mole, density = 1.782*mg/cm3);
         // 납을 정의
        G4Material *Pb = new G4Material("Lead", z = 82., a = 207.19*g/mole, density = 11.35*g/cm3);

        // Volumes 전체 실험공간의 규격을 결정한다.
        G4double expHall_x = 3.0*m;
        G4double expHall_y = 1.0*m;
        G4double expHall_z = 1.0*m;
        // 위에 정의한 파라미터들로 experimentalHall_box 를 선언
        G4Box *experimentalHall_box = new G4Box("expHall_box", expHall_x , expHall_y, expHall_z);
         // Logical volume 과 Physicsl volume 을 할당
        experimentalHall_log = new G4LogicalVolume(experimentalHall_box, Ar, "expHall_log", 0, 0, 0);
        experimentalHall_phys = new G4PVPlacement(0, G4ThreeVector(), experimentalHall_log, "expHall", 0, false, 0);

        // A calorimeter(lead) panel
        // 납판떼기의 규격과 위치를 설정한다.
        G4double panelSize_x = 50.0*cm;
        G4double panelSize_y = 1.0*m;
        G4double panelSize_z = 1.0*m;
        G4double panelPos_x = 1.0*m;
        G4double panelPos_y = 0.0*m;
        G4double panelPos_z = 0.0*m;
         // 납판떼기를 생성한다.
        G4Box *calorimeterPanel_box = new G4Box("calPanel_box", panelSize_x, panelSize_y, panelSize_z);
        // Logical volume 선언
        calorimeterPanel_log = new G4LogicalVolume(calorimeterPanel_box, Pb, "caloPanel_log", 0, 0, 0);
        // Physical volume 선언 (납판떼기를 얼마나 돌려서 놓을 것인가, 혹은 중심위치를 어디로 놓을 것인가 등을 설정할 수 있다.)
        calorimeterPanel_phys = new G4PVPlacement(0, G4ThreeVector(panelPos_x, panelPos_y, panelPos_z), calorimeterPanel_log, "caloPanel", experimentalHall_log, false, 0);

        return experimentalHall_phys;
}

요렇게 하면 기본적으로 시뮬레이션이 이루어지는 공간에 대한 정의가 끝난다.

PhysicsList 는 어차피 제일 복잡한걸 갖다 쓰면 되기 때문에 별 문제가 안되고, 어떤 입자소스를 이용할 것인지에 대해 정의하게 되는 PrimaryGeneratorAction 을 다음으로 보자.

#include "leadTest_PrimaryGeneratorAction.hh"

#include "G4Event.hh"
#include "G4ParticleGun.hh" // 입자총에 대한 라이브러리 헤더
#include "G4ParticleTable.hh" // 입자들의 목록에 관한 라이브러리 헤더
#include "G4ParticleDefinition.hh" // 입자들의 정의에 관한 라이브러리 헤더
#include "globals.hh"

leadTest_PrimaryGeneratorAction::leadTest_PrimaryGeneratorAction()
{
        G4int n_particle = 1; // 사용할 파티클의 개수를 정의.
        particleGun = new G4ParticleGun(n_particle); // 파티클 건 생성

        G4ParticleTable *particleTable = G4ParticleTable::GetParticleTable(); // 파티클 테이블을 가져옴
        G4String particleName;
        // 파티클 테이블로부터 감마의 데피니션을 들고온다.
        particleGun->SetParticleDefinition(particleTable->FindParticle(particleName="gamma"));
        // 파티클 건의 셋팅 조정. 파티클의 에너지를 1기가 전자볼트로 설정한다.
        particleGun->SetParticleEnergy(1.0*GeV);
        // 파티클의 초기위치 설정. G4ThreeVector 메소드를 참조하여 설정한다.
        particleGun->SetParticlePosition(G4ThreeVector(-2.0*m, 0.0, 0.0));
}

// PrimaryGeneratorAction 의 소멸자
leadTest_PrimaryGeneratorAction::~leadTest_PrimaryGeneratorAction()
{
        delete particleGun;
}

// 매 event 에 대한 Activity 에 관한 기술
void leadTest_PrimaryGeneratorAction::GeneratePrimaries(G4Event *anEvent)
{
        G4ThreeVector v(1.0, 0.0, 0.0); // 벡터 v 를 정의.
        particleGun->SetParticleMomentumDirection(v); // 파티클의 모멘텀 방향을 v로 설정.
        particleGun->GeneratePrimaryVertex(anEvent);
}

대충 요런식으로 코드를 짜놓고 maincode.cc 에서 runManager 를 돌리고 셋팅들을 initialize 하는 과정들을 거치고 매크로 파일을 만들어서 시점을 돌리고 줌을 하니 마니 디테일들을 결정하고나면 다음과 같은 시뮬레이션 결과를 얻는다. (매 event 들의 step 이나 verbosity 에 대한 코드를 추가함에 따라 엄마 입자가 무슨 반응을 거쳐 얼마의 에너지를 가진 딸입자로 디케이했느니 어쩌니 하는 등의 전체 프로세스를 레코드해서 파일로 내보낼 수도 있고, 동시에 비주얼라이즈 할 수도 있다. 비주얼만 보자 --;)


큰 직육면체 안에 있는 작은 직육면체가 납덩이다. 녹색은 1 GeV 감마선의 궤적.