刚刚开始学习Geant4 , 在知乎上找到一系列特别特别好的文章,记录一下。(https://www.zhihu.com/people/wang-jian-jun-78-22),大家感兴趣一定去看看.为了学习理解,简单记录学习情况,方便之后反复学习.
先浅谈一下
geant4实质上是一些代码,用户在利用geant4来进行模拟的时候,是通过编写一个程序,编写的程序是按照一定的规则来利用geant4(实际上继承了geant4里面定义好的类)
geant4里边的一些概念:
Run
假设一次模拟要发射1000个光子,那么从第一个光子开始反应一直到这1000个光子都反应结束,其中包括产生的次级粒子也结束相应的反应,成为一次Run。
Event
一个粒子从发射到与材料进行相互作用再到最后沉积到材料内部进入稳定状态或者是飞出本次模拟的几何范围是一个粒子的生命周期,为一个事例,在Geant4中被称为"Event"。假设要模拟1000个光子打靶,那么对于这个Run来说就有1000个event。event并不单指入射粒子,而是每一个粒子从反应到结束的过程。
Track
每个粒子或者是次级粒子在材料中行进的轨迹,被称为"Track"。用来记录粒子的信息如,位置、能量、动量。
Step
以每个Track上发生的相互作用为节点,把每个Track都分为了若干个步,每一个Step代表着粒子与材料发生了一次相互作用。一般来说,输出项中大部分信息都以Step为单位进行记录,记录的是本次相互作用发生的时间/位置/沉积能量等信息。
Presteppoint
PostSteppoint
如果自己要写一个程序进行模拟,必须要有的部分:
-
构建几何体模型,如:444cm^3的金属铝板
-
设置粒子源,类型、能量和位置
-
确定要统计的物理量 能量沉积和能谱
-
物理过程
Geant4提供了许多可供学习的例子,B1 B2 B3等等,B1中所包含的文件:
主程序main文件:exampleB1.cc
头文件/源文件:即上图中include/src文件夹下的文件。下面将逐一介绍其作用:
1.ActionInitialization.hh/cc:与Geant4的多线程运行有关
2.DetectorConstruction.hh/cc:定义类"DetectorConstruction",指定本次Run中的所有材料。
3.PrimaryGeneratorAction.hh/cc:定义类"PrimaryGeneratorAction",指定本次Run中的粒子源项。
4.RunAction.hh/cc:定义类"RunAction",指定在本次Run中,Run的初始化/开始/结束的所有操作。
5.EventAction.hh/cc:定义类"EventAction",指定在本次Run中,每一个Event的初始化/开始/结束的所有操作。
6.SteppingAction.hh/cc:定义类"SteppingAction",指定在本次Run中,每一个Step的初始化/开始/结束的所有操作。
#include "B1DetectorConstruction.hh"
#include "B1ActionInitialization.hh"
#ifdef G4MULTITHREADED
#include "G4MTRunManager.hh"
#else
#include "G4RunManager.hh"
#endif
#include "G4UImanager.hh"
#include "QBBC.hh"
#include "G4VisExecutive.hh"
#include "G4UIExecutive.hh"
#include "Randomize.hh"
///以上为include需要的头文件
int evtid=0;//定义外部变量,用于记录当前Event的序号
int main(int argc,char** argv)
{
G4UIExecutive* ui = 0;
if ( argc == 1 ) {
ui = new G4UIExecutive(argc, argv);
}
//判断为图形交互模式还是批处理模式
//图形交互模式:图形界面(在安装Geant4时安装了图形引擎),可在图形界面输入运行命令
//批处理模式:没有图形交互界面,输入指令后直接运行
//如果argc==1则为图形交互模式
G4Random::setTheEngine(new CLHEP::RanecuEngine);
//初始化Geant4产生随机数的引擎
#ifdef G4MULTITHREADED
G4MTRunManager* runManager = new G4MTRunManager;
#else
G4RunManager* runManager = new G4RunManager;
#endif
//初始化RunManager类的对象,此对象起到管理整个Run的作用,G4MTRunManager为多线程下的RunManager
runManager->SetUserInitialization(new B1DetectorConstruction());
//通过RunManager指定本次Run中的所有材料,即DetectorConstruction类的对象
G4VModularPhysicsList* physicsList = new QBBC;
physicsList->SetVerboseLevel(1);
runManager->SetUserInitialization(physicsList);
//通过RunManager指定本次Run中的相互作用列表
runManager->SetUserInitialization(new B1ActionInitialization());
//指定本次Run中粒子源(PrimaryGeneratorAction);
//指定在本次Run中,Run的初始化/开始/结束的所有操作。(RunAction);
//指定在本次Run中,每一个Event的初始化/开始/结束的所有操作。(EventAction);
//指定在本次Run中,每一个Step的初始化/开始/结束的所有操作。(SteppingAction);
//一般在多线程中使用,非多线程程序可直接在main函数中指定上述对象,方法与材料的指定方法相同
G4VisManager* visManager = new G4VisExecutive;
visManager->Initialize();
//初始化图形交互界面(Visualization UI)
G4UImanager* UImanager = G4UImanager::GetUIpointer();
//初始化负责执行用户输入命令的manager
if ( ! ui ) {
//批处理模式
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager->ApplyCommand(command+fileName);
}
else {
//图形交互模式
UImanager->ApplyCommand("/control/execute init_vis.mac");
ui->SessionStart();
delete ui;
}
delete visManager;
delete runManager;
//释放内存,删除前面动态分配定义的runManager和visManager
}
Geant4:材料
材料确定的两个信息:材料的物理状态和几何位置,材料信息一般都被写在件 “DetectorConstruction.hh/.cc” 中。
一.材料的物理状态
材料的物理状态有两种定义方式:
- 直接定义 ,即直接定义材料, G4Material
- 间接定义,即先定义原子参数(原子序数和核电子数)并形成分子化合物,再形成材料,G4Element
总之,无论使用哪种方法,最终模拟的材料都是G4Material
1.1 直接定义
- 通过Geant4的数据库直接定义
G4NistManager* man = G4NistManager::Instance();
//创建对象以访问Geant4材料数据库
G4Material* H2O = man->FindOrBuildMaterial("G4_WATER");
//在数据库中查找"WATER"这种材料并创建
G4Material* Air = man->FindOrBuildMaterial("G4_AIR");
//在数据库中查找"AIR"这种材料并创建
- 直接定义简单材料
G4double z, a, density;
G4String name;
density = 1.390*g/cm3;
//指定材料的密度
a = 39.95*g/mole;
//指定材料的摩尔质量
G4Material* lAr = new G4Material(name="liquidArgon", z=18., a, density);
//创建名称为"liquidArgon"的材料,其材料的原子序数为18,摩尔质量为39.95*g/mole,密度为1.390g/cm3。
1.2 间接定义
- 间接定义----原子组合形成分子
G4double z, a, density;
G4String name, symbol;
G4int ncomponents, natoms;
a = 1.01*g/mole;
//指定氢原子(氕)的摩尔质量
G4Element* elH = new G4Element(name="Hydrogen",symbol="H" , z= 1., a);
//创建氢原子(氕)
a = 16.00*g/mole;
//指定氧16原子的摩尔质量
G4Element* elO = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
//创建O16原子
density = 1.000*g/cm3;
//指定材料的密度
G4Material* H2O = new G4Material(name="Water",density,ncomponents=2);
//创建名称为"Water"的材料,指定其密度与构成成分的数量("ncomponents=2"表示每个该材料有两种成分)
H2O->AddElement(elH, natoms=2);
//加入第一种原子氕,其在一个材料分子中有两个(natoms=2)
H2O->AddElement(elO, natoms=1);
//加入第二种原子氧16,其在一个材料分子中有一个(natoms=1)
//可以看出,上述的代码构建了水这种材料
- 间接定义----混合材料(比如空气)
G4double z, a, fractionmass, density;
G4String name, symbol;
G4int ncomponents;
a = 14.01*g/mole;
//指定氮14原子的摩尔质量
G4Element* elN = new G4Element(name="Nitrogen",symbol="N" , z= 7., a);
//创建氮14原子
a = 16.00*g/mole;
//指定氧16原子的摩尔质量
G4Element* elO = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
//创建氧16原子
density = 1.290*mg/cm3;
//指定材料的密度
G4Material* Air = new G4Material(name="Air ",density,ncomponents=2);
创建名称为"Air"的材料,指定其密度与构成成分的数量("ncomponents=2"表示每个该材料有两种成分)
Air->AddElement(elN, fractionmass=70*perCent);
//加入第一种原子氮14,其质量分数为70%
Air->AddElement(elO, fractionmass=30*perCent);
//加入第二种原子氧16,其质量分数为30%
//可以看出,上述的代码创建了空气这种材料,当然与实际有一定的差异
- 定义新材料
G4double density;
//方法1
density = 1.05*mg/cm3;
//指定新材料的密度
G4Material* water1 = new G4Material("Water_1.05",density,"G4_WATER");
//在"G4_WATER"即Geant4材料数据库中已有材料的基础上,创建密度不同的新材料
//方法2
density = 1.03*mg/cm3;
//指定新材料的密度
G4NistManager* man = G4NistManager::Instance();
//创建对象以访问Geant4数据库
G4Material* water2 = man->BuildMaterialWithNewDensity("Water_1.03","G4_WATER",density);
//在Geant4材料数据库中查找"G4_WATER",然后以此为基础但采用不同的密度来创建新材料
二.材料的位置
Geant4中最大的几何体称为"World",所有其他定义的材料都放在这个world空间中.G4中几何体分为三种:Solid(实体)/Logical Volume(逻辑几何体)/Physical Volume(物理几何体)
- 实体几合体:包含几何体形状和尺寸
G4double world_hx = 3.0*m;
G4double world_hy = 1.0*m;
G4double world_hz = 1.0*m;
//指定几何体的长宽高
G4Box* worldBox
= new G4Box("WorldBox", world_hx, world_hy, world_hz);
//创建一个长方体(盒子),名称为"WorldBox",变量指针为"worldBox"
//在其自身的坐标系中,其X轴的范围是-3m到3m,总长6m;其Y轴的范围是-1m至1m,总长2m;
//其Z轴的范围是-1m至1m,总长2m
G4Box* envBox
= new G4Box("environmentBox",world_hx/2,world_hy/2,world_hz/2);
//创建一个长方体(盒子),名称为"environmentBox",变量指针为"env"
//在其自身的坐标系中,其X轴的范围是-1.5m到1.5m,总长3m;其Y轴的范围是-0.5m至0.5m,总长1m;
//其Z轴的范围是-0.5m至0.5m,总长1m
- 逻辑几合体:指定几何体材料
G4LogicalVolume( G4VSolid* pSolid,//指定依赖的实体
G4Material* pMaterial,//指定材料的种类
const G4String& Name,//名称
G4FieldManager* pFieldMgr=0,//指定所在磁场的状况,默认为没有磁场
G4VSensitiveDetector* pSDetector=0,//指定是否为探测器的一部分,默认不是
//如果指定其为探测器的一部分,则可以在SteppingAction中获取粒子在该部位相互作用的信息
G4UserLimits* pULimits=0,//指定是否应用用户自定义限制
//用户自定义限制是指用户自行设置的关于粒子在逻辑几何体中的最大步长等逻辑几何体属性的设置
G4bool Optimise=true)//指定是否开启优化,默认开启
//此处的优化指的是Geant4在处理粒子在逻辑几何体中的track时将几何体体素化的方法
- 物理几何体:指定几何体的位置
bool checkOverlaps=true;
// 指定是否检查有无重叠部分,一般应设置为true
G4VPhysicalVolume* physWorld
= new G4PVPlacement(0,G4ThreeVector(),worldLog,"physWorld",0,false,0,checkOverlaps);
//创建一个物理几何体,名称为"physWorld",其逻辑几何体为"worldLog",它不依附于任何母体,本身为Geant4中的World。
//这种不依附任何母体的World应该有且仅有一个。
G4VPhysicalVolume* physenv
= new G4PVPlacement(0,G4ThreeVector(),envLog,"physenvironment",worldLog,false,0,checkOverlaps);
//创建一个物理几何体,名称为"physenvironment",其逻辑几何体为"envLog",依附于逻辑几何体"worldLog",
//即依附于World
三.DetectorConstruction文件
DetectorConstruction为Geant4程序中材料相关的内容,一般包括头文件:DetectorConstruction.hh与对应的源文件:DetectorConstruction.cc。 这两个文件共同指定了Geant4程序中的材料的相关信息与接口。
在main文件中的使用:
#include "DetectorConstruction.hh"
runManager->SetUserInitialization(new DetectorConstruction());
Geant4粒子源
Geant4中把确定粒子源分为确定粒子源的物理信息与几何信息这两个步骤,这些信息一般都被写在文件"PrimaryGeneratorAction.hh/.cc"中
四.粒子源物理信息设置
通过确定粒子的***种类***与***能量***就可以确定粒子源的物理信息。但对于gamma(光子)/e-(电子)/e+(正电子),在模拟中为了避免红外发散,需要设置第三个信息:截断范围,才可以产生可用于模拟的上述三种粒子。在截断范围以下的上述三种粒子将不再产生任何次级粒子。一般使用Geant4默认的截断范围1mm即可,如有特殊需要,Geant4也支持对不同的粒子与区域分别设置不同的截断范围。
4.1粒子源物理信息----粒子种类
Geant4中有以下六种粒子,几乎包含了所有种类的微观粒子
· lepton 轻粒子
· meson 介子
· baryon 重粒子
· boson 玻色子
· shortlived
· ion 离子
此外,Geant4中还有一种特殊的粒子称为“geantino”,这是Geant4自创的粒子,不与任何材料发生相互作用,是在debug阶段常用的一种粒子。
G4int n_particle = 1;
fParticleGun = new G4ParticleGun(n_particle);
//在Geant4中一般用G4ParticleGun来创建粒子
//n_particle=1 表示在一个event中产生1个粒子,可修改为其他数字以产生不同数量的粒子
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
//创建粒子数据库G4ParticleTable对象以从中查找对应粒子
G4String particleName;
G4ParticleDefinition* particle
= particleTable->FindParticle(particleName="alpha");
//从创建的G4ParticleTable中查找名为"alpha"的粒子
fParticleGun->SetParticleDefinition(particle);
//指定G4ParticleGun将要产生的粒子为刚刚查找到的alpha粒子
4.2粒子源物理信息----粒子源能量
粒子源能量的设置同样通过G4ParticleGun的成员函数进行
fParticleGun->SetParticleEnergy(1000*keV);
//将alpha粒子的能量设置为1000keV
五.粒子源的几何信息
通过确定粒子的***位置***与***发射动量方向***就可以确定粒子源的几何信息。
5.1粒子源的几何信息----位置
由于真实世界中粒子源是有一定尺寸的,所以在Geant4模拟的绝大部分情况下,粒子源的位置是在一定几何范围内随机分布的。在程序中则要产生随机数来确定粒子的初始位置。这里的位置采用坐标系的方式确定,坐标系采用的是世界的坐标系。
G4double envSizeXY = 1*m;
G4double envSizeZ = 2*m;
//确定粒子源几何范围:长宽为1m,高为2m的长方体
G4double x0 = envSizeXY * (G4UniformRand()-0.5);
//确定粒子源在x轴上的位置,通过G4UniformRand()产生0-1均匀分布的一个随机数,
//再减去0.5即为-0.5到0.5均匀分布的随机数,
//再乘以envSizeXY,即为-0.5*envSizeXY到0.5*envSizeXY均匀分布的随机数,
//该随机数分布范围的大小即为envSizeXY
G4double y0 = envSizeXY * (G4UniformRand()-0.5);
G4double z0 = envSizeZ * (G4UniformRand()-0.5);
//与x0的确定方法相同
fParticleGun->SetParticlePosition(G4ThreeVector(x0,y0,z0));
//使用刚才产生的三个位置坐标来指定本次event中的粒子源位置
5.2粒子源的几何信息----发射动量信息
在确定了粒子源的能量后,需要确定粒子的发射方向,即确定粒子动量在xyz三个方向的分配情况。
G4double a=0;
G4double b=0;
G4double c=1;
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(a,b,c));
//按照此方法确定的动量分配方式为:
//x方向:分配|a|/sqrt(a^2+b^2+c^2)的动量
//y方向:分配|b|/sqrt(a^2+b^2+c^2)的动量
//z方向:分配|c|/sqrt(a^2+b^2+c^2)的动量
//如果a/b/c为负数,则表示与对应坐标轴正方向相反
//e.g.a=0,b=0,c=1表示粒子仅在z轴方向有速度,粒子源沿着z轴方向发射。
//也可以采用随机分布的方法确定动量方向,与确定位置类似
六.PrimaryGeneratorAction文件
PrimaryGeneratorAction为Geant4程序中粒子源相关的内容,一般包括头文件PrimaryGeneratorAction.hh与对应的源文件PrimaryGeneratorAction.cc。这两个文件共同指定了Geant4程序中的粒子源的相关信息与接口
在Geant4.10之后的版本中,如果要使用多线程,则必须引入ActionInitialization.hh/.cc,这里推荐大家选择引入ActionInitialization.hh/.cc的方式,因为一般来说如果要得到有统计意义的结果,多线程的使用是必需的。
与DetectorConstruction不同的是,PrimaryGeneratorAction需要在ActionInitialization.cc中进行指定。
指定需要两个步骤:
#include "PrimaryGeneratorAction.hh"
SetUserAction(new PrimaryGeneratorAction);
//通过new动态创建PrimaryGeneratorAction类,并通过SetUserAction方法指定其为Geant4程序中的粒子源,具体将在介绍ActionInitialization时说明
Geant4物理过程
七.G4物理过程设置
在现实世界中,粒子与材料的反应可能涉及多种复杂的物理过程,而用户往往仅关心某几种物理过程,如果模拟全部的物理过程会导致模拟时间与数据量的冗余,因此在Geant4中可以指定模拟过程中可以发生的物理过程。在Geant4中,物理过程分为7类:
· electromagnetic-------------------------------------- 电磁作用
· hadronic------------------------------------------------
· transportation------------------------------------------
· decay----------------------------------------------------衰减效应
· optical----------------------------------------------------光学
· photolepton_hadron----------------------------------光电
· parameterisation--------------------------------------自定义参数化过程
Geant4中,通过RegisterPhysics()函数来指定物理过程,可以指定多个。
RegisterPhysics(new G4DecayPhysics()); //指定基本粒子衰变物理过程
RegisterPhysics(new G4EmStandardPhysics()); //指定电磁相互作用物理过程
RegisterPhysics(new G4RadioactiveDecayPhysics());//指定放射性核素衰变物理过程
G4VUserPhysicsList::SetCuts();
//使用G4VUserPhysicsList类的SetCuts()函数进行截断设置,一般使用默认参数即可。
八. PhysicsList文件
在Geant4中物理过程对应的程序文件为:头文件PhysicsList.hh及对应的源文件PhysicsList.cc。
在main文件中,指定PhysicsList,需要两个步骤:
#include "PhysicsList.hh"
在main文件的main函数中,使用PhysicsList文件
G4VModularPhysicsList* physicsList = new PhysicsList();
runManager->SetUserInitialization(physicsList);
通过new动态创建PhysicsList类,并通过runManager指定其为Geant4程序中的物理过程。
一般来说PhysicsList只需在main文件中调用即可。
以上内容均来自知乎 https://www.zhihu.com/people/wang-jian-jun-78-22 , 作者大大总结得特别详细 ,原文中还有很多内容 ,