G4double - Politechnika Warszawska
Transkrypt
G4double - Politechnika Warszawska
Modelowanie
Procesów
Jądrowych
Modelowanie geometryczne,
symulacje w środowisku Geant4
Marcin Słodkowski
Pracownia Reakcji Ciężkich Jonów,Zakład Fizyki Jądrowej
Wydział Fizyki, Politechnika Warszawska
Podstawowe pytania ?
Czym
jest Geant4 ?
Jak
jest zbudowany ?
Jak
wygląda przykładowa symulacja ?
2/63
Geant4 – wprowadzenie (I)
Geant4
jest to zestaw narzędzi do
modelowania przejść cząsteczek przez
materię
Wykorzystywany
w wielu dziedzinach jak:
W fizyce:
Wysokich energii
Akceleratorów
Jądrowej
W medycynie
3/63
Geant4 – wprowadzenie (II)
Cel:
ulepszenie dotychczas istniejącego
programu Geant3 (bazujący na
FORTRAN’ie)
Nowa
implementacja w C++ (model
obiektowy)
Geant5
- następca wersji 4 (główna
zaletą jest obsługa wielowątkowości co da
znacz¡cy wzrost wydajności)
4/63
Geant4 – wprowadzenie (III)
Poprzez
Geant4 otrzymujemy narzędzia
np. do:
Tworzenie skompilowanej geometrii detektorów
złożonych z elementów o zróżnicowanych
kształtach i rodzaju materiału.
Określeniu jak miałoby wyglądać „wyjście” z
detektora
Możliwość konfiguracji procesów fizycznych w
zależności od naszych potrzeb
5/63
Etapy tworzenia symulacji
Geometria i materiały
Określenie cząsteczek
Procesy fizyczne, interakcje cząstek w
materii
Generator pierwszego zdarzenia
Śledzenie cząstek przy przejściach przez
materię i pola elektromagnetyczne
Zarządzane zdarzenia
Wizualizacja
Definiowanie interface’u użytkownika
…
6/63
Geant4 – model transportu cząstek
Jądro
Geant4 zapewnia:
Transport cząstek przez materię (z
uwzględnieniem oddziaływań z ośrodkiem wpływ
pól elektromagnetycznych)
Dostęp do informacji o procesie transportu
oraz wyników symulacji
7/63
Geant4 – elementy
Konieczne:
Definicja detektora (kształt, materiał)
Informacja o symulowanych procesach
Kinematyka cząstek pierwotnych
Opcjonalne:
Definiowanie zewnętrznych pól
elektromagnetycznych
Określenie działań przy poszczególnych
krokach symulacji
8/63
Geant4 – zdarzenie (Event)
Podstawowa
jednostka symulacji
Reprezentowany
jest przez klasę G4Event
(IN) Cząstka pierwotna
(OUT) deponowana energia, trajektoria
Zarządca:
klasa G4EventManager
9/63
Geant4 – „Run”
Zbiór
Event’ów przetwarzanych przez ten
sam detektor
W
trakcie wykonywania warunki
(detektor, procesy) nie mogą zostać
zmienione
Reprezentacja:
Zarządca:
klasa G4Run
G4RunManager
10/63
Geant4 – ślad
Ślad
aktualnie transportowanej cząstki
Aktualizacja
po każdym kroku
Reprezentacja:
Zarządca:
G4Track
G4TrackManager
11/63
Geant4 - krok
Krok
aktualnie wykonywany
Zawiera
informacje o zmianie stanu
cząstki: punkty wejścia, punkty wyjścia,
straty energii, czas trwania itp.
Klasa:
G4Step
Zarządca:
G4SetpManager
12/63
Geant4 - trajektoria
Służy
do zapamiętywania śladów oraz
kroków dla każdej cząstki
Klasy:
G4Trajectory – ślady
G4TrajectoryPoint - kroki
13/63
Geant4 - cząstka
Do
zdefiniowania cząstki używane są:
G4ParticleDefinition – parametry „statyczne”
(np. ładunek, czas życia, masa)
G4DynamicParticle – dynamiczne wielkości
fizyczne np. pęd (obiekty tego samego typu
używają jednego obiektu klasy
G4ParticleDefinition)
G4ParticleDefinition
G4Track – informacje geometryczne (zawszę
posiada unikatowy obiekt
G4DynamicParticle )
14/63
Geant4 - procesy
Każda
cząstka ma określoną listę
procesów
W
każdym kroku każdy proces z listy
wpływa na: długość kroku, zmiana
wielkości fizycznych, produkcja wtórnych
cząstek …
15/63
Geant4 – wykonanie
1. Aktywny proces losuje odległość do następnego
oddziaływania (wykonywane dla wszystkich procesów)
2. Najmniejsza odległość jest to „krok fizyczny”
3. Obliczenie „kroku geometrycznego” (odległość do
granicy ośrodków)
4. Faktyczna długość kroku jest to min. z korku
fizycznego i geometrycznego
5. Zmiana energii kinetycznej (suma wkładów procesów
ciągłych)
6. Jeżeli cząstka nie została zatrzymana wykonują się
proces dyskretny, który zdecydował o długości kroku.
7. W przeciwnym wypadku przechodzi do następnego kroku
16/63
Architektura
17/63
Komponenty podstawowe (Global)
Zdefiniowane
Generatory
System
cm2,
stałe
liczbowe
jednostek: np.: MeV, GeV, mm,
g/cm3 itd.
18/63
Definiowanie własnych jednostek
#include<G4UnitsTable.hh>
G4UnitDefinition (<nazwa>,<symbol>,
<kategoria>,<wartość>)
Np.: G4UnitDefinition("km/godz", "km/h", "Predkosc", km/(3600*s));
19/63
Klasy opisujące symulację
Konieczne:
Definicja detektora (kształt, materiał)
G4VUserDetectorConstruction
Informacja o symulowanych procesach
G4VUserPhysicsList
Kinematyka cząstek pierwotnych
G4VUserPrimaryGeneratorAction
Element główny: G4RunManager
Opcjonalne:
G4UserRunAction
G4UserEventAction
G4UserStackingAction
G4UserTrackingAction
G4UserSteppingAction
20/63
Definiowanie detektora
W
celu stworzenia detektora musimy
określić kilka podstawowych komponentów:
Geometria
Materiały
Gdy
nasza symulacja ma na celu dogłębne
modelowanie zachowania detektora
możemy również podać jak ma przebiegać:
„digitalizacja” danych, określić sektory
„wrażliwe”, fizyczne
określenie
itp.
interakcji ścieżek w regionach
21/63
Geometria
W
celu zdefiniowania geometrii musimy
Określić:
Modele brył
Zdefiniować reprezentację właściwości
detektora
Zadbać o odpowiednie umiejscowienie
Elementów
22/63
Bryły
Każdy
element „logiczny” detektora musi
mięć odpowiednio zdefiniowany kształt
oraz materiał.
Geant4
dostarcza nam wiele klas, które
umożliwiają odpowiednie ich zdefiniowanie.
23/63
GBox
#include<G4Box.hh>
G4Box(
const G4String& pName,
G4double pX,
G4double pY,
G4double pZ
);
24/63
G4Tubs
#include<G4Tubs.hh>
G4Tubs(const G4String& pName,
G4double pRMin, //promień wew.
G4double pRMax, //prom. zew.
G4double pDz, //połowa długości z
G4double pSPhi, //kąt początkowy
G4double pDPhi //kąt segmentu
25/63
G4Cons
#include<G4Cons.hh>
G4Cons(const G4String& pName,
G4double pRmin1, //prom. wew.od -pDz
G4double pRmax1, //prom. wew od +pDz
G4double pRmin2, //prom. zew. od -pDz
G4double pRmax2, //prom. zew. od +pDz
G4double pDz, //połowa dług. z
G4double pSPhi, //kąt początkowy
G4double pDPhi //kąt segmentu
26/63
G4Para
#include<G4Para.hh>
G4Para(const G4String& pName,
G4double dx, //połowa dług. x
G4double dy, //połowa dług. y
G4double dz, //połowa dług. z
G4double alpha, //kąt OY a || do z-x w +/- dy
G4double theta, //kąt biegunowy
G4double phi //kąt azymutalny
27/63
G4Trd
#include<G4Trd.hh>
G4Trd(const G4String& pName,
G4double dx1, //połowa dług. X w -dz
G4double dx2, //połowa dług. X w +dz
G4double dy1, //poowa dług. Y w -dy
G4double dy2, //połowa długości y w +dz
G4double dz //połowa dług. z
28/63
G4Sphere
#include<G4Sphere.hh>
G4Sphere(const G4String& pName,
G4double pRmin, //prom. wew.
G4double pRmax, //prom. zew.
G4double pSPhi, //początkowy kąt φ
G4double pDPhi, //kąt φ
G4double pSTheta, //początkowy kąt θ
G4double pDTheta //kąt θ
29/63
G4Orb
#include<G4Orb.hh>
G4Orb(const G4String& pName,
G4double pRmax);
30/63
Łączenie brył
Z
predefiniowanych prymitywów można
tworzyć bardziej
złożone
kształty:
o
logiczne zsumowanie dwóch prymitywów
o
zrobienie przekroju
o
„odejmowanie”
G4Box* box = new G4Box("Box",20*mm,30*mm,40*mm);
G4Tubs* cyl = new G4Tubs("Cylinder",0,50*mm,50*mm,0,6.28);
G4UnionSolid* union = new G4UnionSolid("Box+Cylinder", box, cyl);
G4IntersectionSolid* intersection = new G4IntersectionSolid("Box*Cylinder",
box, cyl); G4SubtractionSolid* subtraction = new G4SubtractionSolid("BoxCylinder", box, cyl);
31/63
Definiowanie materiałów (I)
#include<G4Material.hh>
G4Material
G4Material(name,Z,A,density,state,temp,pressu
re);
name – nazwa (G4String)
Z – liczba protonów (G4double)
A – masa molowa (G4double)
density – gęstość (G4double)
State – stan skupienia (G4State )
temp – temperatura (G4double)
pressure – ciśnienie (G4double)
32/63
Nowy materiał (I)
Aluminum:
ρ = 2.7 g/cm3
A = 26.98 g/mol
G4Material *Al = new G4Material("Aluminium", 13, 26.98*g/mole,
2.7*g/cm3);
33/63
Defioniowanie materiałów (II)
G4Material(name,density,nComponents,state,temp,pressure);
n name – nazwa (G4String)
G4String
n density – gęstość (G4double)
G4double
n nComponents – ilość elementów (G4int )
n state – stan skupienia (G4State)
G4State
n temp – temperatura (G4double)
G4double
n pressure – ciśnienie (G4double)
G4double
Następnie trzeba wywołać metodęAddElement w celu określenia
składu atomowego:
void AddElement(G4Element *element, G4int nAtoms);
void AddElement (G4Element *element, G4double fraction);
void AddMaterial(G4Material *material, G4double fraction);
34/63
Definiowanie elemetów
#include<G4Element.hh>
G4Element
G4Element(name,symbol,Z,A);
name – nazwa (G4String)
G4String
symbol (G4String)
G4String
Z – liczba protonów (G4double)
G4double
A – masa molowa (G4double)
G4double
35/63
Nowy materiał (II)
CO2
ρ
= 27 mg/cm3
p
= 50 atm
T
= 325 ºK
G4Element *C=new G4Element("Wegiel", "C", 6, 12.01*g/mole),
*O=new G4Element("Tlen", "O", 8, 16.*g/mole);
G4Material *CO2 = new G4Material("CO2", 27*g/cm3, 2, kStateGas,
325*kelvin, 50*atmosphere);
CO2>AddElement(C,1);
CO2>AddElement(O,2);
36/63
Baza materiałów
#include<G4NistManager.hh>
Nie
musimy tworzyć nowej instancji (jest
generowana przy„włączeniu” Geant4).
G4Material* FindOrBuildMaterial(const G4String& name,
G4bool isotopes=true,
G4bool warning=false);
G4Material *mat=
G4NistManager::Instance()->FindOrBuildMaterial("CO2");
37/63
u
m
e
(
G
4
V
S
o
l
i
d
*
Wolumen logiczny
G4LogicalVolume(
G4VSolid* pSolid,
G4Material* pMaterial,
const G4String& Name,
p
G4FieldManager* pFieldMgr,
S
o
G4VSensitiveDetector* pSDetector,
l
i
G4UserLimits* pULimits,
d
,
G4bool Optimise);
G
4
M
a
38/63
Ustawianie elementów
Dysponując
już wolumen logicznym należy
go odpowiednio umiejscowić w przestrzeni.
Do
tego celu tworzy się tzw. fizyczny
wolumen.
39/63
Umiejscawianie pojedynczej kopii
G4PVPlacement(
G4RotationMatrix* pRot, const
G4ThreeVector& tlate,
G4LogicalVolume* pCurrentLogical,
const G4String& pName,
G4LogicalVolume* pMotherLogical,
G4bool pMany,
G4int pCopyNo,
G4bool pSurfChk
) ;
40/63
Umiejscawianie kilku kopii
G4PVReplica(
const G4String& pName,
G4LogicalVolume* pCurrentLogical,
G4LogicalVolume* pMotherLogical, // OR
G4VPhysicalVolume* const EAxis pAxis,
const G4int nReplicas,
const G4double width,
const G4double offset
);
41/63
Umiejscawianie kilku kopii z
parametryzacją
G4PVParameterised(
const G4String& pName,
G4LogicalVolume* pCurrentLogical,
G4LogicalVolume* pMotherLogical, // OR
G4VPhysicalVolume* const EAxis pAxis,
const G4int nReplicas,
G4VPVParameterisation* pParam,
G4bool pSurfChk
);
42/63
Definiowanie detektora
W celu stworzenia detektora należy utworzyć klasę
dziedziczącą po:
G4VUserDetectorConstruction
Naszym zadaniem jest przeładowanie metody
Construct()
G4VPhysicalVolume* Construct();
43/63
Przykładowy detektor
Zdefiniujmy materiały:
Proznia=new G4Material("Proznia", 1, 1.01*g/mole,
universe_mean_density, kStateGas, 2.73*kelvin, 3e18*pascal);
PArgon=new G4Material("PArgon", 18, 39.95*g/mole, 1.390*g/cm3);
Olow=new G4Material("Olow", 82, 207.19*g/mole, 11.35*g/cm3);
AbsorberThickness = 10.*mm;
GapThickness = 5.*mm;
NbOfLayers = 10;
CalorSizeYZ = 10.*cm;
LayerThickness = AbsorberThickness + GapThickness;
CalorThickness = NbOfLayers*LayerThickness;
WorldSizeX = 1.2*CalorThickness;
WorldSizeYZ = 1.2*CalorSizeYZ;
44/63
Określanie geometrii (przestrzeń)
solidWorld = new G4Box("World",
WorldSizeX/2,
WorldSizeYZ/2,
WorldSizeYZ/2);
logicWorld = new G4LogicalVolume(solidWorld, Proznia,"World");
physiWorld = new G4PVPlacement(0,G4ThreeVector(),logicWorld,
"World", 0, false, 0);
45/63
Kalorymetr
solidCalor = new G4Box("Calorimeter",
CalorThickness/2,
CalorSizeYZ/2,
CalorSizeYZ/2);
logicCalor = new G4LogicalVolume(solidCalor,
Proznia,"Calorimeter");
physiCalor = new G4PVPlacement(0,G4ThreeVector(), logicCalor,"Calorimeter", logicWorld, false,0);
46/63
Warstwy
solidLayer = new G4Box("Layer",
LayerThickness/2,
CalorSizeYZ/2,
CalorSizeYZ/2);
logicLayer = new G4LogicalVolume(solidLayer,Proznia,"Layer");
physiLayer = new G4PVReplica("Layer",
logicLayer, logicCalor,kXAxis,
NbOfLayers, LayerThickness);
47/63
„Przerwa”
solidGap = new G4Box("Gap",
GapThickness/2,
CalorSizeYZ/2,
CalorSizeYZ/2);
logicGap = new G4LogicalVolume(solidGap,PArgon,
PArgon >GetName());
physiGap = new G4PVPlacement(0,
G4ThreeVector(AbsorberThickness/2,0,0),
logicGap, PArgon>GetName(), logicLayer, false, 0);
48/63
Konstrukcja detektora
class DetectorConstruction : public
class
G4VUserDetectorConstruction {
G4VUserDetectorConstruction
…
public:
G4VPhysicalVolume* Construct(){
G4VPhysicalVolume
return physiWorld;
}
};
49/63
Generator pierwszego zdarzenia
Klasa dziedziczy z
G4VUserPrimaryGeneratorAction
Metoda do „przeładowania”:
void GeneratePrimaries(G4Event*
G4Event anEvent);
50/63
Implementacja generatora
Poprawnie stworzony generator wymaga od nas powołania
do życia obiektu G4ParticleGun.
G4ParticleGun
partGun=new G4ParticleGun(1);
Mając do niego dostęp jesteśmy w stanie określić
poszczególne parametry:
•rodzaj cząstki
•kierunek propagacji
•energię cząstki
•pozycję startową
51/63
Metody G4ParticleGun
Ustawienie cząstki:
G4ParticleDefinition *part; part=G4ParticleTable::GetParticleTable()
>FindParticle("e");
partGun>SetParticleDefinition(part);
o Kierunek:
partGun
>SetParticleMomentumDirection(G4ThreeVector(1.,0.,0.
));
o Energia:
partGun>SetParticleEnergy(50.*MeV);
o Pozycja startowa:
G4double position=0.5*WorldSizeX;
partGun
>SetParticlePosition(G4ThreeVector(position,0.*cm,0.
*cm));
52/63
Implementacja generatora
Wspomniana metoda GeneratePrimaries
przeważnie sprowadza się do wywołania
metody obiektu klasy G4PartcleGun czyli:
void GeneratePrimaries(
G4Event* event){
void
G4Event
partGun>GeneratePrimaryVertex(event);
GeneratePrimaryVertex
}
53/63
Cząstki i procesy
Do definicji cząstek i procesów używa się:
G4VUserPhysicsList
Klasa dziedziczące po niej musi mieć
przygotowane 3 metody:
void ConstructParticle(); //dodaje void
cząstki
void ConstructProcess(); /
/dodaje void
procesy
void SetCuts(); /
/określa „cięcia”
void
54/63
Definiowanie cząstek
W tym przypadku naszym jedynym zadaniem jest wywołanie kilku metod statycznych, które uzupełnią listy
cząstek.
void ConstructParticle(){
//pseudocząstki
G4Geantino::GeantinoDefinition();
G4ChargedGeantino::ChargedGeantinoDefinition();
G4Gamma::GammaDefinition(); // gamma
G4OpticalPhoton::OpticalPhotonDefinition(); //optical photon
// leptony
G4Electron::ElectronDefinition(); G4Positron::PositronDefinition(); G4MuonPlus::MuonPlusDefinition();
G4MuonMinus::MuonMinusDefinition(); G4NeutrinoE::NeutrinoEDefinition();
G4AntiNeutrinoE::AntiNeutrinoEDefinition(); G4NeutrinoMu::NeutrinoMuDefinition();
G4AntiNeutrinoMu::AntiNeutrinoMuDefinition();
// mezony
G4PionPlus::PionPlusDefinition(); G4PionMinus::PionMinusDefinition(); G4PionZero::PionZeroDefinition();
G4Eta::EtaDefinition(); G4EtaPrime::EtaPrimeDefinition(); G4KaonPlus::KaonPlusDefinition();
G4KaonMinus::KaonMinusDefinition(); G4KaonZero::KaonZeroDefinition();
G4AntiKaonZero::AntiKaonZeroDefinition(); G4KaonZeroLong::KaonZeroLongDefinition();
G4KaonZeroShort::KaonZeroShortDefinition();
// bariony
G4Proton::ProtonDefinition(); G4AntiProton::AntiProtonDefinition(); G4Neutron::NeutronDefinition();
G4AntiNeutron::AntiNeutronDefinition();
// ions
G4Deuteron::DeuteronDefinition(); G4Triton::TritonDefinition(); G4He3::He3Definition();
G4Alpha::AlphaDefinition(); G4GenericIon::GenericIonDefinition();
}
55/63
Określanie progu odcięcia
W zależności od potrzeb określamy odcięcia
dla poszczególnych cząstek:
void SetCuts(){
SetCutValue(1*mm,"gamma");
SetCutValue(1*mm,"e");
SetCutValue(1*mm,"e+");
}
56/63
Jak dodaje się procesy
Procesy określamy dla wybranych przez nas cząstek.
Do dodawania procesów dla konkretnego rodzaju cząstek służy obiekty klasy:
G4ProcessManager
Wykorzystywane metody:
G4int AddProcess(
G4VProcess *aProcess, //dodawany proces
G4int ordAtRestDoIt, //flaga metody AtRestDoIt
G4int ordAlongSteptDoIt, //flaga metody AlongStepDoIt
G4int ordPostStepDoIt //flaga metody PostStepDoIt
); //jest to podstawowa metoda dodawania procesów
Mamy również do dyspozycji ułatwione wersje powyższej metody:
G4int AddRestProcess(G4VProcess *aProcess, G4int ord);
G4int AddDiscreteProcess(G4VProcess *aProcess, G4int ord);
G4int AddContinuousProcess(G4VProcess *aProcess, G4int ord);
57/63
Implementacja ConstructProcess()
void ConstructProcess(){
theParticleIterator->reset();
while( (*theParticleIterator)() ){
G4ParticleDefinition*
G4ParticleDefinition p = theParticleIterator->value();
G4ProcessManager*
G4ProcessManager pman = particle->GetProcessManager();
G4String pname = particle->GetParticleName();
if (pname == "gamma") {
pman->AddDiscreteProcess(new G4PhotoElectricEffect);
pman->AddDiscreteProcess(new G4ComptonScattering);
pman->AddDiscreteProcess(new G4GammaConversion);
}
else if (pname == "e-" || pname == "e+") {
pman->AddProcess(new G4eMultipleScattering,-1, 1, 1);
pman->AddProcess(new G4eIonisation, -1, 2, 2);
pman->AddProcess(new G4eBremsstrahlung, -1, 3, 3);
if (pname == "e+")
pman->AddProcess(new G4eplusAnnihilation, 0,-1, 4);
}
}
}
58/63
Zbierzmy teraz wszystko razem
Zdefiniowane powyżej 3 klasy są to
podstawowe elementy, które musi posiadać
każda symulacja w Geant4.
G4VUserDetectorConstruction
G4VUserPrimaryGeneratorAction
G4VUserPhysicsList
59/63
Symulacja
G4RunManager * runManager = new G4RunManager;
runManager>SetUserInitialization(detector);
runManager>SetUserInitialization(physics);
runManager>SetUserAction(gen_action);
Następnie wywołujemy inicjalizację:
runManager>Initialize();
runManager inicjuje w tym momencie Geant4 poprzez wywołanie
zdefiniowanych przez nas obiektów.
Jeżeli proces przeszedł bez błędów symulacja jest gotowa do
uruchomienia:
runManager>BeamOn(ilosc_powtorzen);
60/63
Symulacje + wizualizacja
61/63
Interface użytkownika i wizualizacja
Moduł odpowiedzialny za wisualizację dodajemy po
zainicjowaniu symulacji:
G4VisManager* vis = new G4VisExecutive;
G4VisManager
new
vis>Initialize();
Jak również linie komend dla użytkownika:
G4UImanager* UI = G4UImanager::GetUIpointer();
G4UIsession* session = new G4UIterminal();
Obiekty vis oraz session nie są zarządzane przez
runManager’a więc na koniec musimy zadbać o
zwolnienie pamięci.
62/63
Dziękuję za uwagę
63/63