刚刚开始学习Geant4 , 在知乎上找到一系列特别特别好的文章,记录一下。(https://www.zhihu.com/people/wang-jian-jun-78-22),大家感兴趣一定去看看.为了学习理解,简单记录学习情况,方便之后反复学习.
先浅谈一下
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
}
材料确定的两个信息:材料的物理状态和几何位置,材料信息一般都被写在件 “DetectorConstruction.hh/.cc” 中。
材料的物理状态有两种定义方式:
总之,无论使用哪种方法,最终模拟的材料都是G4Material
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。
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为Geant4程序中材料相关的内容,一般包括头文件:DetectorConstruction.hh与对应的源文件:DetectorConstruction.cc。 这两个文件共同指定了Geant4程序中的材料的相关信息与接口。
在main文件中的使用:
#include "DetectorConstruction.hh"
runManager->SetUserInitialization(new DetectorConstruction());
Geant4中把确定粒子源分为确定粒子源的物理信息与几何信息这两个步骤,这些信息一般都被写在文件"PrimaryGeneratorAction.hh/.cc"中
通过确定粒子的***种类***与***能量***就可以确定粒子源的物理信息。但对于gamma(光子)/e-(电子)/e+(正电子),在模拟中为了避免红外发散,需要设置第三个信息:截断范围,才可以产生可用于模拟的上述三种粒子。在截断范围以下的上述三种粒子将不再产生任何次级粒子。一般使用Geant4默认的截断范围1mm即可,如有特殊需要,Geant4也支持对不同的粒子与区域分别设置不同的截断范围。
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粒子
粒子源能量的设置同样通过G4ParticleGun的成员函数进行
fParticleGun->SetParticleEnergy(1000*keV);
//将alpha粒子的能量设置为1000keV
通过确定粒子的***位置***与***发射动量方向***就可以确定粒子源的几何信息。
由于真实世界中粒子源是有一定尺寸的,所以在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中的粒子源位置
在确定了粒子源的能量后,需要确定粒子的发射方向,即确定粒子动量在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为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中可以指定模拟过程中可以发生的物理过程。在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()函数进行截断设置,一般使用默认参数即可。
在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 , 作者大大总结得特别详细 ,原文中还有很多内容 ,
文章浏览阅读687次。Android 新手想要入门,很容易会遇到各类困难和学习瓶颈。没有一个好学的学习方向,学习规划,学习教程,这都是新手会面临的问题。 很多人会在百度上搜索,查阅相关资料。但是网上搜索的很多资料,都是断片式的学习,缺乏完整性和系统性。那么新手应该从何学起?这样学习呢?这里给大家一份最强Android入门指南:_android 开发指南
文章浏览阅读1k次。在不开启 Opcache 的情况下,PHP解释器在解释PHP脚本的时候,首先会经过词法分析(Lexing),而词法分析的具体实现就是将PHP代码转换成 Tokens,此过程成为 Lexing / Tokenizing / Scanning 。那么 Tokens 是啥样的呢,Lex就是一个词法分析的依据表。 Zend/zend_language_scanner.c会根据Zend/zend_language_scanner.l (Lex文件),来输入的 PHP代码进行词法分析,从而得到一个一个的“词”,PHP_phpscanning
文章浏览阅读1.7k次。在编程语言中区分变量的数据类型;最简单的是数值型和字符型;以SQL为例;新建一个表如下图;name列是字符型,age列是数值型;保存表名为pp;录入如下图的数据;看这里name列输入的‘123’、'789',这些是字符型的数据;age输入的内容是数值型;显示结果如下;因为age列是数值型,输入的 009 自动变为了 9;写查询语句时字符型数据按语法规则是用引号括起来;如果如下图写也可以运行出结果;是因为sqlserver本身具有一定的智能识别功能;写比较长的SQL语句_数值 字符
文章浏览阅读558次。Caffe2 Tutorials[0](转)https://github.com/wizardforcel/data-science-notebook/blob/master/dl/more/caffe2-tut.md本系列教程包括9个小节,对应Caffe2官网的前9个教程,第10个教程讲的是在安卓下用SqueezeNet进行物体检测,此处不再翻译。另外由于栏主不关注RNN和LS..._writer.add_scalar [enforce fail at pybind_state.cc:221] ws->hasblob(name). c
文章浏览阅读155次。java学习笔记day09思维导图final 、 多态 、 抽象类 、 接口 (都很重要)一、final二、多态多态中的成员访问特点 【P237】多态的好处 【P239]多态的弊端向上转型、向下转型 【P241】形象案例:孔子装爹多态的问题理解: class 孔子爹 { public int age = 40; public void teach() { System.out.println("讲解JavaSE"); } _} } class a { public void show() { show2(); } public void show2() { s
文章浏览阅读2.4k次,点赞3次,收藏9次。在写qt网口通信的过程中,遇到中文就乱码。解决方法如下:1.接收端处理中文乱码代码如下 QByteArray-> QString 中文乱码解决: #include <QTextCodec>QByteArray data= tcpSocket->readAll(); QTextCodec *tc = QTextCodec::codecForName("GBK"); QString str = tc->toUnicode(data);//str如果是中文则是中文字符_qbytearray中文乱码
文章浏览阅读820次。表输出控件如下1)步骤名称,2)数据库连接,前面有过部分解释3)目标模式,数据库中的概念,引用:https://www.cnblogs.com/csniper/p/5509620.html(感谢)4)目标表:数据库中的表,这里有两种方式:(1) 应用数据库中已经存在的表,浏览表选中对应表即可,下图有部分sql功能。ddl可以执行ddl语句。(2) 创建新的表,填写表的名字,点击下面的sql就可以执..._kettle 步骤 提交
文章浏览阅读4.4k次,点赞2次,收藏2次。鼠标选中多行,按下 widows 下 Ctrl Shift L( Mac下 Command Shift L)即可同时编辑这些行;鼠标选中文本,反复按widows 下CTRL D(Mac下 Command D)即可继续向下同时选中下一个相同的文本进行同时编辑;鼠标选中文本,按下Alt F3(Win)或Ctrl Command G(Mac)即可一次性选择全部的相同文本进行同时编辑;..._submlite 同时操作多行 macos
文章浏览阅读252次。尽管Linux是具有广泛硬件和软件支持的出色操作系统,但现实是有时您必须使用Windows,这可能是由于关键应用程序无法在Linux下运行。 幸运的是,双重引导Windows和Linux非常简单-本文将向您展示如何使用Windows 10和Ubuntu 18.04进行设置。 在开始之前,请确保已备份计算机。 尽管双启动设置过程不是很复杂,但是仍然可能发生事故。 因此,请花点时间备份您的重要..._windows linux双启动
文章浏览阅读1.6w次,点赞25次,收藏20次。本文主要介绍Flink 的3种常用的operator(map、flatmap和filter)及以具体可运行示例进行说明.将集合中的每个元素变成一个或多个元素,并返回扁平化之后的结果。按照指定的条件对集合中的元素进行过滤,过滤出返回true/符合条件的元素。本文主要介绍Flink 的3种常用的operator及以具体可运行示例进行说明。这是最简单的转换之一,其中输入是一个数据流,输出的也是一个数据流。下文中所有示例都是用该maven依赖,除非有特殊说明的情况。中了解更新系统的内容。中了解更新系统的内容。_flink 常用的分类和计算
文章浏览阅读590次。IMP-00019: row rejected due to ORACLE error 12899IMP-00003: ORACLE error 12899 encounteredORA-12899: value too large for column "CRM"."BK_ECS_ORDER_INFO_00413"."POSTSCRIPT" (actual: 895, maximum..._row rejected due to oracle
文章浏览阅读918次。目前很多Web的项目在部署的时候会采用Nginx做为前端的反向代理服务器,后端会部署很多业务处理服务器,通常情况下Nginx代理服务器部署的还是比较少,而且其以高效性能著称,几万的并发连接处理速度都不在话下。然而去年的时候,我们的线上系统也采用类似的部署结构,同时由于我们的业务需求,Nginx的部署环境在虚拟机上面,复用了其他虚拟机的整体磁盘,在高IO消耗的场景中,我们发现Nginx的磁盘_nginx tcp转发 硬盘io