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:

Cross-section data (mono-energetic, cm-1)#

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_pellet where 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.