G4 探测器构建顺序
几何体 -> 逻辑体 -> 物理体
用户必须继承抽象基类 G4VUserDetectorConstruction 来实现探测器的定义
以下几点要求是多年经验的总结,目的在于提高代码可读性,方便修改。
为了代码的规范及可重复性,我们这里将材料的定义、探测器的定义分离成两个函数。
参数的定义建议放在函数头部部分,方便对数值的修改。
G4LogicalVolume,G4VPhysicalVolume 类对象的声明放在 hh 文件中。
下面是可视化界面的颜色设置示例,只要修改 G4Colour 中 RGB 三原色的比例即可,数值均为 [0.0,1.0]。对哪一个探测器设置颜色就仿照示例进行修改即可。
参考 https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/material.html
在自然界中,一般材料(化合物、混合物)由元素构成,元素由同位素构成。因此,这是 Geant4 中设计的三个主要类(G4Isotope/G4Element/G4Material)。每个类都有一个表作为静态数据成员,用于跟踪各个类创建的实例。所有三个对象在构造时都会自动注册到相应的表中,并且永远不应该在用户代码中删除它们。
G4Isotope/G4Element/G4Material 这三个类 new 的对象,不需要 delete
G4Materrial 材料只要一定义,就放置在一个全局的容器内,随时可以拿来使用。
//定义元素,方法一
G4Element *H = new G4Element("Hydrogen", "H" , 1., 1.01*g/mole);
//定义元素,方法二
G4NistManager *man = G4NistManager::Instance();
G4Element *N = man->FindOrBuildElement("N");//采用天然丰度
G4Element *O = man->FindOrBuildElement("O");
单质
G4Material* lAr = new G4Material("liquidArgon", 18., 39.95*g/mole, 1.390*g/cm3);
分子/混合物
G4Material *pVacuum = new G4Material("Vacuum", 1.29e-10*mg/cm3, 2, kStateGas,
0.1*kelvin, 1.e-19*pascal);
pVacuum->AddElement(N, 7);//注意这里是整型
pVacuum->AddElement(O, 3);//表示原子个数比
//或者
pVacuum->AddElement(N, 70.*perCent);//注意这里是浮点型
pVacuum->AddElement(O, 30.*perCent);//表示质量占比
//原子个数比还是质量比,设置方式需要非常小心!
// define a material from elements and/or others materials (mixture of mixtures)
density = 0.200*g/cm3;
G4Material* Aerog = new G4Material(name = "Aerogel", density, ncomponents = 3);
Aerog->AddMaterial(SiO2, fractionmass = 62.5*perCent);
Aerog->AddMaterial(H2O , fractionmass = 37.4*perCent);
Aerog->AddElement (elC , fractionmass = 0.1*perCent);
// examples of gas in non STP conditions
density = 27.*mg/cm3;
pressure = 50.*atmosphere;
temperature = 325.*kelvin;
G4Material* CO2 = new G4Material(name = "Carbonic gas", density, ncomponents = 2,
kStateGas, temperature, pressure);
CO2->AddElement(elC, natoms=1);
CO2->AddElement(elO, natoms=2);
对于常见的材料,G4已经封装好,直接调用即可
G4NistManager* man = G4NistManager::Instance();
G4Material * pAir = man->FindOrBuildMaterial("G4_AIR");
G4Material *pSi = man->FindOrBuildMaterial("G4_Si");
void wuDetectorConstruction::DefineMaterials()
{
//在这里先定义所有可能用到的材料
// Get nist material manager
G4NistManager* nist = G4NistManager::Instance();
//注册G4自身定义好的材料
nist->FindOrBuildMaterial("G4_Galactic");//真空
nist->FindOrBuildMaterial("G4_Ge");//
nist->FindOrBuildMaterial("G4_Pu");
nist->FindOrBuildMaterial("G4_H");
nist->FindOrBuildMaterial("G4_Al");
nist->FindOrBuildMaterial("G4_lH2");//
nist->FindOrBuildMaterial("G4_lN2");//
nist->FindOrBuildMaterial("G4_lO2");//
nist->FindOrBuildMaterial("G4_lAr");//Liquid argon
nist->FindOrBuildMaterial("G4_Be");
nist->FindOrBuildMaterial("G4_WATER");
nist->FindOrBuildMaterial("G4_WATER_VAPOR");//水蒸气
nist->FindOrBuildMaterial("G4_POLYETHYLENE");//聚乙烯
nist->FindOrBuildMaterial("G4_BGO");//
nist->FindOrBuildMaterial("G4_CARBON_DIOXIDE");//二氧化碳
nist->FindOrBuildMaterial("G4_LEAD_OXIDE");//氧化铅
nist->FindOrBuildMaterial("G4_MYLAR");//mylar膜
nist->FindOrBuildMaterial("G4_PLEXIGLASS");//有机玻璃
nist->FindOrBuildMaterial("G4_STAINLESS-STEEL");//不锈钢
nist->FindOrBuildMaterial("G4_LUCITE");//透明合成树脂(有机玻璃)
nist->FindOrBuildMaterial("G4_CONCRETE");//混凝土
nist->FindOrBuildMaterial("G4_GRAPHITE");//石墨
nist->FindOrBuildMaterial("G4_SILICON_DIOXIDE");//二氧化硅
nist->FindOrBuildMaterial("G4_RUBBER_NATURAL");//天然橡胶
nist->FindOrBuildMaterial("G4_PbWO4");//
nist->FindOrBuildMaterial("G4_URANIUM_OXIDE");//氧化铀
nist->FindOrBuildMaterial("G4_URANIUM_MONOCARBIDE");//碳化铀
nist->FindOrBuildMaterial("G4_URANIUM_DICARBIDE");//二碳化铀
// 更多预定义材料请看说明书 https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Appendix/materialNames.html#g4matrdb
// 注册G4自身定义好的 elements,采用天然丰度
G4Element* H = nist->FindOrBuildElement("H",false);//1
G4Element* Li = nist->FindOrBuildElement("Li",false);//3
G4Element* C = nist->FindOrBuildElement("C",false);//6
G4Element* N = nist->FindOrBuildElement("N",false);//7
G4Element* O = nist->FindOrBuildElement("O",false);//8
G4Element* Mg = nist->FindOrBuildElement("Mg",false);//12
G4Element* Al = nist->FindOrBuildElement("Al",false);//13
G4Element* Si = nist->FindOrBuildElement("Si",false);//14
G4Element* P = nist->FindOrBuildElement("P",false);//15
G4Element* S = nist->FindOrBuildElement("S",false);//16
G4Element* Cr = nist->FindOrBuildElement("Cr",false);//24
G4Element* Mn = nist->FindOrBuildElement("Mn",false);//25
G4Element* Fe = nist->FindOrBuildElement("Fe",false);//26
G4Element* Ni = nist->FindOrBuildElement("Ni",false);//28
G4Element* I = nist->FindOrBuildElement("I",false);//53
G4Element* Cs = nist->FindOrBuildElement("Cs",false);//55
G4Element* Ce = nist->FindOrBuildElement("Ce",false);//58
// 同位素构建元素,用来调整材料丰度
G4Isotope* U4 = new G4Isotope("U234",92,234,234.02*g/mole);
G4Isotope* U5 = new G4Isotope("U235",92,235,235.01*g/mole);
G4Isotope* U6 = new G4Isotope("U236",92,236,236.04*g/mole);
G4Isotope* U8 = new G4Isotope("U238",92,238,238.03*g/mole);
G4Element* HEU58 = new G4Element("Highly-enriched Uranium 58", "HEU58", 2);
HEU58->AddIsotope(U5, 0.93);
HEU58->AddIsotope(U8, 0.07);
G4Element* HEU4568 = new G4Element("Highly-enriched Uranium 4568","HEU4568",4);
HEU4568->AddIsotope(U4,0.0097);
HEU4568->AddIsotope(U5,0.9315);
HEU4568->AddIsotope(U6,0.0024);
HEU4568->AddIsotope(U8,0.0564);
//---------------------------------------------------------------------------------
// Scintillator(BC408) 塑闪
G4Material* BC408 = new G4Material("BC408", 1.032*g/cm3, 2);
BC408->AddElement(H, 11);BC408->AddElement(C, 10);
// BC408->AddElement(H, 10);BC408->AddElement(C, 9);
// LiquidScint(NE213) 液闪
G4Material* NE213 = new G4Material("NE213",0.874*g/cm3,2);
NE213->AddElement(H,1212);
NE213->AddElement(C,1000);
// He-3 detector materials
G4Material* matHe3 = new G4Material("He3", 2., 3.*g/mole, 0.00049*g/cm3, kStateGas);
// Uranium material
G4Material* matHEU58 = new G4Material("HEU58", 19.1*g/cm3, 1, kStateSolid);
matHEU58->AddElement(HEU58, 1.00);
G4Material* matHEU4568 = new G4Material("HEU4568",18.75*g/cm3,1);
matHEU4568->AddElement(HEU4568, 1.0);
G4Material* matSteel = new G4Material("Steel",7.788*g/cm3,9);
matSteel->AddElement(Fe,62.1805*perCent);
matSteel->AddElement(Cr,20.26*perCent);
matSteel->AddElement(Mn,9.37*perCent);
matSteel->AddElement(Ni,7.5*perCent);
matSteel->AddElement(Si,0.34*perCent);
matSteel->AddElement(N,0.29*perCent);
matSteel->AddElement(C,0.04*perCent);
matSteel->AddElement(P,0.018*perCent);
matSteel->AddElement(S,0.0015*perCent);
// Print materials,运行时在终端输出材料信息
G4cout << *(G4Material::GetMaterialTable()) << G4endl;
}
几何体的名字虽然允许出现相同的情况,但是不建议使用相同的名字。
查阅说明书,基本几何形状可直接创建,需要特别注意的地方:长度是全长还是半长表示。使用哪个几何体,则在 wuDetectorConstruction.cc 文件中添加相应的头文件。
以下是最常用的几何,长方体、柱状/管状、球/球壳等。
G4Box *pSolidWorld= new G4Box("solidWorld",0.5*10*cm,0.5*10*cm,0.5*10*cm);
布尔运算生成几何体
简单几何体可以在说明书中直接找到它的使用方法。很多时候探测器的形状不在基本的几何体库中,这种情况就需要使用者通过布尔运算来构建所需要的几何体了。G4几何体构建中支持的布尔运算有:union, intersection, subtraction。参与运算中的第二个几何体可以进行平移、旋转等操作。
G4Box* box =
new G4Box("Box", 20*mm, 30*mm, 40*mm);
G4Tubs* cyl =
new G4Tubs("Cylinder", 0, 50*mm, 50*mm, 0, twopi); // r: 0 mm -> 50 mm
// z: -50 mm -> 50 mm
// phi: 0 -> 2 pi
G4UnionSolid* union =
new G4UnionSolid("Box+Cylinder", box, cyl);
G4IntersectionSolid* intersection =
new G4IntersectionSolid("Box*Cylinder", box, cyl);
G4SubtractionSolid* subtraction =
new G4SubtractionSolid("Box-Cylinder", box, cyl);
G4RotationMatrix* yRot = new G4RotationMatrix; // Rotates X and Z axes only
yRot->rotateY(M_PI/4.*rad); // Rotates 45 degrees
G4ThreeVector zTrans(0, 0, 50);
G4UnionSolid* unionMoved =
new G4UnionSolid("Box+CylinderMoved", box, cyl, yRot, zTrans);
G4RotationMatrix invRot = yRot->invert();
G4Transform3D transform(invRot, zTrans);
G4UnionSolid* unionMoved =
new G4UnionSolid("Box+CylinderMoved", box, cyl, transform);
以上两种方法基本能满足大部分的探测器构建需要,特别大规模或者形状复杂的还可以通过三维软件构造,然后 STL 格式图纸导入的方式。
G4LogicalVolume (
G4VSolid *pSolid,
G4Material *pMaterial,
const G4String &name,
G4FieldManager *pFieldMgr=0,
G4VSensitiveDetector *pSDetector=0,
G4UserLimits *pULimits=0,
G4bool optimise=true)
// 参数:几何体,材料,逻辑体名字, 电磁场,灵敏探测器,截断,优化
// 其中 几何体,材料,逻辑体名字 三个必须指定
这里要求每个逻辑体的名字必须唯一,这样方便后期的数据处理。
G4PVPlacement (
G4RotationMatrix *pRot,
const G4ThreeVector &tlate,
G4LogicalVolume *pCurrentLogical,
const G4String &pName,
G4LogicalVolume *pMotherLogical,
G4bool pMany,
G4int pCopyNo,
G4bool pSurfChk=false)
// 参数:旋转,平移,逻辑体,本物理体名字,母体,(无用参数),拷贝号,重叠检查
多个物理体可以共用同一个逻辑体,然后通过不同的拷贝号来区分。这在同一个型号的探测器有几千上万的情况下显得特别必要(因为重复 new 那么多对象需要占用非常大的内存,而且初始化它们所需要的时间也很长,而它们仅仅名字不一样)。但是对于我们一般的模拟来说,创建的逻辑体不会太多,为了方便后期的数据处理,建议每个探测器创建各自的逻辑体和物理体,且逻辑体和对应的物理体用相同的名字。
问题:如何将物理体A放入物理体B的内部?
物理体A与物理体B的重叠部分:?
Geant4:嵌套模型(盒子模型)
G4中,所有的物理体必须被指定母体。对于最外层的物理体,其母体为空,此物理体称为“World”。
思考
对于一个正面 48 条,条宽 1mm,条缝隙 0.1mm;背面 128 条,条宽 1mm,条缝隙 0.1mm 的双面硅微条。安装在束流方向 45度,探测器中心距离靶点 15 cm 的位置。
为了模拟粒子最终沉积在哪一个像素,因此在几何构造的时候,需要构造 48x128 个像素。如何构造?
!date
!jupyter nbconvert DetectorConstruction.ipynb --to html
2024年 04月 21日 星期日 19:42:12 CST [NbConvertApp] Converting notebook DetectorConstruction.ipynb to html [NbConvertApp] Writing 621041 bytes to DetectorConstruction.html