如果你是跟着“Ubuntu WSL2环境下从下载CORSIKA到跑通第一次模拟”这个需求点进来的,大概率已经知道CORSIKA是什么了:它全称是COsmic Ray SImulations for KAscade,是大气簇射蒙特卡洛模拟里绕不开的标准工具,KASCADE、KCDC以及不少宇宙线实验都在用它做参考基准。这篇文章我想用跑通一次真实模拟的完整过程,把从环境搭建、源码下载、编译到写输入卡、看结果这条路捋一遍。目标读者就是两类人:一是刚接触宇宙线物理、想在WSL2里跑一个最小例子验证流程的学生;二是做探测器模拟、急需拿到CORSIKA输出数据继续往下走的工程向选手。下面每一步都是我在Ubuntu 22.04 + WSL2环境里实际用过的方案,尽量把容易卡住的地方一并讲清楚。
1. 为什么要先选WSL2:CORSIKA 对运行环境到底有多挑
1.1 在 Windows 上直接跑 CORSIKA 的难点在哪里
CORSIKA 的经典版本是 Fortran 程序,官方发布的是 Linux 源码,你拿到 tar 包后要自己配置、编译、链接粒子物理模型库。虽然有一些第三方打包好的 Windows 可执行版,但版本老、模型不全,跑起来一旦出问题很难排查,因为你不知道编译时用了哪个模型、哪个Fortran编译选项。所以多数人最终都会回到 Linux 环境。
那有人会问:用 VMware 虚拟机或者直接装双系统不行吗?行,但 WSL2 在“复制粘贴命令—看到输出—改参数—再跑”这个循环里体验最好。虚拟机需要单独分配 CPU 和内存,图形界面要装增强工具,文件共享有时候还很别扭;双系统更麻烦,你只是为了跑个模拟不想每次重启切换系统。WSL2 本质上是一个轻量级虚拟机,但集成度做得高,Windows 和 Linux 文件可以互相访问,网络共享也做了处理,对跑 CORSIKA 这种命令行程序来说非常顺手。
1.2 WSL2 相比虚拟机和双系统的取舍
说句公道话,WSL2 不是完全没有代价。它是基于 Hyper-V 虚拟化平台的,第一次启用后可能需要重启;另外,如果你做的是需要用到 CUDA 的 GPU 加速任务,WSL2 虽然官方支持 NVIDIA CUDA,但配置复杂度明显高于纯 Linux 主机。CORSIKA 本身是 CPU 密集型的蒙特卡洛模拟,主要吃主频和内存带宽,GPU 不是必需,所以 WSL2 对它来说反而是很合适的环境。
如果你是 Windows 10 用户,请先确认系统版本在 2004 以上,并且 BIOS 里开启了虚拟化。装好之后我先跑一个简单的性能感受:我用一台 i5-12400、16GB 内存的机器,在 WSL2 里跑 10 个 10^4 到 10^5 GeV 的质子簇射,用时在几十秒量级,跟物理机上的体验没什么差别。但如果把数据放在 /mnt/c 下运行,速度会明显变慢,这个坑后面单独说。
1.3 安装 WSL2 与 Ubuntu 22.04 的具体操作
安装步骤不复杂,管理员权限打开 PowerShell 或 Windows Terminal,依次执行:
wsl --install wsl --install -d Ubuntu-22.04第一条命令会帮你启用需要的 Windows 功能并安装 WSL2 内核,第二条直接装 Ubuntu 22.04。装完重启,首次启动会让你设 Linux 用户名和密码。随后进入 Ubuntu 终端,先把包装源和基础工具刷新一遍:
sudo apt update && sudo apt upgrade -y我习惯顺手确认一下 WSL 版本,避免后面出现奇怪问题:
wsl -l -v看到 Ubuntu 那行的 VERSION 是 2 就没问题。如果显示 1,用wsl --set-version Ubuntu-22.04 2转一下。
2. CORSIKA 下载与版本选择
2.1 CORSIKA 到底是干什么的
在写下载步骤之前,我稍微解释一下它解决的问题。高能宇宙线进入大气层后会和原子核碰撞,产生一堆次级粒子,这些粒子继续碰撞或者衰变,形成一簇覆盖面很大的“空气簇射”。CORSIKA 就是用一个非常详细的蒙特卡洛模型逐粒子跟踪这个过程,从入射核子开始一路模拟到地面,输出每个粒子的种类、能量、位置、方向、到达时间等信息。
它的核心价值在于“逐粒子、分模型、可微调”:你可以选择不同的高能强子模型,比如 QGSJET-II-04、SIBYLL 2.3d、EPOS-LHC,也可以控制能量阈值、观测高度、大气模型、切伦科夫光输出等。这正好是 WSL2 这种命令行友好环境最擅长的场景:写一个输入卡,跑一遍,改参数,再跑一遍。
2.2 到哪里拿源码
CORSIKA 的官方发布站点是卡尔斯鲁厄理工学院(KIT)维护的页面,直接搜“CORSIKA KIT”就能找到。下载不是随意点击就能拿到,需要填写一个申请表格,写清楚单位、用途、所属研究组。审核通过后,官方会邮件回复一个带密码的下载链接。整个过程通常一两个工作日。
经历过的人都知道,这个流程对国内用户稍微有点考验:有时收件延迟,有时下载链接的服务器速度一般。我的建议是尽早提交申请,同时看下实验室有没有人保留过 7.74x 的包。需要注意,CORSIKA 的许可协议要求仅用于科研和教育,不能随便外传,所以我不建议在这里贴任何第三方下载链接,你自己从官方渠道申请最稳妥。
拿到 tar 包之后,文件名一般长这样:corsika-77400.tar.gz,7.74 对应 77400,7.75 对应 77500。解压:
mkdir -p ~/CORSIKA tar xvzf corsika-77400.tar.gz -C ~/CORSIKA cd ~/CORSIKA/corsika-774002.3 版本怎么选:7.x 与 8.x 的区别
经典路线选 7.x,也就是 CORSIKA 7.74 或 7.75。这类版本使用 configure + makefile 的构建方式,输入卡格式非常成熟,文档和网上资料最多,绝大多数后处理工具也是围绕 7.x 输出格式写的。第一次跑模拟,我强烈建议用 7.x。
CORSIKA 8 是官方新的模块化重写版本,用 C++17 和 CMake 构建,架构更清爽,也在持续增加新物理模型。但它迭代很快,接口还在变,很多人光是把 CORSIKA 8 编译出来就折腾了半天,更别提不同版本的输入参数经常对不上。如果你不是非要用某种新特性,现阶段别拿 8.x 做第一个项目。先把 7.x 跑通,理解了粒子数据流,再切换到 8 会轻松很多。
3. Ubuntu 侧依赖安装与目录规划
3.1 需要装哪些依赖包
CORSIKA 的编译器和库依赖并不多,Ubuntu 22.04 默认源里就能装齐。我一般先装这一套:
sudo apt install -y gfortran gcc g++ make sudo apt install -y libpng-dev libgsl-dev libx11-dev sudo apt install -y zlib1g-dev perl逐个说下用途:
- gfortran:CORSIKA 7.x 的粒子传输核心是 Fortran 写的,必须靠它编译。
- gcc / g++:部分辅助程序、接口工具和绘图相关组件需要 C/C++ 编译器。
- make:驱动整个编译流程。
- libpng-dev:生成绘图结果时需要写 PNG 文件。
- libgsl-dev:GNU 科学计算库,某些版本的可选功能会用到。
- libx11-dev:如果你的编译选项里包含了 X11 显示相关功能,需要这个头文件库。
- perl:configure 脚本和一些辅助工具会用到。
这里有个小提醒:Ubuntu 22.04 默认的 gfortran 是 11 版,对 CORSIKA 7.74 完全没问题。如果以后碰到老版本源码在较新 gfortran 下编译报错,优先想到-fno-range-check这类兼容性选项,不要一上来就想卸载重装。
3.2 目录规划与文件系统注意事项
WSL2 的 Linux 文件系统和 Windows 文件系统是分开放置的。你的 Linux 家目录在\\wsl$\Ubuntu-22.04\home\用户名\这样的隐藏位置,而 Windows 盘符挂载为/mnt/c、/mnt/d等。
CORSIKA 最好放在 Linux 文件系统里,也就是/home/用户名/xxx,不要图方便放到/mnt/c/Users/xxx下面。原因有两个:第一,drvfs 文件系统对符号链接、文件锁和权限的支持没有本地 ext4 那么自然,configure 过程会生成很多链接和脚本,在 /mnt/c 下容易出问题;第二,跨文件系统 I/O 性能差,蒙特卡洛程序要频繁写中间状态和输出文件,放在 /mnt/c 上可能比本地 Linux 目录慢一个数量级。我把源码放在~/CORSIKA/下,运行目录单独留一个run/,这样所有产物都在同一个地方,后续清理也方便。
mkdir -p ~/CORSIKA/corsika-77400/run/outrun/out目录是给模拟输出数据用的,后面写 OUTFILE 参数时会直接引用这个路径。
4. configure 到 make:真正把 CORSIKA 编译出来
4.1 configure 的工作原理
CORSIKA 7.x 的构建流程和很多经典 Fortran 程序类似:源码根目录下有一个configure脚本,它负责检测你系统里的编译器、是否安装了 X11、GSL、libpng,根据检测结果生成 makefile,然后把一份干净的运行目录复制到你指定的位置。
进入源码目录后,先看看帮助信息:
./configure --help不同小版本的选项有差异,但核心逻辑一致。我通常直接运行:
./configure运行过程中脚本会问一些问题,比如安装目录、要不要启用某些耦合输出、使用哪种强子模型。如果你不确定,全部回车用默认值即可。也可以用非交互方式指定前缀:
./configure --prefix=$HOME/CORSIKA/corsika-77400--prefix是最终可执行文件所在的位置。configure 结束后,源码目录里会多出一个makefile,同时会生成一个类似run的目录,里面放着一份默认输入卡default.input和一套编译好的可执行文件模板。这里稍微注意:不同版本复制出来的运行目录名字可能不同,有的叫run,有的直接在源码树里生成corsika目录,以实际输出为准。
4.2 编译几个模型库的产物
接下来就是经典的 make:
make -f makefile这条命令会把选定的模型库和 CORSIKA 主程序一起编译。具体编译哪些模型,取决于 configure 阶段的选项。比如选了 QGSJET-II-04 和 SIBYLL 2.3d,make 之后在 run 目录下通常能看到类似这些名字的文件:
corsika77400Linux_QGSII_gfortran corsika77400Linux_SIBYLL23_gfortran corsika77400Linux_QGSJETII_proton_gfortran命名规律一般是corsika版本_平台_模型_编译器。不同小版本和后缀命名不完全一致,但按这个规律去找不会错。
第一次 make 需要几分钟,因为要把强子模型的大段 Fortran 代码和主程序一起编译。看到类似Generation of CORSIKA program version 7.7400 successful的提示就说明成功了,然后去 run 目录里确认可执行文件存在。
ls -lh ~/CORSIKA/corsika-77400/run/4.3 编译报错怎么排查
如果 make 过程报错,最常见的是三类:
第一类,找不到编译器。报错信息里直接出现gfortran: command not found,这种就是前面依赖没装全,回 3.1 把包装上。
第二类,Fortran 语法兼容性问题。Ubuntu 22.04 的 gfortran 11 对语言标准检查比较严格,有些老代码会触发Error: Unclassifiable statement之类的错误。这时候可以给 configure 或 make 加上宽松选项。比如:
export FCFLAGS="-ffixed-line-length-none -fno-range-check" ./configure make -f makefile这是我对付老 Fortran 程序最常用的组合拳。-ffixed-line-length-none允许固定格式源码行长度超过 72 字符,-fno-range-check允许比如sqrt(-0.0)这类不影响实际结果的数值检查通过。
第三类,链接阶段缺少数学库、png 库。报错末尾通常会有undefined reference to字样,顺着末尾去补对应的 dev 包即可。
5. 编写第一个输入卡并跑通模拟
5.1 输入卡参数逐行说明
CORSIKA 的输入文件是纯文本,扩展名随意,我习惯叫proton10.inp。每一行一个关键词加若干参数。下面这个例子是我在一个 7.74 版本上实际跑通过的最小配置,模拟 10 个能量在 10^4 到 10^5 GeV 范围内的垂直入射质子:
RUNNR 1 EVTNR 1 NSHOW 10 PRMPAR 14 ESLOPE -2.0 ERANGE 1.E+04 1.E+05 THETAP 0. 0. PHIP 0. 0. ECUTS 0.3 0.3 0.3 0.3 ATMOD 1 SEED 1 0 0 SEED 2 0 0 SEED 3 0 0 SEED 4 0 0 SEED 5 0 0 SEED 6 0 0 OUTFILE /home/你的用户名/CORSIKA/corsika-77400/run/out/proton10.dat逐行解释:
RUNNR:这次运行的编号,输出文件里会用它做标识,默认 1。EVTNR:起始事件号,跟 RUNNR 配合使用,一般也是 1。NSHOW:模拟多少个簇射。我建议第一次只跑 10,目的就是验证流程,别一上来就 5000 个。PRMPAR:入射粒子类型。14 是质子,如果你是氦核或铁核要换对应代码,最常见的几个是 1=gamma、14=proton、56=iron。ESLOPE:能谱指数。CORSIKA 会按你指定的谱型抽取能量,这里 -2.0 表示平坦一点;如果你只要离散能量点,可以研究ERANGE配合能量抽样模式,但第一次不用管那么多。ERANGE:能量范围下限和上限,单位 GeV。1.E+04 到 1.E+05 对 WSL2 来说是安全选择,既能体现簇射过程,又不会慢到怀疑人生。THETAP:天顶角范围和抽样,单位度。0. 0.表示固定垂直入射。PHIP:方位角范围和抽样。0. 0.表示固定。ECUTS:能量截断阈值,四个数分别是 e+、e-、gamma、mu 的截断能量,单位 GeV。0.3 是常用经验值,低于这个能量的粒子不再往下跟踪。ATMOD:大气模型,1 表示美国标准大气,也是最常用的默认选项。SEED:随机数种子。CORSIKA 允许很多个SEED行,分别对应强子相互作用、衰变、底强子截面等不同的随机流。第二三个数一般写成0 0,第一个数每个 SEED 必须不同,否则粒子流高度相关。OUTFILE:二进制输出文件路径。记得把路径里的“你的用户名”换成实际值,而且确保run/out目录已经存在。
5.2 实际运行与判断成功的方法
把输入文件放到 run 目录,然后执行可执行文件,把输入重定向进去:
cd ~/CORSIKA/corsika-77400/run ./corsika77400Linux_QGSII_gfortran < proton10.inp程序启动后会打印一连串初始化信息,包括大气模型参数、能量范围、粒子种类、随机数种子等。接着开始逐事件模拟。10 个质子在这个能量区间通常很快,可能半分钟左右就结束了。如果想看耗时,加time:
time ./corsika77400Linux_QGSII_gfortran < proton10.inp跑完怎么判断成功了?我的方法是看三处:
一是终端有没有出现 Fortran runtime error、Segmentation fault、STOP这类中断信息。正常的结尾会输出类似“end of run”和 CPU 时间统计的段。
二是检查 OUTFILE 指定的文件是否生成:
ls -lh ~/CORSIKA/corsika-77400/run/out/proton10.dat文件体积在几十 KB 到几百 KB 之间通常就说明有数据。
三是看跑完的事件数是不是你输入的 NSHOW。如果只跑了 3 个就退出,多半是随机数种子或者能量抽样设置有问题,可以回头检查 SEED 行。
5.3 输出文件和后续读取
CORSIKA 的二进制输出格式不是简单的 CSV,里面有事件头、粒子记录、运行结尾标记等结构。用记事本打开是乱码,这正常。后续处理一般有以下几种方式:
- 用 CORSIKA 自带的读数据例程去解析二进制流,官方源码里能找到读文件模板;
- 转换成 ROOT 文件后用 ROOT 分析;
- 先用
corsika前处理工具把二进制输出转成你需要的文本格式。
第一次跑通后,我建议先确认“有文件生成”这件事本身,暂时别急着解析全部粒子。你可以用hexdump -C proton10.dat | head看一眼文件头,看到非全零的内容就行。等你需要做纵向发展曲线、地面粒子分布、Cherenkov 光子输出时,再来针对具体 OUTFILE 格式写解析器。
6. WSL2 图形显示:给后处理程序一个 X11 环境
6.1 CORSIKA 本体不需要图形,但后处理可能要
CORSIKA 的主模拟阶段是纯命令行,不需要窗口环境。但跑完之后很多人想画个簇射纵向发展图、粒子横向分布图,如果用到经典 X11 风格的可视化工具,或者你想在 WSL2 里跑一些别的 Linux 图形软件,就需要一个 X Server。
最新版的 Windows 11 自带 WSLg,Linux GUI 程序可以直接弹出窗口,一般不用额外配置。但不少 Windows 10 用户或特殊构建的 WSL2 环境没有 WSLg,这时推荐用 VcXsrv 来补一个 X Server。
我不建议以“让 CORSIKA 自带一个图形界面”为目标,因为它本来就没有这种界面。图形显示主要用于数据可视化环节,比如临时用 Python 画图时需要一个 Qt 后端,或者用 xool、ROOT 的 TBrowser 看数据。配置好 X11 后这些都能用。
6.2 实际配置步骤
Windows 侧安装 VcXsrv,一路默认。启动 XLaunch 时,注意几个选项:
- Display settings 选 Multiple windows;
- Select how to start clients 选 Start no client;
- 勾选 Disable access control,否则连接时经常被拒绝。
在 Ubuntu 侧设置显示地址。WSL2 里最简单的方式是直接用 :0:
export DISPLAY=:0为了测试是否生效,先安一个小工具:
sudo apt install -y x11-apps xeyes如果屏幕上出现一个跟着鼠标转的眼睛,说明 X11 通道已经通了。要是:0连不上,可以试试把宿主机 IP 填进去。在 Ubuntu 里查看:
ip route | grep default cat /etc/resolv.conf | grep nameserver有些版本需要用 nameserver 那个地址作为 DISPLAY,类似:
export DISPLAY=192.168.x.x:0.0每次新开终端都要重新 export 很烦,可以在~/.bashrc末尾加一行export DISPLAY=:0,然后source ~/.bashrc。
配置结束后,再启动你的可视化后处理工具就不会报cannot connect to X server了。
7. 实操中比较常见的坑:编译期和运行期
7.1 文件系统带来的坑
我在前面反复强调源码和运行目录不要放 /mnt/c,这不是玄学,是我踩过的坑。有一次我把整个 CORSIKA 解压到 Windows 桌面,configure 一切正常,但 make 时总报permission denied或者符号链接创建失败。原因就是 drvfs 对 Linux 符号链接的支持不一致,Fortran 编译过程要生成的 Mod 文件也会受文件锁机制影响,时好时坏。
如果你已经报错了,不要犹豫,直接拷贝回 Linux 目录重新 configure 一遍,正常情况下能省下很多排查时间。接收文件可以用:
cp -r /mnt/c/Users/xxx/Desktop/corsika-77400 ~/CORSIKA/删掉源码目录里之前残留的 makefile 和编译中间产物再重新走流程。
7.2 Fortran 与编译宏的坑
Ubuntu 22.04 的 gfortran 11 对老代码比较“严格”,编译时会报一些标准不匹配的问题。除了前面提的FCFLAGS,还有一个小技巧是在 configure 之前清空环境,避免你之前 export 过乱七八糟的变量:
unset FC F77 FFLAGS FCFLAGS如果你要换不同版本的 gfortran,还可以装:
sudo apt install -y gfortran-10然后用:
./configure --with-fortran=/usr/bin/gfortran-10但注意 configure 是否支持这个参数要看版本,不支持的话就用FC=/usr/bin/gfortran-10 ./configure的方式临时指定。
7.3 模拟运行效率的坑
第一次跑模拟最容易犯的错误是参数给太大。有人直接把 ERANGE 写到 10^8 GeV,还跑 5000 个事件,在 WSL2 里跑了一个多小时没结束,还以为是程序卡死了。实际上高能量簇射粒子数会指数级膨胀,计算量暴增非常明显。
我的建议是从小到大测试:
- 先跑 10 个事件,能量 10^4 到 10^5 GeV,验证流程;
- 再跑 100 个事件,看文件输出速度和体积;
- 最后再按物理需求逐步放开能量范围、天顶角范围和事件数。
另外,WSL2 默认会占用你 Windows 一半内存,但实际可用内存不够时,它会启动回收机制。你可以自己在 Windows 用户目录下建一个.wslconfig文件,限制 WSL2 的资源,比如:
[wsl2] memory=8GB processors=4 swap=2GB改完在 PowerShell 里执行wsl --shutdown再重新进 Ubuntu 生效。这样能避免 WSL2 把宿主机内存占满,也可以在内存充足时给模拟预留更多空间。
7.4 随机数种子引发的结果重复
CORSIKA 对随机数种子非常敏感,多个 SEED 行之间第一个参数不能重复。我以前偷懒把所有 SEED 都写成1 0 0,结果跑出来的簇射高度相关,数据完全不能用。正确做法是让每个 SEED 互不相同,比如1 0 0、2 0 0、3 0 0这样依次递增。想做可重复实验时记录下这次输入卡,下次跑同样的 SEED 就能复现同一条随机流。
最后再分享一个我的运行习惯:每次模拟的输入卡命名不要用input.txt这种无意义名字,改成p_1e4_1e5_th0_10evt.inp这种能自解释的文件名,输出文件也按事件和能量归档。CORSIKA 的输入卡本身不长,但等你要跑几十组参数扫谱时,一个清晰的文件命名体系能帮你省掉大量找文件的时间。
我现在跑 CORSIKA 基本就在这个 WSL2 环境里进行,日常也不需要额外开虚拟机。先把这条“下载-编译-跑通-出数据”的最小链路打通,后面无论切换到 ROOT 分析、做切伦科夫光模拟,还是升级到 CORSIKA 8,都是在它基础上继续加东西。如果你在跑通的路上卡住了,回看一下第 4 节和第 7 节的报错场景,大部分问题都能在那里找到答案。