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