Moving Neutron Source#
Problem Description#
A time-dependent problem in which an isotropic neutron source moves through a three-dimensional box of air-like material along a prescribed piecewise-linear trajectory. This example demonstrates MC/DC’s moving-source capability.
Geometry and Materials#
The computational domain is a rectangular box: \(x \in [-5,5]\), \(y \in [-5,5]\), \(z \in [-10,10]\) cm, with vacuum boundary conditions on all faces.
A single homogeneous material (air analogue) fills the entire domain:
Region |
\(\Sigma_c\) |
\(\Sigma_s\) |
Air |
0.002 |
0.008 |
Neutron speed: \(v = 2 \times 10^{5}\) cm/s.
Physical Assumptions#
Mono-energetic (one-speed) neutron transport.
Isotropic scattering.
Time-dependent transport with a moving point-like source.
No fission.
Numerical Setup#
The source moves in three consecutive phases:
Phase |
Velocity (cm/s) |
Duration (s) |
1 |
\((1, 0, 0)\) |
7 |
2 |
\((-0.5,\; 2,\; 0)\) |
2 |
3 |
\((0,\; -3,\; 0)\) |
1 |
Spatial mesh (tally) |
\(201 \times 201\) in the \((x,y)\)-plane |
Time mesh (tally) |
46 equally spaced bins over \(t \in [0,10]\) s |
Tally score |
Scalar flux |
Source particles |
\(10^{5}\) |
Batches |
2 |
Quantities of Interest#
Time-resolved 2-D flux distribution \(\phi(x,y,t)\).
Animated GIF of the neutron cloud following the moving source.
Reference Solution#
No analytical reference. The solution is validated qualitatively by confirming that the flux maximum tracks the prescribed source trajectory.
Step-by-Step Walkthrough#
1. Materials (lines 1–15)
1import numpy as np
2
3import mcdc
4
5simulation = mcdc.Simulation("Moving source")
6
7# ======================================================================================
8# Set model
9# ======================================================================================
10
11# Set materials
12air = mcdc.Material.multigroup(
13 capture=np.array([0.002]),
14 scatter=np.array([[0.008]]),
15 speed=np.array([200000.0]),
A single air-like material with speed defined for time-dependent
transport.
2. Geometry (lines 17–27)
17
18# Set container cell surfaces
19min_x = mcdc.Surface.PlaneX(x=-5.0, boundary_condition="vacuum")
20max_x = mcdc.Surface.PlaneX(x=5.0, boundary_condition="vacuum")
21min_y = mcdc.Surface.PlaneY(y=-5.0, boundary_condition="vacuum")
22max_y = mcdc.Surface.PlaneY(y=5.0, boundary_condition="vacuum")
23min_z = mcdc.Surface.PlaneZ(z=-10.0, boundary_condition="vacuum")
24max_z = mcdc.Surface.PlaneZ(z=10.0, boundary_condition="vacuum")
25
26# Make cells
27cell = mcdc.Cell(region=+min_x & -max_x & +min_y & -max_y & +min_z & -max_z, fill=air)
A simple box with vacuum boundaries. One cell fills the entire domain.
3. Moving Source (lines 33–49)
33
34src = mcdc.Source(
35 x=[-4.0, -3.0],
36 y=[-0.5, 0.5],
37 z=[-0.5, 0.5],
38 direction=[1.0, 1.0, 0.0],
39 polar_cosine=[-1.0, -0.9],
40 energy=0,
41 time=[0.0, 10.0],
42)
43src.move(
44 velocities=[
45 [1.0, 0.0, 0.0],
46 [-0.5, 2.0, 0.0],
47 [0.0, -3.0, 0.0],
48 ],
49 durations=[7.0, 2.0, 1.0],
The source is created with spatial and angular extent, then src.move()
assigns a piecewise-linear trajectory: three velocity segments with their
durations. The source physically translates through the domain over time.
4. Tallies, Settings, and Run (lines 55–65)
55# ======================================================================================
56
57# Tallies
58mesh = mcdc.MeshStructured(
59 x=np.linspace(-5.0, 5.0, 201),
60 y=np.linspace(-5.0, 5.0, 201),
61)
62tally = mcdc.Tally(mesh=mesh, scores=["flux"], time=np.linspace(0, 10, 46))
63simulation.set_tallies([tally])
64
65# Settings
A structured \(201 \times 201\) mesh tally with 46 time bins captures
the evolving 2-D flux. The companion process-output.py script
generates an animated GIF.
What to try:
Change the velocity vectors to create a circular or zigzag path.
Add more time-resolution bins for smoother animation.
Compare with
moving_pelletwhere the geometry moves instead of the source.
Full Input#
Click here to view the input file: examples/moving_source/input.py.
The complete input used for this example is embedded below:
1import numpy as np
2
3import mcdc
4
5simulation = mcdc.Simulation("Moving source")
6
7# ======================================================================================
8# Set model
9# ======================================================================================
10
11# Set materials
12air = mcdc.Material.multigroup(
13 capture=np.array([0.002]),
14 scatter=np.array([[0.008]]),
15 speed=np.array([200000.0]),
16)
17
18# Set container cell surfaces
19min_x = mcdc.Surface.PlaneX(x=-5.0, boundary_condition="vacuum")
20max_x = mcdc.Surface.PlaneX(x=5.0, boundary_condition="vacuum")
21min_y = mcdc.Surface.PlaneY(y=-5.0, boundary_condition="vacuum")
22max_y = mcdc.Surface.PlaneY(y=5.0, boundary_condition="vacuum")
23min_z = mcdc.Surface.PlaneZ(z=-10.0, boundary_condition="vacuum")
24max_z = mcdc.Surface.PlaneZ(z=10.0, boundary_condition="vacuum")
25
26# Make cells
27cell = mcdc.Cell(region=+min_x & -max_x & +min_y & -max_y & +min_z & -max_z, fill=air)
28simulation.set_model([cell])
29
30# ======================================================================================
31# Set source
32# ======================================================================================
33
34src = mcdc.Source(
35 x=[-4.0, -3.0],
36 y=[-0.5, 0.5],
37 z=[-0.5, 0.5],
38 direction=[1.0, 1.0, 0.0],
39 polar_cosine=[-1.0, -0.9],
40 energy=0,
41 time=[0.0, 10.0],
42)
43src.move(
44 velocities=[
45 [1.0, 0.0, 0.0],
46 [-0.5, 2.0, 0.0],
47 [0.0, -3.0, 0.0],
48 ],
49 durations=[7.0, 2.0, 1.0],
50)
51simulation.set_sources([src])
52
53# ======================================================================================
54# Set tallies, settings, and run MC/DC
55# ======================================================================================
56
57# Tallies
58mesh = mcdc.MeshStructured(
59 x=np.linspace(-5.0, 5.0, 201),
60 y=np.linspace(-5.0, 5.0, 201),
61)
62tally = mcdc.Tally(mesh=mesh, scores=["flux"], time=np.linspace(0, 10, 46))
63simulation.set_tallies([tally])
64
65# Settings
66simulation.settings.N_particle = 100000
67simulation.settings.N_batch = 2
68
69# Run
70simulation.run()
How to Run#
From inside examples/moving_source run:
python input.py
Expected Output#
An HDF5 mesh tally with time-resolved 2-D flux slices and a GIF animation produced by the example’s post-processing script.