mcdc.Source#

class mcdc.Source(name: str = '', position: Sequence[float] | None = None, x: Sequence[float] | None = None, y: Sequence[float] | None = None, z: Sequence[float] | None = None, direction: Sequence[float] | None = None, white_direction: Sequence[float] | None = None, isotropic: bool | None = None, polar_cosine: Sequence[float] | None = None, azimuthal: Sequence[float] | None = None, energy: float | ArrayLike | int | None = None, discrete_energy: ArrayLike | None = None, time: ArrayLike = 0.0, particle_type: str = 'neutron', probability: float = 1.0)#

Distributions of particles introduced into the simulation.

A source specifies the position, direction, energy, time, particle type, and relative sampling probability for emitted particles.

Parameters:
  • name (str, optional) – User label. If omitted, a default name is generated from the source ID.

  • position (array_like of float, optional) – Point-source position [x, y, z] in cm. If provided, the source is treated as a point source. Cannot be supplied with x, y, or z.

  • x (array_like of float, optional) – Spatial bounds of a box source in cm, given as [min, max] for each coordinate. Cannot be supplied with position.

  • y (array_like of float, optional) – Spatial bounds of a box source in cm, given as [min, max] for each coordinate. Cannot be supplied with position.

  • z (array_like of float, optional) – Spatial bounds of a box source in cm, given as [min, max] for each coordinate. Cannot be supplied with position.

  • direction (array_like of float, optional) –

    Source direction vector [ux, uy, uz]. The vector is normalized internally. If provided without angular bounds, the source is mono-directional. Cannot be supplied with isotropic=True or white_direction.

    When polar_cosine and/or azimuthal are specified, this vector defines the reference (polar) axis about which directions are sampled.

  • white_direction (array_like of float, optional) – Outward normal direction for a white boundary source. The vector is normalized internally. Cannot be supplied with isotropic=True or direction.

  • isotropic (bool, optional) – If True, emit particles isotropically. Cannot be supplied with direction or white_direction.

  • polar_cosine (array_like of float, optional) – Bounds for the sampled polar cosine, [mu_min, mu_max], measured with respect to direction. Requires direction. Defaults to [-1.0, 1.0].

  • azimuthal (array_like of float, optional) – Bounds for the sampled azimuthal angle, [azi_min, azi_max] in radians, measured about direction. Requires direction. Defaults to [0.0, 2π].

  • energy (float, array_like of float, or int, optional) – Source energy in eV. A real scalar, including a NumPy scalar, defines a mono-energetic source. An array-like value with shape (2, N) defines a tabulated distribution: the first row contains energy values and the second row contains their probability density in eV^-1. Defaults to a mono-energetic source at 1 MeV. In standard neutron multigroup transport, an integer conventionally specifies a group-coordinate energy and is stored internally as a float. The coordinate must identify an available group. Continuous energy distributions are not supported in standard multigroup transport.

  • discrete_energy (array_like of float, optional) – Discrete source-energy distribution with shape (2, N). The first row contains sampled energy values and the second row contains their probabilities. Values are physical energies in eV for continuous-energy transport and group-coordinate energies for standard multigroup transport. Standard-multigroup coordinates must be integer-valued and identify available groups. Cannot be supplied with energy.

  • time (real or array_like of float, optional) – Emission time in seconds. A real scalar, including a NumPy scalar, defines a discrete emission time. An array-like value with shape (2,) defines a uniform interval [t_min, t_max]. Defaults to 0.0.

  • particle_type ({"neutron", "electron", "proton"}, optional) – Type of emitted particle. Defaults to "neutron".

  • probability (float, optional) – Relative source probability weight. Defaults to 1.0.

Notes

position and the box bounds x, y, and z are alternative spatial specifications and cannot be combined.

When position is not provided, the source is treated as a box source. Any unspecified coordinate range defaults to [0.0, 0.0] cm. For example, if only z=[-1.0, 1.0] is specified, then the source occupies x=[0.0, 0.0], y=[0.0, 0.0], and z=[-1.0, 1.0].

isotropic=True, direction, and white_direction are alternative angular specifications and cannot be combined. polar_cosine and azimuthal describe an angular spread about direction and therefore require it. If no angular specification is provided, the source is isotropic.

Examples

Point source at the origin emitting mono-energetic neutrons isotropically:

>>> import numpy as np
>>> import mcdc
>>> src = mcdc.Source(position=[0.0, 0.0, 0.0], isotropic=True)

Uniform box source distributed along z:

>>> src = mcdc.Source(
...     z=[-1.0, 1.0],
...     isotropic=True,
...     energy=1.0e6,
... )

The unspecified x and y ranges default to [0.0, 0.0] cm.

Rectangular volume source:

>>> src = mcdc.Source(
...     x=[-1.0, 1.0],
...     y=[-2.0, 2.0],
...     z=[0.0, 5.0],
...     isotropic=True,
... )

Mono-directional source:

>>> src = mcdc.Source(
...     position=[0.0, 0.0, 0.0],
...     direction=[0.0, 0.0, 1.0],
... )

Directional source with angular spread:

>>> src = mcdc.Source(
...     direction=[0.0, 0.0, 1.0],
...     polar_cosine=[0.8, 1.0],
...     azimuthal=[0.0, np.pi / 2],
... )

Sample discrete emission lines in a continuous-energy calculation:

>>> decay_electrons = mcdc.Source(
...     particle_type="electron",
...     discrete_energy=(
...         [1.0e5, 2.0e5],
...         [0.8, 0.2],
...     ),
... )

Sample a continuous-energy source from a tabulated probability density:

>>> electron_source = mcdc.Source(
...     particle_type="electron",
...     energy=np.array([
...         [9_999.0, 10_001.0],
...         [0.5, 0.5],
...     ]),
...     direction=[0.0, 0.0, 1.0],
... )

Sample between groups 0 and 1 in standard multigroup transport:

>>> multigroup_source = mcdc.Source(
...     discrete_energy=(
...         [0.0, 1.0],
...         [0.25, 0.75],
...     ),
... )

Time-dependent source:

>>> src = mcdc.Source(
...     time=[0.0, 1.0e-3],
... )
move(velocities: ArrayLike, durations: ArrayLike) None#

Define piecewise-constant motion for the source.

The source moves through a sequence of constant-velocity segments. Each segment is defined by a velocity vector and its duration. After the last segment, a final static segment with zero velocity and infinite duration is appended automatically so that the source position remains well-defined for the remainder of the simulation.

Parameters:
  • velocities (array_like of float, shape (N, 3)) – Velocity vector [vx, vy, vz] in cm/s for each motion segment.

  • durations (array_like of float, shape (N,)) – Duration of each motion segment in seconds. Must contain the same number of entries as velocities.

Notes

This method

  • enables source motion by setting moving=True;

  • constructs the internal time grid (move_time_grid);

  • computes the cumulative translation at the end of each segment (move_translations);

  • appends a final static segment with zero velocity and infinite duration.

The resulting number of motion segments is len(durations) + 1.

Examples

Move a source upward at 1 cm/s for 0.5 s, then keep it stationary:

>>> src = mcdc.Source(
...     z=[-0.1, 0.1],
...     isotropic=True,
...     energy=1.0e6,
...     time=[0.0, 1.0],
... )
>>> src.move(
...     velocities=[[0.0, 0.0, 1.0]],
...     durations=[0.5],
... )
>>> src.N_move
2

Piecewise motion with two segments:

>>> src.move(
...     velocities=[
...         [1.0, 0.0, 0.0],
...         [0.0, 1.0, 0.0],
...     ],
...     durations=[0.5, 1.0],
... )