Geant4 무작정 따라하기 시리즈의 여덟번째. Event의 시작에 해당하는 선원항을 정의하는 방법에 대해 알아봅니다.
지오메트리를 정의할 때와 마찬가지로, Geant4 코드 작성 시 초기 입자에 대한 내용을 적는 곳도 정해져 있습니다.
G4VUserPrimaryGeneratorAction 클래스를 상속받아 만드는 UserClass에 적어야 하며, 이 중에서도 void GeneratePrimaries(G4Event*) 함수가 매 Event마다 초기 입자를 발생시키는 역할을 담당합니다.
제가 제공해드린 템플릿 코드의 src 디렉토리 내부에 PrimaryGeneratorAction.cc라는 파일이 있을 것입니다. 이 파일을 열면 다음과 같은 코드가 나옵니다.
여기서 16번째 줄부터 나오는 void PrimaryGeneratorAction::GeneratePrimaries(G4Event *anEvent) 함수 안에 초기 입자에 대한 내용을 적으면 됩니다.
엄밀히 말하면, Event마다 바뀌는 설정값은 이 함수 안에 적고, 바뀌지 않는 설정값은 생성자에 적는 것이 연산효율측면에서 이득이 있습니다.
다만, 이 시리즈에서는 설명과 이해의 용이성을 위해 그냥 GeneratePrimaries 함수 안에 모두 작성하도록 하겠습니다.
GeneratePrimaries 함수 안에는 다음과 같은 줄이 이미 작성되어 있습니다.
1fPrimary->GeneratePrimaryVertex(anEvent);
여기서 fPrimary 변수는 초기 입자에 대한 설정을 담당하는 클래스인 G4ParticleGun 클래스 객체의 포인터입니다.
이 클래스는 GeneratePrimaryVertex라는 함수를 갖고 있습니다. 이 함수는 “초기 입자를 발생시켜서 Event를 한 회 수행하라“는 기능을 가진 함수입니다. 즉 위의 코드 한 줄에 의해 초기 입자가 발생되는 것이지요.
우리가 할 일은, “초기 입자를 발생시키기 전에 초기 입자의 특성을 설정“하는 것입니다. 그래서, 우리가 쓸 내용은 전부 fPrimary->GeneratePrimaryVertex(anEvent);
줄보다 위쪽에 위치해야 합니다.
fPrimary 변수는 G4ParticleGun 클래스 객체의 포인터라고 하였습니다. 이 클래스에서 초기 입자의 특성을 설정하기 위해 제공하는 함수 중 대표적으로 몇 가지를 알아봅시다.
입자의 종류를 설정하기 위한 함수로, SetParticleDefinition이라는 함수를 제공합니다. 원형은 다음과 같습니다.
1void SetParticleDefinition(G4ParticleDefinition* aParticleDefinition);
G4ParticleDefinition이라는 클래스가 생소하실텐데요, Geant4에서 입자에 대한 정의를 담당하는 클래스라고만 해두고 넘어가겠습니다.
Geant4가 기본적으로 지원하는 입자의 모든 종류는 Geant4 Doxygen에서 G4ParticleDefinition 클래스의 레퍼런스 페이지(10.7.p01 버전)에 들어가면 상속받은 클래스 목록(Inheritance diagram for G4VSolid)에서 확인할 수 있습니다.
사실, Geant4 프로그램에서 사용 가능한 입자는 그 프로그램에서 어떤 PhysicsLists를 사용하느냐에 따라 좌우됩니다. 하지만 이 시리즈에서는 PhysicsLists를 아예 다루지 않을 예정이므로, 그냥 넘어가도록 하겠습니다.
참고로 g4_minimal
템플릿 코드는 QBBC 물리모델을 사용하고 있습니다.
여기서는 대표적으로 몇 가지 입자만 언급하도록 하겠습니다.
Geantino, Charged Geantino
각각 G4Geantino 클래스, G4ChargedGeantino 클래스를 통해 이용할 수 있습니다.
Geantino란 Geant4에서 정의한 가상의 입자로, 질량/스핀/parity가 0이며 어떠한 반응도 일으키지 않는 중성 입자입니다.
Charged Geantino는 Geantino와 기본적인 특성은 동일하나, 전하만 +1인 입자입니다.
이 두 가지 입자는 시뮬레이션의 검증단계에서 주로 활용됩니다.
Gamma
G4Gamma 클래스를 통해 이용할 수 있습니다. 일반적으로 알려진 광자(Photon)에 해당합니다.
Electron, Positron
각각 G4Electron 클래스, G4Positron 클래스를 통해 이용할 수 있습니다. 일반적으로 알려진 전자(Electron)와 양전자(Positron)에 해당합니다.
Proton
G4Proton 클래스를 통해 이용 가능합니다. 일반적으로 알려진 양성자(Proton)에 해당합니다.
Neutron
G4Neutron 클래스를 통해 이용 가능합니다. 일반적으로 알려진 중성자(Neutron)에 해당합니다.
Muon, Antimuon
각각 G4MuonMinus 클래스, G4MuonPlus 클래스를 통해 이용 가능합니다. 일반적으로 알려진 뮤온(Muon)과 반뮤온(Antimuon)에 해당합니다.
모든 입자 클래스들은 각 입자의 ParticleDefinition 클래스 객체의 포인터를 반환하는 static 함수인 Definition() 함수를 제공합니다. 즉, 어느 입자를 사용하든 클래스명::Definition()
이라고 입력하여 그 입자의 ParticleDefinition을 가져올 수 있습니다. 예를 들어 G4Gamma 클래스라면, G4Gamma::Definition()
과 같이 말이죠.
여러가지 입자를 알아보았으니, 이들을 초기 입자로 설정하는 방법을 살펴봅시다. 다음의 두 단계를 거치면 됩니다.
예를 들어 Gamma를 초기 입자로 설정하고 싶다면, 다음과 같이 입력하면 됩니다.
1#include "G4Gamma.hh" // Include header for G4Gamma class
2// ...
3void PrimaryGeneratorAction::GeneratePrimaries(G4Event *anEvent)
4{
5 fPrimary->SetParticleDefinition(G4Gamma::Definition()); // Set primary as gamma
6
7 fPrimary->GeneratePrimaryVertex(anEvent);
8}
실제 코드는 다음과 같습니다.
이렇게 변경한 뒤, Tracking Verbose를 1레벨로 하여 출력해보면 다음과 같이 초기 입자가 바뀐 것을 확인할 수 있습니다.
입자의 운동에너지를 설정하기 위한 함수로, SetParticleEnergy라는 함수를 제공합니다. 원형은 다음과 같습니다.
1void SetParticleEnergy(G4double aKineticEnergy);
입력 인자는 간단하게 G4double형입니다. 다만, 에너지에 대한 단위를 입력할 필요가 있으므로, G4SystemOfUnits 헤더를 포함시켜줘야 한다는 점에 주의하세요.
예를 들어 초기 입자의 운동에너지를 0.662 MeV로 설정하고 싶다면, 다음과 같이 입력하면 됩니다.
1#include "G4SystemOfUnits.hh" // Include header for unit system
2// ...
3void PrimaryGeneratorAction::GeneratePrimaries(G4Event *anEvent)
4{
5 // ...
6 fPrimary->SetParticleEnergy(0.662 * MeV);
7
8 fPrimary->GeneratePrimaryVertex(anEvent);
9}
실제 코드는 다음과 같습니다.
이렇게 변경한 뒤, Tracking Verbose를 1레벨로 하여 출력해보면 다음과 같이 초기 입자의 운동에너지가 바뀐 것을 확인할 수 있습니다.
입자의 위치를 설정하기 위한 함수로, SetParticlePosition이라는 함수를 제공합니다. 원형은 다음과 같습니다.
1void SetParticlePosition(G4ThreeVector aPosition);
입력 인자는 G4ThreeVector 객체입니다.
예를 들어 초기 입자의 위치를 (0, 0, 0)으로 설정하고 싶다면, 다음과 같이 입력하면 됩니다.
1// ...
2void PrimaryGeneratorAction::GeneratePrimaries(G4Event *anEvent)
3{
4 // ...
5 fPrimary->SetParticlePosition(G4ThreeVector());
6
7 fPrimary->GeneratePrimaryVertex(anEvent);
8
9}
실제 코드는 다음과 같습니다.
이 부분은 원래 기본 값이 (0, 0, 0)이어서 바뀌지 않습니다만, 원하는 값으로 변경해보시면 Tracking Verbose에서 차이를 확인할 수 있을 것입니다.
입자의 운동방향을 설정하기 위한 함수로, SetParticleMomentumDirection이라는 함수를 제공합니다. 원형은 다음과 같습니다.
1void SetParticleMomentumDirection(G4ParticleMomentum aMomDirection);
입력 인자는 G4ParticleMomentum라고 적혀있습니다만, 이는 사실 G4ThreeVector의 다른 이름일 뿐입니다. 위치 때와 동일하게 G4ThreeVector 객체를 넣으시면 됩니다.
예를 들어 초기 입자의 운동방향을 +Z축인 (0, 0, 1)으로 설정하고 싶다면, 다음과 같이 입력하면 됩니다.
1// ...
2void PrimaryGeneratorAction::GeneratePrimaries(G4Event *anEvent)
3{
4 // ...
5 fPrimary->SetParticleMomentumDirection(G4ThreeVector(0., 0., 1.));
6
7 fPrimary->GeneratePrimaryVertex(anEvent);
8
9}
실제 코드는 다음과 같습니다.
이렇게 변경한 뒤, Tracking Verbose를 1레벨로 하여 출력해보면 다음과 같이 초기 입자의 진행 방향이 바뀐 것을 확인할 수 있습니다. 제가 보여드리는 예제 코드의 경우 +Z축 방향에 앞서 정의했던 phantom이 있다보니, 감마선이 이 지오메트리와 충돌하여 여러 반응이 일어나는 모습까지 확인이 되네요.
지금까지 변경한 내용을 UI로 실행하면 그래픽으로 살펴볼 수도 있습니다. build 디렉토리에서 ./g4_minimal
을 입력하여 실행해서 UI창을 띄워봅니다. 다음 그림과 같이 Geometry가 보일 것입니다.
여기서, 그림 하단에 빨간색으로 표시해 둔 Session 입력창에 /run/beamOn 100
이라고 입력한 뒤 [Enter]를 누르면 UI 상에서 Event 100개 묶음의 Run 한 번을 실행시킬 수 있습니다.
좀 확대해보시면 다음과 같은 모습을 확인할 수 있습니다.
vis.mac
등에서 설정한 값에 따라 달라질 수 있습니다.
기본적으로는 다음과 같이 해석하시면 됩니다.
이번 글에서는 초기 입자의 정보를 설정하고 확인하는 방법에 대해 살펴보았습니다. 그러나 이런식으로 입력하면, 항상 동일한 조건의 초기 입자만 발생될 것입니다.
다음 글에서는 G4RandomTools 헤더를 활용하여, Event 마다 초기 입자의 위치나 방향을 변경하며 발생시키는 방법에 대해 알아보겠습니다.