从零开始折腾 Geant4 的头一天,很多人根本不是倒在物理上,而是倒在前面的编译环境上。作为一个把第一个周末全部搭进去的人,我想把 Day01 应该做的、应该懂的、应该避开的,一次性写清楚。本文会用最直接的方式带你建立对 Geant4 的整体认知,完成环境配置,跑通官方示例,并且理解它最核心的几个抽象概念,让你第二天的学习有一个扎实的起点。
1. 为什么一个粒子模拟工具能让无数人卡在第一天
先说结论:Geant4 不是一个“装上就能用”的软件,而是一套用 C++ 写的工具包。这句话是劝退率最高的一句话,也是理解它的关键。它由 CERN 开发并维护,主要用于模拟粒子在物质中的输运过程,覆盖了从几十 eV 的热中子到 TeV 级高能粒子的巨大能量范围,在核物理、粒子物理、医学物理、辐射防护和空间科学等领域应用极广。它没有图形化的一键安装向导,没有统一的启动按钮,你需要自己写 C++ 代码、写 CMake 脚本、链接一大堆库文件,然后编译成可执行程序,再运行它。
我第一次听说 Geant4 时以为它和 Origin 或者 MATLAB 差不多,双击图标、选个模板、点运行就出结果。直到我第一次打开安装文档,发现里面在讨论LD_LIBRARY_PATH、CMAKE_INSTALL_PREFIX、Qt5和X11的时候,我的第一反应是——这真的是物理软件而不是某个大型开源项目的构建文档吗?是的,Geant4 就是这种风格。它是一个库,你通过调用它提供的类来完成几何建模、物理过程定义、粒子源设置、结果统计。你的代码是“主人”,Geant4 只是“仆人”,一切主流程由你控制。
那为什么这么难学还要学?因为它的能力太强了。以医学物理为例,放射治疗中的剂量计算、质子治疗束流线设计、PET 探测器开发,很多工作都需要通过 Geant4 做蒙特卡洛模拟。在辐射防护领域,屏蔽设计、环境剂量评估、宇宙射线对电子器件的影响分析也离不开它。航空航天领域使用 GEANT4 模拟空间辐射环境对卫星元器件和宇航员的影响。它虽然难,但它是这个领域的通用语言,掌握了这套语言,很多问题都能用它来验证和预测。
所以 Day01 的核心目标是什么?不是学会所有物理过程,也不是熟练掌握 C++ 面向对象设计,而是“把环境搞定、把官方示例跑起来、搞清楚 Geant4 的一级抽象模型”。这件事听起来简单,但实操下来往往会消耗一整天,值得从一开始就认真对待。
这里还要提醒一点:如果你之前没有 C++ 基础,不要慌,Geant4 的官方示例写得相对规整,Day01 阶段不需要理解每个类的继承关系,只要能够通过阅读代码大致知道“哪个文件负责几何、哪个文件负责粒子源”即可。也就是说,你完全可以从一个“会用”的状态开始,再慢慢积累 C++ 面向对象的细节。
2. 动手搭建环境前,先把三件事想清楚
2.1 操作系统选 Linux 还是 Windows
如果你想走最省力的路,答案是 Linux,尤其是 Ubuntu/Debian 系发行版。Geant4 在 Linux 上的编译工具链最顺、资料最多、遇到问题时社区最容易给出可复现的命令。Windows 下有原生编译的尝试路径,但坑很多,比如 CMake 生成器选择、Visual Studio 版本匹配、PATH 环境变量、不同库的二进制兼容性等,新手很容易迷失在这些和物理毫无关系的事情里。macOS 也可以跑,但如果你用的是 Apple Silicon(M 系列芯片),还会遇到部分依赖库的编译兼容问题,虽然近两年已经改善很多,但依然不如 Linux 开箱即用。
我现在比较推荐的学习方案是:本地装一个虚拟机或者直接物理安装 Ubuntu 22.04/24.04,然后按照官方文档操作。另一条路径是使用 Windows 自带的 WSL2(子系统),在里面装 Ubuntu,体验也很接近原生 Linux。唯一需要注意的是文件目录的跨系统访问速度和图形界面的转发问题,不过 Geant4 本身的默认可视化大多可以通过 X11 转发或者离线渲染模式绕开,不影响 Day01 的核心任务。
2.2 选对版本:不要继续用老版本的教程硬套新版本
先从大版本说起。Geant4 目前主流是 11.x 系列,11.0 是一个分水岭,它在 CMake 配置、类的命名空间、部分接口上相比 10.x 有较大变化。网上老旧的教程很多基于 10.4 或 10.7,虽然核心概念仍然适用,但如果直接复制命令,大概率会碰到“找不到某个模块”“变量名不匹配”之类的问题。
我建议直接到 Geant4 官网下载最新的稳定版源码包,文件名类似geant4-v11.2.1.tar.gz。不要选择beta或rc版本,除非你想帮官方测 bug。如果你需要的是带完整数据和物理列表的版本,记得同时下载geant4-data相关数据集。这一步可以参考官方 Download 页面上的说明,按版本号对应关系下载即可。
2.3 编译方式:用源码编译,还是用包管理器
Ubuntu 的 apt 源里有geant4相关包,可以通过apt install geant4快速安装,但在 Day01 阶段我强烈不建议这么干。原因有两点:第一,apt 源里的版本通常滞后,而且往往不会附带完整的数据文件,运行某些物理过程时会提示找不到数据;第二,Geant4 的学习一定会涉及修改源码、重新编译的环节,如果你对编译流程没有亲身体验,后续会非常被动。
因此,我建议走标准流程:源码编译安装。听上去很吓人,但只要按顺序做完,你会发现它比想象中顺利。官方源码的编译安装本质上是三步:配置、编译、安装(cmake + make + make install),只不过依赖库比较多,编译时间较长,一般取决于 CPU 核心数,通常是 20 分钟到一个小时。编译本身不需要干预,可以把它当成一次耐心的等待。
2.4 依赖库检查清单
编译 Geant4 之前,请先确认系统里有以下基础工具和依赖库:
| 组件 | 作用 | Ubuntu 下安装示例 |
|---|---|---|
| gcc/g++ | C++ 编译器 | sudo apt install g++ |
| make | 构建工具 | sudo apt install make |
| cmake | 构建配置工具 | sudo apt install cmake |
| X11 开发库 | 基础图形界面支持 | sudo apt install libx11-dev libxmu-dev libxerces-c-dev |
| OpenGL 开发库 | 可视化渲染 | sudo apt install libgl1-mesa-dev libglu1-mesa-dev |
| Qt5 开发库(可选) | 高级可视化界面 | sudo apt install qtbase5-dev qtchooser libqt5opengl5-dev |
| expat 开发库 | 解析宏观文件配置 | sudo apt install libexpat1-dev |
建议先用cmake --version确认 CMake 版本,Geant4 11.x 系列要求 CMake 3.16 以上。如果版本不够,需要先升级 CMake,否则编译阶段会直接报错。我这里假设你使用的系统是 Ubuntu 22.04 以上,默认仓库的 CMake 版本基本满足要求。
3. 源码编译与安装:每一步的预期结果是什么
3.1 目录规划
强烈建议把源码、构建目录、安装目录分成三个独立目录。很多人图省事直接在源码目录里执行 cmake,称之为 in-source build,这会在源码文件夹里生成一堆中间文件,后续想清理或者切换编译选项会变得很混乱。Geant4 官方推荐 out-of-source build,即源码只读,编译产物放在单独的 build 目录,安装产物放在单独的 install 目录。
我使用的目录结构如下:
mkdir -p ~/geant4/src mkdir -p ~/geant4/build mkdir -p ~/geant4/install源码包解压到src目录下:
cd ~/geant4/src tar -xzf geant4-v11.2.1.tar.gz解压后会得到geant4-v11.2.1文件夹。注意不要把它解压到带中文或空格的路径下,Geant4 的编译工具链对路径中的特殊字符比较敏感,遇到问题排查起来非常糟心。
3.2 CMake 配置阶段的常用选项
进入 build 目录,执行第一次配置命令:
cd ~/geant4/build cmake -DCMAKE_INSTALL_PREFIX=~/geant4/install \ -DGEANT4_INSTALL_DATA=ON \ -DGEANT4_USE_OPENGL_X11=ON \ -DGEANT4_USE_QT=ON \ ../src/geant4-v11.2.1逐个解释这些选项:
CMAKE_INSTALL_PREFIX:指定安装目录。GEANT4_INSTALL_DATA=ON:在安装过程中自动下载并安装物理数据文件。这非常关键,如果关闭,之后运行某些物理过程会报数据缺失错误。GEANT4_USE_OPENGL_X11=ON:启用 OpenGL 可视化驱动,用于显示探测器几何和粒子径迹。GEANT4_USE_QT=ON:启用 Qt 界面,可提供更友好的交互显示窗口,但它会明显延长编译时间。如果你对可视化要求不高,可以先用纯 OpenGL,之后再补。
执行完成后,你应该能看到 CMake 给出的配置摘要,其中包含安装路径、数据文件路径、可用的可视化驱动列表。如果在配置阶段报缺失依赖的错误,不要再继续往后走,先解决缺失项再重新执行 cmake。因为对整个编译过程来说,配置阶段是最容易暴露环境问题的地方,越往后拖越难排查。
3.3 编译与安装
配置成功后,执行编译:
make -j$(nproc)-j参数是并行编译的核心数,nproc会自动读取机器逻辑核心数。我建议手动把并行数设置为核心数减一,防止电脑卡死。如果你的电脑内存不足 16 GB,并行数不建议拉满,否则编译器吃满内存后系统会变得异常缓慢。
编译结束后执行安装:
make install安装完成后,检查安装目录:
ls ~/geant4/install/bin这里能看到geant4-config、geant4.sh等脚本和工具。geant4.sh是环境变量脚本,包含动态库路径、数据文件路径等设置。每次打开新终端想使用 Geant4 时,先执行:
source ~/geant4/install/bin/geant4.sh这行命令在后面的学习里会反复用到,建议直接写进~/.bashrc中,省得每次手动 source:
echo "source ~/geant4/install/bin/geant4.sh" >> ~/.bashrc source ~/.bashrc3.4 使用 Geant4 的快捷命令验证安装
geant4-config是官方提供的查询工具,使用它可以在不写 CMakeLists 的前提下快速验证安装是否成功:
geant4-config --version geant4-config --help如果输出版本号就说明安装成功。geant4-config还可以输出编译所需的 include 路径、库路径等,后续写 CMake 文件时可以通过它来自动获取参数,不过官方更推荐直接使用find_package(Geant4)的方式,这个在第 4 节展开。
4. 跑通官方示例:example B1 是 Day01 的及格线
4.1 找到并拷贝示例源码
Geant4 的源码包中自带几十个示例代码,按由浅入深排列在examples目录下。basic/B1是最简单的一个,适合第一天跑通。它的物理场景不复杂:一个铅屏蔽层后面放置一个探测器,一束质子穿过屏蔽层后,在探测器中沉积能量并统计穿过数量。这个场景简单但完整,包含了几何构造、粒子源设置、物理列表选择、Run 输出,是理解 Geant4 运行机制的最小闭环。
把示例复制到自己的 workspace,不要在源码目录里直接跑:
mkdir -p ~/geant4/workspace cp -r ~/geant4/src/geant4-v11.2.1/examples/basic/B1 ~/geant4/workspace/ cd ~/geant4/workspace/B1看一下这个目录里有什么:
ls -l你会看到CMakeLists.txt、src目录、include目录、B1.in、init_vis.mac、vis.mac、run1.mac等文件。其中.mac是 Geant4 的宏观文件,可以理解为预先写好的命令序列,作用类似于给程序下指令。CMakeLists.txt是构建项目的入口。
4.2 构建示例工程
示例工程的构建和 Geant4 本身的构建思路一致,但步骤更简单:
mkdir build cd build cmake .. make -j$(nproc)在 CMake 配置阶段,find_package(Geant4)会通过环境变量自动寻找安装好的 Geant4。如果你之前没有 sourcegeant4.sh,这里大概率会报错:找不到 Geant4 的 CMake 模块。解决办法就是先 source 一下环境脚本,再重新 cmake。
编译完成后,目录里会生成名为exampleB1的可执行文件。运行它有两种方式:一种是没有参数直接运行,会弹出交互式可视化界面;另一种是带宏观文件参数运行,进入批处理模式,例如:
./exampleB1 run1.macDay01 阶段建议先运行批处理模式,因为少了很多图形交互的干扰,而且能够立刻看到物理输出。
4.3 预期输出怎么读
运行./exampleB1 run1.mac后,终端会滚动大量日志,但最核心的输出在末尾,会看到类似下面的信息:
-------- Begin Run --------- Initializing Run... Run 0 starts. ... Number of events = 1000 total Energy deposit in detector : 0.567 GeV number of tracks entered detector : 832这里Number of events = 1000表示模拟了 1000 个入射粒子;total Energy deposit in detector是所有粒子在探测器中沉积的总能量;number of tracks entered detector是进入探测器的粒子轨迹数。这段输出来自示例代码中的B1RunAction.cc文件,是作者特意写好的统计逻辑,你可以用它来判断程序是否正常运行。
4.4 理解 B1 示例的代码骨架
在 Day01 阶段,不需要完全理解每一个类的细节,但建议把主流程跑一遍:
int main(int argc, char** argv) { auto runManager = G4RunManagerFactory::CreateRunManager(G4RunManagerType::Serial); runManager->SetUserInitialization(new B1DetectorConstruction()); runManager->SetUserInitialization(new B1ActionInitialization()); runManager->Initialize(); // 可视化或批处理循环 delete runManager; return 0; }代码中的逻辑顺序反映了 Geant4 初始化流程:
- 创建 RunManager:管理整个模拟过程的主控对象。
SetUserInitialization(new B1DetectorConstruction()):定义探测器几何。SetUserInitialization(new B1ActionInitialization()):注册粒子源、Run/Event 的统计行为。Initialize():完成物理列表和几何检查。BeamOn(次数):发射指定数量的粒子,开始模拟。
这一连串操作就像拍电影:先搭好摄影棚(几何),然后制定物理规则(物理列表),再把演员(入射粒子)叫上场。你的所有工作都是围绕这几个步骤去展开的。
4.5 可视化运行看粒子径迹
如果你编译时启用了 Qt 或 OpenGL 可视化,运行./exampleB1(不跟参数)会弹出可视化窗口。界面上能看到铅屏蔽层和后面的探测器,粒子入射后会有彩色径迹。按h键可以看到交互命令帮助。第一次真正在屏幕上看到粒子穿过屏蔽物的时候,那种感觉还是相当直观的——你的代码已经把抽象的物理过程变成了具象的模拟场景。
如果运行时提示cannot open display,说明你的环境没有图形界面或者 X11 转发没有配置好,此时不要死磕可视化,直接改用.mac批处理文件完成模拟即可。可视化只是锦上添花,不是 Day01 的必需品。
5. 理解 Geant4 的一级抽象模型:Run、Event、Track、Step
跑通示例之后,最重要的认知任务是理解 Geant4 的抽象模型。这套模型是学习所有后续内容的地基,一旦理解了这个框架,看任何示例代码都不会再感到陌生。
5.1 一层层拆开:从 Run 到 Step
从宏观到微观,Geant4 的粒子输运过程可以拆分成四个层级:
| 层级 | 含义 | 生活化类比 |
|---|---|---|
| Run | 一次完整的模拟过程,由固定数量的入射粒子触发 | 拍摄一整季电视剧 |
| Event | 一个初始粒子及其所有次级粒子的全部输运历史 | 电视剧里的单集 |
| Track | 一个粒子(包括次级粒子)从诞生到消亡、或离开世界的连续轨迹 | 单集里某个角色的完整出场片段 |
| Step | 粒子在两次连续相互作用之间的一次移动 | 角色在片段中的某一个动作 |
举例说明:你运行了BeamOn(1000),这就是一个 Run,包含 1000 个事件。每个事件对应一个质子从束流源头出发,可能穿透屏蔽层,可能在屏蔽层中发生核反应产生次级粒子,这些粒子继续输运,直到能量耗尽或飞出边界。其中任意一个次级粒子的完整轨迹就是一个 Track,而它在两次相互作用之间的直线段就是 Step。
为什么初学者要理解这四个层级?因为 Geant4 的用户接口正是建立在这个分级之上的。你想在每次粒子进入探测器时做统计,就要重写SteppingAction或TrackingAction;你想在每次事件结束时记录数据,就要关注EventAction;你想统计整个 Run 的总剂量,就要在RunAction中做汇总。理解了这四个层级,代码中每个 Action 类的位置和作用就会非常清晰。
5.2 另一个关键抽象:几何构造中的 Logical Volume 和 Physical Volume
Geant4 建几何模型的方式,很多新手第一次看会很懵。它用到了三个层级:Solid(实体形状)、Logical Volume(逻辑体)、Physical Volume(物理体)。
- Solid:定义形状和尺寸。比如一个长方体,长宽高各多少。
- Logical Volume:在 Solid 基础上加入材料属性(比如铅、水、空气),还定义了是否包含场(磁场、电场等)。
- Physical Volume:把 Logical Volume 放置在某个具体位置和旋转角度,构成整个探测器系统。
类比来说:Solid 就像一块已经塑形的毛坯,Logical Volume 决定了毛坯用什么材料浇铸,而 Physical Volume 则是把这块材料真正放置到场景里的特定坐标上。同一个 Logical Volume 可以被多次放置成多个 Physical Volume,这在模拟探测器阵列时非常实用,不需要为每个探测器单独定义材料。
在 B1 示例的B1DetectorConstruction.cc里,你会看到大量构造 Volume 的代码。比如定义靶材料和屏蔽层材料、设定世界体积的大小、最后把探测器体积“放置”在世界中心。这部分代码是 Geant4 中最繁琐但也最可控的部分,后面几乎每个应用场景都要改写它。
5.3 物理列表:模拟的引擎
Geant4 并不会默认“什么过程都模拟”,一切粒子相互作用都要显式启用。物理列表(Physics List)就是一组物理过程和相关粒子定义的集合。它包含三部分内容:哪些粒子参与输运、粒子的能量范围、粒子与物质之间发生哪些相互作用(电离、轫致辐射、弹性散射、核反应等)。
对于初学者,我最常推荐的建议是:直接用官方预设好的“参考物理列表”,比如FTFP_BERT、QGSP_BIC等。这些列表经过充分验证,适用于绝大多数基础模拟场景。在 B1 示例中,物理列表通过B1ActionInitialization.cc中的某行代码设置,跑到 Day 05 之前,建议不要自己定义物理过程,先用参考列表跑通业务逻辑。
6. Day01 的坑,我替你踩过了
6.1 CMake 找不到 Geant4 模块
报错典型长这样:
CMake Error at CMakeLists.txt:30 (find_package): By not providing "FindGeant4.cmake" in CMAKE_MODULE_PATH this project asked for Geant4 to be found, but CMake did not find it.这个坑的根因几乎都是没有 sourcegeant4.sh,或者 source 的环境变量没有传递到当前终端。解决办法是:
source ~/geant4/install/bin/geant4.sh cd ~/geant4/workspace/B1/build cmake ..还有一个更隐蔽的原因:如果安装了多个版本的 Geant4,环境变量会指向旧版本,需要检查echo $Geant4_DIR是否指向预期的安装目录。
6.2 编译通过,但运行报错找不到动态库
运行./exampleB1时可能报错:
error while loading shared libraries: libG4globals.so: cannot open shared object file: No such file or directory这表示动态库搜索路径没有包含 Geant4 的 lib 目录。再次强调,先source ~/geant4/install/bin/geant4.sh,它会设置LD_LIBRARY_PATH。如果你已经写过.bashrc,那就重新打开终端或手动source ~/.bashrc一次。
6.3 可视化启动失败,黑屏或提示缺库
如果编译时启用了 Qt 可视化,但运行时界面一片黑或直接卡死,大概率是显卡驱动或 OpenGL 环境问题。Geant4 自带的 OpenGL 可视化基于libGL,在远程服务器上需要 X11 转发或者使用VirtualGL一类的工具。最简单稳妥的办法是:在.mac中把可视化驱动换成更稳定的离线渲染模式,比如用vis.mac中提供的/vis/open TG或/vis/open OGLSX来回切换测试。
我在第一次遇到黑屏时折腾了两个多小时,最后发现是远程连接时 OpenGL 上下文创建失败。如果本地有图形界面,基本不会遇到这个问题;如果是在服务器上学习,建议 Day01 先把批处理模式玩熟,可视化留到以后有桌面的环境再体验。
6.4 多个数据版本混杂导致运行报错
有时候你已经装了 Geant4 10.x,又装了 11.x,但数据文件目录G4LEDATA、G4RADIOACTIVEDATA还指向旧版本。运行时会报一些核数据版本不匹配的警告,甚至直接中断。解决办法是安装新版本前,彻底卸载旧版本,或者在.bashrc中清理旧的 Geant4 相关环境变量。
下面把常见问题整理成一张速查表:
| 现象 | 可能原因 | 解决动作 |
|---|---|---|
| cmake 找不到 Geant4 | 未 source 环境脚本 | source ~/geant4/install/bin/geant4.sh |
| 编译报缺头文件 | 缺少 X11/OpenGL 开发包 | 安装对应依赖库后重试 |
| 运行提示找不到 .so | 动态库路径未设置 | 重新进入终端或手动 source |
| 可视化黑屏 | 远程环境无 OpenGL 上下文 | 改用批处理模式或切换可视化驱动 |
| 离子核数据警告 | 数据目录指向旧版本 | 检查G4LEVELGAMMADATA等变量 |
7. 第一天的合理结束姿势
学 Geant4 最忌讳的是第一天就直奔“我要模拟一个 XX 实验”,然后卡在环境配置里自暴自弃。我认为合理的 Day01 结束标准只有三条:
第一,Geant4 已经成功编译并安装到本地,geant4-config --version能输出版本号。第二,exampleB1能在批处理模式下跑通,并输出统计结果。第三,你能用自己的话说出 Run、Event、Track、Step 之间的关系,能指出 B1 示例中哪个文件负责几何、哪个文件负责粒子源、哪个文件处理统计。
这三条看起来简单,但亲身做过一遍之后,你对 Geant4 的构建体系、执行流程、代码组织方式都会有切身感受,远比看十篇教程更有用。
至于接下来的学习路线,我的建议是分阶段推进:Day02 的重点是精读 B1 的四个核心类文件,理解DetectorConstruction里每个 Volume 的作用;Day03 开始动手修改几何——比如把屏蔽层换成水、改变探测器的尺寸,观察模拟结果变化;Day04 接触粒子源PrimaryGeneratorAction,学会自定义入射粒子的种类、能量和方向;Day05 再深入物理列表,使用不同的参考物理列表对比结果。每天一个小目标,每个目标都能立刻看到运行结果,这种正反馈会让你坚持更久。
我个人体会最深的一点是:学习 Geant4 最难的其实是克服前几天的“挫败感”。因为它的反馈链路太长了,从写代码到看到结果,中间要经历编译、链接、运行、分析,任何一个环节出错都会让你觉得“怎么这么难”。但你要知道,一旦你完整地经历过一遍“配置成功——编译成功——运行成功——统计合理”的闭环,后面所有的调试和修改都会变得有迹可循。你已经在跨越最难的那道门槛了,第二天继续就行。