OpenMC Guide
Cross Sections
Understanding Cross Sections
Nuclear cross sections represent the probability of neutron interactions with atomic nuclei. Think of them as effective target areas - larger cross sections mean higher interaction probabilities. OpenMC uses these data to determine what happens when neutrons encounter different materials.
Cross sections vary dramatically with neutron energy and depend on the specific nuclide and reaction type. Understanding this behavior is crucial for accurate reactor modeling, which is why OpenMC uses continuous-energy data rather than simplified group averages.
Main Reaction Types
- Absorption: Neutron disappears (fission, capture)
- Scattering: Neutron changes direction/energy
- Fission: Nucleus splits, produces new neutrons
- Total: Sum of all possible interactions
Key Properties
- Units: barns (10⁻²⁴ cm²)
- Energy-dependent (thermal to fast)
- Temperature-dependent (Doppler effect)
- Isotope-specific
Nuclear Data Libraries
OpenMC requires nuclear data files that contain cross section information for all nuclides in your model. These libraries are based on evaluated nuclear data like ENDF/B-VIII.0 and are processed into HDF5 format for efficient access.
Getting Nuclear Data
# Download recommended nuclear data (one-time setup)
import openmc.data
openmc.data.download_endf_data(release='endfb80_hdf5')
# Downloads ENDF/B-VIII.0 data (~1.5 GB) into ~/.local/share/openmcUsing Custom Data Libraries
# Point to a specific cross sections file
import openmc
# Set cross sections path for all materials
openmc.config['cross_sections'] = '/path/to/cross_sections.xml'
# Or set for specific materials
materials = openmc.Materials()
materials.cross_sections = '/path/to/cross_sections.xml'
# Check what's available
print(f"Using cross sections: {openmc.config['cross_sections']}")Data Requirements: Every nuclide in your materials must have corresponding cross section data. OpenMC will tell you if any data is missing when you run a simulation.
Temperature Effects
Cross sections change with temperature due to thermal motion of nuclei (Doppler broadening). This effect is most important for resonance reactions and significantly impacts reactor physics calculations.
Basic Temperature Handling
# Set material temperature
fuel = openmc.Material(name='Hot Fuel')
fuel.set_density('g/cm3', 10.4)
fuel.add_nuclide('U235', 0.045)
fuel.add_nuclide('U238', 0.955)
fuel.add_element('O', 2.0)
fuel.temperature = 900 # Kelvin
# OpenMC will interpolate cross sections to this temperature
# (if data is available at multiple temperatures)Multiple Temperature Points
# Material with temperature-dependent data
hot_fuel = openmc.Material(name='Variable Temperature Fuel')
hot_fuel.set_density('g/cm3', 10.4)
hot_fuel.add_nuclide('U235', 0.045)
hot_fuel.add_nuclide('U238', 0.955)
hot_fuel.add_element('O', 2.0)
# Specify multiple temperatures for interpolation
hot_fuel.temperatures = [600, 900, 1200] # K
# Configure simulation temperature handling
settings = openmc.Settings()
settings.temperature = {
'method': 'interpolation', # or 'nearest'
'multipole': True # Use windowed multipole data if available
}Temperature effects are particularly important for U-238 resonance absorption and fuel Doppler feedback calculations. Proper temperature modeling can significantly impact calculated reactivity and safety parameters.
Thermal Scattering
For materials containing light nuclei (like hydrogen in water), thermal neutron scattering is affected by molecular binding. OpenMC uses S(α,β) thermal scattering data to account for these effects accurately.
# Water with thermal scattering (essential for accuracy)
water = openmc.Material(name='Light Water')
water.set_density('g/cm3', 1.0)
water.add_nuclide('H1', 2.0)
water.add_element('O', 1.0)
water.add_s_alpha_beta('c_H_in_H2O') # Critical for thermal neutrons
# Graphite moderator
graphite = openmc.Material(name='Graphite')
graphite.set_density('g/cm3', 1.7)
graphite.add_element('C', 1.0)
graphite.add_s_alpha_beta('c_Graphite')
# Available thermal scattering data:
# c_H_in_H2O - hydrogen in water
# c_Graphite - graphite
# c_Be - beryllium metal
# c_BeO - beryllium oxide
# ... and others in your nuclear data libraryCritical for Accuracy: Always include thermal scattering data for water, graphite, and other light-nucleus materials. Omitting this data can lead to significant errors in thermal neutron calculations.
Working with Cross Section Data
OpenMC provides tools to examine and understand cross section data programmatically. This is useful for validation, education, and understanding your simulation physics.
Basic Data Inspection
import openmc.data
import numpy as np
import matplotlib.pyplot as plt
# Load cross section data for a nuclide
u235_path = '/path/to/nuclear/data/U235.h5'
u235 = openmc.data.IncidentNeutron.from_hdf5(u235_path)
# Pick one of the available temperature evaluations (K)
temp = sorted(u235.temperatures)[0]
u235_data = u235[temp]
# Examine available reactions
print("Available reactions for U-235:")
for mt, rxn in u235.reactions.items():
print(f" MT {mt}: {rxn}")
# Plot total cross section vs energy
energies = np.logspace(-2, 7, 1000) # 0.01 eV to 10 MeV
total_xs = u235_data.xs['total'](energies)
plt.figure(figsize=(10, 6))
plt.loglog(energies, total_xs, 'b-', linewidth=2)
plt.xlabel('Energy (eV)')
plt.ylabel('Cross Section (barns)')
plt.title('U-235 Total Cross Section')
plt.grid(True, which='both', alpha=0.3)
plt.show()
# Check cross section at specific energy
thermal_energy = 0.0253 # eV (thermal)
fast_energy = 1e6 # eV (1 MeV)
print(f"U-235 total XS at thermal: {u235_data.xs['total'](thermal_energy):.1f} barns")
print(f"U-235 total XS at 1 MeV: {u235_data.xs['total'](fast_energy):.1f} barns")Understanding Cross Section Behavior
# Compare different nuclides
u235 = openmc.data.IncidentNeutron.from_hdf5('/path/to/U235.h5')
u238 = openmc.data.IncidentNeutron.from_hdf5('/path/to/U238.h5')
energies = np.logspace(-2, 7, 1000)
# Use the coldest temperature evaluation for each nuclide
u235_data = u235[sorted(u235.temperatures)[0]]
u238_data = u238[sorted(u238.temperatures)[0]]
plt.figure(figsize=(12, 8))
# Fission cross sections
plt.subplot(2, 2, 1)
u235_fission = u235_data.xs['fission'](energies)
plt.loglog(energies, u235_fission, 'r-', label='U-235')
plt.xlabel('Energy (eV)')
plt.ylabel('Fission XS (barns)')
plt.title('Fission Cross Sections')
plt.legend()
plt.grid(True)
# Absorption cross sections
plt.subplot(2, 2, 2)
u235_abs = u235_data.xs['absorption'](energies)
u238_abs = u238_data.xs['absorption'](energies)
plt.loglog(energies, u235_abs, 'r-', label='U-235')
plt.loglog(energies, u238_abs, 'b-', label='U-238')
plt.xlabel('Energy (eV)')
plt.ylabel('Absorption XS (barns)')
plt.title('Absorption Cross Sections')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
# This helps explain why U-235 is fissile and U-238 has strong resonancesPractical Tips
Here are essential tips for working effectively with cross sections in OpenMC:
Data Management
- Start Simple: Use the default ENDF/B-VIII.0 data for most applications
- Check Coverage: Ensure your data library includes all nuclides in your materials
- Temperature Consistency: Use appropriate temperatures for your operating conditions
- Thermal Scattering: Always include S(α,β) data for light-nucleus materials
Common Issues
# Check for missing cross section data
try:
model = openmc.Model(geometry, materials, settings)
model.run()
except Exception as e:
if "does not contain cross sections" in str(e):
print("Missing nuclear data - check your cross_sections.xml")
print("Missing nuclide:", str(e).split("'")[1])
else:
raise e
# Verify thermal scattering is included
for material in materials:
if 'H1' in material.nuclides:
if not material.sab:
print(f"Warning: {material.name} contains H1 but no S(a,b) data")
# Check temperature coverage
print("Material temperatures:")
for material in materials:
if material.temperature:
print(f" {material.name}: {material.temperature} K")Cross sections are the foundation of accurate neutron transport calculations. Understanding their behavior and proper usage is essential for reliable reactor physics analysis with OpenMC.