Merge pull request #1538 from paulromano/pullrequestinc-part3

Address review from PullRequest Inc. (Part 3)
This commit is contained in:
Patrick Shriwise 2020-04-07 16:29:10 -05:00 committed by GitHub
commit d2cfe1e6a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 517 additions and 609 deletions

View file

@ -1,13 +1,12 @@
import sys
import copy
from collections.abc import Iterable
import copy
import numpy as np
import pandas as pd
import openmc
from openmc.filter import _FILTER_TYPES
import openmc.checkvalue as cv
from .filter import _FILTER_TYPES
# Acceptable tally arithmetic binary operations

View file

@ -4,18 +4,16 @@ from copy import deepcopy
from math import cos, sin, pi
from numbers import Real
from xml.etree import ElementTree as ET
from uncertainties import UFloat
import sys
import warnings
import numpy as np
from uncertainties import UFloat
import openmc
import openmc.checkvalue as cv
from openmc.surface import Halfspace
from openmc.region import Region, Intersection, Complement
from openmc._xml import get_text
from ._xml import get_text
from .mixin import IDManagerMixin
from .region import Region, Complement
from .surface import Halfspace
class Cell(IDManagerMixin):

View file

@ -10,22 +10,21 @@ References
"""
from contextlib import contextmanager
from collections.abc import Iterable, Mapping
from contextlib import contextmanager
from numbers import Real, Integral
import sys
import time
from ctypes import c_int
import warnings
import h5py
import numpy as np
from scipy import sparse
import h5py
import openmc.lib
from openmc.checkvalue import (check_type, check_length, check_value,
check_greater_than, check_less_than)
from openmc.exceptions import OpenMCError
from .checkvalue import (check_type, check_length, check_value,
check_greater_than, check_less_than)
from .exceptions import OpenMCError
# See if mpi4py module can be imported, define have_mpi global variable
try:

View file

@ -17,15 +17,14 @@ generates ACE-format cross sections.
from collections import OrderedDict
import enum
from pathlib import PurePath, Path
from pathlib import Path
import struct
import sys
import numpy as np
from openmc.mixin import EqualityMixin
import openmc.checkvalue as cv
from .data import ATOMIC_SYMBOL, gnd_name
from openmc.mixin import EqualityMixin
from .data import ATOMIC_SYMBOL, gnd_name, EV_PER_MEV, K_BOLTZMANN
from .endf import ENDF_FLOAT_RE
@ -106,66 +105,59 @@ def ascii_to_binary(ascii_file, binary_file):
"""
# Open ASCII file
ascii = open(str(ascii_file), 'r')
# Read data from ASCII file
with open(str(ascii_file), 'r') as ascii_file:
lines = ascii_file.readlines()
# Set default record length
record_length = 4096
# Read data from ASCII file
lines = ascii.readlines()
ascii.close()
# Open binary file
binary = open(str(binary_file), 'wb')
with open(str(binary_file), 'wb') as binary_file:
idx = 0
while idx < len(lines):
# check if it's a > 2.0.0 version header
if lines[idx].split()[0][1] == '.':
if lines[idx + 1].split()[3] == '3':
idx = idx + 3
else:
raise NotImplementedError('Only backwards compatible ACE'
'headers currently supported')
# Read/write header block
hz = lines[idx][:10].encode()
aw0 = float(lines[idx][10:22])
tz = float(lines[idx][22:34])
hd = lines[idx][35:45].encode()
hk = lines[idx + 1][:70].encode()
hm = lines[idx + 1][70:80].encode()
binary_file.write(struct.pack(str('=10sdd10s70s10s'),
hz, aw0, tz, hd, hk, hm))
idx = 0
# Read/write IZ/AW pairs
data = ' '.join(lines[idx + 2:idx + 6]).split()
iz = np.array(data[::2], dtype=int)
aw = np.array(data[1::2], dtype=float)
izaw = [item for sublist in zip(iz, aw) for item in sublist]
binary_file.write(struct.pack(str('=' + 16*'id'), *izaw))
while idx < len(lines):
# check if it's a > 2.0.0 version header
if lines[idx].split()[0][1] == '.':
if lines[idx + 1].split()[3] == '3':
idx = idx + 3
else:
raise NotImplementedError('Only backwards compatible ACE'
'headers currently supported')
# Read/write header block
hz = lines[idx][:10].encode('UTF-8')
aw0 = float(lines[idx][10:22])
tz = float(lines[idx][22:34])
hd = lines[idx][35:45].encode('UTF-8')
hk = lines[idx + 1][:70].encode('UTF-8')
hm = lines[idx + 1][70:80].encode('UTF-8')
binary.write(struct.pack(str('=10sdd10s70s10s'), hz, aw0, tz, hd, hk, hm))
# Read/write NXS and JXS arrays. Null bytes are added at the end so
# that XSS will start at the second record
nxs = [int(x) for x in ' '.join(lines[idx + 6:idx + 8]).split()]
jxs = [int(x) for x in ' '.join(lines[idx + 8:idx + 12]).split()]
binary_file.write(struct.pack(str('=16i32i{}x'.format(record_length - 500)),
*(nxs + jxs)))
# Read/write IZ/AW pairs
data = ' '.join(lines[idx + 2:idx + 6]).split()
iz = list(map(int, data[::2]))
aw = list(map(float, data[1::2]))
izaw = [item for sublist in zip(iz, aw) for item in sublist]
binary.write(struct.pack(str('=' + 16*'id'), *izaw))
# Read/write XSS array. Null bytes are added to form a complete record
# at the end of the file
n_lines = (nxs[0] + 3)//4
start = idx + _ACE_HEADER_SIZE
xss = np.fromstring(' '.join(lines[start:start + n_lines]), sep=' ')
extra_bytes = record_length - ((len(xss)*8 - 1) % record_length + 1)
binary_file.write(struct.pack(str('={}d{}x'.format(
nxs[0], extra_bytes)), *xss))
# Read/write NXS and JXS arrays. Null bytes are added at the end so
# that XSS will start at the second record
nxs = list(map(int, ' '.join(lines[idx + 6:idx + 8]).split()))
jxs = list(map(int, ' '.join(lines[idx + 8:idx + 12]).split()))
binary.write(struct.pack(str('=16i32i{0}x'.format(record_length - 500)),
*(nxs + jxs)))
# Read/write XSS array. Null bytes are added to form a complete record
# at the end of the file
n_lines = (nxs[0] + 3)//4
xss = list(map(float, ' '.join(lines[
idx + 12:idx + 12 + n_lines]).split()))
extra_bytes = record_length - ((len(xss)*8 - 1) % record_length + 1)
binary.write(struct.pack(str('={0}d{1}x'.format(nxs[0], extra_bytes)),
*xss))
# Advance to next table in file
idx += 12 + n_lines
# Close binary file
binary.close()
# Advance to next table in file
idx += _ACE_HEADER_SIZE + n_lines
def get_table(filename, name=None):
@ -197,6 +189,11 @@ def get_table(filename, name=None):
.format(name))
# The beginning of an ASCII ACE file consists of 12 lines that include the name,
# atomic weight ratio, iz/aw pairs, and the NXS and JXS arrays
_ACE_HEADER_SIZE = 12
class Library(EqualityMixin):
"""A Library objects represents an ACE-formatted file which may contain
multiple tables with data.
@ -298,15 +295,15 @@ class Library(EqualityMixin):
continue
if verbose:
kelvin = round(temperature * 1e6 / 8.617342e-5)
print("Loading nuclide {0} at {1} K".format(name, kelvin))
kelvin = round(temperature * EV_PER_MEV / K_BOLTZMANN)
print("Loading nuclide {} at {} K".format(name, kelvin))
# Read JXS
jxs = list(struct.unpack(str('=32i'), ace_file.read(128)))
# Read XSS
ace_file.seek(start_position + recl_length)
xss = list(struct.unpack(str('={0}d'.format(length)),
xss = list(struct.unpack(str('={}d'.format(length)),
ace_file.read(length*8)))
# Insert zeros at beginning of NXS, JXS, and XSS arrays so that the
@ -346,7 +343,7 @@ class Library(EqualityMixin):
tables_seen = set()
lines = [ace_file.readline() for i in range(13)]
lines = [ace_file.readline() for i in range(_ACE_HEADER_SIZE + 1)]
while len(lines) != 0 and lines[0].strip() != '':
# Read name of table, atomic mass ratio, and temperature. If first
@ -376,6 +373,8 @@ class Library(EqualityMixin):
datastr = '0 ' + ' '.join(lines[6:8])
nxs = np.fromstring(datastr, sep=' ', dtype=int)
# Detemrine number of lines in the XSS array; each line consists of
# four values
n_lines = (nxs[1] + 3)//4
# Ensure that we have more tables to read in
@ -387,23 +386,23 @@ class Library(EqualityMixin):
if (table_names is not None) and (name not in table_names):
for _ in range(n_lines - 1):
ace_file.readline()
lines = [ace_file.readline() for i in range(13)]
lines = [ace_file.readline() for i in range(_ACE_HEADER_SIZE + 1)]
continue
# Read lines corresponding to this table
lines += [ace_file.readline() for i in range(n_lines - 1)]
if verbose:
kelvin = round(temperature * 1e6 / 8.617342e-5)
print("Loading nuclide {0} at {1} K".format(name, kelvin))
kelvin = round(temperature * EV_PER_MEV / K_BOLTZMANN)
print("Loading nuclide {} at {} K".format(name, kelvin))
# Insert zeros at beginning of NXS, JXS, and XSS arrays so that the
# indexing will be the same as Fortran. This makes it easier to
# follow the ACE format specification.
datastr = '0 ' + ' '.join(lines[8:12])
datastr = '0 ' + ' '.join(lines[8:_ACE_HEADER_SIZE])
jxs = np.fromstring(datastr, dtype=int, sep=' ')
datastr = '0.0 ' + ''.join(lines[12:12+n_lines])
datastr = '0.0 ' + ''.join(lines[_ACE_HEADER_SIZE:_ACE_HEADER_SIZE + n_lines])
xss = np.fromstring(datastr, sep=' ')
# When NJOY writes an ACE file, any values less than 1e-100 actually
@ -422,7 +421,7 @@ class Library(EqualityMixin):
self.tables.append(table)
# Read all data blocks
lines = [ace_file.readline() for i in range(13)]
lines = [ace_file.readline() for i in range(_ACE_HEADER_SIZE + 1)]
class TableType(enum.Enum):

View file

@ -179,11 +179,12 @@ class AngleDistribution(EqualityMixin):
for i in range(n_energies):
if lc[i] > 0:
# Equiprobable 32 bin distribution
n_bins = 32
idx = location_dist + abs(lc[i]) - 1
cos = ace.xss[idx:idx + 33]
pdf = np.zeros(33)
pdf[:32] = 1.0/(32.0*np.diff(cos))
cdf = np.linspace(0.0, 1.0, 33)
cos = ace.xss[idx:idx + n_bins + 1]
pdf = np.zeros(n_bins + 1)
pdf[:n_bins] = 1.0/(n_bins*np.diff(cos))
cdf = np.linspace(0.0, 1.0, n_bins + 1)
mu_i = Tabular(cos, pdf, 'histogram', ignore_negative=True)
mu_i.c = cdf
@ -192,6 +193,7 @@ class AngleDistribution(EqualityMixin):
idx = location_dist + abs(lc[i]) - 1
intt = int(ace.xss[idx])
n_points = int(ace.xss[idx + 1])
# Data is given as rows of (values, PDF, CDF)
data = ace.xss[idx + 2:idx + 2 + 3*n_points]
data.shape = (3, n_points)

View file

@ -1,11 +1,10 @@
from abc import ABCMeta, abstractmethod
from io import StringIO
from abc import ABC, abstractmethod
import openmc.data
from openmc.mixin import EqualityMixin
class AngleEnergy(EqualityMixin, metaclass=ABCMeta):
class AngleEnergy(EqualityMixin, ABC):
"""Distribution in angle and energy of a secondary particle."""
@abstractmethod
def to_hdf5(self, group):

View file

@ -163,6 +163,10 @@ class CorrelatedAngleEnergy(AngleEnergy):
elif isinstance(d, Discrete):
n_discrete_lines[i] = n
interpolation[i] = 1
else:
raise ValueError(
'Invalid univariate energy distribution as part of '
'correlated angle-energy: {}'.format(d))
eout[0, offset_e:offset_e+n] = d.x
eout[1, offset_e:offset_e+n] = d.p
eout[2, offset_e:offset_e+n] = d.c
@ -345,10 +349,9 @@ class CorrelatedAngleEnergy(AngleEnergy):
for i in range(n_energy_in):
idx = ldis + loc_dist[i] - 1
# intt = interpolation scheme (1=hist, 2=lin-lin)
INTTp = int(ace.xss[idx])
intt = INTTp % 10
n_discrete_lines = (INTTp - intt)//10
# intt = interpolation scheme (1=hist, 2=lin-lin). When discrete
# lines are present, the value given is 10*n_discrete_lines + intt
n_discrete_lines, intt = divmod(int(ace.xss[idx]), 10)
if intt not in (1, 2):
warn("Interpolation scheme for continuous tabular distribution "
"is not histogram or linear-linear.")

View file

@ -177,8 +177,26 @@ ATOMIC_SYMBOL = {0: 'n', 1: 'H', 2: 'He', 3: 'Li', 4: 'Be', 5: 'B', 6: 'C',
118: 'Og'}
ATOMIC_NUMBER = {value: key for key, value in ATOMIC_SYMBOL.items()}
# Values here are from the Committee on Data for Science and Technology
# (CODATA) 2014 recommendation (doi:10.1103/RevModPhys.88.035009).
# The value of the Boltzman constant in units of eV / K
K_BOLTZMANN = 8.6173303e-5
# Unit conversions
EV_PER_MEV = 1.0e6
JOULE_PER_EV = 1.6021766208e-19
# Avogadro's constant
AVOGADRO = 6.022140857e23
# Neutron mass in units of amu
NEUTRON_MASS = 1.00866491588
# Used in atomic_mass function as a cache
_ATOMIC_MASS = {}
# Regex for GND nuclide names (used in zam function)
_GND_NAME_RE = re.compile(r'([A-Zn][a-z]*)(\d+)((?:_[em]\d+)?)')
@ -290,12 +308,14 @@ def water_density(temperature, pressure=0.1013):
# but they only use 3 digits for their conversion to K.)
if pressure > 100.0:
warn("Results are not valid for pressures above 100 MPa.")
if pressure < 0.0:
warn("Results are not valid for pressures below zero.")
elif pressure < 0.0:
raise ValueError("Pressure must be positive.")
if temperature < 273:
warn("Results are not valid for temperatures below 273.15 K.")
if temperature > 623.15:
elif temperature > 623.15:
warn("Results are not valid for temperatures above 623.15 K.")
elif temperature <= 0.0:
raise ValueError('Temperature must be positive.')
# IAPWS region 4 parameters
n4 = [0.11670521452767e4, -0.72421316703206e6, -0.17073846940092e2,
@ -410,20 +430,3 @@ def zam(name):
metastable = int(state[2:]) if state else 0
return (ATOMIC_NUMBER[symbol], int(A), metastable)
# Values here are from the Committee on Data for Science and Technology
# (CODATA) 2014 recommendation (doi:10.1103/RevModPhys.88.035009).
# The value of the Boltzman constant in units of eV / K
K_BOLTZMANN = 8.6173303e-5
# Unit conversions
EV_PER_MEV = 1.0e6
JOULE_PER_EV = 1.6021766208e-19
# Avogadro's constant
AVOGADRO = 6.022140857e23
# Neutron mass in units of amu
NEUTRON_MASS = 1.00866491588

View file

@ -1,13 +1,11 @@
from collections import namedtuple
from collections.abc import Iterable
from io import StringIO
from math import log
from numbers import Real
import re
from warnings import warn
import numpy as np
from uncertainties import ufloat, unumpy, UFloat
from uncertainties import ufloat, UFloat
import openmc.checkvalue as cv
from openmc.mixin import EqualityMixin
@ -142,12 +140,12 @@ class FissionProductYields(EqualityMixin):
'isomeric_state': ev.target['isomeric_state']
}
# Read independent yields
# Read independent yields (MF=8, MT=454)
if (8, 454) in ev.section:
file_obj = StringIO(ev.section[8, 454])
self.energies, self.independent = get_yields(file_obj)
# Read cumulative yields
# Read cumulative yields (MF=8, MT=459)
if (8, 459) in ev.section:
file_obj = StringIO(ev.section[8, 459])
energies, self.cumulative = get_yields(file_obj)
@ -372,6 +370,7 @@ class Decay(EqualityMixin):
items, values = get_list_record(file_obj)
spin = items[0]
# ENDF-102 specifies that unknown spin should be reported as -77.777
if spin == -77.777:
self.nuclide['spin'] = None
else:

View file

@ -7,19 +7,13 @@ http://www-nds.iaea.org/ndspub/documents/endf/endf102/endf102.pdf
"""
import io
import re
import os
from math import pi
from pathlib import PurePath
from collections import OrderedDict
from collections.abc import Iterable
import re
import numpy as np
from numpy.polynomial.polynomial import Polynomial
from .data import ATOMIC_SYMBOL, gnd_name
from .function import Tabulated1D, INTERPOLATION_SCHEME
from openmc.stats.univariate import Uniform, Tabular, Legendre
from .data import gnd_name
from .function import Tabulated1D
try:
from ._endf import float_endf
_CYTHON = True
@ -397,8 +391,10 @@ class Evaluation:
def __init__(self, filename_or_obj):
if isinstance(filename_or_obj, (str, PurePath)):
fh = open(str(filename_or_obj), 'r')
need_to_close = True
else:
fh = filename_or_obj
need_to_close = False
self.section = {}
self.info = {}
self.target = {}
@ -446,6 +442,9 @@ class Evaluation:
section_data += line
self.section[MF, MT] = section_data
if need_to_close:
fh.close()
self._read_header()
def __repr__(self):

View file

@ -1,19 +1,19 @@
from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from collections.abc import Iterable
from numbers import Integral, Real
from warnings import warn
import numpy as np
from .function import Tabulated1D, INTERPOLATION_SCHEME
from openmc.stats.univariate import Univariate, Tabular, Discrete, Mixture
import openmc.checkvalue as cv
from openmc.mixin import EqualityMixin
from openmc.stats.univariate import Univariate, Tabular, Discrete, Mixture
from .data import EV_PER_MEV
from .endf import get_tab1_record, get_tab2_record
from .function import Tabulated1D, INTERPOLATION_SCHEME
class EnergyDistribution(EqualityMixin, metaclass=ABCMeta):
class EnergyDistribution(EqualityMixin, ABC):
"""Abstract superclass for all energy distributions."""
def __init__(self):
pass

View file

@ -1,16 +1,12 @@
from collections.abc import Callable
from copy import deepcopy
from io import StringIO
import sys
import h5py
import numpy as np
import openmc.checkvalue as cv
from openmc.mixin import EqualityMixin
from .data import EV_PER_MEV
from .endf import get_cont_record, get_list_record, get_tab1_record, Evaluation
from .function import Function1D, Tabulated1D, Polynomial, sum_functions
import openmc.checkvalue as cv
from openmc.mixin import EqualityMixin
_NAMES = (

View file

@ -1,14 +1,14 @@
from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from collections.abc import Iterable, Callable
from functools import reduce
from itertools import zip_longest
from numbers import Real, Integral
from math import exp, log
from numbers import Real, Integral
import numpy as np
import openmc.data
import openmc.checkvalue as cv
import openmc.data
from openmc.mixin import EqualityMixin
from .data import EV_PER_MEV
@ -56,7 +56,7 @@ def sum_functions(funcs):
return Polynomial(coeffs)
class Function1D(EqualityMixin, metaclass=ABCMeta):
class Function1D(EqualityMixin, ABC):
"""A function of one independent variable with HDF5 support."""
@abstractmethod
def __call__(self): pass

View file

@ -4,7 +4,7 @@ from numbers import Real, Integral
import numpy as np
import openmc.checkvalue as cv
from openmc.stats import Tabular, Univariate, Discrete
from openmc.stats import Tabular, Univariate
from .angle_energy import AngleEnergy
from .endf import get_tab2_record, get_tab1_record

View file

@ -1,13 +1,13 @@
from numbers import Integral, Real
from numbers import Real
from math import exp, erf, pi, sqrt
import h5py
import numpy as np
from . import WMP_VERSION, WMP_VERSION_MAJOR
from .data import K_BOLTZMANN
import openmc.checkvalue as cv
from openmc.mixin import EqualityMixin
from . import WMP_VERSION, WMP_VERSION_MAJOR
from .data import K_BOLTZMANN
# Constants that determine which value to access

View file

@ -2,18 +2,17 @@ from collections import OrderedDict
from collections.abc import Mapping, Callable
from copy import deepcopy
from io import StringIO
from math import pi
from numbers import Integral, Real
from math import pi, sqrt
import os
import h5py
import numpy as np
import pandas as pd
from scipy.interpolate import CubicSpline
from scipy.integrate import quad
from openmc.mixin import EqualityMixin
import openmc.checkvalue as cv
from openmc.mixin import EqualityMixin
from . import HDF5_VERSION
from .ace import Table, get_metadata, get_table
from .data import ATOMIC_SYMBOL, EV_PER_MEV

View file

@ -1,7 +1,5 @@
from collections.abc import Iterable
from io import StringIO
from numbers import Real
import sys
import numpy as np

View file

@ -1,8 +1,8 @@
from collections.abc import Iterable, Callable, MutableMapping
from copy import deepcopy
from numbers import Real, Integral
from warnings import warn
from io import StringIO
from numbers import Real
from warnings import warn
import numpy as np

View file

@ -1,4 +1,3 @@
from collections import defaultdict
from collections.abc import MutableSequence, Iterable
import io
@ -6,6 +5,7 @@ import numpy as np
from numpy.polynomial import Polynomial
import pandas as pd
import openmc.checkvalue as cv
from .data import NEUTRON_MASS
from .endf import get_head_record, get_cont_record, get_tab1_record, get_list_record
try:
@ -14,7 +14,6 @@ try:
_reconstruct = True
except ImportError:
_reconstruct = False
import openmc.checkvalue as cv
class Resonances:

View file

@ -2,8 +2,6 @@
An ndarray to store reaction rates with string, integer, or slice indexing.
"""
from collections import OrderedDict
import numpy as np

View file

@ -5,10 +5,9 @@ Contains results generation and saving capabilities.
from collections import OrderedDict
import copy
from warnings import warn
import numpy as np
import h5py
import numpy as np
from . import comm, have_mpi, MPI
from .reaction_rates import ReactionRates

View file

@ -1,10 +1,9 @@
from collections import OrderedDict
import re
import os
import re
from xml.etree import ElementTree as ET
import openmc.checkvalue as cv
from numbers import Real
from openmc.data import NATURAL_ABUNDANCE, atomic_mass

View file

@ -1,7 +1,6 @@
from abc import ABCMeta
from collections import OrderedDict
from collections.abc import Iterable
import copy
import hashlib
from itertools import product
from numbers import Real, Integral

View file

@ -1,9 +1,6 @@
from numbers import Integral, Real
from xml.etree import ElementTree as ET
import numpy as np
import pandas as pd
import openmc.checkvalue as cv
from . import Filter

View file

@ -4,11 +4,9 @@ from copy import deepcopy
from pathlib import Path
from xml.etree import ElementTree as ET
import numpy as np
import openmc
import openmc._xml as xml
from openmc.checkvalue import check_type
from .checkvalue import check_type
class Geometry:

View file

@ -1,22 +1,21 @@
from abc import ABCMeta
from abc import ABC
from collections import OrderedDict
from collections.abc import Iterable
from copy import deepcopy
from math import sqrt, floor
from numbers import Real
import types
from xml.etree import ElementTree as ET
import numpy as np
import warnings
import types
import openmc.checkvalue as cv
import openmc
from openmc._xml import get_text
from openmc.mixin import IDManagerMixin
import openmc.checkvalue as cv
from ._xml import get_text
from .mixin import IDManagerMixin
class Lattice(IDManagerMixin, metaclass=ABCMeta):
class Lattice(IDManagerMixin, ABC):
"""A repeating structure wherein each element is a universe.
Parameters

View file

@ -5,9 +5,8 @@ from ctypes import c_int, c_int32, c_double, c_char_p, POINTER
from weakref import WeakValueDictionary
import numpy as np
from numpy.ctypeslib import as_array
from openmc.exceptions import AllocationError, InvalidIDError
from ..exceptions import AllocationError, InvalidIDError
from . import _dll
from .core import _FortranObjectWithID
from .error import _error_handler

View file

@ -1,14 +1,11 @@
import sys
from contextlib import contextmanager
from ctypes import (CDLL, c_bool, c_int, c_int32, c_int64, c_double, c_char_p,
from ctypes import (c_bool, c_int, c_int32, c_int64, c_double, c_char_p,
c_char, POINTER, Structure, c_void_p, create_string_buffer)
from warnings import warn
import sys
import numpy as np
from numpy.ctypeslib import as_array
from openmc.exceptions import AllocationError
from . import _dll
from .error import _error_handler
import openmc.lib

View file

@ -1,15 +1,13 @@
from collections.abc import Mapping, Iterable
from collections.abc import Mapping
from ctypes import c_int, c_int32, c_double, POINTER
from weakref import WeakValueDictionary
import numpy as np
from numpy.ctypeslib import as_array
from openmc.exceptions import AllocationError, InvalidIDError
from ..exceptions import AllocationError, InvalidIDError
from . import _dll
from .core import _FortranObjectWithID
from .error import _error_handler
from .material import Material
__all__ = ['RegularMesh', 'meshes']

View file

@ -2,10 +2,7 @@ from collections.abc import Mapping
from ctypes import c_int, c_char_p, POINTER, c_size_t
from weakref import WeakValueDictionary
import numpy as np
from numpy.ctypeslib import as_array
from openmc.exceptions import DataError, AllocationError
from ..exceptions import DataError, AllocationError
from . import _dll
from .core import _FortranObject
from .error import _error_handler

View file

@ -1,9 +1,7 @@
from ctypes import (c_int, c_int32, c_int64, c_double, c_char_p, c_bool,
POINTER)
from ctypes import c_int, c_int32, c_int64, c_double, c_char_p, c_bool
from . import _dll
from .core import _DLLGlobal
from .error import _error_handler
_RUN_MODES = {1: 'fixed source',
2: 'eigenvalue',

View file

@ -1,10 +1,10 @@
from collections import OrderedDict, defaultdict, namedtuple, Counter
from collections.abc import Iterable
from copy import deepcopy
from numbers import Real, Integral
from numbers import Real
from pathlib import Path
import warnings
import re
import warnings
from xml.etree import ElementTree as ET
import numpy as np
@ -12,13 +12,13 @@ import numpy as np
import openmc
import openmc.data
import openmc.checkvalue as cv
from openmc._xml import clean_indentation
from ._xml import clean_indentation
from .mixin import IDManagerMixin
# Units for density supported by OpenMC
DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/m3', 'atom/b-cm', 'atom/cm3', 'sum',
'macro']
DENSITY_UNITS = ('g/cm3', 'g/cc', 'kg/m3', 'atom/b-cm', 'atom/cm3', 'sum',
'macro')
NuclideTuple = namedtuple('NuclideTuple', ['name', 'percent', 'percent_type'])

View file

@ -1,19 +1,19 @@
from abc import ABCMeta
from abc import ABC
from collections.abc import Iterable
from numbers import Real, Integral
from xml.etree import ElementTree as ET
import sys
import warnings
from xml.etree import ElementTree as ET
import numpy as np
import openmc.checkvalue as cv
import openmc
from openmc._xml import get_text
from openmc.mixin import EqualityMixin, IDManagerMixin
from ._xml import get_text
from .mixin import IDManagerMixin
from .surface import _BOUNDARY_TYPES
class MeshBase(IDManagerMixin, metaclass=ABCMeta):
class MeshBase(IDManagerMixin, ABC):
"""A mesh that partitions geometry for tallying purposes.
Parameters
@ -323,7 +323,7 @@ class RegularMesh(MeshBase):
return mesh
def build_cells(self, bc=['reflective'] * 6):
def build_cells(self, bc=None):
"""Generates a lattice of universes with the same dimensionality
as the mesh object. The individual cells/universes produced
will not have material definitions applied and so downstream code
@ -331,12 +331,13 @@ class RegularMesh(MeshBase):
Parameters
----------
bc : iterable of {'reflective', 'periodic', 'transmission', or 'vacuum'}
bc : iterable of {'reflective', 'periodic', 'transmission', 'vacuum', or 'white'}
Boundary conditions for each of the four faces of a rectangle
(if aplying to a 2D mesh) or six faces of a parallelepiped
(if applying to a 2D mesh) or six faces of a parallelepiped
(if applying to a 3D mesh) provided in the following order:
[x min, x max, y min, y max, z min, z max]. 2-D cells do not
contain the z min and z max entries.
contain the z min and z max entries. Defaults to 'reflective' for
all faces.
Returns
-------
@ -350,11 +351,12 @@ class RegularMesh(MeshBase):
geometry.
"""
cv.check_length('bc', bc, length_min=4, length_max=6)
if bc is None:
bc = ['reflective'] * 6
if len(bc) not in (4, 6):
raise ValueError('Boundary condition must be of length 4 or 6')
for entry in bc:
cv.check_value('bc', entry, ['transmission', 'vacuum',
'reflective', 'periodic'])
cv.check_value('bc', entry, _BOUNDARY_TYPES)
n_dim = len(self.dimension)
@ -391,7 +393,7 @@ class RegularMesh(MeshBase):
# We will concurrently build cells to assign to these universes
cells = []
universes = []
for index in self.indices:
for _ in self.indices:
cells.append(openmc.Cell())
universes.append(openmc.Universe())
universes[-1].add_cell(cells[-1])

View file

@ -1,7 +1,6 @@
from collections.abc import Iterable
from numbers import Real
import copy
import sys
from numbers import Real
import numpy as np

View file

@ -1,10 +1,9 @@
import sys
import os
import copy
import pickle
from numbers import Integral
from collections import OrderedDict
from collections.abc import Iterable
import copy
from numbers import Integral
import os
import pickle
from warnings import warn
import numpy as np
@ -12,7 +11,7 @@ import numpy as np
import openmc
import openmc.mgxs
import openmc.checkvalue as cv
from openmc.tallies import ESTIMATOR_TYPES
from ..tallies import ESTIMATOR_TYPES
class Library:
@ -864,11 +863,12 @@ class Library:
if not os.path.exists(directory):
os.makedirs(directory)
full_filename = os.path.join(directory, filename + '.pkl')
full_filename = os.path.join(directory, '{}.pkl'.format(filename))
full_filename = full_filename.replace(' ', '-')
# Load and return pickled Library object
pickle.dump(self, open(full_filename, 'wb'))
with open(full_filename, 'wb') as f:
pickle.dump(self, f)
@staticmethod
def load_from_file(filename='mgxs', directory='mgxs'):
@ -903,7 +903,8 @@ class Library:
full_filename = full_filename.replace(' ', '-')
# Load and return pickled Library object
return pickle.load(open(full_filename, 'rb'))
with open(full_filename, 'rb') as f:
return pickle.load(f)
def get_xsdata(self, domain, xsdata_name, nuclide='total', xs_type='macro',
subdomain=None):

View file

@ -1,27 +1,25 @@
from collections import OrderedDict
from collections.abc import Iterable
import copy
import itertools
from numbers import Integral
import warnings
import os
import sys
import copy
from abc import ABCMeta
import numpy as np
import openmc
from openmc.mgxs import MGXS
from openmc.mgxs.mgxs import _DOMAIN_TO_FILTER
import openmc.checkvalue as cv
from openmc.mgxs import MGXS
from .mgxs import _DOMAIN_TO_FILTER
# Supported cross section types
MDGXS_TYPES = ['delayed-nu-fission',
'chi-delayed',
'beta',
'decay-rate',
'delayed-nu-fission matrix']
MDGXS_TYPES = (
'delayed-nu-fission',
'chi-delayed',
'beta',
'decay-rate',
'delayed-nu-fission matrix'
)
# Maximum number of delayed groups, from src/constants.F90
MAX_DELAYED_GROUPS = 8
@ -51,7 +49,7 @@ class MDGXS(MGXS):
name : str, optional
Name of the multi-group cross section. Used as a label to identify
tallies in OpenMC 'tallies.xml' file.
delayed_groups : list of int
delayed_groups : list of int, optional
Delayed groups to filter out the xs
num_polar : Integral, optional
Number of equi-width polar angle bins for angle discretization;
@ -74,7 +72,7 @@ class MDGXS(MGXS):
Domain type for spatial homogenization
energy_groups : openmc.mgxs.EnergyGroups
Energy group structure for energy condensation
delayed_groups : list of int
delayed_groups : list of int, optional
Delayed groups to filter out the xs
num_polar : Integral
Number of equi-width polar angle bins for angle discretization
@ -250,7 +248,7 @@ class MDGXS(MGXS):
name : str, optional
Name of the multi-group cross section. Used as a label to identify
tallies in OpenMC 'tallies.xml' file. Defaults to the empty string.
delayed_groups : list of int
delayed_groups : list of int, optional
Delayed groups to filter out the xs
num_polar : Integral, optional
Number of equi-width polar angle bins for angle discretization;
@ -1320,10 +1318,10 @@ class ChiDelayed(MDGXS):
# Sum out all nuclides
nuclides = self.get_nuclides()
delayed_nu_fission_in = delayed_nu_fission_in.summation\
(nuclides=nuclides)
delayed_nu_fission_out = delayed_nu_fission_out.summation\
(nuclides=nuclides)
delayed_nu_fission_in = delayed_nu_fission_in.summation(
nuclides=nuclides)
delayed_nu_fission_out = delayed_nu_fission_out.summation(
nuclides=nuclides)
# Remove coarse energy filter to keep it out of tally arithmetic
energy_filter = delayed_nu_fission_in.find_filter(
@ -2173,6 +2171,8 @@ class MatrixMDGXS(MDGXS):
# Eliminate the trivial score dimension
xs = np.squeeze(xs, axis=len(xs.shape) - 1)
# Eliminate NaNs which may have been produced by dividing by density
xs = np.nan_to_num(xs)
if in_groups == 'all':

View file

@ -1,65 +1,80 @@
from collections import OrderedDict
from numbers import Integral
import warnings
import os
import copy
from abc import ABCMeta
from numbers import Integral
import os
import warnings
import numpy as np
import h5py
import numpy as np
import openmc
import openmc.checkvalue as cv
from openmc.tallies import ESTIMATOR_TYPES
from openmc.mgxs import EnergyGroups
from ..tallies import ESTIMATOR_TYPES
from . import EnergyGroups
# Supported cross section types
MGXS_TYPES = ['total',
'transport',
'nu-transport',
'absorption',
'capture',
'fission',
'nu-fission',
'kappa-fission',
'scatter',
'nu-scatter',
'scatter matrix',
'nu-scatter matrix',
'multiplicity matrix',
'nu-fission matrix',
'scatter probability matrix',
'consistent scatter matrix',
'consistent nu-scatter matrix',
'chi',
'chi-prompt',
'inverse-velocity',
'prompt-nu-fission',
'prompt-nu-fission matrix']
MGXS_TYPES = (
'total',
'transport',
'nu-transport',
'absorption',
'capture',
'fission',
'nu-fission',
'kappa-fission',
'scatter',
'nu-scatter',
'scatter matrix',
'nu-scatter matrix',
'multiplicity matrix',
'nu-fission matrix',
'scatter probability matrix',
'consistent scatter matrix',
'consistent nu-scatter matrix',
'chi',
'chi-prompt',
'inverse-velocity',
'prompt-nu-fission',
'prompt-nu-fission matrix'
)
# Supported domain types
DOMAIN_TYPES = ['cell',
'distribcell',
'universe',
'material',
'mesh']
DOMAIN_TYPES = (
'cell',
'distribcell',
'universe',
'material',
'mesh'
)
# Filter types corresponding to each domain
_DOMAIN_TO_FILTER = {'cell': openmc.CellFilter,
'distribcell': openmc.DistribcellFilter,
'universe': openmc.UniverseFilter,
'material': openmc.MaterialFilter,
'mesh': openmc.MeshFilter}
_DOMAIN_TO_FILTER = {
'cell': openmc.CellFilter,
'distribcell': openmc.DistribcellFilter,
'universe': openmc.UniverseFilter,
'material': openmc.MaterialFilter,
'mesh': openmc.MeshFilter
}
# Supported domain classes
_DOMAINS = (openmc.Cell,
openmc.Universe,
openmc.Material,
openmc.RegularMesh)
_DOMAINS = (
openmc.Cell,
openmc.Universe,
openmc.Material,
openmc.RegularMesh
)
# Supported ScatterMatrixXS angular distribution types
MU_TREATMENTS = ('legendre', 'histogram')
# Supported ScatterMatrixXS angular distribution types. Note that 'histogram' is
# defined here and used in mgxs_library.py, but it is not used for the current
# module
SCATTER_TABULAR = 'tabular'
SCATTER_LEGENDRE = 'legendre'
SCATTER_HISTOGRAM = 'histogram'
MU_TREATMENTS = (
SCATTER_LEGENDRE,
SCATTER_HISTOGRAM
)
# Maximum Legendre order supported by OpenMC
_MAX_LEGENDRE = 10
@ -112,7 +127,7 @@ def _df_column_convert_to_bin(df, current_name, new_name, values_to_bin,
df.rename(columns={current_name: new_name}, inplace=True)
class MGXS(metaclass=ABCMeta):
class MGXS:
"""An abstract multi-group cross section for some energy group structure
within some spatial domain.
@ -245,38 +260,37 @@ class MGXS(metaclass=ABCMeta):
def __deepcopy__(self, memo):
existing = memo.get(id(self))
# If this is the first time we have tried to copy this object, copy it
if existing is None:
clone = type(self).__new__(type(self))
clone._name = self.name
clone._rxn_type = self.rxn_type
clone._by_nuclide = self.by_nuclide
clone._nuclides = copy.deepcopy(self._nuclides, memo)
clone._domain = self.domain
clone._domain_type = self.domain_type
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)
clone._num_polar = self._num_polar
clone._num_azimuthal = self._num_azimuthal
clone._tally_trigger = copy.deepcopy(self.tally_trigger, memo)
clone._rxn_rate_tally = copy.deepcopy(self._rxn_rate_tally, memo)
clone._xs_tally = copy.deepcopy(self._xs_tally, memo)
clone._sparse = self.sparse
clone._loaded_sp = self._loaded_sp
clone._derived = self.derived
clone._hdf5_key = self._hdf5_key
clone._tallies = OrderedDict()
for tally_type, tally in self.tallies.items():
clone.tallies[tally_type] = copy.deepcopy(tally, memo)
memo[id(self)] = clone
return clone
# If this object has been copied before, return the first copy made
else:
if existing is not None:
return existing
# If this is the first time we have tried to copy this object, copy it
clone = type(self).__new__(type(self))
clone._name = self.name
clone._rxn_type = self.rxn_type
clone._by_nuclide = self.by_nuclide
clone._nuclides = copy.deepcopy(self._nuclides, memo)
clone._domain = self.domain
clone._domain_type = self.domain_type
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)
clone._num_polar = self._num_polar
clone._num_azimuthal = self._num_azimuthal
clone._tally_trigger = copy.deepcopy(self.tally_trigger, memo)
clone._rxn_rate_tally = copy.deepcopy(self._rxn_rate_tally, memo)
clone._xs_tally = copy.deepcopy(self._xs_tally, memo)
clone._sparse = self.sparse
clone._loaded_sp = self._loaded_sp
clone._derived = self.derived
clone._hdf5_key = self._hdf5_key
clone._tallies = OrderedDict()
for tally_type, tally in self.tallies.items():
clone.tallies[tally_type] = copy.deepcopy(tally, memo)
memo[id(self)] = clone
return clone
def _add_angle_filters(self, filters):
"""Add the azimuthal and polar bins to the MGXS filters if needed.
Filters will be provided as a ragged 2D list of openmc.Filter objects.
@ -2170,6 +2184,7 @@ class MatrixMGXS(MGXS):
if not isinstance(in_groups, str):
cv.check_iterable_type('groups', in_groups, Integral)
filters.append(openmc.EnergyFilter)
energy_bins = []
for group in in_groups:
energy_bins.append((self.energy_groups.get_group_bounds(group),))
filter_bins.append(tuple(energy_bins))
@ -3725,7 +3740,7 @@ class ScatterMatrixXS(MatrixMGXS):
num_polar, num_azimuthal)
self._formulation = 'simple'
self._correction = 'P0'
self._scatter_format = 'legendre'
self._scatter_format = SCATTER_LEGENDRE
self._legendre_order = 0
self._histogram_bins = 16
self._estimator = 'analog'
@ -3748,12 +3763,12 @@ class ScatterMatrixXS(MatrixMGXS):
process
"""
if self.num_polar > 1 or self.num_azimuthal > 1:
if self.scatter_format == 'histogram':
if self.scatter_format == SCATTER_HISTOGRAM:
return (0, 1, 3, 4, 5)
else:
return (0, 1, 3, 4)
else:
if self.scatter_format == 'histogram':
if self.scatter_format == SCATTER_HISTOGRAM:
return (1, 2, 3)
else:
return (1, 2)
@ -3857,13 +3872,13 @@ class ScatterMatrixXS(MatrixMGXS):
energy = openmc.EnergyFilter(group_edges)
energyout = openmc.EnergyoutFilter(group_edges)
if self.scatter_format == 'legendre':
if self.scatter_format == SCATTER_LEGENDRE:
if self.correction == 'P0' and self.legendre_order == 0:
angle_filter = openmc.LegendreFilter(order=1)
else:
angle_filter = \
openmc.LegendreFilter(order=self.legendre_order)
elif self.scatter_format == 'histogram':
elif self.scatter_format == SCATTER_HISTOGRAM:
bins = np.linspace(-1., 1., num=self.histogram_bins + 1,
endpoint=True)
angle_filter = openmc.MuFilter(bins)
@ -3878,9 +3893,9 @@ class ScatterMatrixXS(MatrixMGXS):
filters = [[energy], [energy]]
# Group-to-group scattering probability matrix
if self.scatter_format == 'legendre':
if self.scatter_format == SCATTER_LEGENDRE:
angle_filter = openmc.LegendreFilter(order=self.legendre_order)
elif self.scatter_format == 'histogram':
elif self.scatter_format == SCATTER_HISTOGRAM:
bins = np.linspace(-1., 1., num=self.histogram_bins + 1,
endpoint=True)
angle_filter = openmc.MuFilter(bins)
@ -3903,7 +3918,7 @@ class ScatterMatrixXS(MatrixMGXS):
if self._rxn_rate_tally is None:
if self.formulation == 'simple':
if self.scatter_format == 'legendre':
if self.scatter_format == SCATTER_LEGENDRE:
# If using P0 correction subtract P1 scatter from the diag.
if self.correction == 'P0' and self.legendre_order == 0:
scatter_p0 = self.tallies[self.rxn_type].get_slice(
@ -3937,7 +3952,7 @@ class ScatterMatrixXS(MatrixMGXS):
# Otherwise, extract scattering moment reaction rate Tally
else:
self._rxn_rate_tally = self.tallies[self.rxn_type]
elif self.scatter_format == 'histogram':
elif self.scatter_format == SCATTER_HISTOGRAM:
# Extract scattering rate distribution tally
self._rxn_rate_tally = self.tallies[self.rxn_type]
@ -3967,14 +3982,14 @@ class ScatterMatrixXS(MatrixMGXS):
tally_key = 'scatter matrix'
# Compute normalization factor summed across outgoing energies
if self.scatter_format == 'legendre':
if self.scatter_format == SCATTER_LEGENDRE:
norm = self.tallies[tally_key].get_slice(
scores=['scatter'],
filters=[openmc.LegendreFilter],
filter_bins=[('P0',)], squeeze=True)
# Compute normalization factor summed across outgoing mu bins
elif self.scatter_format == 'histogram':
elif self.scatter_format == SCATTER_HISTOGRAM:
norm = self.tallies[tally_key].get_slice(
scores=['scatter'])
norm = norm.summation(
@ -3994,14 +4009,14 @@ class ScatterMatrixXS(MatrixMGXS):
if self.nu:
numer = self.tallies['nu-scatter']
# Get the denominator
if self.scatter_format == 'legendre':
if self.scatter_format == SCATTER_LEGENDRE:
denom = self.tallies[tally_key].get_slice(
scores=['scatter'],
filters=[openmc.LegendreFilter],
filter_bins=[('P0',)], squeeze=True)
# Compute normalization factor summed across mu bins
elif self.scatter_format == 'histogram':
elif self.scatter_format == SCATTER_HISTOGRAM:
denom = self.tallies[tally_key].get_slice(
scores=['scatter'])
@ -4048,7 +4063,7 @@ class ScatterMatrixXS(MatrixMGXS):
self._compute_xs()
# Force the angle filter to be the last filter
if self.scatter_format == 'histogram':
if self.scatter_format == SCATTER_HISTOGRAM:
angle_filter = self._xs_tally.find_filter(openmc.MuFilter)
else:
angle_filter = \
@ -4105,13 +4120,13 @@ class ScatterMatrixXS(MatrixMGXS):
def correction(self, correction):
cv.check_value('correction', correction, ('P0', None))
if self.scatter_format == 'legendre':
if self.scatter_format == SCATTER_LEGENDRE:
if correction == 'P0' and self.legendre_order > 0:
msg = 'The P0 correction will be ignored since the ' \
'scattering order {} is greater than '\
'zero'.format(self.legendre_order)
warnings.warn(msg)
elif self.scatter_format == 'histogram':
elif self.scatter_format == SCATTER_HISTOGRAM:
msg = 'The P0 correction will be ignored since the ' \
'scatter format is set to histogram'
warnings.warn(msg)
@ -4131,14 +4146,14 @@ class ScatterMatrixXS(MatrixMGXS):
cv.check_less_than('legendre_order', legendre_order, _MAX_LEGENDRE,
equality=True)
if self.scatter_format == 'legendre':
if self.scatter_format == SCATTER_LEGENDRE:
if self.correction == 'P0' and legendre_order > 0:
msg = 'The P0 correction will be ignored since the ' \
'scattering order {} is greater than '\
'zero'.format(self.legendre_order)
warnings.warn(msg, RuntimeWarning)
self.correction = None
elif self.scatter_format == 'histogram':
elif self.scatter_format == SCATTER_HISTOGRAM:
msg = 'The legendre order will be ignored since the ' \
'scatter format is set to histogram'
warnings.warn(msg)
@ -4226,7 +4241,7 @@ class ScatterMatrixXS(MatrixMGXS):
slice_xs._xs_tally = None
# Slice the Legendre order if needed
if legendre_order != 'same' and self.scatter_format == 'legendre':
if legendre_order != 'same' and self.scatter_format == SCATTER_LEGENDRE:
cv.check_type('legendre_order', legendre_order, Integral)
cv.check_less_than('legendre_order', legendre_order,
self.legendre_order, equality=True)
@ -4363,7 +4378,7 @@ class ScatterMatrixXS(MatrixMGXS):
filter_bins.append((self.energy_groups.get_group_bounds(group),))
# Construct CrossScore for requested scattering moment
if self.scatter_format == 'legendre':
if self.scatter_format == SCATTER_LEGENDRE:
if moment != 'all':
cv.check_type('moment', moment, Integral)
cv.check_greater_than('moment', moment, 0, equality=True)
@ -4508,7 +4523,7 @@ class ScatterMatrixXS(MatrixMGXS):
paths=paths)
# If the matrix is P0, remove the legendre column
if self.scatter_format == 'legendre' and self.legendre_order == 0:
if self.scatter_format == SCATTER_LEGENDRE and self.legendre_order == 0:
df = df.drop(axis=1, labels=['legendre'])
return df
@ -4560,7 +4575,7 @@ class ScatterMatrixXS(MatrixMGXS):
cv.check_value('xs_type', xs_type, ['macro', 'micro'])
if self.correction != 'P0' and self.scatter_format == 'legendre':
if self.correction != 'P0' and self.scatter_format == SCATTER_LEGENDRE:
rxn_type = '{0} (P{1})'.format(self.rxn_type, moment)
else:
rxn_type = self.rxn_type
@ -4648,7 +4663,7 @@ class ScatterMatrixXS(MatrixMGXS):
return to_print
# Set the number of histogram bins
if self.scatter_format == 'histogram':
if self.scatter_format == SCATTER_HISTOGRAM:
num_mu_bins = self.histogram_bins
else:
num_mu_bins = 0

View file

@ -2,15 +2,16 @@ import copy
from numbers import Real, Integral
import os
import numpy as np
import h5py
from scipy.interpolate import interp1d
import numpy as np
from scipy.integrate import simps
from scipy.interpolate import interp1d
from scipy.special import eval_legendre
import openmc
import openmc.mgxs
from openmc.checkvalue import check_type, check_value, check_greater_than, \
from openmc.mgxs import SCATTER_TABULAR, SCATTER_LEGENDRE, SCATTER_HISTOGRAM
from .checkvalue import check_type, check_value, check_greater_than, \
check_iterable_type, check_less_than, check_filetype_version
ROOM_TEMPERATURE_KELVIN = 294.0
@ -24,9 +25,6 @@ _REPRESENTATIONS = [
]
# Supported scattering angular distribution representations
SCATTER_TABULAR = 'tabular'
SCATTER_LEGENDRE = 'legendre'
SCATTER_HISTOGRAM = 'histogram'
_SCATTER_TYPES = [
SCATTER_TABULAR,
SCATTER_LEGENDRE,

View file

@ -7,8 +7,8 @@ import openmc.checkvalue as cv
class EqualityMixin:
"""A Class which provides generic __eq__ and __ne__ functionality which
can easily be inherited by downstream classes.
"""A Class which provides a generic __eq__ method that can be inherited
by downstream classes.
"""
def __eq__(self, other):

View file

@ -1,19 +1,24 @@
from collections.abc import Iterable
from functools import partial
from math import sqrt
from numbers import Real
from functools import partial
from warnings import warn
from operator import attrgetter
from warnings import warn
from openmc import (
XPlane, YPlane, Plane, ZCylinder, Quadric, Cylinder, XCylinder,
YCylinder, Material, Universe, Cell)
from openmc.checkvalue import (
XPlane, YPlane, Plane, ZCylinder, Cylinder, XCylinder,
YCylinder, Universe, Cell)
from ..checkvalue import (
check_type, check_value, check_length, check_less_than,
check_iterable_type)
import openmc.data
ZERO_CELSIUS_TO_KELVIN = 273.15
ZERO_FAHRENHEIT_TO_KELVIN = 459.67
PSI_TO_MPA = 0.006895
def borated_water(boron_ppm, temperature=293., pressure=0.1013, temp_unit='K',
press_unit='MPa', density=None, **kwargs):
"""Return a Material with the composition of boron dissolved in water.
@ -53,14 +58,14 @@ def borated_water(boron_ppm, temperature=293., pressure=0.1013, temp_unit='K',
if temp_unit == 'K':
T = temperature
elif temp_unit == 'C':
T = temperature + 273.15
T = temperature + ZERO_CELSIUS_TO_KELVIN
elif temp_unit == 'F':
T = (temperature + 459.67) * 5.0 / 9.0
T = (temperature + ZERO_FAHRENHEIT_TO_KELVIN) * (5/9)
check_value('pressure unit', press_unit, ('MPa', 'psi'))
if press_unit == 'MPa':
P = pressure
elif press_unit == 'psi':
P = pressure * 0.006895
P = pressure * PSI_TO_MPA
# Set the density of water, either from an explicitly given density or from
# temperature and pressure.
@ -440,7 +445,7 @@ def pin(surfaces, items, subdivisions=None, divide_vols=True,
items
"""
if "cells" in kwargs:
raise SyntaxError(
raise ValueError(
"Cells will be set by this function, not from input arguments.")
check_type("items", items, Iterable)
check_length("surfaces", surfaces, len(items) - 1, len(items) - 1)

View file

@ -1,24 +1,29 @@
import copy
import warnings
import itertools
import random
from abc import ABCMeta, abstractproperty, abstractmethod
from abc import ABC, abstractproperty, abstractmethod
from collections import Counter, defaultdict
from collections.abc import Iterable
import copy
from heapq import heappush, heappop
import itertools
from math import pi, sin, cos, floor, log10, sqrt
from numbers import Real
import random
from random import uniform, gauss
import warnings
import numpy as np
import scipy.spatial
import openmc
from openmc.checkvalue import check_type
from ..checkvalue import check_type
MAX_PF_RSP = 0.38
MAX_PF_CRP = 0.64
MAX_PF_RSP = 0.38 # maximum packing fraction for random sequential packing
MAX_PF_CRP = 0.64 # maximum packing fraction for close random packing
def _volume_sphere(r):
"""Return volume of a sphere of radius r"""
return 4/3 * pi * r**3
class TRISO(openmc.Cell):
@ -95,7 +100,7 @@ class TRISO(openmc.Cell):
k_min:k_max+1, j_min:j_max+1, i_min:i_max+1]))
class _Container(metaclass=ABCMeta):
class _Container(ABC):
"""Container in which to pack spheres.
Parameters
@ -696,7 +701,7 @@ class _SphericalShell(_Container):
@property
def volume(self):
return 4/3*pi*(self.radius**3 - self.inner_radius**3)
return _volume_sphere(self.radius) - _volume_sphere(self.inner_radius)
@radius.setter
def radius(self, radius):
@ -1073,8 +1078,8 @@ def _close_random_pack(domain, spheres, contraction_rate):
"""
inner_pf = 4/3*pi*(inner_diameter/2)**3*num_spheres/domain.volume
outer_pf = 4/3*pi*(outer_diameter/2)**3*num_spheres/domain.volume
inner_pf = _volume_sphere(inner_diameter/2)*num_spheres / domain.volume
outer_pf = _volume_sphere(outer_diameter/2)*num_spheres / domain.volume
j = floor(-log10(outer_pf - inner_pf))
return (outer_diameter - 0.5**j * contraction_rate *
@ -1289,7 +1294,7 @@ def pack_spheres(radius, region, pf=None, num_spheres=None, initial_pf=0.3,
'sphere, and spherical shell.'.format(region))
# Determine the packing fraction/number of spheres
volume = 4/3*pi*radius**3
volume = _volume_sphere(radius)
if pf is None and num_spheres is None:
raise ValueError('`pf` or `num_spheres` must be specified.')
elif pf is None:

View file

@ -1,7 +1,5 @@
import warnings
import openmc.checkvalue as cv
class Nuclide(str):
"""A nuclide that can be used in a material.

View file

@ -1,12 +1,10 @@
import copy
import operator
import numpy as np
import openmoc
import openmc
import openmc.checkvalue as cv
# TODO: Get rid of global state by using memoization on functions below
# A dictionary of all OpenMC Materials created
# Keys - Material IDs
@ -408,12 +406,12 @@ def get_openmc_region(openmoc_region):
side = '-' if openmoc_region.getHalfspace() == -1 else '+'
openmc_region = openmc.Halfspace(surface, side)
elif openmoc_region.getRegionType() == openmoc.INTERSECTION:
openmc_region = openmc.Intersection()
openmc_region = openmc.Intersection([])
for openmoc_node in openmoc_region.getNodes():
openmc_node = get_openmc_region(openmoc_node)
openmc_region.append(openmc_node)
elif openmoc_region.getRegionType() == openmoc.UNION:
openmc_region = openmc.Union()
openmc_region = openmc.Union([])
for openmoc_node in openmoc_region.getNodes():
openmc_node = get_openmc_region(openmoc_node)
openmc_region.append(openmc_node)
@ -452,10 +450,10 @@ def get_openmc_cell(openmoc_cell):
name = openmoc_cell.getName()
openmc_cell = openmc.Cell(cell_id, name)
if (openmoc_cell.getType() == openmoc.MATERIAL):
if openmoc_cell.getType() == openmoc.MATERIAL:
fill = openmoc_cell.getFillMaterial()
openmc_cell.fill = get_openmc_material(fill)
elif (openmoc_cell.getType() == openmoc.FILL):
elif openmoc_cell.getType() == openmoc.FILL:
fill = openmoc_cell.getFillUniverse()
if fill.getType() == openmoc.LATTICE:
fill = openmoc.castUniverseToLattice(fill)
@ -464,9 +462,11 @@ def get_openmc_cell(openmoc_cell):
openmc_cell.fill = get_openmc_universe(fill)
if openmoc_cell.isRotated():
# get rotation for each of 3 axes
rotation = openmoc_cell.retrieveRotation(3)
openmc_cell.rotation = rotation
if openmoc_cell.isTranslated():
# get translation for each of 3 axes
translation = openmoc_cell.retrieveTranslation(3)
openmc_cell.translation = translation

View file

@ -42,52 +42,19 @@ class Particle:
"""
def __init__(self, filename):
self._f = h5py.File(filename, 'r')
with h5py.File(filename, 'r') as f:
# Ensure filetype and version are correct
cv.check_filetype_version(self._f, 'particle restart',
_VERSION_PARTICLE_RESTART)
# Ensure filetype and version are correct
cv.check_filetype_version(f, 'particle restart', _VERSION_PARTICLE_RESTART)
@property
def current_batch(self):
return self._f['current_batch'][()]
@property
def current_generation(self):
return self._f['current_generation'][()]
@property
def energy(self):
return self._f['energy'][()]
@property
def generations_per_batch(self):
return self._f['generations_per_batch'][()]
@property
def id(self):
return self._f['id'][()]
@property
def type(self):
return self._f['type'][()]
@property
def n_particles(self):
return self._f['n_particles'][()]
@property
def run_mode(self):
return self._f['run_mode'][()].decode()
@property
def uvw(self):
return self._f['uvw'][()]
@property
def weight(self):
return self._f['weight'][()]
@property
def xyz(self):
return self._f['xyz'][()]
self.current_batch = f['current_batch'][()]
self.current_generation = f['current_generation'][()]
self.energy = f['energy'][()]
self.generations_per_batch = f['generations_per_batch'][()]
self.id = f['id'][()]
self.type = f['type'][()]
self.n_particles = f['n_particles'][()]
self.run_mode = f['run_mode'][()].decode()
self.uvw = f['uvw'][()]
self.weight = f['weight'][()]
self.xyz = f['xyz'][()]

View file

@ -2,16 +2,14 @@ from collections.abc import Iterable, Mapping
from numbers import Real, Integral
from pathlib import Path
import subprocess
import sys
import warnings
from xml.etree import ElementTree as ET
import numpy as np
import openmc
import openmc.checkvalue as cv
from openmc._xml import clean_indentation
from openmc.mixin import IDManagerMixin
from ._xml import clean_indentation
from .mixin import IDManagerMixin
_BASES = ['xy', 'xz', 'yz']
@ -400,13 +398,13 @@ class Plot(IDManagerMixin):
def meshlines(self, meshlines):
cv.check_type('plot meshlines', meshlines, dict)
if 'type' not in meshlines:
msg = 'Unable to set on plot the meshlines "{0}" which ' \
msg = 'Unable to set the meshlines to "{}" which ' \
'does not have a "type" key'.format(meshlines)
raise ValueError(msg)
elif meshlines['type'] not in ['tally', 'entropy', 'ufs', 'cmfd']:
msg = 'Unable to set the meshlines with ' \
'type "{0}"'.format(meshlines['type'])
'type "{}"'.format(meshlines['type'])
raise ValueError(msg)
if 'id' in meshlines:
@ -450,11 +448,11 @@ class Plot(IDManagerMixin):
string += '{: <16}=\t{}\n'.format('\tColor by', self._color_by)
string += '{: <16}=\t{}\n'.format('\tBackground', self._background)
string += '{: <16}=\t{}\n'.format('\tMask components',
self._mask_components)
self._mask_components)
string += '{: <16}=\t{}\n'.format('\tMask background',
self._mask_background)
string += '{: <16}=\t{}\n'.format('\Overlap Color',
self._overlap_color)
self._mask_background)
string += '{: <16}=\t{}\n'.format('\tOverlap Color',
self._overlap_color)
string += '{: <16}=\t{}\n'.format('\tColors', self._colors)
string += '{: <16}=\t{}\n'.format('\tLevel', self._level)
string += '{: <16}=\t{}\n'.format('\tMeshlines', self._meshlines)

View file

@ -1,5 +1,5 @@
from numbers import Integral, Real
from itertools import chain
from numbers import Integral, Real
import string
import numpy as np
@ -29,30 +29,37 @@ XI_MT = -2
# MTs to combine to generate associated plot_types
_INELASTIC = [mt for mt in openmc.data.SUM_RULES[3] if mt != 27]
PLOT_TYPES_MT = {'total': openmc.data.SUM_RULES[1],
'scatter': [2] + _INELASTIC,
'elastic': [2],
'inelastic': _INELASTIC,
'fission': [18],
'absorption': [27], 'capture': [101],
'nu-fission': [18],
'nu-scatter': [2] + _INELASTIC,
'unity': [UNITY_MT],
'slowing-down power': [2] + _INELASTIC + [XI_MT],
'damage': [444]}
PLOT_TYPES_MT = {
'total': openmc.data.SUM_RULES[1],
'scatter': [2] + _INELASTIC,
'elastic': [2],
'inelastic': _INELASTIC,
'fission': [18],
'absorption': [27],
'capture': [101],
'nu-fission': [18],
'nu-scatter': [2] + _INELASTIC,
'unity': [UNITY_MT],
'slowing-down power': [2] + _INELASTIC + [XI_MT],
'damage': [444]
}
# Operations to use when combining MTs the first np.add is used in reference
# to zero
PLOT_TYPES_OP = {'total': (np.add,),
'scatter': (np.add,) * (len(PLOT_TYPES_MT['scatter']) - 1),
'elastic': (),
'inelastic': (np.add,) * (len(PLOT_TYPES_MT['inelastic']) - 1),
'fission': (), 'absorption': (),
'capture': (), 'nu-fission': (),
'nu-scatter': (np.add,) * (len(PLOT_TYPES_MT['nu-scatter']) - 1),
'unity': (),
'slowing-down power':
(np.add,) * (len(PLOT_TYPES_MT['slowing-down power']) - 2) + (np.multiply,),
'damage': ()}
PLOT_TYPES_OP = {
'total': (np.add,),
'scatter': (np.add,) * (len(PLOT_TYPES_MT['scatter']) - 1),
'elastic': (),
'inelastic': (np.add,) * (len(PLOT_TYPES_MT['inelastic']) - 1),
'fission': (),
'absorption': (),
'capture': (),
'nu-fission': (),
'nu-scatter': (np.add,) * (len(PLOT_TYPES_MT['nu-scatter']) - 1),
'unity': (),
'slowing-down power': \
(np.add,) * (len(PLOT_TYPES_MT['slowing-down power']) - 2) + (np.multiply,),
'damage': ()
}
# Types of plots to plot linearly in y
PLOT_TYPES_LINEAR = {'nu-fission / fission', 'nu-scatter / scatter',
@ -189,8 +196,7 @@ def plot_xs(this, types, divisor_types=None, temperature=294., data_type=None,
# Generate the plot
if axis is None:
fig = plt.figure(**kwargs)
ax = fig.add_subplot(111)
fig, ax = plt.subplots()
else:
fig = None
ax = axis
@ -287,7 +293,7 @@ def calculate_cexs(this, data_type, types, temperature=294., sab_name=None,
energy_grid, xs = _calculate_cexs_nuclide(nuc, types, temperature,
sab_name, cross_sections)
# Convert xs (Iterable of Callable) to a grid of cross section values
# calculated on @ the points in energy_grid for consistency with the
# calculated on the points in energy_grid for consistency with the
# element and material functions.
data = np.zeros((len(types), len(energy_grid)))
for line in range(len(types)):
@ -397,8 +403,8 @@ def _calculate_cexs_nuclide(this, types, temperature=294., sab_name=None,
grid = nuc.energy[nucT]
sab_Emax = 0.
sab_funcs = []
if sab.elastic_xs:
elastic = sab.elastic_xs[sabT]
if sab.elastic is not None:
elastic = sab.elastic.xs[sabT]
if isinstance(elastic, openmc.data.CoherentElastic):
grid = np.union1d(grid, elastic.bragg_edges)
if elastic.bragg_edges[-1] > sab_Emax:
@ -408,8 +414,8 @@ def _calculate_cexs_nuclide(this, types, temperature=294., sab_name=None,
if elastic.x[-1] > sab_Emax:
sab_Emax = elastic.x[-1]
sab_funcs.append(elastic)
if sab.inelastic_xs:
inelastic = sab.inelastic_xs[sabT]
if sab.inelastic is not None:
inelastic = sab.inelastic.xs[sabT]
grid = np.union1d(grid, inelastic.x)
if inelastic.x[-1] > sab_Emax:
sab_Emax = inelastic.x[-1]

View file

@ -1,7 +1,7 @@
import math
import numpy as np
import openmc
from collections.abc import Iterable
import math
import numpy as np
def legendre_from_expcoef(coef, domain=(-1, 1)):

View file

@ -1,14 +1,14 @@
from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from collections import OrderedDict
from collections.abc import Iterable, MutableSequence
from collections.abc import MutableSequence
from copy import deepcopy
import numpy as np
from openmc.checkvalue import check_type
from .checkvalue import check_type
class Region(metaclass=ABCMeta):
class Region(ABC):
"""Region of space that can be assigned to a cell.
Region is an abstract base class that is inherited by

View file

@ -2,15 +2,11 @@ from collections.abc import Iterable, MutableSequence, Mapping
from enum import Enum
from pathlib import Path
from numbers import Real, Integral
import warnings
from xml.etree import ElementTree as ET
import sys
import numpy as np
from openmc._xml import clean_indentation, get_text
import openmc.checkvalue as cv
from openmc import VolumeCalculation, Source, RegularMesh
from . import VolumeCalculation, Source, RegularMesh
from ._xml import clean_indentation, get_text
class RunMode(Enum):

View file

@ -1,11 +1,10 @@
from numbers import Real
import sys
from xml.etree import ElementTree as ET
from openmc._xml import get_text
from openmc.stats.univariate import Univariate
from openmc.stats.multivariate import UnitSphere, Spatial
import openmc.checkvalue as cv
from openmc.stats.multivariate import UnitSphere, Spatial
from openmc.stats.univariate import Univariate
from ._xml import get_text
class Source:

View file

@ -1,11 +1,11 @@
from datetime import datetime
import glob
import re
import os
import warnings
import glob
import numpy as np
import h5py
import numpy as np
from uncertainties import ufloat
import openmc
@ -416,14 +416,10 @@ class StatePoint:
nuclide = openmc.Nuclide(name.decode().strip())
tally.nuclides.append(nuclide)
scores = group['score_bins'][()]
n_score_bins = group['n_score_bins'][()]
# Add the scores to the Tally
for j, score in enumerate(scores):
score = score.decode()
tally.scores.append(score)
scores = group['score_bins'][()]
for score in scores:
tally.scores.append(score.decode())
# Add Tally to the global dictionary of all Tallies
tally.sparse = self.sparse
@ -586,15 +582,7 @@ class StatePoint:
# Determine if Tally has the queried score(s)
if scores:
contains_scores = True
# Iterate over the scores requested by the user
for score in scores:
if score not in test_tally.scores:
contains_scores = False
break
if not contains_scores:
if not all(score in test_tally.scores for score in scores):
continue
# Determine if Tally has the queried Filter(s)
@ -620,15 +608,7 @@ class StatePoint:
# Determine if Tally has the queried Nuclide(s)
if nuclides:
contains_nuclides = True
# Iterate over the Nuclides requested by the user
for nuclide in nuclides:
if nuclide not in test_tally.nuclides:
contains_nuclides = False
break
if not contains_nuclides:
if not all(nuclide in test_tally.nuclides for nuclide in nuclides):
continue
# If the current Tally met user's request, break loop and return it
@ -676,7 +656,7 @@ class StatePoint:
cells = summary.geometry.get_all_cells()
for tally_id, tally in self.tallies.items():
for tally in self.tallies.values():
tally.with_summary = True
for tally_filter in tally.filters:

View file

@ -1,18 +1,17 @@
from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from collections.abc import Iterable
from math import pi
from numbers import Real
import sys
from xml.etree import ElementTree as ET
import numpy as np
import openmc.checkvalue as cv
from openmc._xml import get_text
from openmc.stats.univariate import Univariate, Uniform
from .._xml import get_text
from .univariate import Univariate, Uniform
class UnitSphere(metaclass=ABCMeta):
class UnitSphere(ABC):
"""Distribution of points on the unit sphere.
This abstract class is used for angular distributions, since a direction is
@ -86,7 +85,7 @@ class PolarAzimuthal(UnitSphere):
"""
def __init__(self, mu=None, phi=None, reference_uvw=[0., 0., 1.]):
def __init__(self, mu=None, phi=None, reference_uvw=(0., 0., 1.)):
super().__init__(reference_uvw)
if mu is not None:
self.mu = mu
@ -158,9 +157,7 @@ class PolarAzimuthal(UnitSphere):
class Isotropic(UnitSphere):
"""Isotropic angular distribution.
"""
"""Isotropic angular distribution."""
def __init__(self):
super().__init__()
@ -252,16 +249,13 @@ class Monodirectional(UnitSphere):
return monodirectional
class Spatial(metaclass=ABCMeta):
class Spatial(ABC):
"""Distribution of locations in three-dimensional Euclidean space.
Classes derived from this abstract class can be used for spatial
distributions of source sites.
"""
def __init__(self):
pass
@abstractmethod
def to_xml_element(self):
return ''
@ -309,7 +303,6 @@ class CartesianIndependent(Spatial):
"""
def __init__(self, x, y, z):
super().__init__()
self.x = x
self.y = y
self.z = z
@ -417,7 +410,6 @@ class SphericalIndependent(Spatial):
"""
def __init__(self, r, theta, phi, origin=(0.0, 0.0, 0.0)):
super().__init__()
self.r = r
self.theta = theta
self.phi = phi
@ -537,7 +529,6 @@ class CylindricalIndependent(Spatial):
"""
def __init__(self, r, phi, z, origin=(0.0, 0.0, 0.0)):
super().__init__()
self.r = r
self.phi = phi
self.z = z
@ -646,7 +637,6 @@ class Box(Spatial):
def __init__(self, lower_left, upper_right, only_fissionable=False):
super().__init__()
self.lower_left = lower_left
self.upper_right = upper_right
self.only_fissionable = only_fissionable
@ -740,7 +730,6 @@ class Point(Spatial):
"""
def __init__(self, xyz=(0., 0., 0.)):
super().__init__()
self.xyz = xyz
@property

View file

@ -1,30 +1,31 @@
from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from collections.abc import Iterable
from numbers import Real
import sys
from xml.etree import ElementTree as ET
import numpy as np
import openmc.checkvalue as cv
from openmc._xml import get_text
from openmc.mixin import EqualityMixin
from .._xml import get_text
from ..mixin import EqualityMixin
_INTERPOLATION_SCHEMES = ['histogram', 'linear-linear', 'linear-log',
'log-linear', 'log-log']
_INTERPOLATION_SCHEMES = [
'histogram',
'linear-linear',
'linear-log',
'log-linear',
'log-log'
]
class Univariate(EqualityMixin, metaclass=ABCMeta):
class Univariate(EqualityMixin, ABC):
"""Probability distribution of a single random variable.
The Univariate class is an abstract class that can be derived to implement a
specific probability distribution.
"""
def __init__(self):
pass
@abstractmethod
def to_xml_element(self, element_name):
return ''
@ -81,7 +82,6 @@ class Discrete(Univariate):
"""
def __init__(self, x, p):
super().__init__()
self.x = x
self.p = p
@ -175,7 +175,6 @@ class Uniform(Univariate):
"""
def __init__(self, a=0.0, b=1.0):
super().__init__()
self.a = a
self.b = b
@ -264,7 +263,6 @@ class Maxwell(Univariate):
"""
def __init__(self, theta):
super().__init__()
self.theta = theta
def __len__(self):
@ -342,7 +340,6 @@ class Watt(Univariate):
"""
def __init__(self, a=0.988e6, b=2.249e-6):
super().__init__()
self.a = a
self.b = b
@ -430,7 +427,6 @@ class Normal(Univariate):
"""
def __init__(self, mean_value, std_dev):
super().__init__()
self.mean_value = mean_value
self.std_dev = std_dev
@ -525,7 +521,6 @@ class Muir(Univariate):
"""
def __init__(self, e0=14.08e6, m_rat = 5., kt = 20000.):
super().__init__()
self.e0 = e0
self.m_rat = m_rat
self.kt = kt
@ -634,7 +629,6 @@ class Tabular(Univariate):
def __init__(self, x, p, interpolation='linear-linear',
ignore_negative=False):
super().__init__()
self._ignore_negative = ignore_negative
self.x = x
self.p = p
@ -788,7 +782,6 @@ class Mixture(Univariate):
"""
def __init__(self, probability, distribution):
super().__init__()
self.probability = probability
self.distribution = distribution

View file

@ -1,13 +1,12 @@
from collections.abc import Iterable
import re
import warnings
import numpy as np
import h5py
import numpy as np
import openmc
import openmc.checkvalue as cv
from openmc.region import Region
from .region import Region
_VERSION_SUMMARY = 6
@ -55,9 +54,7 @@ class Summary:
self._read_nuclides()
self._read_macroscopics()
with warnings.catch_warnings():
warnings.simplefilter("ignore", openmc.IDWarning)
self._read_geometry()
self._read_geometry()
@property
def date_and_time(self):
@ -93,21 +90,25 @@ class Summary:
def _read_macroscopics(self):
if 'macroscopics/names' in self._f:
names = self._f['macroscopics/names'][()]
for name in names:
self._macroscopics = name.decode()
self._macroscopics = [name.decode() for name in names]
def _read_geometry(self):
with warnings.catch_warnings():
# We expect that new objects will be created with the same IDs as
# objects that might already exist in the Python process (if it was
# also used to create the model), so silence ID warnings
warnings.simplefilter("ignore", openmc.IDWarning)
# Read in and initialize the Materials
self._read_materials()
# Read in and initialize the Materials
self._read_materials()
# Read native geometry only
if "dagmc" not in self._f['geometry'].attrs.keys():
self._read_surfaces()
cell_fills = self._read_cells()
self._read_universes()
self._read_lattices()
self._finalize_geometry(cell_fills)
# Read native geometry only
if "dagmc" not in self._f['geometry'].attrs.keys():
self._read_surfaces()
cell_fills = self._read_cells()
self._read_universes()
self._read_lattices()
self._finalize_geometry(cell_fills)
def _read_materials(self):
for group in self._f['materials'].values():
@ -135,11 +136,11 @@ class Summary:
fill_type = group['fill_type'][()].decode()
if fill_type == 'material':
fill = group['material'][()]
fill_id = group['material'][()]
elif fill_type == 'universe':
fill = group['fill'][()]
fill_id = group['fill'][()]
else:
fill = group['lattice'][()]
fill_id = group['lattice'][()]
region = group['region'][()].decode() if 'region' in group else ''
@ -162,7 +163,7 @@ class Summary:
cell.temperature = group['temperature'][()]
# Store Cell fill information for after Universe/Lattice creation
cell_fills[cell.id] = (fill_type, fill)
cell_fills[cell.id] = (fill_type, fill_id)
# Generate Region object given infix expression
if region:

View file

@ -1,17 +1,17 @@
from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from collections import OrderedDict
from collections.abc import Iterable
from copy import deepcopy
import math
from numbers import Real
from xml.etree import ElementTree as ET
from warnings import warn, catch_warnings, simplefilter
import math
import numpy as np
from openmc.checkvalue import check_type, check_value, check_length
from openmc.region import Region, Intersection, Union
from openmc.mixin import IDManagerMixin, IDWarning
from .checkvalue import check_type, check_value, check_length
from .mixin import IDManagerMixin, IDWarning
from .region import Region, Intersection, Union
_BOUNDARY_TYPES = ['transmission', 'vacuum', 'reflective', 'periodic', 'white']
@ -103,7 +103,7 @@ def get_rotation_matrix(rotation, order='xyz'):
return R3 @ R2 @ R1
class Surface(IDManagerMixin, metaclass=ABCMeta):
class Surface(IDManagerMixin, ABC):
"""An implicit surface with an associated boundary condition.
An implicit surface is defined as the set of zeros of a function of the
@ -459,7 +459,7 @@ class Surface(IDManagerMixin, metaclass=ABCMeta):
return cls(*coeffs, **kwargs)
class PlaneMixin(metaclass=ABCMeta):
class PlaneMixin:
"""A Plane mixin class for all operations on order 1 surfaces"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
@ -918,7 +918,7 @@ class ZPlane(PlaneMixin, Surface):
return point[2] - self.z0
class QuadricMixin(metaclass=ABCMeta):
class QuadricMixin:
"""A Mixin class implementing common functionality for quadric surfaces"""
@property

View file

@ -1,22 +1,20 @@
from collections.abc import Iterable, MutableSequence
import copy
import re
from functools import partial, reduce
from itertools import product
from numbers import Integral, Real
import operator
from pathlib import Path
import warnings
from xml.etree import ElementTree as ET
import h5py
import numpy as np
import pandas as pd
import scipy.sparse as sps
import h5py
import openmc
import openmc.checkvalue as cv
from openmc._xml import clean_indentation
from ._xml import clean_indentation
from .mixin import IDManagerMixin

View file

@ -1,9 +1,8 @@
import sys
from numbers import Integral
from xml.etree import ElementTree as ET
import openmc.checkvalue as cv
from openmc.mixin import EqualityMixin, IDManagerMixin
from .mixin import EqualityMixin, IDManagerMixin
class TallyDerivative(EqualityMixin, IDManagerMixin):
@ -51,14 +50,9 @@ class TallyDerivative(EqualityMixin, IDManagerMixin):
string = 'Tally Derivative\n'
string += '{: <16}=\t{}\n'.format('\tID', self.id)
string += '{: <16}=\t{}\n'.format('\tVariable', self.variable)
if self.variable == 'density':
string += '{: <16}=\t{}\n'.format('\tMaterial', self.material)
elif self.variable == 'nuclide_density':
string += '{: <16}=\t{}\n'.format('\tMaterial', self.material)
string += '{: <16}=\t{}\n'.format('\tMaterial', self.material)
if self.variable == 'nuclide_density':
string += '{: <16}=\t{}\n'.format('\tNuclide', self.nuclide)
elif self.variable == 'temperature':
string += '{: <16}=\t{}\n'.format('\tMaterial', self.material)
return string

View file

@ -1,13 +1,12 @@
from collections.abc import Iterable
from numbers import Real
from xml.etree import ElementTree as ET
import sys
import warnings
from collections.abc import Iterable
import openmc.checkvalue as cv
from .mixin import EqualityMixin
class Trigger:
class Trigger(EqualityMixin):
"""A criterion for when to finish a simulation based on tally uncertainties.
Parameters
@ -35,14 +34,11 @@ class Trigger:
self.threshold = threshold
self._scores = []
def __eq__(self, other):
return str(self) == str(other)
def __repr__(self):
string = 'Trigger\n'
string += '{0: <16}{1}{2}\n'.format('\tType', '=\t', self._trigger_type)
string += '{0: <16}{1}{2}\n'.format('\tThreshold', '=\t', self._threshold)
string += '{0: <16}{1}{2}\n'.format('\tScores', '=\t', self._scores)
string += '{: <16}=\t{}\n'.format('\tType', self._trigger_type)
string += '{: <16}=\t{}\n'.format('\tThreshold', self._threshold)
string += '{: <16}=\t{}\n'.format('\tScores', self._scores)
return string
@property

View file

@ -1,16 +1,15 @@
from collections import OrderedDict
from collections.abc import Iterable
from copy import copy, deepcopy
from numbers import Integral, Real
from numbers import Real
import random
import sys
import numpy as np
import openmc
import openmc.checkvalue as cv
from openmc.plots import _SVG_COLORS
from openmc.mixin import IDManagerMixin
from .mixin import IDManagerMixin
from .plots import _SVG_COLORS
class Universe(IDManagerMixin):
@ -55,7 +54,7 @@ class Universe(IDManagerMixin):
self._volume = None
self._atoms = {}
# Keys - Cell IDs
# Keys - Cell IDs
# Values - Cells
self._cells = OrderedDict()
@ -64,10 +63,9 @@ class Universe(IDManagerMixin):
def __repr__(self):
string = 'Universe\n'
string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self._id)
string += '{0: <16}{1}{2}\n'.format('\tName', '=\t', self._name)
string += '{0: <16}{1}{2}\n'.format('\tCells', '=\t',
list(self._cells.keys()))
string += '{: <16}=\t{}\n'.format('\tID', self._id)
string += '{: <16}=\t{}\n'.format('\tName', self._name)
string += '{: <16}=\t{}\n'.format('\tCells', list(self._cells.keys()))
return string
@property
@ -543,7 +541,7 @@ class Universe(IDManagerMixin):
"""
# Iterate over all Cells
for cell_id, cell in self._cells.items():
for cell in self._cells.values():
# If the cell was already written, move on
if memo and cell in memo:

View file

@ -62,7 +62,7 @@ def test_failure(pin_mats, good_radii):
pin(surfs, pin_mats)
# Passing cells argument
with pytest.raises(SyntaxError, match="Cells"):
with pytest.raises(ValueError, match="Cells"):
pin(surfs, pin_mats, cells=[])