Merge branch 'develop' into local-photon-heating

This commit is contained in:
Paul Romano 2019-09-16 11:00:33 -05:00
commit 348dd74dcc
35 changed files with 344 additions and 328 deletions

View file

@ -336,7 +336,7 @@ set_target_properties(
add_custom_command(TARGET libopenmc POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:libopenmc>
${CMAKE_CURRENT_SOURCE_DIR}/openmc/capi/$<TARGET_FILE_NAME:libopenmc>
${CMAKE_CURRENT_SOURCE_DIR}/openmc/lib/$<TARGET_FILE_NAME:libopenmc>
COMMENT "Copying libopenmc to Python module directory")
#===============================================================================

View file

@ -1,17 +1,17 @@
.. _capi:
=====
C API
=====
=========
C/C++ API
=========
The libopenmc shared library that is built when installing OpenMC exports a
number of C interoperable functions and global variables that can be used for
in-memory coupling. While it is possible to directly use the C API as documented
here for coupling, most advanced users will find it easier to work with the
Python bindings in the :py:mod:`openmc.capi` module.
in-memory coupling. While it is possible to directly use the C/C++ API as
documented here for coupling, most advanced users will find it easier to work
with the Python bindings in the :py:mod:`openmc.lib` module.
.. warning:: The C API is still experimental and may undergo substantial changes
in future releases.
.. warning:: The C/C++ API is still experimental and may undergo substantial
changes in future releases.
----------------
Type Definitions

View file

@ -1,8 +1,8 @@
--------------------------------------------------
:mod:`openmc.capi` -- Python bindings to the C API
--------------------------------------------------
------------------------------------------------------
:mod:`openmc.lib` -- Python bindings to the C/C++ API
------------------------------------------------------
.. automodule:: openmc.capi
.. automodule:: openmc.lib
Functions
---------

View file

@ -81,6 +81,8 @@ Python API Changes
:func:`openmc.model.rectangular_prism`.
- The ``get_hexagonal_prism`` function has been renamed
:func:`openmc.model.hexagonal_prism`.
- Python bindings to the C/C++ API have been move from ``openmc.capi`` to
:mod:`openmc.lib`.
---------
Bug Fixes

View file

@ -22,7 +22,7 @@ import numpy as np
from scipy import sparse
import h5py
import openmc.capi
import openmc.lib
from openmc.checkvalue import (check_type, check_length, check_value,
check_greater_than, check_less_than)
from openmc.exceptions import OpenMCError
@ -701,7 +701,7 @@ class CMFDRun(object):
----------
**kwargs
All keyword arguments are passed to
:func:`openmc.capi.run_in_memory`.
:func:`openmc.lib.run_in_memory`.
"""
with self.run_in_memory(**kwargs):
@ -726,7 +726,7 @@ class CMFDRun(object):
Parameters
----------
**kwargs
All keyword arguments passed to :func:`openmc.capi.run_in_memory`.
All keyword arguments passed to :func:`openmc.lib.run_in_memory`.
"""
# Store intracomm for part of CMFD routine where MPI reduce and
@ -737,7 +737,7 @@ class CMFDRun(object):
self._intracomm = MPI.COMM_WORLD
# Run and pass arguments to C API run_in_memory function
with openmc.capi.run_in_memory(**kwargs):
with openmc.lib.run_in_memory(**kwargs):
self.init()
yield
self.finalize()
@ -759,7 +759,7 @@ class CMFDRun(object):
def init(self):
""" Initialize CMFDRun instance by setting up CMFD parameters and
calling :func:`openmc.capi.simulation_init`
calling :func:`openmc.lib.simulation_init`
"""
# Configure CMFD parameters and tallies
@ -780,10 +780,10 @@ class CMFDRun(object):
self._initialize_linsolver()
# Initialize simulation
openmc.capi.simulation_init()
openmc.lib.simulation_init()
# Set cmfd_run variable to True through C API
openmc.capi.settings.cmfd_run = True
openmc.lib.settings.cmfd_run = True
def next_batch(self):
""" Run next batch for CMFDRun.
@ -799,29 +799,29 @@ class CMFDRun(object):
self._cmfd_init_batch()
# Run next batch
status = openmc.capi.next_batch()
status = openmc.lib.next_batch()
# Perform CMFD calculation if on
if self._cmfd_on:
self._execute_cmfd()
# Write CMFD output if CMFD on for current batch
if openmc.capi.master():
if openmc.lib.master():
self._write_cmfd_output()
# Write CMFD data to statepoint
if openmc.capi.is_statepoint_batch():
if openmc.lib.is_statepoint_batch():
self.statepoint_write()
return status
def finalize(self):
""" Finalize simulation by calling
:func:`openmc.capi.simulation_finalize` and print out CMFD timing
:func:`openmc.lib.simulation_finalize` and print out CMFD timing
information.
"""
# Finalize simuation
openmc.capi.simulation_finalize()
openmc.lib.simulation_finalize()
# Print out CMFD timing statistics
self._write_cmfd_timing_stats()
@ -836,13 +836,13 @@ class CMFDRun(object):
"""
if filename is None:
batch_str_len = len(str(openmc.capi.settings.batches))
batch_str = str(openmc.capi.current_batch()).zfill(batch_str_len)
batch_str_len = len(str(openmc.lib.settings.batches))
batch_str = str(openmc.lib.current_batch()).zfill(batch_str_len)
filename = 'statepoint.{}.h5'.format(batch_str)
# Call C API statepoint_write to save source distribution with CMFD
# feedback
openmc.capi.statepoint_write(filename=filename)
openmc.lib.statepoint_write(filename=filename)
# Append CMFD data to statepoint file using h5py
self._write_cmfd_statepoint(filename)
@ -856,10 +856,10 @@ class CMFDRun(object):
Filename of statepoint
"""
if openmc.capi.master():
if openmc.lib.master():
with h5py.File(filename, 'a') as f:
if 'cmfd' not in f:
if openmc.capi.settings.verbosity >= 5:
if openmc.lib.settings.verbosity >= 5:
print(' Writing CMFD data to {}...'.format(filename))
sys.stdout.flush()
cmfd_group = f.create_group("cmfd")
@ -922,7 +922,7 @@ class CMFDRun(object):
args = temp_loss.indptr, len(temp_loss.indptr), \
temp_loss.indices, len(temp_loss.indices), n, \
self._spectral, self._indices, coremap
return openmc.capi._dll.openmc_initialize_linsolver(*args)
return openmc.lib._dll.openmc_initialize_linsolver(*args)
def _write_cmfd_output(self):
"""Write CMFD output to buffer at the end of each batch"""
@ -948,7 +948,7 @@ class CMFDRun(object):
def _write_cmfd_timing_stats(self):
"""Write CMFD timing stats to buffer after finalizing simulation"""
if openmc.capi.master():
if openmc.lib.master():
outstr = ("=====================> "
"CMFD TIMING STATISTICS <====================\n\n"
" Time in CMFD = {:.5E} seconds\n"
@ -961,7 +961,7 @@ class CMFDRun(object):
def _configure_cmfd(self):
"""Initialize CMFD parameters and set CMFD input variables"""
# Check if restarting simulation from statepoint file
if not openmc.capi.settings.restart_run:
if not openmc.lib.settings.restart_run:
# Read in cmfd input defined in Python
self._read_cmfd_input()
@ -990,13 +990,13 @@ class CMFDRun(object):
else:
# Reset CMFD parameters from statepoint file
path_statepoint = openmc.capi.settings.path_statepoint
path_statepoint = openmc.lib.settings.path_statepoint
self._reset_cmfd(path_statepoint)
def _read_cmfd_input(self):
"""Sets values of additional instance variables based on user input"""
# Print message to user and flush output to stdout
if openmc.capi.settings.verbosity >= 7 and openmc.capi.master():
if openmc.lib.settings.verbosity >= 7 and openmc.lib.master():
print(' Configuring CMFD parameters for simulation')
sys.stdout.flush()
@ -1010,7 +1010,7 @@ class CMFDRun(object):
self._indices[i] = n
# Check if in continuous energy mode
if not openmc.capi.settings.run_CE:
if not openmc.lib.settings.run_CE:
raise OpenMCError('CMFD must be run in continuous energy mode')
# Set number of energy groups
@ -1065,8 +1065,8 @@ class CMFDRun(object):
'file {}'.format(filename))
else:
# Overwrite CMFD values from statepoint
if (openmc.capi.master() and
openmc.capi.settings.verbosity >= 5):
if (openmc.lib.master() and
openmc.lib.settings.verbosity >= 5):
print(' Loading CMFD data from {}...'.format(filename))
sys.stdout.flush()
cmfd_group = f['cmfd']
@ -1126,7 +1126,7 @@ class CMFDRun(object):
# Allocate dimensions for each mesh cell
self._hxyz = np.zeros((nx, ny, nz, 3))
self._hxyz[:] = openmc.capi.meshes[self._mesh_id].width
self._hxyz[:] = openmc.lib.meshes[self._mesh_id].width
# Allocate flux, cross sections and diffusion coefficient
self._flux = np.zeros((nx, ny, nz, ng))
@ -1167,7 +1167,7 @@ class CMFDRun(object):
"""Handles CMFD options at the beginning of each batch"""
# Get current batch through C API
# Add 1 as next_batch has not been called yet
current_batch = openmc.capi.current_batch() + 1
current_batch = openmc.lib.current_batch() + 1
# Check to activate CMFD diffusion and possible feedback
# Check to activate CMFD tallies
@ -1182,7 +1182,7 @@ class CMFDRun(object):
def _execute_cmfd(self):
"""Runs CMFD calculation on master node"""
# Run CMFD on single processor on master
if openmc.capi.master():
if openmc.lib.master():
# Start CMFD timer
time_start_cmfd = time.time()
@ -1196,7 +1196,7 @@ class CMFDRun(object):
self._k_cmfd.append(self._keff)
# Check to perform adjoint on last batch
if (openmc.capi.current_batch() == openmc.capi.settings.batches
if (openmc.lib.current_batch() == openmc.lib.settings.batches
and self._run_adjoint):
self._cmfd_solver_execute(adjoint=True)
@ -1207,20 +1207,20 @@ class CMFDRun(object):
self._cmfd_reweight(True)
# Stop CMFD timer
if openmc.capi.master():
if openmc.lib.master():
time_stop_cmfd = time.time()
self._time_cmfd += time_stop_cmfd - time_start_cmfd
def _cmfd_tally_reset(self):
"""Resets all CMFD tallies in memory"""
# Print message
if (openmc.capi.settings.verbosity >= 6 and openmc.capi.master() and
if (openmc.lib.settings.verbosity >= 6 and openmc.lib.master() and
not self._reset_every):
print(' CMFD tallies reset')
sys.stdout.flush()
# Reset CMFD tallies
tallies = openmc.capi.tallies
tallies = openmc.lib.tallies
for tally_id in self._tally_ids:
tallies[tally_id].reset()
@ -1407,7 +1407,7 @@ class CMFDRun(object):
self._cmfd_src = cmfd_src / np.sum(cmfd_src)
# Compute entropy
if openmc.capi.settings.entropy_on:
if openmc.lib.settings.entropy_on:
# Compute source times log_2(source)
source = self._cmfd_src[self._cmfd_src > 0] \
* np.log(self._cmfd_src[self._cmfd_src > 0])/np.log(2)
@ -1441,12 +1441,12 @@ class CMFDRun(object):
outside = self._count_bank_sites()
# Check and raise error if source sites exist outside of CMFD mesh
if openmc.capi.master() and outside:
if openmc.lib.master() and outside:
raise OpenMCError('Source sites outside of the CMFD mesh')
# Have master compute weight factors, ignore any zeros in
# sourcecounts or cmfd_src
if openmc.capi.master():
if openmc.lib.master():
# Compute normalization factor
norm = np.sum(self._sourcecounts) / np.sum(self._cmfd_src)
@ -1471,7 +1471,7 @@ class CMFDRun(object):
dtype=np.float32))
if (not self._feedback
or openmc.capi.current_batch() < self._feedback_begin):
or openmc.lib.current_batch() < self._feedback_begin):
return
# Broadcast weight factors to all procs
@ -1479,13 +1479,13 @@ class CMFDRun(object):
self._weightfactors = self._intracomm.bcast(
self._weightfactors)
m = openmc.capi.meshes[self._mesh_id]
m = openmc.lib.meshes[self._mesh_id]
energy = self._egrid
ng = self._indices[3]
# Get locations and energies of all particles in source bank
source_xyz = openmc.capi.source_bank()['r']
source_energies = openmc.capi.source_bank()['E']
source_xyz = openmc.lib.source_bank()['r']
source_energies = openmc.lib.source_bank()['E']
# Convert xyz location to the CMFD mesh index
mesh_ijk = np.floor((source_xyz-m.lower_left)/m.width).astype(int)
@ -1503,13 +1503,13 @@ class CMFDRun(object):
# Determine weight factor of each particle based on its mesh index
# and energy bin and updates its weight
openmc.capi.source_bank()['wgt'] *= self._weightfactors[
openmc.lib.source_bank()['wgt'] *= self._weightfactors[
mesh_ijk[:,0], mesh_ijk[:,1], mesh_ijk[:,2], energy_bins]
if openmc.capi.master() and np.any(source_energies < energy[0]):
if openmc.lib.master() and np.any(source_energies < energy[0]):
print(' WARNING: Source pt below energy grid')
sys.stdout.flush()
if openmc.capi.master() and np.any(source_energies > energy[-1]):
if openmc.lib.master() and np.any(source_energies > energy[-1]):
print(' WARNING: Source pt above energy grid')
sys.stdout.flush()
@ -1523,8 +1523,8 @@ class CMFDRun(object):
"""
# Initialize variables
m = openmc.capi.meshes[self._mesh_id]
bank = openmc.capi.source_bank()
m = openmc.lib.meshes[self._mesh_id]
bank = openmc.lib.source_bank()
energy = self._egrid
sites_outside = np.zeros(1, dtype=bool)
nxnynz = np.prod(self._indices[0:3])
@ -1535,8 +1535,8 @@ class CMFDRun(object):
count = np.zeros(self._sourcecounts.shape)
# Get location and energy of each particle in source bank
source_xyz = openmc.capi.source_bank()['r']
source_energies = openmc.capi.source_bank()['E']
source_xyz = openmc.lib.source_bank()['r']
source_energies = openmc.lib.source_bank()['E']
# Convert xyz location to mesh index and ravel index to scalar
mesh_locations = np.floor((source_xyz - m.lower_left) / m.width)
@ -1760,7 +1760,7 @@ class CMFDRun(object):
s_o = np.zeros((n,))
# Set initial guess
k_n = openmc.capi.keff()[0]
k_n = openmc.lib.keff()[0]
k_o = k_n
dw = self._w_shift
k_s = k_o + dw
@ -1791,7 +1791,7 @@ class CMFDRun(object):
s_o /= k_lo
# Compute new flux with C++ solver
innerits = openmc.capi._dll.openmc_run_linsolver(loss.data, s_o,
innerits = openmc.lib._dll.openmc_run_linsolver(loss.data, s_o,
phi_n, toli)
# Compute new source vector
@ -1863,7 +1863,7 @@ class CMFDRun(object):
iconv = kerr < self._cmfd_ktol and serr < self._stol
# Print out to user
if self._power_monitor and openmc.capi.master():
if self._power_monitor and openmc.lib.master():
str1 = ' {:d}:'.format(iter)
str2 = 'k-eff: {:0.8f}'.format(k_n)
str3 = 'k-error: {:.5E}'.format(kerr)
@ -1904,7 +1904,7 @@ class CMFDRun(object):
"""
# Update window size for expanding window if necessary
num_cmfd_batches = openmc.capi.current_batch() - self._tally_begin + 1
num_cmfd_batches = openmc.lib.current_batch() - self._tally_begin + 1
if (self._window_type == 'expanding' and
num_cmfd_batches == self._window_size * 2):
self._window_size *= 2
@ -1925,7 +1925,7 @@ class CMFDRun(object):
nx, ny, nz, ng = self._indices
# Get tallies in-memory
tallies = openmc.capi.tallies
tallies = openmc.lib.tallies
# Ravel coremap as 1d array similar to how tally data is arranged
coremap = np.ravel(self._coremap.swapaxes(0, 2))
@ -2181,7 +2181,7 @@ class CMFDRun(object):
num_accel = self._mat_dim
# Get openmc k-effective
keff = openmc.capi.keff()[0]
keff = openmc.lib.keff()[0]
# Define leakage in each mesh cell and energy group
leakage = (((self._current[:,:,:,_CURRENTS['out_right'],:] -
@ -2973,7 +2973,7 @@ class CMFDRun(object):
def _create_cmfd_tally(self):
"""Creates all tallies in-memory that are used to solve CMFD problem"""
# Create Mesh object based on CMFDMesh, stored internally
cmfd_mesh = openmc.capi.RegularMesh()
cmfd_mesh = openmc.lib.RegularMesh()
# Store id of mesh object
self._mesh_id = cmfd_mesh.id
# Set dimension and parameters of mesh object
@ -2983,29 +2983,29 @@ class CMFDRun(object):
width=self._mesh.width)
# Create mesh Filter object, stored internally
mesh_filter = openmc.capi.MeshFilter()
mesh_filter = openmc.lib.MeshFilter()
# Set mesh for Mesh Filter
mesh_filter.mesh = cmfd_mesh
# Set up energy filters, if applicable
if self._energy_filters:
# Create Energy Filter object, stored internally
energy_filter = openmc.capi.EnergyFilter()
energy_filter = openmc.lib.EnergyFilter()
# Set bins for Energy Filter
energy_filter.bins = self._egrid
# Create Energy Out Filter object, stored internally
energyout_filter = openmc.capi.EnergyoutFilter()
energyout_filter = openmc.lib.EnergyoutFilter()
# Set bins for Energy Filter
energyout_filter.bins = self._egrid
# Create Mesh Surface Filter object, stored internally
meshsurface_filter = openmc.capi.MeshSurfaceFilter()
meshsurface_filter = openmc.lib.MeshSurfaceFilter()
# Set mesh for Mesh Surface Filter
meshsurface_filter.mesh = cmfd_mesh
# Create Legendre Filter object, stored internally
legendre_filter = openmc.capi.LegendreFilter()
legendre_filter = openmc.lib.LegendreFilter()
# Set order for Legendre Filter
legendre_filter.order = 1
@ -3013,7 +3013,7 @@ class CMFDRun(object):
n_tallies = 4
self._tally_ids = []
for i in range(n_tallies):
cmfd_tally = openmc.capi.Tally()
cmfd_tally = openmc.lib.Tally()
# Set nuclide bins
cmfd_tally.nuclides = ['total']
self._tally_ids.append(cmfd_tally.id)

View file

@ -5,6 +5,7 @@ to run a full depletion simulation.
"""
from collections import namedtuple
from collections import defaultdict
from collections.abc import Iterable
import os
from pathlib import Path
@ -17,7 +18,7 @@ from numpy import nonzero, empty, asarray
from uncertainties import ufloat
from openmc.data import DataLibrary, JOULE_PER_EV
from openmc.capi import MaterialFilter, Tally
from openmc.lib import MaterialFilter, Tally
from openmc.checkvalue import check_type, check_greater_than
from .results import Results
from .chain import Chain
@ -376,14 +377,17 @@ class FissionYieldHelper(ABC):
Attributes
----------
constant_yields : dict of str to :class:`openmc.deplete.FissionYield`
constant_yields : collections.defaultdict
Fission yields for all nuclides that only have one set of
fission yield data. Can be accessed as ``{parent: {product: yield}}``
fission yield data. Dictionary of form ``{str: {str: float}}``
representing yields for ``{parent: {product: yield}}``. Default
return object is an empty dictionary
"""
def __init__(self, chain_nuclides):
self._chain_nuclides = {}
self._constant_yields = {}
self._constant_yields = defaultdict(dict)
# Get all nuclides with fission yield data
for nuc in chain_nuclides:
@ -407,14 +411,16 @@ class FissionYieldHelper(ABC):
Parameters
----------
local_mat_index : int
Index for material tracked on this process that
exists in :attr:`local_mat_index` and fits within
the first axis in :attr:`results`
Index for the material with requested fission yields.
Should correspond to the material represented in
``mat_indexes[local_mat_index]`` during
:meth:`generate_tallies`.
Returns
-------
library : dict
Dictionary of ``{parent: {product: fyield}}``
library : collections.abc.Mapping
Dictionary-like object mapping ``{str: {str: float}``.
This reflects fission yields for ``{parent: {product: fyield}}``.
"""
@staticmethod
@ -438,7 +444,7 @@ class FissionYieldHelper(ABC):
Parameters
----------
materials : iterable of C-API materials
Materials to be used in :class:`openmc.capi.MaterialFilter`
Materials to be used in :class:`openmc.lib.MaterialFilter`
mat_indexes : iterable of int
Indices of tallied materials that will have their fission
yields computed by this helper. Necessary as the
@ -520,8 +526,8 @@ class TalliedFissionYieldHelper(FissionYieldHelper):
Parameters
----------
materials : iterable of :class:`openmc.capi.Material`
Materials to be used in :class:`openmc.capi.MaterialFilter`
materials : iterable of :class:`openmc.lib.Material`
Materials to be used in :class:`openmc.lib.MaterialFilter`
mat_indexes : iterable of int
Indices of tallied materials that will have their fission
yields computed by this helper. Necessary as the

View file

@ -398,7 +398,7 @@ class Chain(object):
clean_indentation(root_elem)
tree.write(str(filename), encoding='utf-8')
def get_thermal_fission_yields(self):
def get_default_fission_yields(self):
"""Return fission yields at lowest incident neutron energy
Used as the default set of fission yields for :meth:`form_matrix`
@ -412,7 +412,7 @@ class Chain(object):
names of nuclides with yield data and ``f_yield``
is a float for the fission yield.
"""
out = {}
out = defaultdict(dict)
for nuc in self.nuclides:
if nuc.yield_data is None:
continue
@ -440,13 +440,13 @@ class Chain(object):
See Also
--------
:meth:`get_thermal_fission_yields`
:meth:`get_default_fission_yields`
"""
matrix = defaultdict(float)
reactions = set()
if fission_yields is None:
fission_yields = self.get_thermal_fission_yields()
fission_yields = self.get_default_fission_yields()
for i, nuc in enumerate(self.nuclides):
@ -721,7 +721,7 @@ class Chain(object):
@property
def fission_yields(self):
if self._fission_yields is None:
self._fission_yields = [self.get_thermal_fission_yields()]
self._fission_yields = [self.get_default_fission_yields()]
return self._fission_yields
@fission_yields.setter

View file

@ -5,11 +5,12 @@ from copy import deepcopy
from itertools import product
from numbers import Real
import bisect
from collections import defaultdict
from numpy import dot, zeros, newaxis
from openmc.checkvalue import check_type, check_greater_than
from openmc.capi import (
from openmc.lib import (
Tally, MaterialFilter, EnergyFilter, EnergyFunctionFilter)
from .abc import (
ReactionRateHelper, EnergyHelper, FissionYieldHelper,
@ -44,7 +45,7 @@ class DirectReactionRateHelper(ReactionRateHelper):
def generate_tallies(self, materials, scores):
"""Produce one-group reaction rate tally
Uses the :mod:`openmc.capi` to generate a tally
Uses the :mod:`openmc.lib` to generate a tally
of relevant reactions across all burnable materials.
Parameters
@ -179,9 +180,11 @@ class ConstantFissionYieldHelper(FissionYieldHelper):
Attributes
----------
constant_yields : dict of str to :class:`openmc.deplete.FissionYield`
constant_yields : collections.defaultdict
Fission yields for all nuclides that only have one set of
fission yield data. Can be accessed as ``{parent: {product: yield}}``
fission yield data. Dictionary of form ``{str: {str: float}}``
representing yields for ``{parent: {product: yield}}``. Default
return object is an empty dictionary
energy : float
Energy of fission yield libraries.
"""
@ -237,7 +240,7 @@ class ConstantFissionYieldHelper(FissionYieldHelper):
Returns
-------
library : dict
library : collections.defaultdict
Dictionary of ``{parent: {product: fyield}}``
"""
return self.constant_yields
@ -282,6 +285,11 @@ class FissionYieldCutoffHelper(TalliedFissionYieldHelper):
fast_yields : dict
Dictionary of the form ``{parent: {product: yield}}``
with fast yields
constant_yields : collections.defaultdict
Fission yields for all nuclides that only have one set of
fission yield data. Dictionary of form ``{str: {str: float}}``
representing yields for ``{parent: {product: yield}}``. Default
return object is an empty dictionary
results : numpy.ndarray
Array of fission rate fractions with shape
``(n_mats, 2, n_nucs)``. ``results[:, 0]``
@ -362,13 +370,13 @@ class FissionYieldCutoffHelper(TalliedFissionYieldHelper):
def generate_tallies(self, materials, mat_indexes):
"""Use C API to produce a fission rate tally in burnable materials
Include a :class:`openmc.capi.EnergyFilter` to tally fission rates
Include a :class:`openmc.lib.EnergyFilter` to tally fission rates
above and below cutoff energy.
Parameters
----------
materials : iterable of :class:`openmc.capi.Material`
Materials to be used in :class:`openmc.capi.MaterialFilter`
materials : iterable of :class:`openmc.lib.Material`
Materials to be used in :class:`openmc.lib.MaterialFilter`
mat_indexes : iterable of int
Indices of tallied materials that will have their fission
yields computed by this helper. Necessary as the
@ -417,7 +425,7 @@ class FissionYieldCutoffHelper(TalliedFissionYieldHelper):
Returns
-------
library : dict
library : collections.defaultdict
Dictionary of ``{parent: {product: fyield}}``
"""
yields = self.constant_yields
@ -469,9 +477,11 @@ class AveragedFissionYieldHelper(TalliedFissionYieldHelper):
Attributes
----------
constant_yields : dict of str to :class:`openmc.deplete.FissionYield`
constant_yields : collections.defaultdict
Fission yields for all nuclides that only have one set of
fission yield data. Can be accessed as ``{parent: {product: yield}}``
fission yield data. Dictionary of form ``{str: {str: float}}``
representing yields for ``{parent: {product: yield}}``. Default
return object is an empty dictionary
results : None or numpy.ndarray
If tallies have been generated and unpacked, then the array will
have shape ``(n_mats, n_tnucs)``, where ``n_mats`` is the number
@ -490,8 +500,8 @@ class AveragedFissionYieldHelper(TalliedFissionYieldHelper):
Parameters
----------
materials : iterable of :class:`openmc.capi.Material`
Materials to be used in :class:`openmc.capi.MaterialFilter`
materials : iterable of :class:`openmc.lib.Material`
Materials to be used in :class:`openmc.lib.MaterialFilter`
mat_indexes : iterable of int
Indices of tallied materials that will have their fission
yields computed by this helper. Necessary as the
@ -569,12 +579,13 @@ class AveragedFissionYieldHelper(TalliedFissionYieldHelper):
Returns
-------
library : dict
Dictionary of ``{parent: {product: fyield}}``
library : collections.defaultdict
Dictionary of ``{parent: {product: fyield}}``. Default return
value is an empty dictionary
"""
if not self._tally_nucs:
return self.constant_yields
mat_yields = {}
mat_yields = defaultdict(dict)
average_energies = self.results[local_mat_index]
for avg_e, nuc in zip(average_energies, self._tally_nucs):
nuc_energies = nuc.yield_energies

View file

@ -19,7 +19,7 @@ import numpy as np
from uncertainties import ufloat
import openmc
import openmc.capi
import openmc.lib
from . import comm
from .abc import TransportOperator, OperatorResult
from .atom_number import AtomNumber
@ -245,8 +245,8 @@ class Operator(TransportOperator):
self._yield_helper.update_tally_nuclides(nuclides)
# Run OpenMC
openmc.capi.reset()
openmc.capi.run()
openmc.lib.reset()
openmc.lib.run()
time_openmc = time.time()
@ -264,7 +264,7 @@ class Operator(TransportOperator):
step : int
Current depletion step including restarts
"""
openmc.capi.statepoint_write(
openmc.lib.statepoint_write(
"openmc_simulation_n{}.h5".format(step),
write_source=False)
@ -438,10 +438,10 @@ class Operator(TransportOperator):
# Initialize OpenMC library
comm.barrier()
openmc.capi.init(intracomm=comm)
openmc.lib.init(intracomm=comm)
# Generate tallies in memory
materials = [openmc.capi.materials[int(i)]
materials = [openmc.lib.materials[int(i)]
for i in self.burnable_mats]
self._rate_helper.generate_tallies(materials, self.chain.reactions)
self._energy_helper.prepare(
@ -456,7 +456,7 @@ class Operator(TransportOperator):
def finalize(self):
"""Finalize a depletion simulation and release resources."""
openmc.capi.finalize()
openmc.lib.finalize()
def _update_materials(self):
"""Updates material compositions in OpenMC on all processes."""
@ -491,7 +491,7 @@ class Operator(TransportOperator):
number_i[mat, nuc] = 0.0
# Update densities on C API side
mat_internal = openmc.capi.materials[int(mat)]
mat_internal = openmc.lib.materials[int(mat)]
mat_internal.set_densities(nuclides, densities)
#TODO Update densities on the Python side, otherwise the
@ -581,7 +581,7 @@ class Operator(TransportOperator):
rates.fill(0.0)
# Get k and uncertainty
k_combined = ufloat(*openmc.capi.keff())
k_combined = ufloat(*openmc.lib.keff())
# Extract tally bins
nuclides = self._rate_helper.nuclides

View file

@ -1,14 +1,14 @@
"""
This module provides bindings to C functions defined by OpenMC shared library.
When the :mod:`openmc` package is imported, the OpenMC shared library is
automatically loaded. Calls to the OpenMC library can then be via functions or
objects in the :mod:`openmc.capi` subpackage, for example:
This module provides bindings to C/C++ functions defined by OpenMC shared
library. When the :mod:`openmc.lib` package is imported, the OpenMC shared
library is automatically loaded. Calls to the OpenMC library can then be via
functions or objects in :mod:`openmc.lib`, for example:
.. code-block:: python
openmc.capi.init()
openmc.capi.run()
openmc.capi.finalize()
openmc.lib.init()
openmc.lib.run()
openmc.lib.finalize()
"""
@ -33,7 +33,7 @@ if os.environ.get('READTHEDOCS', None) != 'True':
else:
# For documentation builds, we don't actually have the shared library
# available. Instead, we create a mock object so that when the modules
# within the openmc.capi package try to configure arguments and return
# within the openmc.lib package try to configure arguments and return
# values for symbols, no errors occur
from unittest.mock import Mock
_dll = Mock()

View file

@ -63,7 +63,7 @@ class Cell(_FortranObjectWithID):
This class exposes a cell that is stored internally in the OpenMC
library. To obtain a view of a cell with a given ID, use the
:data:`openmc.capi.cells` mapping.
:data:`openmc.lib.cells` mapping.
Parameters
----------

View file

@ -11,7 +11,7 @@ from numpy.ctypeslib import as_array
from openmc.exceptions import AllocationError
from . import _dll
from .error import _error_handler
import openmc.capi
import openmc.lib
class _Bank(Structure):
@ -127,7 +127,7 @@ def find_cell(xyz):
Returns
-------
openmc.capi.Cell
openmc.lib.Cell
Cell containing the point
int
If the cell at the given point is repeated in the geometry, this
@ -137,7 +137,7 @@ def find_cell(xyz):
index = c_int32()
instance = c_int32()
_dll.openmc_find_cell((c_double*3)(*xyz), index, instance)
return openmc.capi.Cell(index=index.value), instance.value
return openmc.lib.Cell(index=index.value), instance.value
def find_material(xyz):
@ -150,7 +150,7 @@ def find_material(xyz):
Returns
-------
openmc.capi.Material or None
openmc.lib.Material or None
Material containing the point, or None is no material is found
"""
@ -158,8 +158,8 @@ def find_material(xyz):
instance = c_int32()
_dll.openmc_find_cell((c_double*3)(*xyz), index, instance)
mats = openmc.capi.Cell(index=index.value).fill
if isinstance(mats, (openmc.capi.Material, type(None))):
mats = openmc.lib.Cell(index=index.value).fill
if isinstance(mats, (openmc.lib.Material, type(None))):
return mats
else:
return mats[instance.value]
@ -225,21 +225,21 @@ def iter_batches():
This function returns a generator-iterator that allows Python code to be run
between batches in an OpenMC simulation. It should be used in conjunction
with :func:`openmc.capi.simulation_init` and
:func:`openmc.capi.simulation_finalize`. For example:
with :func:`openmc.lib.simulation_init` and
:func:`openmc.lib.simulation_finalize`. For example:
.. code-block:: Python
with openmc.capi.run_in_memory():
openmc.capi.simulation_init()
for _ in openmc.capi.iter_batches():
with openmc.lib.run_in_memory():
openmc.lib.simulation_init()
for _ in openmc.lib.iter_batches():
# Look at convergence of tallies, for example
...
openmc.capi.simulation_finalize()
openmc.lib.simulation_finalize()
See Also
--------
openmc.capi.next_batch
openmc.lib.next_batch
"""
while True:
@ -365,11 +365,11 @@ def run_in_memory(**kwargs):
block, all memory that was allocated during the block is freed. For
example::
with openmc.capi.run_in_memory():
with openmc.lib.run_in_memory():
for i in range(n_iters):
openmc.capi.reset()
openmc.lib.reset()
do_stuff()
openmc.capi.run()
openmc.lib.run()
Parameters
----------

View file

@ -66,7 +66,7 @@ class Material(_FortranObjectWithID):
This class exposes a material that is stored internally in the OpenMC
library. To obtain a view of a material with a given ID, use the
:data:`openmc.capi.materials` mapping.
:data:`openmc.lib.materials` mapping.
Parameters
----------

View file

@ -50,7 +50,7 @@ class RegularMesh(_FortranObjectWithID):
This class exposes a mesh that is stored internally in the OpenMC
library. To obtain a view of a mesh with a given ID, use the
:data:`openmc.capi.meshes` mapping.
:data:`openmc.lib.meshes` mapping.
Parameters
----------

View file

@ -43,7 +43,7 @@ class Nuclide(_FortranObject):
This class exposes a nuclide that is stored internally in the OpenMC
solver. To obtain a view of a nuclide with a given name, use the
:data:`openmc.capi.nuclides` mapping.
:data:`openmc.lib.nuclides` mapping.
Parameters
----------

View file

@ -52,9 +52,9 @@ class _PlotBase(Structure):
C-Type Attributes
-----------------
origin : openmc.capi.plot._Position
origin : openmc.lib.plot._Position
A position defining the origin of the plot.
width_ : openmc.capi.plot._Position
width_ : openmc.lib.plot._Position
The width of the plot along the x, y, and z axes, respectively
basis_ : c_int
The axes basis of the plot view.
@ -222,7 +222,7 @@ def id_map(plot):
Parameters
----------
plot : openmc.capi.plot._PlotBase
plot : openmc.lib.plot._PlotBase
Object describing the slice of the model to be generated
Returns
@ -250,7 +250,7 @@ def property_map(plot):
Parameters
----------
plot : openmc.capi.plot._PlotBase
plot : openmc.lib.plot._PlotBase
Object describing the slice of the model to be generated
Returns

View file

@ -143,7 +143,7 @@ class Tally(_FortranObjectWithID):
This class exposes a tally that is stored internally in the OpenMC
library. To obtain a view of a tally with a given ID, use the
:data:`openmc.capi.tallies` mapping.
:data:`openmc.lib.tallies` mapping.
Parameters
----------

View file

@ -147,7 +147,7 @@ class Model(object):
"""
# Import the depletion module. This is done here rather than the module
# header to delay importing openmc.capi (through openmc.deplete) which
# header to delay importing openmc.lib (through openmc.deplete) which
# can be tough to install properly.
import openmc.deplete as dep

View file

@ -73,9 +73,9 @@ class ZernikeRadial(Polynomial):
return self._order
def __call__(self, r):
import openmc.capi as capi
import openmc.lib as lib
if isinstance(r, Iterable):
return [np.sum(self._norm_coef * capi.calc_zn_rad(self.order, r_i))
return [np.sum(self._norm_coef * lib.calc_zn_rad(self.order, r_i))
for r_i in r]
else:
return np.sum(self._norm_coef * capi.calc_zn_rad(self.order, r))
return np.sum(self._norm_coef * lib.calc_zn_rad(self.order, r))

View file

@ -31,7 +31,7 @@ kwargs = {
# Data files and librarries
'package_data': {
'openmc.capi': ['libopenmc.{}'.format(suffix)],
'openmc.lib': ['libopenmc.{}'.format(suffix)],
'openmc.data': ['mass16.txt', 'BREMX.DAT', '*.h5']
},

View file

@ -83,7 +83,7 @@ class TestChain(object):
fission_yields = [None]
@staticmethod
def get_thermal_fission_yields():
def get_default_fission_yields():
return None
def form_matrix(self, rates, _fission_yields=None):

View file

@ -1,8 +1,5 @@
from tests.testing_harness import TestHarness
import sys
import openmc.capi
def test_complex_cell():
harness = TestHarness('statepoint.10.h5')

View file

@ -1,11 +1,11 @@
import openmc
import openmc.capi
import openmc.lib
import pytest
from tests.testing_harness import PyAPITestHarness
pytestmark = pytest.mark.skipif(
not openmc.capi._dagmc_enabled(),
not openmc.lib._dagmc_enabled(),
reason="DAGMC CAD geometry is not enabled.")
def test_dagmc():

View file

@ -1,12 +1,12 @@
import openmc
import openmc.capi
import openmc.lib
from openmc.stats import Box
import pytest
from tests.testing_harness import PyAPITestHarness
pytestmark = pytest.mark.skipif(
not openmc.capi._dagmc_enabled(),
not openmc.lib._dagmc_enabled(),
reason="DAGMC CAD geometry is not enabled.")
class UWUWTest(PyAPITestHarness):

View file

@ -1,12 +1,12 @@
import openmc
import openmc.capi
import openmc.lib
from openmc.stats import Box
import pytest
from tests.testing_harness import PyAPITestHarness
pytestmark = pytest.mark.skipif(
not openmc.capi._dagmc_enabled(),
not openmc.lib._dagmc_enabled(),
reason="DAGMC CAD geometry is not enabled.")
class UWUWTest(PyAPITestHarness):

View file

@ -4,12 +4,12 @@ import numpy as np
import pytest
import openmc
import openmc.capi
import openmc.lib
from tests import cdtemp
pytestmark = pytest.mark.skipif(
not openmc.capi._dagmc_enabled(),
not openmc.lib._dagmc_enabled(),
reason="DAGMC CAD geometry is not enabled.")
@ -60,15 +60,15 @@ def dagmc_model(request):
with cdtemp():
shutil.copyfile(dagmc_file, "./dagmc.h5m")
model.export_to_xml()
openmc.capi.init()
openmc.lib.init()
yield
openmc.capi.finalize()
openmc.lib.finalize()
@pytest.mark.parametrize("cell_id,exp_temp", ((1, 320.0), # assigned by material
(2, 300.0), # assigned in dagmc file
(3, 293.6))) # assigned by default
def test_dagmc_temperatures(cell_id, exp_temp):
cell = openmc.capi.cells[cell_id]
cell = openmc.lib.cells[cell_id]
assert np.isclose(cell.get_temperature(), exp_temp)

View file

@ -1,5 +1,5 @@
import numpy as np
import openmc.capi
import openmc.lib
import pytest
@pytest.fixture(autouse=True)
@ -73,12 +73,12 @@ def complex_cell(run_in_tmpdir, mpi_intracomm):
model.export_to_xml()
openmc.capi.finalize()
openmc.capi.init(intracomm=mpi_intracomm)
openmc.lib.finalize()
openmc.lib.init(intracomm=mpi_intracomm)
yield
openmc.capi.finalize()
openmc.lib.finalize()
expected_results = ( (1, (( -4., -4., -np.inf),
@ -93,6 +93,6 @@ expected_results = ( (1, (( -4., -4., -np.inf),
( np.inf, np.inf, np.inf))) )
@pytest.mark.parametrize("cell_id,expected_box", expected_results)
def test_cell_box(cell_id, expected_box):
cell_box = openmc.capi.cells[cell_id].bounding_box
cell_box = openmc.lib.cells[cell_id].bounding_box
assert tuple(cell_box[0]) == expected_box[0]
assert tuple(cell_box[1]) == expected_box[1]

View file

@ -385,13 +385,13 @@ def test_set_alpha_branches():
def test_simple_fission_yields(simple_chain):
"""Check the default fission yields that can be used to form the matrix
"""
fission_yields = simple_chain.get_thermal_fission_yields()
fission_yields = simple_chain.get_default_fission_yields()
assert fission_yields == {"C": {"A": 0.0292737, "B": 0.002566345}}
def test_fission_yield_attribute(simple_chain):
"""Test the fission_yields property"""
thermal_yields = simple_chain.get_thermal_fission_yields()
thermal_yields = simple_chain.get_default_fission_yields()
# generate default with property
assert simple_chain.fission_yields[0] == thermal_yields
empty_chain = Chain()

View file

@ -8,7 +8,7 @@ import bisect
import pytest
import numpy as np
import openmc
from openmc import capi
from openmc import lib
from openmc.deplete.nuclide import Nuclide, FissionYieldDistribution
from openmc.deplete.helpers import (
FissionYieldCutoffHelper, ConstantFissionYieldHelper,
@ -18,7 +18,7 @@ from openmc.deplete.helpers import (
@pytest.fixture(scope="module")
def materials(tmpdir_factory):
"""Use C API to construct realistic materials for testing tallies"""
tmpdir = tmpdir_factory.mktemp("capi")
tmpdir = tmpdir_factory.mktemp("lib")
orig = tmpdir.chdir()
# Create proxy problem to please openmc
mfuel = openmc.Material(name="test_fuel")
@ -40,8 +40,8 @@ def materials(tmpdir_factory):
settings.export_to_xml()
try:
with capi.run_in_memory():
yield [capi.Material(), capi.Material()]
with lib.run_in_memory():
yield [lib.Material(), lib.Material()]
finally:
# Convert to strings as os.remove in py 3.5 doesn't support Paths
for file_path in ("settings.xml", "geometry.xml", "materials.xml",
@ -64,7 +64,7 @@ def proxy_tally_data(tally, fill=None):
if not hasattr(tfilter, "bins"):
continue
this_bins = len(tfilter.bins)
if isinstance(tfilter, capi.EnergyFilter):
if isinstance(tfilter, lib.EnergyFilter):
this_bins -= 1
n_bins *= max(this_bins, 1)
data = np.empty((n_bins, n_nucs * n_scores, 3))
@ -192,9 +192,9 @@ def test_cutoff_helper(materials, nuclide_bundle, therm_frac):
assert fission_tally is not None
filters = fission_tally.filters
assert len(filters) == 2
assert isinstance(filters[0], capi.MaterialFilter)
assert isinstance(filters[0], lib.MaterialFilter)
assert len(filters[0].bins) == len(materials)
assert isinstance(filters[1], capi.EnergyFilter)
assert isinstance(filters[1], lib.EnergyFilter)
# lower, cutoff, and upper energy
assert len(filters[1].bins) == 3
@ -235,9 +235,9 @@ def test_averaged_helper(materials, nuclide_bundle, avg_energy):
assert fission_tally is not None
fission_filters = fission_tally.filters
assert len(fission_filters) == 2
assert isinstance(fission_filters[0], capi.MaterialFilter)
assert isinstance(fission_filters[0], lib.MaterialFilter)
assert len(fission_filters[0].bins) == len(materials)
assert isinstance(fission_filters[1], capi.EnergyFilter)
assert isinstance(fission_filters[1], lib.EnergyFilter)
assert len(fission_filters[1].bins) == 2
assert fission_tally.scores == ["fission"]
assert fission_tally.nuclides == list(tallied_nucs)
@ -246,9 +246,9 @@ def test_averaged_helper(materials, nuclide_bundle, avg_energy):
assert weighted_tally is not None
weighted_filters = weighted_tally.filters
assert len(weighted_filters) == 2
assert isinstance(weighted_filters[0], capi.MaterialFilter)
assert isinstance(weighted_filters[0], lib.MaterialFilter)
assert len(weighted_filters[0].bins) == len(materials)
assert isinstance(weighted_filters[1], capi.EnergyFunctionFilter)
assert isinstance(weighted_filters[1], lib.EnergyFunctionFilter)
assert len(weighted_filters[1].energy) == 2
assert len(weighted_filters[1].y) == 2
assert weighted_tally.scores == ["fission"]

View file

@ -5,7 +5,7 @@ import numpy as np
import pytest
import openmc
import openmc.exceptions as exc
import openmc.capi
import openmc.lib
from tests import cdtemp
@ -51,42 +51,42 @@ def pincell_model():
@pytest.fixture(scope='module')
def capi_init(pincell_model, mpi_intracomm):
openmc.capi.init(intracomm=mpi_intracomm)
openmc.lib.init(intracomm=mpi_intracomm)
yield
openmc.capi.finalize()
openmc.lib.finalize()
@pytest.fixture(scope='module')
def capi_simulation_init(capi_init):
openmc.capi.simulation_init()
openmc.lib.simulation_init()
yield
@pytest.fixture(scope='module')
def capi_run(capi_simulation_init):
openmc.capi.run()
openmc.lib.run()
def test_cell_mapping(capi_init):
cells = openmc.capi.cells
cells = openmc.lib.cells
assert isinstance(cells, Mapping)
assert len(cells) == 3
for cell_id, cell in cells.items():
assert isinstance(cell, openmc.capi.Cell)
assert isinstance(cell, openmc.lib.Cell)
assert cell_id == cell.id
def test_cell(capi_init):
cell = openmc.capi.cells[1]
assert isinstance(cell.fill, openmc.capi.Material)
cell.fill = openmc.capi.materials[1]
cell = openmc.lib.cells[1]
assert isinstance(cell.fill, openmc.lib.Material)
cell.fill = openmc.lib.materials[1]
assert str(cell) == 'Cell[0]'
assert cell.name == "Fuel"
cell.name = "Not fuel"
assert cell.name == "Not fuel"
def test_cell_temperature(capi_init):
cell = openmc.capi.cells[1]
cell = openmc.lib.cells[1]
cell.set_temperature(100.0, 0)
assert cell.get_temperature(0) == 100.0
cell.set_temperature(200)
@ -95,23 +95,23 @@ def test_cell_temperature(capi_init):
def test_new_cell(capi_init):
with pytest.raises(exc.AllocationError):
openmc.capi.Cell(1)
new_cell = openmc.capi.Cell()
new_cell_with_id = openmc.capi.Cell(10)
assert len(openmc.capi.cells) == 5
openmc.lib.Cell(1)
new_cell = openmc.lib.Cell()
new_cell_with_id = openmc.lib.Cell(10)
assert len(openmc.lib.cells) == 5
def test_material_mapping(capi_init):
mats = openmc.capi.materials
mats = openmc.lib.materials
assert isinstance(mats, Mapping)
assert len(mats) == 3
for mat_id, mat in mats.items():
assert isinstance(mat, openmc.capi.Material)
assert isinstance(mat, openmc.lib.Material)
assert mat_id == mat.id
def test_material(capi_init):
m = openmc.capi.materials[3]
m = openmc.lib.materials[3]
assert m.nuclides == ['H1', 'O16', 'B10', 'B11']
old_dens = m.densities
@ -137,7 +137,7 @@ def test_material(capi_init):
assert m.name == "Not hot borated water"
def test_material_add_nuclide(capi_init):
m = openmc.capi.materials[3]
m = openmc.lib.materials[3]
m.add_nuclide('Xe135', 1e-12)
assert m.nuclides[-1] == 'Xe135'
assert m.densities[-1] == 1e-12
@ -145,23 +145,23 @@ def test_material_add_nuclide(capi_init):
def test_new_material(capi_init):
with pytest.raises(exc.AllocationError):
openmc.capi.Material(1)
new_mat = openmc.capi.Material()
new_mat_with_id = openmc.capi.Material(10)
assert len(openmc.capi.materials) == 5
openmc.lib.Material(1)
new_mat = openmc.lib.Material()
new_mat_with_id = openmc.lib.Material(10)
assert len(openmc.lib.materials) == 5
def test_nuclide_mapping(capi_init):
nucs = openmc.capi.nuclides
nucs = openmc.lib.nuclides
assert isinstance(nucs, Mapping)
assert len(nucs) == 13
for name, nuc in nucs.items():
assert isinstance(nuc, openmc.capi.Nuclide)
assert isinstance(nuc, openmc.lib.Nuclide)
assert name == nuc.name
def test_settings(capi_init):
settings = openmc.capi.settings
settings = openmc.lib.settings
assert settings.batches == 10
settings.batches = 10
assert settings.inactive == 5
@ -176,17 +176,17 @@ def test_settings(capi_init):
def test_tally_mapping(capi_init):
tallies = openmc.capi.tallies
tallies = openmc.lib.tallies
assert isinstance(tallies, Mapping)
assert len(tallies) == 3
for tally_id, tally in tallies.items():
assert isinstance(tally, openmc.capi.Tally)
assert isinstance(tally, openmc.lib.Tally)
assert tally_id == tally.id
def test_energy_function_filter(capi_init):
"""Test special __new__ and __init__ for EnergyFunctionFilter"""
efunc = openmc.capi.EnergyFunctionFilter([0.0, 1.0], [0.0, 2.0])
efunc = openmc.lib.EnergyFunctionFilter([0.0, 1.0], [0.0, 2.0])
assert len(efunc.energy) == 2
assert (efunc.energy == [0.0, 1.0]).all()
assert len(efunc.y) == 2
@ -194,17 +194,17 @@ def test_energy_function_filter(capi_init):
def test_tally(capi_init):
t = openmc.capi.tallies[1]
t = openmc.lib.tallies[1]
assert t.type == 'volume'
assert len(t.filters) == 2
assert isinstance(t.filters[0], openmc.capi.MaterialFilter)
assert isinstance(t.filters[1], openmc.capi.EnergyFilter)
assert isinstance(t.filters[0], openmc.lib.MaterialFilter)
assert isinstance(t.filters[1], openmc.lib.EnergyFilter)
# Create new filter and replace existing
with pytest.raises(exc.AllocationError):
openmc.capi.MaterialFilter(uid=1)
mats = openmc.capi.materials
f = openmc.capi.MaterialFilter([mats[2], mats[1]])
openmc.lib.MaterialFilter(uid=1)
mats = openmc.lib.materials
f = openmc.lib.MaterialFilter([mats[2], mats[1]])
assert f.bins[0] == mats[2]
assert f.bins[1] == mats[1]
t.filters = [f]
@ -221,17 +221,17 @@ def test_tally(capi_init):
t.scores = new_scores
assert t.scores == new_scores
t2 = openmc.capi.tallies[2]
t2 = openmc.lib.tallies[2]
assert len(t2.filters) == 2
assert isinstance(t2.filters[0], openmc.capi.ZernikeFilter)
assert isinstance(t2.filters[1], openmc.capi.CellFilter)
assert isinstance(t2.filters[0], openmc.lib.ZernikeFilter)
assert isinstance(t2.filters[1], openmc.lib.CellFilter)
assert len(t2.filters[1].bins) == 3
assert t2.filters[0].order == 5
t3 = openmc.capi.tallies[3]
t3 = openmc.lib.tallies[3]
assert len(t3.filters) == 1
t3_f = t3.filters[0]
assert isinstance(t3_f, openmc.capi.EnergyFunctionFilter)
assert isinstance(t3_f, openmc.lib.EnergyFunctionFilter)
assert len(t3_f.energy) == 2
assert len(t3_f.y) == 2
t3_f.set_data([0.0, 1.0, 2.0], [0.0, 1.0, 4.0])
@ -241,144 +241,144 @@ def test_tally(capi_init):
def test_new_tally(capi_init):
with pytest.raises(exc.AllocationError):
openmc.capi.Material(1)
new_tally = openmc.capi.Tally()
openmc.lib.Material(1)
new_tally = openmc.lib.Tally()
new_tally.scores = ['flux']
new_tally_with_id = openmc.capi.Tally(10)
new_tally_with_id = openmc.lib.Tally(10)
new_tally_with_id.scores = ['flux']
assert len(openmc.capi.tallies) == 5
assert len(openmc.lib.tallies) == 5
def test_tally_activate(capi_simulation_init):
t = openmc.capi.tallies[1]
t = openmc.lib.tallies[1]
assert not t.active
t.active = True
assert t.active
def test_tally_results(capi_run):
t = openmc.capi.tallies[1]
t = openmc.lib.tallies[1]
assert t.num_realizations == 10 # t was made active in test_tally
assert np.all(t.mean >= 0)
nonzero = (t.mean > 0.0)
assert np.all(t.std_dev[nonzero] >= 0)
assert np.all(t.ci_width()[nonzero] >= 1.95*t.std_dev[nonzero])
t2 = openmc.capi.tallies[2]
t2 = openmc.lib.tallies[2]
n = 5
assert t2.mean.size == (n + 1) * (n + 2) // 2 * 3 # Number of Zernike coeffs * 3 cells
def test_global_tallies(capi_run):
assert openmc.capi.num_realizations() == 5
gt = openmc.capi.global_tallies()
assert openmc.lib.num_realizations() == 5
gt = openmc.lib.global_tallies()
for mean, std_dev in gt:
assert mean >= 0
def test_statepoint(capi_run):
openmc.capi.statepoint_write('test_sp.h5')
openmc.lib.statepoint_write('test_sp.h5')
assert os.path.exists('test_sp.h5')
def test_source_bank(capi_run):
source = openmc.capi.source_bank()
source = openmc.lib.source_bank()
assert np.all(source['E'] > 0.0)
assert np.all(source['wgt'] == 1.0)
assert np.allclose(np.linalg.norm(source['u'], axis=1), 1.0)
def test_by_batch(capi_run):
openmc.capi.hard_reset()
openmc.lib.hard_reset()
# Running next batch before simulation is initialized should raise an
# exception
with pytest.raises(exc.AllocationError):
openmc.capi.next_batch()
openmc.lib.next_batch()
openmc.capi.simulation_init()
openmc.lib.simulation_init()
try:
for _ in openmc.capi.iter_batches():
for _ in openmc.lib.iter_batches():
# Make sure we can get k-effective during inactive/active batches
mean, std_dev = openmc.capi.keff()
mean, std_dev = openmc.lib.keff()
assert 0.0 < mean < 2.5
assert std_dev > 0.0
assert openmc.capi.num_realizations() == 5
assert openmc.lib.num_realizations() == 5
for i in range(3):
openmc.capi.next_batch()
assert openmc.capi.num_realizations() == 8
openmc.lib.next_batch()
assert openmc.lib.num_realizations() == 8
finally:
openmc.capi.simulation_finalize()
openmc.lib.simulation_finalize()
def test_reset(capi_run):
# Init and run 10 batches.
openmc.capi.hard_reset()
openmc.capi.simulation_init()
openmc.lib.hard_reset()
openmc.lib.simulation_init()
try:
for i in range(10):
openmc.capi.next_batch()
openmc.lib.next_batch()
# Make sure there are 5 realizations for the 5 active batches.
assert openmc.capi.num_realizations() == 5
assert openmc.capi.tallies[2].num_realizations == 5
_, keff_sd1 = openmc.capi.keff()
tally_sd1 = openmc.capi.tallies[2].std_dev[0]
assert openmc.lib.num_realizations() == 5
assert openmc.lib.tallies[2].num_realizations == 5
_, keff_sd1 = openmc.lib.keff()
tally_sd1 = openmc.lib.tallies[2].std_dev[0]
# Reset and run 3 more batches. Check the number of realizations.
openmc.capi.reset()
openmc.lib.reset()
for i in range(3):
openmc.capi.next_batch()
assert openmc.capi.num_realizations() == 3
assert openmc.capi.tallies[2].num_realizations == 3
openmc.lib.next_batch()
assert openmc.lib.num_realizations() == 3
assert openmc.lib.tallies[2].num_realizations == 3
# Check the tally std devs to make sure results were cleared.
_, keff_sd2 = openmc.capi.keff()
tally_sd2 = openmc.capi.tallies[2].std_dev[0]
_, keff_sd2 = openmc.lib.keff()
tally_sd2 = openmc.lib.tallies[2].std_dev[0]
assert keff_sd2 > keff_sd1
assert tally_sd2 > tally_sd1
finally:
openmc.capi.simulation_finalize()
openmc.lib.simulation_finalize()
def test_reproduce_keff(capi_init):
# Get k-effective after run
openmc.capi.hard_reset()
openmc.capi.run()
keff0 = openmc.capi.keff()
openmc.lib.hard_reset()
openmc.lib.run()
keff0 = openmc.lib.keff()
# Reset, run again, and get k-effective again. they should match
openmc.capi.hard_reset()
openmc.capi.run()
keff1 = openmc.capi.keff()
openmc.lib.hard_reset()
openmc.lib.run()
keff1 = openmc.lib.keff()
assert keff0 == pytest.approx(keff1)
def test_find_cell(capi_init):
cell, instance = openmc.capi.find_cell((0., 0., 0.))
assert cell is openmc.capi.cells[1]
cell, instance = openmc.capi.find_cell((0.4, 0., 0.))
assert cell is openmc.capi.cells[2]
cell, instance = openmc.lib.find_cell((0., 0., 0.))
assert cell is openmc.lib.cells[1]
cell, instance = openmc.lib.find_cell((0.4, 0., 0.))
assert cell is openmc.lib.cells[2]
with pytest.raises(exc.GeometryError):
openmc.capi.find_cell((100., 100., 100.))
openmc.lib.find_cell((100., 100., 100.))
def test_find_material(capi_init):
mat = openmc.capi.find_material((0., 0., 0.))
assert mat is openmc.capi.materials[1]
mat = openmc.capi.find_material((0.4, 0., 0.))
assert mat is openmc.capi.materials[2]
mat = openmc.lib.find_material((0., 0., 0.))
assert mat is openmc.lib.materials[1]
mat = openmc.lib.find_material((0.4, 0., 0.))
assert mat is openmc.lib.materials[2]
def test_mesh(capi_init):
mesh = openmc.capi.RegularMesh()
mesh = openmc.lib.RegularMesh()
mesh.dimension = (2, 3, 4)
assert mesh.dimension == (2, 3, 4)
with pytest.raises(exc.AllocationError):
mesh2 = openmc.capi.RegularMesh(mesh.id)
mesh2 = openmc.lib.RegularMesh(mesh.id)
# Make sure each combination of parameters works
ll = (0., 0., 0.)
@ -394,47 +394,47 @@ def test_mesh(capi_init):
assert mesh.upper_right == pytest.approx(ur)
assert mesh.width == pytest.approx(width)
meshes = openmc.capi.meshes
meshes = openmc.lib.meshes
assert isinstance(meshes, Mapping)
assert len(meshes) == 1
for mesh_id, mesh in meshes.items():
assert isinstance(mesh, openmc.capi.RegularMesh)
assert isinstance(mesh, openmc.lib.RegularMesh)
assert mesh_id == mesh.id
mf = openmc.capi.MeshFilter(mesh)
mf = openmc.lib.MeshFilter(mesh)
assert mf.mesh == mesh
msf = openmc.capi.MeshSurfaceFilter(mesh)
msf = openmc.lib.MeshSurfaceFilter(mesh)
assert msf.mesh == mesh
def test_restart(capi_init, mpi_intracomm):
# Finalize and re-init to make internal state consistent with XML.
openmc.capi.hard_reset()
openmc.capi.finalize()
openmc.capi.init(intracomm=mpi_intracomm)
openmc.capi.simulation_init()
openmc.lib.hard_reset()
openmc.lib.finalize()
openmc.lib.init(intracomm=mpi_intracomm)
openmc.lib.simulation_init()
# Run for 7 batches then write a statepoint.
for i in range(7):
openmc.capi.next_batch()
openmc.capi.statepoint_write('restart_test.h5', True)
openmc.lib.next_batch()
openmc.lib.statepoint_write('restart_test.h5', True)
# Run 3 more batches and copy the keff.
for i in range(3):
openmc.capi.next_batch()
keff0 = openmc.capi.keff()
openmc.lib.next_batch()
keff0 = openmc.lib.keff()
# Restart the simulation from the statepoint and the 3 remaining active batches.
openmc.capi.simulation_finalize()
openmc.capi.hard_reset()
openmc.capi.finalize()
openmc.capi.init(args=('-r', 'restart_test.h5'))
openmc.capi.simulation_init()
openmc.lib.simulation_finalize()
openmc.lib.hard_reset()
openmc.lib.finalize()
openmc.lib.init(args=('-r', 'restart_test.h5'))
openmc.lib.simulation_init()
for i in range(3):
openmc.capi.next_batch()
keff1 = openmc.capi.keff()
openmc.capi.simulation_finalize()
openmc.lib.next_batch()
keff1 = openmc.lib.keff()
openmc.lib.simulation_finalize()
# Compare the keff values.
assert keff0 == pytest.approx(keff1)
@ -442,13 +442,13 @@ def test_restart(capi_init, mpi_intracomm):
def test_load_nuclide(capi_init):
# load multiple nuclides
openmc.capi.load_nuclide('H3')
assert 'H3' in openmc.capi.nuclides
openmc.capi.load_nuclide('Pu239')
assert 'Pu239' in openmc.capi.nuclides
openmc.lib.load_nuclide('H3')
assert 'H3' in openmc.lib.nuclides
openmc.lib.load_nuclide('Pu239')
assert 'Pu239' in openmc.lib.nuclides
# load non-existent nuclide
with pytest.raises(exc.DataError):
openmc.capi.load_nuclide('Pu3')
openmc.lib.load_nuclide('Pu3')
def test_id_map(capi_init):
@ -457,7 +457,7 @@ def test_id_map(capi_init):
[(3, 3), (2, 2), (3, 3)]], dtype='int32')
# create a plot object
s = openmc.capi.plot._PlotBase()
s = openmc.lib.plot._PlotBase()
s.width = 1.26
s.height = 1.26
s.v_res = 3
@ -466,7 +466,7 @@ def test_id_map(capi_init):
s.basis = 'xy'
s.level = -1
ids = openmc.capi.plot.id_map(s)
ids = openmc.lib.plot.id_map(s)
assert np.array_equal(expected_ids, ids)
def test_property_map(capi_init):
@ -476,7 +476,7 @@ def test_property_map(capi_init):
[(293.6, 0.740582), (293.6, 6.55), (293.6, 0.740582)]], dtype='float')
# create a plot object
s = openmc.capi.plot._PlotBase()
s = openmc.lib.plot._PlotBase()
s.width = 1.26
s.height = 1.26
s.v_res = 3
@ -485,13 +485,13 @@ def test_property_map(capi_init):
s.basis = 'xy'
s.level = -1
properties = openmc.capi.plot.property_map(s)
properties = openmc.lib.plot.property_map(s)
assert np.allclose(expected_properties, properties, atol=1e-04)
def test_position(capi_init):
pos = openmc.capi.plot._Position(1.0, 2.0, 3.0)
pos = openmc.lib.plot._Position(1.0, 2.0, 3.0)
assert tuple(pos) == (1.0, 2.0, 3.0)
@ -506,7 +506,7 @@ def test_global_bounding_box(capi_init):
expected_llc = (-0.63, -0.63, -np.inf)
expected_urc = (0.63, 0.63, np.inf)
llc, urc = openmc.capi.global_bounding_box()
llc, urc = openmc.lib.global_bounding_box()
assert tuple(llc) == expected_llc
assert tuple(urc) == expected_urc

View file

@ -2,7 +2,7 @@ import numpy as np
import scipy as sp
import openmc
import openmc.capi
import openmc.lib
import pytest
@ -15,10 +15,10 @@ def test_t_percentile():
# The reference solutions come from Scipy
ref_ts = [[sp.stats.t.ppf(p, df) for p in test_ps] for df in test_dfs]
test_ts = [[openmc.capi.math.t_percentile(p, df) for p in test_ps]
test_ts = [[openmc.lib.math.t_percentile(p, df) for p in test_ps]
for df in test_dfs]
# The 5 DoF approximation in openmc.capi.math.t_percentile is off by up to
# The 5 DoF approximation in openmc.lib.math.t_percentile is off by up to
# 8e-3 from the scipy solution, so test that one separately with looser
# tolerance
assert np.allclose(ref_ts[:-1], test_ts[:-1])
@ -35,7 +35,7 @@ def test_calc_pn():
test_vals = []
for x in test_xs:
test_vals.append(openmc.capi.math.calc_pn(max_order, x).tolist())
test_vals.append(openmc.lib.math.calc_pn(max_order, x).tolist())
test_vals = np.swapaxes(np.array(test_vals), 0, 1)
@ -55,7 +55,7 @@ def test_evaluate_legendre():
# evaluate legendre incorporates the (2l+1)/2 term on its own
test_coeffs = [1. for l in range(max_order + 1)]
test_vals = np.array([openmc.capi.math.evaluate_legendre(test_coeffs, x)
test_vals = np.array([openmc.lib.math.evaluate_legendre(test_coeffs, x)
for x in test_xs])
assert np.allclose(ref_vals, test_vals)
@ -98,7 +98,7 @@ def test_calc_rn():
ref_vals.append(ylm)
test_vals = []
test_vals = openmc.capi.math.calc_rn(max_order, test_uvw)
test_vals = openmc.lib.math.calc_rn(max_order, test_uvw)
assert np.allclose(ref_vals, test_vals)
@ -133,7 +133,7 @@ def test_calc_zn():
-8.98437500e-02, -1.08693628e-01, 1.78813094e-01,
-1.98191857e-01, 1.65964201e-02, 2.77013853e-04])
test_vals = openmc.capi.math.calc_zn(n, rho, phi)
test_vals = openmc.lib.math.calc_zn(n, rho, phi)
assert np.allclose(ref_vals, test_vals)
@ -147,7 +147,7 @@ def test_calc_zn_rad():
1.00000000e+00, -5.00000000e-01, -1.25000000e-01,
4.37500000e-01, -2.89062500e-01,-8.98437500e-02])
test_vals = openmc.capi.math.calc_zn_rad(n, rho)
test_vals = openmc.lib.math.calc_zn_rad(n, rho)
assert np.allclose(ref_vals, test_vals)
@ -160,7 +160,7 @@ def test_rotate_angle():
# reference: mu of 0 pulls the vector the bottom, so:
ref_uvw = np.array([0., 0., -1.])
test_uvw = openmc.capi.math.rotate_angle(uvw0, mu, phi)
test_uvw = openmc.lib.math.rotate_angle(uvw0, mu, phi)
assert np.array_equal(ref_uvw, test_uvw)
@ -168,51 +168,51 @@ def test_rotate_angle():
mu = 1.
ref_uvw = np.array([1., 0., 0.])
test_uvw = openmc.capi.math.rotate_angle(uvw0, mu, phi)
test_uvw = openmc.lib.math.rotate_angle(uvw0, mu, phi)
assert np.array_equal(ref_uvw, test_uvw)
# Now to test phi is None
mu = 0.9
settings = openmc.capi.settings
settings = openmc.lib.settings
settings.seed = 1
# When seed = 1, phi will be sampled as 1.9116495709698769
# The resultant reference is from hand-calculations given the above
ref_uvw = [0.9, 0.410813051297112, 0.1457142302040]
test_uvw = openmc.capi.math.rotate_angle(uvw0, mu)
test_uvw = openmc.lib.math.rotate_angle(uvw0, mu)
assert np.allclose(ref_uvw, test_uvw)
def test_maxwell_spectrum():
settings = openmc.capi.settings
settings = openmc.lib.settings
settings.seed = 1
T = 0.5
ref_val = 0.6129982175261098
test_val = openmc.capi.math.maxwell_spectrum(T)
test_val = openmc.lib.math.maxwell_spectrum(T)
assert ref_val == test_val
def test_watt_spectrum():
settings = openmc.capi.settings
settings = openmc.lib.settings
settings.seed = 1
a = 0.5
b = 0.75
ref_val = 0.6247242713640233
test_val = openmc.capi.math.watt_spectrum(a, b)
test_val = openmc.lib.math.watt_spectrum(a, b)
assert ref_val == test_val
def test_normal_dist():
settings = openmc.capi.settings
settings = openmc.lib.settings
settings.seed = 1
a = 14.08
b = 0.0
ref_val = 14.08
test_val = openmc.capi.math.normal_variate(a, b)
test_val = openmc.lib.math.normal_variate(a, b)
assert ref_val == pytest.approx(test_val)
@ -220,7 +220,7 @@ def test_normal_dist():
a = 14.08
b = 1.0
ref_val = 16.436645416691427
test_val = openmc.capi.math.normal_variate(a, b)
test_val = openmc.lib.math.normal_variate(a, b)
assert ref_val == pytest.approx(test_val)
@ -234,13 +234,13 @@ def test_broaden_wmp_polynomials():
n = 6
ref_val = [2., 1.41421356, 1.0001, 0.70731891, 0.50030001, 0.353907]
test_val = openmc.capi.math.broaden_wmp_polynomials(test_E, test_dopp, n)
test_val = openmc.lib.math.broaden_wmp_polynomials(test_E, test_dopp, n)
assert np.allclose(ref_val, test_val)
# now beta < 6
test_dopp = 5.
ref_val = [1.99999885, 1.41421356, 1.04, 0.79195959, 0.6224, 0.50346003]
test_val = openmc.capi.math.broaden_wmp_polynomials(test_E, test_dopp, n)
test_val = openmc.lib.math.broaden_wmp_polynomials(test_E, test_dopp, n)
assert np.allclose(ref_val, test_val)