Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# 构建与运行产物(不提交)
*.exe
*.lib
*.exp
*.obj
*.o
*.bin
*.nsys-rep
*.sqlite
# 脚本生成的数据(可用 generate_particles.py 重新生成)
data/particles_1k.txt
data/particles_10k.txt
22 changes: 3 additions & 19 deletions 09_particle_sim/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
## 简介
# 09_particle_sim

你是粒子对撞机项目的核心算法工程师,负责模拟粒子在加速器中的运动轨迹,以优化探测器布局和碰撞参数。对撞机每天产生海量粒子数据,但物理学家需要直观地看到粒子如何在磁场中偏转,以验证理论模型
带电粒子在磁场中的运动轨迹模拟(CUDA + Python 可视化)

你的任务是开发一个 GPU 加速的粒子追踪模拟器,能够并行计算数千个带电粒子在复杂磁场中的轨迹,并输出数据供 Python 可视化。最终,你将提供一个交互式 3D 动画,展示粒子束的螺旋运动、偏转和碰撞过程,帮助科学家理解实验现象。该模拟器将成为 “星环” 项目的重要设计工具。

## 任务内容
开发 CUDA 程序模拟粒子运动,并输出轨迹点供 Python 可视化。任务包括:
1. 解析输入文件,将粒子初始状态拷贝到 GPU。
2. 使用并行数值积分更新每个粒子的位置和速度。
3. 按指定间隔记录粒子位置到全局数组。
4. 将轨迹数据传输回主机,保存为文件。
5. 提供 Python 脚本读取数据并生成动态 3D 轨迹图。

## 📬 有疑问?

更多详细信息和要求请参考本季度项目文档。

可以在项目群里直接询问导师和助教!

Good luck and happy coding! 🚀
本选题提交见子目录 **nagadoyuji/**。
5 changes: 5 additions & 0 deletions 09_particle_sim/nagadoyuji/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Default clang-format style for CUDA/C++
BasedOnStyle: LLVM
IndentWidth: 4
ColumnLimit: 100
Language: Cpp
12 changes: 12 additions & 0 deletions 09_particle_sim/nagadoyuji/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# 构建与运行产物(不提交)
*.exe
*.lib
*.exp
*.obj
*.o
*.bin
*.nsys-rep
*.sqlite
# 脚本生成的数据(可用 generate_particles.py 重新生成)
data/particles_1k.txt
data/particles_10k.txt
25 changes: 25 additions & 0 deletions 09_particle_sim/nagadoyuji/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Particle simulation in uniform magnetic field (CUDA)
# Requires: CUDA Toolkit 11+, C++17

NVCC = nvcc
NVCCFLAGS = -std=c++17 -O2
TARGET = particle_sim

SRCS = main.cu
OBJS = main.o

.PHONY: all clean run format

all: $(TARGET)

$(TARGET): $(SRCS)
$(NVCC) $(NVCCFLAGS) -o $(TARGET) $(SRCS)

clean:
rm -f $(TARGET) $(OBJS) *.bin

run: $(TARGET)
./$(TARGET) data/particles.txt data/field.txt data/params.txt out.bin

format:
clang-format -i main.cu
46 changes: 46 additions & 0 deletions 09_particle_sim/nagadoyuji/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 09_particle_sim — nagadoyuji

带电粒子在磁场中的运动轨迹 CUDA 模拟,输出轨迹供 Python 3D 可视化。

- **作者 / 提交 ID**:nagadoyuji
- **总结报告**:[总结报告.md](总结报告.md)

## 快速开始

```bash
make
./particle_sim data/particles.txt data/field.txt data/params.txt out.bin
python visualize.py out.bin
```

## 目录说明

| 文件 | 说明 |
|------|------|
| main.cu | CUDA 主程序(解析、Boris 积分、记录、二进制输出) |
| Makefile | 构建(`make` / `make format` 格式化) |
| .clang-format | 代码格式配置 |
| data/ | 粒子、磁场、参数示例 |
| visualize.py | 3D 轨迹动画(Matplotlib FuncAnimation) |
| verify_single_particle.py | 单粒子回旋半径正确性验证 |
| generate_particles.py | 生成 1000 粒子等规模测试数据 |
| generate_B_grid.py | 生成 3D 磁场网格二进制文件 |

## 正确性验证

```bash
./particle_sim data/particles_1.txt data/field.txt data/params_verify.txt out.bin
python verify_single_particle.py out.bin data/particles_1.txt data/field.txt
```

## 规模测试(≥1000 粒子)

```bash
python generate_particles.py -n 1000 -o data/particles_1k.txt
./particle_sim data/particles_1k.txt data/field.txt data/params.txt out.bin
```

## 环境

- CUDA Toolkit 11+,C++17
- Python 3:numpy, matplotlib
1 change: 1 addition & 0 deletions 09_particle_sim/nagadoyuji/data/field.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0 0.0 1.0
3 changes: 3 additions & 0 deletions 09_particle_sim/nagadoyuji/data/params.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dt = 1e-10 # 时间步长(秒)
num_steps = 10000 # 总步数
record_interval = 100 # 每多少步记录一次位置
3 changes: 3 additions & 0 deletions 09_particle_sim/nagadoyuji/data/params_verify.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dt = 1e-12 # 较小步长便于验证
num_steps = 100000 # 多步
record_interval = 1000 # 每 1000 步记录
2 changes: 2 additions & 0 deletions 09_particle_sim/nagadoyuji/data/particles.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0.0 0.0 0.0 1.0e6 0.0 0.0 1.6e-19 9.1e-31
0.0 1.0 0.0 0.0 1.0e6 0.0 -1.6e-19 9.1e-31
1 change: 1 addition & 0 deletions 09_particle_sim/nagadoyuji/data/particles_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0 0.0 0.0 1.0e6 0.0 0.0 1.6e-19 9.1e-31
36 changes: 36 additions & 0 deletions 09_particle_sim/nagadoyuji/generate_B_grid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
"""Generate a binary B-field grid file for 3D grid mode.
Format: 3 int32 (nx,ny,nz), 3 float32 (ox,oy,oz), 3 float32 (dx,dy,dz),
then nx*ny*nz*3 float32 (Bx,By,Bz per cell, order i,j,k)."""
import struct
import argparse

def main():
ap = argparse.ArgumentParser()
ap.add_argument("-o", "--output", default="data/field_grid.bin")
ap.add_argument("--nx", type=int, default=4)
ap.add_argument("--ny", type=int, default=4)
ap.add_argument("--nz", type=int, default=4)
ap.add_argument("--ox", type=float, default=-0.01)
ap.add_argument("--oy", type=float, default=-0.01)
ap.add_argument("--oz", type=float, default=-0.01)
ap.add_argument("--dx", type=float, default=0.01)
ap.add_argument("--dy", type=float, default=0.01)
ap.add_argument("--dz", type=float, default=0.01)
ap.add_argument("--Bz", type=float, default=1.0)
args = ap.parse_args()
nx, ny, nz = args.nx, args.ny, args.nz
ox, oy, oz = args.ox, args.oy, args.oz
dx, dy, dz = args.dx, args.dy, args.dz
with open(args.output, "wb") as f:
f.write(struct.pack("iii", nx, ny, nz))
f.write(struct.pack("fff", ox, oy, oz))
f.write(struct.pack("fff", dx, dy, dz))
for k in range(nz):
for j in range(ny):
for i in range(nx):
f.write(struct.pack("fff", 0.0, 0.0, args.Bz))
print(f"Wrote grid {nx}x{ny}x{nz} to {args.output}")

if __name__ == "__main__":
main()
26 changes: 26 additions & 0 deletions 09_particle_sim/nagadoyuji/generate_particles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3
"""Generate particles.txt with N particles (default 1000) for scale testing."""
import argparse
import random

def main():
ap = argparse.ArgumentParser()
ap.add_argument("-n", "--num", type=int, default=1000, help="Number of particles")
ap.add_argument("-o", "--output", default="data/particles_1k.txt", help="Output path")
args = ap.parse_args()
random.seed(42)
with open(args.output, "w") as f:
for i in range(args.num):
x = random.uniform(-0.01, 0.01)
y = random.uniform(-0.01, 0.01)
z = random.uniform(-0.01, 0.01)
vx = random.uniform(-1e6, 1e6)
vy = random.uniform(-1e6, 1e6)
vz = random.uniform(-0.5e6, 0.5e6)
q = 1.6e-19 if i % 2 == 0 else -1.6e-19
m = 9.1e-31
f.write(f"{x} {y} {z} {vx} {vy} {vz} {q} {m}\n")
print(f"Wrote {args.num} particles to {args.output}")

if __name__ == "__main__":
main()
Loading