mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
Allowing CylindricalMesh and SphericalMesh to be fully made via constructor+ type hints (#2619)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
This commit is contained in:
parent
cd13d3471d
commit
557880aefc
13 changed files with 365 additions and 206 deletions
176
openmc/mesh.py
176
openmc/mesh.py
|
|
@ -1,19 +1,20 @@
|
|||
import typing
|
||||
import warnings
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import Iterable
|
||||
from math import pi
|
||||
from numbers import Real, Integral
|
||||
from numbers import Integral, Real
|
||||
from pathlib import Path
|
||||
import typing
|
||||
import warnings
|
||||
import lxml.etree as ET
|
||||
from typing import Optional, Sequence, Tuple
|
||||
|
||||
import h5py
|
||||
import lxml.etree as ET
|
||||
import numpy as np
|
||||
|
||||
import openmc.checkvalue as cv
|
||||
import openmc
|
||||
from ._xml import get_text
|
||||
import openmc.checkvalue as cv
|
||||
from openmc.checkvalue import PathLike
|
||||
from ._xml import get_text
|
||||
from .mixin import IDManagerMixin
|
||||
from .surface import _BOUNDARY_TYPES
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ class MeshBase(IDManagerMixin, ABC):
|
|||
next_id = 1
|
||||
used_ids = set()
|
||||
|
||||
def __init__(self, mesh_id: typing.Optional[int] = None, name: str = ''):
|
||||
def __init__(self, mesh_id: Optional[int] = None, name: str = ''):
|
||||
# Initialize Mesh class attributes
|
||||
self.id = mesh_id
|
||||
self.name = name
|
||||
|
|
@ -264,7 +265,7 @@ class StructuredMesh(MeshBase):
|
|||
|
||||
def write_data_to_vtk(self,
|
||||
filename: PathLike,
|
||||
datasets: typing.Optional[dict] = None,
|
||||
datasets: Optional[dict] = None,
|
||||
volume_normalization: bool = True,
|
||||
curvilinear: bool = False):
|
||||
"""Creates a VTK object of the mesh
|
||||
|
|
@ -512,7 +513,7 @@ class RegularMesh(StructuredMesh):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, mesh_id: typing.Optional[int] = None, name: str = ''):
|
||||
def __init__(self, mesh_id: Optional[int] = None, name: str = ''):
|
||||
super().__init__(mesh_id, name)
|
||||
|
||||
self._dimension = None
|
||||
|
|
@ -597,7 +598,7 @@ class RegularMesh(StructuredMesh):
|
|||
|
||||
@property
|
||||
def cartesian_vertices(self):
|
||||
"""Returns vertices in cartesian coordiantes. Identical to ``vertices`` for RegularMesh and RectilinearMesh
|
||||
"""Returns vertices in cartesian coordinates. Identical to ``vertices`` for RegularMesh and RectilinearMesh
|
||||
"""
|
||||
return self.vertices
|
||||
|
||||
|
|
@ -697,7 +698,7 @@ class RegularMesh(StructuredMesh):
|
|||
cls,
|
||||
lattice: 'openmc.RectLattice',
|
||||
division: int = 1,
|
||||
mesh_id: typing.Optional[int] = None,
|
||||
mesh_id: Optional[int] = None,
|
||||
name: str = ''
|
||||
):
|
||||
"""Create mesh from an existing rectangular lattice
|
||||
|
|
@ -725,7 +726,7 @@ class RegularMesh(StructuredMesh):
|
|||
shape = np.array(lattice.shape)
|
||||
width = lattice.pitch*shape
|
||||
|
||||
mesh = cls(mesh_id, name)
|
||||
mesh = cls(mesh_id=mesh_id, name=name)
|
||||
mesh.lower_left = lattice.lower_left
|
||||
mesh.upper_right = lattice.lower_left + width
|
||||
mesh.dimension = shape*division
|
||||
|
|
@ -736,8 +737,8 @@ class RegularMesh(StructuredMesh):
|
|||
def from_domain(
|
||||
cls,
|
||||
domain: typing.Union['openmc.Cell', 'openmc.Region', 'openmc.Universe', 'openmc.Geometry'],
|
||||
dimension: typing.Sequence[int] = (10, 10, 10),
|
||||
mesh_id: typing.Optional[int] = None,
|
||||
dimension: Sequence[int] = (10, 10, 10),
|
||||
mesh_id: Optional[int] = None,
|
||||
name: str = ''
|
||||
):
|
||||
"""Create mesh from an existing openmc cell, region, universe or
|
||||
|
|
@ -748,7 +749,7 @@ class RegularMesh(StructuredMesh):
|
|||
domain : {openmc.Cell, openmc.Region, openmc.Universe, openmc.Geometry}
|
||||
The object passed in will be used as a template for this mesh. The
|
||||
bounding box of the property of the object passed will be used to
|
||||
set the lower_left and upper_right of the mesh instance
|
||||
set the lower_left and upper_right and of the mesh instance
|
||||
dimension : Iterable of int
|
||||
The number of mesh cells in each direction (x, y, z).
|
||||
mesh_id : int
|
||||
|
|
@ -768,7 +769,7 @@ class RegularMesh(StructuredMesh):
|
|||
(openmc.Cell, openmc.Region, openmc.Universe, openmc.Geometry),
|
||||
)
|
||||
|
||||
mesh = cls(mesh_id, name)
|
||||
mesh = cls(mesh_id=mesh_id, name=name)
|
||||
mesh.lower_left = domain.bounding_box[0]
|
||||
mesh.upper_right = domain.bounding_box[1]
|
||||
mesh.dimension = dimension
|
||||
|
|
@ -820,7 +821,7 @@ class RegularMesh(StructuredMesh):
|
|||
|
||||
"""
|
||||
mesh_id = int(get_text(elem, 'id'))
|
||||
mesh = cls(mesh_id)
|
||||
mesh = cls(mesh_id=mesh_id)
|
||||
|
||||
mesh_type = get_text(elem, 'type')
|
||||
if mesh_type is not None:
|
||||
|
|
@ -844,7 +845,7 @@ class RegularMesh(StructuredMesh):
|
|||
|
||||
return mesh
|
||||
|
||||
def build_cells(self, bc: typing.Optional[str] = None):
|
||||
def build_cells(self, bc: Optional[str] = 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
|
||||
|
|
@ -1119,7 +1120,7 @@ class RectilinearMesh(StructuredMesh):
|
|||
mesh_id = int(group.name.split('/')[-1].lstrip('mesh '))
|
||||
|
||||
# Read and assign mesh properties
|
||||
mesh = cls(mesh_id)
|
||||
mesh = cls(mesh_id=mesh_id)
|
||||
mesh.x_grid = group['x_grid'][()]
|
||||
mesh.y_grid = group['y_grid'][()]
|
||||
mesh.z_grid = group['z_grid'][()]
|
||||
|
|
@ -1141,8 +1142,8 @@ class RectilinearMesh(StructuredMesh):
|
|||
Rectilinear mesh object
|
||||
|
||||
"""
|
||||
id = int(get_text(elem, 'id'))
|
||||
mesh = cls(id)
|
||||
mesh_id = int(get_text(elem, 'id'))
|
||||
mesh = cls(mesh_id=mesh_id)
|
||||
mesh.x_grid = [float(x) for x in get_text(elem, 'x_grid').split()]
|
||||
mesh.y_grid = [float(y) for y in get_text(elem, 'y_grid').split()]
|
||||
mesh.z_grid = [float(z) for z in get_text(elem, 'z_grid').split()]
|
||||
|
|
@ -1180,6 +1181,17 @@ class CylindricalMesh(StructuredMesh):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
r_grid : numpy.ndarray
|
||||
1-D array of mesh boundary points along the r-axis.
|
||||
Requirement is r >= 0.
|
||||
z_grid : numpy.ndarray
|
||||
1-D array of mesh boundary points along the z-axis.
|
||||
phi_grid : numpy.ndarray
|
||||
1-D array of mesh boundary points along the phi-axis in radians.
|
||||
The default value is [0, 2π], i.e. the full phi range.
|
||||
origin : numpy.ndarray
|
||||
1-D array of length 3 the (x,y,z) origin of the mesh in
|
||||
cartesian coordinates
|
||||
mesh_id : int
|
||||
Unique identifier for the mesh
|
||||
name : str
|
||||
|
|
@ -1213,13 +1225,21 @@ class CylindricalMesh(StructuredMesh):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, mesh_id: int = None, name: str = ''):
|
||||
def __init__(
|
||||
self,
|
||||
r_grid: Sequence[float],
|
||||
z_grid: Sequence[float],
|
||||
phi_grid: Sequence[float] = (0, 2*pi),
|
||||
origin: Sequence[float] = (0., 0., 0.),
|
||||
mesh_id: Optional[int] = None,
|
||||
name: str = '',
|
||||
):
|
||||
super().__init__(mesh_id, name)
|
||||
|
||||
self._r_grid = None
|
||||
self._phi_grid = [0.0, 2*pi]
|
||||
self._z_grid = None
|
||||
self.origin = (0., 0., 0.)
|
||||
self._r_grid = r_grid
|
||||
self._phi_grid = phi_grid
|
||||
self._z_grid = z_grid
|
||||
self.origin = origin
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
|
|
@ -1309,10 +1329,12 @@ class CylindricalMesh(StructuredMesh):
|
|||
mesh_id = int(group.name.split('/')[-1].lstrip('mesh '))
|
||||
|
||||
# Read and assign mesh properties
|
||||
mesh = cls(mesh_id)
|
||||
mesh.r_grid = group['r_grid'][()]
|
||||
mesh.phi_grid = group['phi_grid'][()]
|
||||
mesh.z_grid = group['z_grid'][()]
|
||||
mesh = cls(
|
||||
mesh_id=mesh_id,
|
||||
r_grid = group['r_grid'][()],
|
||||
phi_grid = group['phi_grid'][()],
|
||||
z_grid = group['z_grid'][()],
|
||||
)
|
||||
if 'origin' in group:
|
||||
mesh.origin = group['origin'][()]
|
||||
|
||||
|
|
@ -1322,10 +1344,10 @@ class CylindricalMesh(StructuredMesh):
|
|||
def from_domain(
|
||||
cls,
|
||||
domain: typing.Union['openmc.Cell', 'openmc.Region', 'openmc.Universe', 'openmc.Geometry'],
|
||||
dimension: typing.Sequence[int] = (10, 10, 10),
|
||||
mesh_id: typing.Optional[int] = None,
|
||||
phi_grid_bounds: typing.Sequence[float] = (0.0, 2*pi),
|
||||
name=''
|
||||
dimension: Sequence[int] = (10, 10, 10),
|
||||
mesh_id: Optional[int] = None,
|
||||
phi_grid_bounds: Sequence[float] = (0.0, 2*pi),
|
||||
name: str = ''
|
||||
):
|
||||
"""Creates a regular CylindricalMesh from an existing openmc domain.
|
||||
|
||||
|
|
@ -1358,7 +1380,6 @@ class CylindricalMesh(StructuredMesh):
|
|||
(openmc.Cell, openmc.Region, openmc.Universe, openmc.Geometry),
|
||||
)
|
||||
|
||||
mesh = cls(mesh_id, name)
|
||||
|
||||
# loaded once to avoid reading h5m file repeatedly
|
||||
cached_bb = domain.bounding_box
|
||||
|
|
@ -1370,21 +1391,24 @@ class CylindricalMesh(StructuredMesh):
|
|||
cached_bb[1][1],
|
||||
]
|
||||
)
|
||||
mesh.r_grid = np.linspace(
|
||||
r_grid = np.linspace(
|
||||
0,
|
||||
max_bounding_box_radius,
|
||||
num=dimension[0]+1
|
||||
)
|
||||
mesh.phi_grid = np.linspace(
|
||||
phi_grid = np.linspace(
|
||||
phi_grid_bounds[0],
|
||||
phi_grid_bounds[1],
|
||||
num=dimension[1]+1
|
||||
)
|
||||
mesh.z_grid = np.linspace(
|
||||
z_grid = np.linspace(
|
||||
cached_bb[0][2],
|
||||
cached_bb[1][2],
|
||||
num=dimension[2]+1
|
||||
)
|
||||
mesh = cls(
|
||||
r_grid=r_grid, z_grid=z_grid, phi_grid=phi_grid, mesh_id=mesh_id, name=name
|
||||
)
|
||||
|
||||
return mesh
|
||||
|
||||
|
|
@ -1433,11 +1457,13 @@ class CylindricalMesh(StructuredMesh):
|
|||
"""
|
||||
|
||||
mesh_id = int(get_text(elem, 'id'))
|
||||
mesh = cls(mesh_id)
|
||||
mesh.r_grid = [float(x) for x in get_text(elem, "r_grid").split()]
|
||||
mesh.phi_grid = [float(x) for x in get_text(elem, "phi_grid").split()]
|
||||
mesh.z_grid = [float(x) for x in get_text(elem, "z_grid").split()]
|
||||
mesh.origin = [float(x) for x in get_text(elem, "origin", default=[0., 0., 0.]).split()]
|
||||
mesh = cls(
|
||||
r_grid = [float(x) for x in get_text(elem, "r_grid").split()],
|
||||
phi_grid = [float(x) for x in get_text(elem, "phi_grid").split()],
|
||||
z_grid = [float(x) for x in get_text(elem, "z_grid").split()],
|
||||
origin = [float(x) for x in get_text(elem, "origin", default=[0., 0., 0.]).split()],
|
||||
mesh_id=mesh_id,
|
||||
)
|
||||
|
||||
return mesh
|
||||
|
||||
|
|
@ -1463,7 +1489,7 @@ class CylindricalMesh(StructuredMesh):
|
|||
return self._convert_to_cartesian(self.vertices, self.origin)
|
||||
|
||||
@staticmethod
|
||||
def _convert_to_cartesian(arr, origin: typing.Sequence[float]):
|
||||
def _convert_to_cartesian(arr, origin: Sequence[float]):
|
||||
"""Converts an array with xyz values in the first dimension (shape (3, ...))
|
||||
to Cartesian coordinates.
|
||||
"""
|
||||
|
|
@ -1480,6 +1506,18 @@ class SphericalMesh(StructuredMesh):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
r_grid : numpy.ndarray
|
||||
1-D array of mesh boundary points along the r-axis.
|
||||
Requirement is r >= 0.
|
||||
phi_grid : numpy.ndarray
|
||||
1-D array of mesh boundary points along the phi-axis in radians.
|
||||
The default value is [0, 2π], i.e. the full phi range.
|
||||
theta_grid : numpy.ndarray
|
||||
1-D array of mesh boundary points along the theta-axis in radians.
|
||||
The default value is [0, π], i.e. the full theta range.
|
||||
origin : numpy.ndarray
|
||||
1-D array of length 3 the (x,y,z) origin of the mesh in
|
||||
cartesian coordinates
|
||||
mesh_id : int
|
||||
Unique identifier for the mesh
|
||||
name : str
|
||||
|
|
@ -1514,13 +1552,21 @@ class SphericalMesh(StructuredMesh):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, mesh_id=None, name=''):
|
||||
def __init__(
|
||||
self,
|
||||
r_grid: Sequence[float],
|
||||
phi_grid: Sequence[float] = (0, 2*pi),
|
||||
theta_grid: Sequence[float] = (0, pi),
|
||||
origin: Sequence[float] = (0., 0., 0.),
|
||||
mesh_id: Optional[int] = None,
|
||||
name: str = '',
|
||||
):
|
||||
super().__init__(mesh_id, name)
|
||||
|
||||
self._r_grid = None
|
||||
self._theta_grid = [0, pi]
|
||||
self._phi_grid = [0, 2*pi]
|
||||
self.origin = (0., 0., 0.)
|
||||
self._r_grid = r_grid
|
||||
self._theta_grid = theta_grid
|
||||
self._phi_grid = phi_grid
|
||||
self.origin = origin
|
||||
|
||||
@property
|
||||
def dimension(self):
|
||||
|
|
@ -1610,10 +1656,12 @@ class SphericalMesh(StructuredMesh):
|
|||
mesh_id = int(group.name.split('/')[-1].lstrip('mesh '))
|
||||
|
||||
# Read and assign mesh properties
|
||||
mesh = cls(mesh_id)
|
||||
mesh.r_grid = group['r_grid'][()]
|
||||
mesh.theta_grid = group['theta_grid'][()]
|
||||
mesh.phi_grid = group['phi_grid'][()]
|
||||
mesh = cls(
|
||||
r_grid = group['r_grid'][()],
|
||||
theta_grid = group['theta_grid'][()],
|
||||
phi_grid = group['phi_grid'][()],
|
||||
mesh_id=mesh_id,
|
||||
)
|
||||
if 'origin' in group:
|
||||
mesh.origin = group['origin'][()]
|
||||
|
||||
|
|
@ -1663,11 +1711,13 @@ class SphericalMesh(StructuredMesh):
|
|||
|
||||
"""
|
||||
mesh_id = int(get_text(elem, 'id'))
|
||||
mesh = cls(mesh_id)
|
||||
mesh.r_grid = [float(x) for x in get_text(elem, "r_grid").split()]
|
||||
mesh.theta_grid = [float(x) for x in get_text(elem, "theta_grid").split()]
|
||||
mesh.phi_grid = [float(x) for x in get_text(elem, "phi_grid").split()]
|
||||
mesh.origin = [float(x) for x in get_text(elem, "origin", default=[0., 0., 0.]).split()]
|
||||
mesh = cls(
|
||||
mesh_id=mesh_id,
|
||||
r_grid = [float(x) for x in get_text(elem, "r_grid").split()],
|
||||
theta_grid = [float(x) for x in get_text(elem, "theta_grid").split()],
|
||||
phi_grid = [float(x) for x in get_text(elem, "phi_grid").split()],
|
||||
origin = [float(x) for x in get_text(elem, "origin", default=[0., 0., 0.]).split()],
|
||||
)
|
||||
|
||||
return mesh
|
||||
|
||||
|
|
@ -1693,7 +1743,7 @@ class SphericalMesh(StructuredMesh):
|
|||
return self._convert_to_cartesian(self.vertices, self.origin)
|
||||
|
||||
@staticmethod
|
||||
def _convert_to_cartesian(arr, origin: typing.Sequence[float]):
|
||||
def _convert_to_cartesian(arr, origin: Sequence[float]):
|
||||
"""Converts an array with xyz values in the first dimension (shape (3, ...))
|
||||
to Cartesian coordinates.
|
||||
"""
|
||||
|
|
@ -1768,7 +1818,7 @@ class UnstructuredMesh(MeshBase):
|
|||
_LINEAR_TET = 0
|
||||
_LINEAR_HEX = 1
|
||||
|
||||
def __init__(self, filename: PathLike, library: str, mesh_id: typing.Optional[int] = None,
|
||||
def __init__(self, filename: PathLike, library: str, mesh_id: Optional[int] = None,
|
||||
name: str = '', length_multiplier: float = 1.0):
|
||||
super().__init__(mesh_id, name)
|
||||
self.filename = filename
|
||||
|
|
@ -1940,8 +1990,8 @@ class UnstructuredMesh(MeshBase):
|
|||
|
||||
def write_data_to_vtk(
|
||||
self,
|
||||
filename: typing.Optional[PathLike] = None,
|
||||
datasets: typing.Optional[dict] = None,
|
||||
filename: Optional[PathLike] = None,
|
||||
datasets: Optional[dict] = None,
|
||||
volume_normalization: bool = True
|
||||
):
|
||||
"""Map data to unstructured VTK mesh elements.
|
||||
|
|
@ -2040,7 +2090,7 @@ class UnstructuredMesh(MeshBase):
|
|||
filename = group['filename'][()].decode()
|
||||
library = group['library'][()].decode()
|
||||
|
||||
mesh = cls(filename, library, mesh_id=mesh_id)
|
||||
mesh = cls(filename=filename, library=library, mesh_id=mesh_id)
|
||||
vol_data = group['volumes'][()]
|
||||
mesh.volumes = np.reshape(vol_data, (vol_data.shape[0],))
|
||||
mesh.n_elements = mesh.volumes.size
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
from __future__ import annotations
|
||||
import typing
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import Iterable
|
||||
from math import pi, cos
|
||||
from math import cos, pi
|
||||
from numbers import Real
|
||||
import lxml.etree as ET
|
||||
|
||||
import lxml.etree as ET
|
||||
import numpy as np
|
||||
|
||||
import openmc.checkvalue as cv
|
||||
from .._xml import get_text
|
||||
from .univariate import Univariate, Uniform, PowerLaw
|
||||
from ..mesh import MeshBase
|
||||
from .univariate import PowerLaw, Uniform, Univariate
|
||||
|
||||
|
||||
class UnitSphere(ABC):
|
||||
|
|
@ -177,7 +179,7 @@ class Isotropic(UnitSphere):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate isotropic distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -209,7 +211,7 @@ class Monodirectional(UnitSphere):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, reference_uvw=[1., 0., 0.]):
|
||||
def __init__(self, reference_uvw: typing.Sequence[float] = [1., 0., 0.]):
|
||||
super().__init__(reference_uvw)
|
||||
|
||||
def to_xml_element(self):
|
||||
|
|
@ -228,7 +230,7 @@ class Monodirectional(UnitSphere):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate monodirectional distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -304,7 +306,12 @@ class CartesianIndependent(Spatial):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, x, y, z):
|
||||
def __init__(
|
||||
self,
|
||||
x: openmc.stats.Univariate,
|
||||
y: openmc.stats.Univariate,
|
||||
z: openmc.stats.Univariate
|
||||
):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = z
|
||||
|
|
@ -353,7 +360,7 @@ class CartesianIndependent(Spatial):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate spatial distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -477,7 +484,7 @@ class SphericalIndependent(Spatial):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate spatial distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -599,7 +606,7 @@ class CylindricalIndependent(Spatial):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate spatial distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -772,7 +779,12 @@ class Box(Spatial):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, lower_left, upper_right, only_fissionable=False):
|
||||
def __init__(
|
||||
self,
|
||||
lower_left: typing.Sequence[float],
|
||||
upper_right: typing.Sequence[float],
|
||||
only_fissionable: bool = False
|
||||
):
|
||||
self.lower_left = lower_left
|
||||
self.upper_right = upper_right
|
||||
self.only_fissionable = only_fissionable
|
||||
|
|
@ -826,7 +838,7 @@ class Box(Spatial):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate box distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -865,7 +877,7 @@ class Point(Spatial):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, xyz=(0., 0., 0.)):
|
||||
def __init__(self, xyz: typing.Sequence[float] = (0., 0., 0.)):
|
||||
self.xyz = xyz
|
||||
|
||||
@property
|
||||
|
|
@ -894,7 +906,7 @@ class Point(Spatial):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate point distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -912,8 +924,13 @@ class Point(Spatial):
|
|||
return cls(xyz)
|
||||
|
||||
|
||||
def spherical_uniform(r_outer, r_inner=0.0, thetas=(0., pi), phis=(0., 2*pi),
|
||||
origin=(0., 0., 0.)):
|
||||
def spherical_uniform(
|
||||
r_outer: float,
|
||||
r_inner: float = 0.0,
|
||||
thetas: typing.Sequence[float] = (0., pi),
|
||||
phis: typing.Sequence[float] = (0., 2*pi),
|
||||
origin: typing.Sequence[float] = (0., 0., 0.)
|
||||
):
|
||||
"""Return a uniform spatial distribution over a spherical shell.
|
||||
|
||||
This function provides a uniform spatial distribution over a spherical
|
||||
|
|
@ -926,15 +943,15 @@ def spherical_uniform(r_outer, r_inner=0.0, thetas=(0., pi), phis=(0., 2*pi),
|
|||
----------
|
||||
r_outer : float
|
||||
Outer radius of the spherical shell in [cm]
|
||||
r_inner : float, optional
|
||||
r_inner : float
|
||||
Inner radius of the spherical shell in [cm]
|
||||
thetas : iterable of float, optional
|
||||
thetas : iterable of float
|
||||
Starting and ending theta coordinates (angle relative to
|
||||
the z-axis) in radius in a reference frame centered at `origin`
|
||||
phis : iterable of float, optional
|
||||
phis : iterable of float
|
||||
Starting and ending phi coordinates (azimuthal angle) in
|
||||
radians in a reference frame centered at `origin`
|
||||
origin: iterable of float, optional
|
||||
origin: iterable of float
|
||||
Coordinates (x0, y0, z0) of the center of the spherical
|
||||
reference frame for the distribution.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
import math
|
||||
import typing
|
||||
from abc import ABC, abstractmethod
|
||||
from collections import defaultdict
|
||||
from collections.abc import Iterable
|
||||
from copy import deepcopy
|
||||
import math
|
||||
from numbers import Real
|
||||
from warnings import warn
|
||||
import lxml.etree as ET
|
||||
|
||||
import lxml.etree as ET
|
||||
import numpy as np
|
||||
|
||||
import openmc.checkvalue as cv
|
||||
from .._xml import get_text
|
||||
from ..mixin import EqualityMixin
|
||||
|
||||
|
||||
_INTERPOLATION_SCHEMES = [
|
||||
'histogram',
|
||||
'linear-linear',
|
||||
|
|
@ -66,7 +66,7 @@ class Univariate(EqualityMixin, ABC):
|
|||
return Mixture.from_xml_element(elem)
|
||||
|
||||
@abstractmethod
|
||||
def sample(n_samples=1, seed=None):
|
||||
def sample(n_samples: int = 1, seed: typing.Optional[int] = None):
|
||||
"""Sample the univariate distribution
|
||||
|
||||
Parameters
|
||||
|
|
@ -186,7 +186,7 @@ class Discrete(Univariate):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate discrete distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -206,7 +206,11 @@ class Discrete(Univariate):
|
|||
return cls(x, p)
|
||||
|
||||
@classmethod
|
||||
def merge(cls, dists, probs):
|
||||
def merge(
|
||||
cls,
|
||||
dists: typing.Sequence['openmc.stats.Discrete'],
|
||||
probs: typing.Sequence[int]
|
||||
):
|
||||
"""Merge multiple discrete distributions into a single distribution
|
||||
|
||||
.. versionadded:: 0.13.1
|
||||
|
|
@ -271,7 +275,7 @@ class Uniform(Univariate):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, a=0.0, b=1.0):
|
||||
def __init__(self, a: float = 0.0, b: float = 1.0):
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
|
|
@ -306,7 +310,7 @@ class Uniform(Univariate):
|
|||
np.random.seed(seed)
|
||||
return np.random.uniform(self.a, self.b, n_samples)
|
||||
|
||||
def to_xml_element(self, element_name):
|
||||
def to_xml_element(self, element_name: str):
|
||||
"""Return XML representation of the uniform distribution
|
||||
|
||||
Parameters
|
||||
|
|
@ -326,7 +330,7 @@ class Uniform(Univariate):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate uniform distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -372,7 +376,7 @@ class PowerLaw(Univariate):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, a=0.0, b=1.0, n=0):
|
||||
def __init__(self, a: float = 0.0, b: float = 1.0, n: float = 0.):
|
||||
self.a = a
|
||||
self.b = b
|
||||
self.n = n
|
||||
|
|
@ -415,7 +419,7 @@ class PowerLaw(Univariate):
|
|||
span = self.b**pwr - offset
|
||||
return np.power(offset + xi * span, 1/pwr)
|
||||
|
||||
def to_xml_element(self, element_name):
|
||||
def to_xml_element(self, element_name: str):
|
||||
"""Return XML representation of the power law distribution
|
||||
|
||||
Parameters
|
||||
|
|
@ -435,7 +439,7 @@ class PowerLaw(Univariate):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate power law distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -493,12 +497,12 @@ class Maxwell(Univariate):
|
|||
return self.sample_maxwell(self.theta, n_samples)
|
||||
|
||||
@staticmethod
|
||||
def sample_maxwell(t, n_samples):
|
||||
def sample_maxwell(t, n_samples: int):
|
||||
r1, r2, r3 = np.random.rand(3, n_samples)
|
||||
c = np.cos(0.5 * np.pi * r3)
|
||||
return -t * (np.log(r1) + np.log(r2) * c * c)
|
||||
|
||||
def to_xml_element(self, element_name):
|
||||
def to_xml_element(self, element_name: str):
|
||||
"""Return XML representation of the Maxwellian distribution
|
||||
|
||||
Parameters
|
||||
|
|
@ -518,7 +522,7 @@ class Maxwell(Univariate):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate Maxwellian distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -593,7 +597,7 @@ class Watt(Univariate):
|
|||
aab = self.a * self.a * self.b
|
||||
return w + 0.25*aab + u*np.sqrt(aab*w)
|
||||
|
||||
def to_xml_element(self, element_name):
|
||||
def to_xml_element(self, element_name: str):
|
||||
"""Return XML representation of the Watt distribution
|
||||
|
||||
Parameters
|
||||
|
|
@ -613,7 +617,7 @@ class Watt(Univariate):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate Watt distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -683,7 +687,7 @@ class Normal(Univariate):
|
|||
np.random.seed(seed)
|
||||
return np.random.normal(self.mean_value, self.std_dev, n_samples)
|
||||
|
||||
def to_xml_element(self, element_name):
|
||||
def to_xml_element(self, element_name: str):
|
||||
"""Return XML representation of the Normal distribution
|
||||
|
||||
Parameters
|
||||
|
|
@ -703,7 +707,7 @@ class Normal(Univariate):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate Normal distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -721,7 +725,7 @@ class Normal(Univariate):
|
|||
return cls(*map(float, params))
|
||||
|
||||
|
||||
def muir(e0, m_rat, kt):
|
||||
def muir(e0: float, m_rat: float, kt: float):
|
||||
"""Generate a Muir energy spectrum
|
||||
|
||||
The Muir energy spectrum is a normal distribution, but for convenience
|
||||
|
|
@ -793,8 +797,13 @@ class Tabular(Univariate):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, x, p, interpolation='linear-linear',
|
||||
ignore_negative=False):
|
||||
def __init__(
|
||||
self,
|
||||
x: typing.Sequence[float],
|
||||
p: typing.Sequence[float],
|
||||
interpolation: str = 'linear-linear',
|
||||
ignore_negative: bool = False
|
||||
):
|
||||
self._ignore_negative = ignore_negative
|
||||
self.x = x
|
||||
self.p = p
|
||||
|
|
@ -886,7 +895,7 @@ class Tabular(Univariate):
|
|||
"""Normalize the probabilities stored on the distribution"""
|
||||
self.p /= self.cdf().max()
|
||||
|
||||
def sample(self, n_samples=1, seed=None):
|
||||
def sample(self, n_samples: int = 1, seed: typing.Optional[int] = None):
|
||||
np.random.seed(seed)
|
||||
xi = np.random.rand(n_samples)
|
||||
|
||||
|
|
@ -947,7 +956,7 @@ class Tabular(Univariate):
|
|||
assert all(samples_out < self.x[-1])
|
||||
return samples_out
|
||||
|
||||
def to_xml_element(self, element_name):
|
||||
def to_xml_element(self, element_name: str):
|
||||
"""Return XML representation of the tabular distribution
|
||||
|
||||
Parameters
|
||||
|
|
@ -971,7 +980,7 @@ class Tabular(Univariate):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate tabular distribution from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
@ -1028,7 +1037,7 @@ class Legendre(Univariate):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, coefficients):
|
||||
def __init__(self, coefficients: typing.Sequence[float]):
|
||||
self.coefficients = coefficients
|
||||
self._legendre_poly = None
|
||||
|
||||
|
|
@ -1082,7 +1091,11 @@ class Mixture(Univariate):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, probability, distribution):
|
||||
def __init__(
|
||||
self,
|
||||
probability: typing.Sequence[float],
|
||||
distribution: typing.Sequence['openmc.Univariate']
|
||||
):
|
||||
self.probability = probability
|
||||
self.distribution = distribution
|
||||
|
||||
|
|
@ -1140,7 +1153,7 @@ class Mixture(Univariate):
|
|||
norm = sum(self.probability)
|
||||
self.probability = [val / norm for val in self.probability]
|
||||
|
||||
def to_xml_element(self, element_name):
|
||||
def to_xml_element(self, element_name: str):
|
||||
"""Return XML representation of the mixture distribution
|
||||
|
||||
.. versionadded:: 0.13.0
|
||||
|
|
@ -1167,7 +1180,7 @@ class Mixture(Univariate):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate mixture distribution from an XML element
|
||||
|
||||
.. versionadded:: 0.13.0
|
||||
|
|
@ -1207,7 +1220,10 @@ class Mixture(Univariate):
|
|||
])
|
||||
|
||||
|
||||
def combine_distributions(dists, probs):
|
||||
def combine_distributions(
|
||||
dists: typing.Sequence['openmc.Univariate'],
|
||||
probs: typing.Sequence[float]
|
||||
):
|
||||
"""Combine distributions with specified probabilities
|
||||
|
||||
This function can be used to combine multiple instances of
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class Trigger(EqualityMixin):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, trigger_type, threshold):
|
||||
def __init__(self, trigger_type: str, threshold: float):
|
||||
self.trigger_type = trigger_type
|
||||
self.threshold = threshold
|
||||
self._scores = []
|
||||
|
|
@ -92,7 +92,7 @@ class Trigger(EqualityMixin):
|
|||
return element
|
||||
|
||||
@classmethod
|
||||
def from_xml_element(cls, elem):
|
||||
def from_xml_element(cls, elem: ET.Element):
|
||||
"""Generate trigger object from an XML element
|
||||
|
||||
Parameters
|
||||
|
|
|
|||
|
|
@ -589,13 +589,19 @@ def wwinp_to_wws(path: PathLike) -> List[WeightWindows]:
|
|||
mesh = RectilinearMesh()
|
||||
mesh.x_grid, mesh.y_grid, mesh.z_grid = grids
|
||||
elif nwg == 2:
|
||||
mesh = CylindricalMesh()
|
||||
mesh.r_grid, mesh.z_grid, mesh.phi_grid = grids
|
||||
mesh.origin = xyz0
|
||||
mesh = CylindricalMesh(
|
||||
r_grid=grids[0],
|
||||
z_grid=grids[1],
|
||||
phi_grid=grids[2],
|
||||
origin = xyz0,
|
||||
)
|
||||
elif nwg == 3:
|
||||
mesh = SphericalMesh()
|
||||
mesh.r_grid, mesh.theta_grid, mesh.phi_grid = grids
|
||||
mesh.origin = xyz0
|
||||
mesh = SphericalMesh(
|
||||
r_grid=grids[0],
|
||||
theta_grid=grids[1],
|
||||
phi_grid=grids[2],
|
||||
origin = xyz0
|
||||
)
|
||||
|
||||
# extract weight window values from array
|
||||
wws = []
|
||||
|
|
|
|||
|
|
@ -60,11 +60,11 @@ def model():
|
|||
recti_mesh_exp_vols = np.multiply.outer(dxdy, dz)
|
||||
np.testing.assert_allclose(recti_mesh.volumes, recti_mesh_exp_vols)
|
||||
|
||||
cyl_mesh = openmc.CylindricalMesh()
|
||||
cyl_mesh.r_grid = np.linspace(0, 7.5, 18)
|
||||
cyl_mesh.phi_grid = np.linspace(0, 2*pi, 19)
|
||||
cyl_mesh.z_grid = np.linspace(-7.5, 7.5, 17)
|
||||
|
||||
cyl_mesh = openmc.CylindricalMesh(
|
||||
r_grid=np.linspace(0, 7.5, 18),
|
||||
phi_grid=np.linspace(0, 2*pi, 19),
|
||||
z_grid=np.linspace(-7.5, 7.5, 17),
|
||||
)
|
||||
dr = 0.5 * np.diff(np.linspace(0, 7.5, 18)**2)
|
||||
dp = np.full(cyl_mesh.dimension[1], 2*pi / 18)
|
||||
dz = np.full(cyl_mesh.dimension[2], 15 / 16)
|
||||
|
|
@ -72,10 +72,11 @@ def model():
|
|||
cyl_mesh_exp_vols = np.multiply.outer(drdp, dz)
|
||||
np.testing.assert_allclose(cyl_mesh.volumes, cyl_mesh_exp_vols)
|
||||
|
||||
sph_mesh = openmc.SphericalMesh()
|
||||
sph_mesh.r_grid = np.linspace(0, 7.5, 18)
|
||||
sph_mesh.theta_grid = np.linspace(0, pi, 9)
|
||||
sph_mesh.phi_grid = np.linspace(0, 2*pi, 19)
|
||||
sph_mesh = openmc.SphericalMesh(
|
||||
r_grid=np.linspace(0, 7.5, 18),
|
||||
theta_grid=np.linspace(0, pi, 9),
|
||||
phi_grid=np.linspace(0, 2*pi, 19)
|
||||
)
|
||||
dr = np.diff(np.linspace(0, 7.5, 18)**3) / 3
|
||||
dt = np.diff(-np.cos(np.linspace(0, pi, 9)))
|
||||
dp = np.full(sph_mesh.dimension[2], 2*pi / 18)
|
||||
|
|
|
|||
|
|
@ -32,17 +32,19 @@ rect_mesh.x_grid = np.linspace(0, 10, 5)
|
|||
rect_mesh.y_grid = np.geomspace(5., 20., 10)
|
||||
rect_mesh.z_grid = np.linspace(1, 100, 20)
|
||||
|
||||
cyl_mesh = openmc.CylindricalMesh()
|
||||
cyl_mesh.origin = (10, 10, -10)
|
||||
cyl_mesh.r_grid = np.linspace(0, 5, 5)
|
||||
cyl_mesh.phi_grid = np.linspace(0, 2 * np.pi, 4)
|
||||
cyl_mesh.z_grid = np.linspace(0, 2, 4)
|
||||
cyl_mesh = openmc.CylindricalMesh(
|
||||
origin=(10, 10, -10),
|
||||
r_grid=np.linspace(0, 5, 5),
|
||||
phi_grid=np.linspace(0, 2 * np.pi, 4),
|
||||
z_grid=np.linspace(0, 2, 4),
|
||||
)
|
||||
|
||||
sphere_mesh = openmc.SphericalMesh()
|
||||
sphere_mesh.origin = (10, 10, -10)
|
||||
sphere_mesh.r_grid = np.linspace(0, 5, 3)
|
||||
sphere_mesh.theta_grid = np.linspace(0, 0.5 * np.pi, 4)
|
||||
sphere_mesh.phi_grid = np.linspace(0, 2*np.pi, 8)
|
||||
sphere_mesh = openmc.SphericalMesh(
|
||||
origin=(10, 10, -10),
|
||||
r_grid=np.linspace(0, 5, 3),
|
||||
theta_grid=np.linspace(0, 0.5 * np.pi, 4),
|
||||
phi_grid=np.linspace(0, 2*np.pi, 8),
|
||||
)
|
||||
|
||||
|
||||
def mesh_data(mesh_dims):
|
||||
|
|
|
|||
|
|
@ -49,15 +49,17 @@ rectilinear_mesh.y_grid = \
|
|||
np.concatenate((-rectilinear_mesh.y_grid[::-1], rectilinear_mesh.y_grid))
|
||||
rectilinear_mesh.z_grid = np.linspace(-10, 10, 11)
|
||||
|
||||
cylinder_mesh = openmc.CylindricalMesh()
|
||||
cylinder_mesh.r_grid = np.linspace(0, 10, 23)
|
||||
cylinder_mesh = openmc.CylindricalMesh(
|
||||
r_grid=np.linspace(0, 10, 23),
|
||||
z_grid=np.linspace(0, 1, 15)
|
||||
)
|
||||
cylinder_mesh.phi_grid = np.linspace(0, np.pi, 21)
|
||||
cylinder_mesh.z_grid = np.linspace(0, 1, 15)
|
||||
|
||||
spherical_mesh = openmc.SphericalMesh()
|
||||
spherical_mesh.r_grid = np.linspace(1, 10, 30)
|
||||
spherical_mesh.phi_grid = np.linspace(0, 0.8*np.pi, 25)
|
||||
spherical_mesh.theta_grid = np.linspace(0, np.pi / 2, 15)
|
||||
spherical_mesh = openmc.SphericalMesh(
|
||||
r_grid=np.linspace(1, 10, 30),
|
||||
phi_grid=np.linspace(0, 0.8*np.pi, 25),
|
||||
theta_grid=np.linspace(0, np.pi / 2, 15),
|
||||
)
|
||||
|
||||
MESHES = [cylinder_mesh, regular_mesh, rectilinear_mesh, spherical_mesh]
|
||||
|
||||
|
|
@ -143,16 +145,17 @@ def test_write_data_to_vtk_size_mismatch(mesh):
|
|||
mesh.write_data_to_vtk(filename="out.vtk", datasets={"label": data})
|
||||
|
||||
def test_write_data_to_vtk_round_trip(run_in_tmpdir):
|
||||
cmesh = openmc.CylindricalMesh()
|
||||
cmesh.r_grid = (0.0, 1.0, 2.0)
|
||||
cmesh.z_grid = (0.0, 2.0, 4.0, 5.0)
|
||||
cmesh.phi_grid = (0.0, 3.0, 6.0)
|
||||
|
||||
smesh = openmc.SphericalMesh()
|
||||
smesh.r_grid = (0.0, 1.0, 2.0)
|
||||
smesh.theta_grid = (0.0, 2.0, 4.0, 5.0)
|
||||
smesh.phi_grid = (0.0, 3.0, 6.0)
|
||||
cmesh = openmc.CylindricalMesh(
|
||||
r_grid=(0.0, 1.0, 2.0),
|
||||
z_grid=(0.0, 2.0, 4.0, 5.0),
|
||||
phi_grid=(0.0, 3.0, 6.0),
|
||||
)
|
||||
|
||||
smesh = openmc.SphericalMesh(
|
||||
r_grid=(0.0, 1.0, 2.0),
|
||||
theta_grid=(0.0, 2.0, 4.0, 5.0),
|
||||
phi_grid=(0.0, 3.0, 6.0),
|
||||
)
|
||||
rmesh = openmc.RegularMesh()
|
||||
rmesh.lower_left = (0.0, 0.0, 0.0)
|
||||
rmesh.upper_right = (1.0, 3.0, 5.0)
|
||||
|
|
@ -276,11 +279,11 @@ def test_vtk_write_ordering(run_in_tmpdir, model, mesh, surface):
|
|||
|
||||
|
||||
def test_sphere_mesh_coordinates(run_in_tmpdir):
|
||||
mesh = openmc.SphericalMesh()
|
||||
mesh.r_grid = np.linspace(0.1, 10, 30)
|
||||
mesh.phi_grid = np.linspace(0, 1.5*np.pi, 25)
|
||||
mesh.theta_grid = np.linspace(0, np.pi / 2, 15)
|
||||
|
||||
mesh = openmc.SphericalMesh(
|
||||
r_grid=np.linspace(0.1, 10, 30),
|
||||
phi_grid=np.linspace(0, 1.5*np.pi, 25),
|
||||
theta_grid=np.linspace(0, np.pi / 2, 15),
|
||||
)
|
||||
# write the data to a VTK file (no data)
|
||||
vtk_filename = 'test.vtk'
|
||||
mesh.write_data_to_vtk(vtk_filename, {})
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ def model():
|
|||
settings.run_mode = 'fixed source'
|
||||
|
||||
# build
|
||||
mesh = openmc.CylindricalMesh()
|
||||
mesh.phi_grid = np.linspace(0, 2*np.pi, 21)
|
||||
mesh.z_grid = np.linspace(-geom_size, geom_size, 11)
|
||||
mesh.r_grid = np.linspace(0, geom_size, geom_size)
|
||||
|
||||
mesh = openmc.CylindricalMesh(
|
||||
phi_grid=np.linspace(0, 2*np.pi, 21),
|
||||
z_grid=np.linspace(-geom_size, geom_size, 11),
|
||||
r_grid=np.linspace(0, geom_size, geom_size)
|
||||
)
|
||||
tally = openmc.Tally()
|
||||
|
||||
mesh_filter = openmc.MeshFilter(mesh)
|
||||
|
|
@ -127,10 +127,11 @@ def void_coincident_geom_model():
|
|||
settings.particles = 1000
|
||||
model.settings = settings
|
||||
|
||||
mesh = openmc.CylindricalMesh()
|
||||
mesh.r_grid = np.linspace(0, 250, 501)
|
||||
mesh.z_grid = [-250, 250]
|
||||
mesh.phi_grid = np.linspace(0, 2*np.pi, 2)
|
||||
mesh = openmc.CylindricalMesh(
|
||||
r_grid=np.linspace(0, 250, 501),
|
||||
z_grid=[-250, 250],
|
||||
phi_grid=np.linspace(0, 2*np.pi, 2),
|
||||
)
|
||||
mesh_filter = openmc.MeshFilter(mesh)
|
||||
|
||||
tally = openmc.Tally()
|
||||
|
|
|
|||
|
|
@ -22,15 +22,17 @@ def test_spherical_mesh_estimators(run_in_tmpdir):
|
|||
model.settings.inactive = 10
|
||||
model.settings.batches = 20
|
||||
|
||||
sph_mesh = openmc.SphericalMesh()
|
||||
sph_mesh.r_grid = np.linspace(0.0, 5.0**3, 20)**(1/3)
|
||||
sph_mesh = openmc.SphericalMesh(
|
||||
r_grid=np.linspace(0.0, 5.0**3, 20)**(1/3)
|
||||
)
|
||||
tally1 = openmc.Tally()
|
||||
tally1.filters = [openmc.MeshFilter(sph_mesh)]
|
||||
tally1.scores = ['flux']
|
||||
tally1.estimator = 'collision'
|
||||
|
||||
sph_mesh = openmc.SphericalMesh()
|
||||
sph_mesh.r_grid = np.linspace(0.0, 5.0**3, 20)**(1/3)
|
||||
sph_mesh = openmc.SphericalMesh(
|
||||
r_grid=np.linspace(0.0, 5.0**3, 20)**(1/3)
|
||||
)
|
||||
tally2 = openmc.Tally()
|
||||
tally2.filters = [openmc.MeshFilter(sph_mesh)]
|
||||
tally2.scores = ['flux']
|
||||
|
|
@ -75,17 +77,19 @@ def test_cylindrical_mesh_estimators(run_in_tmpdir):
|
|||
model.settings.inactive = 10
|
||||
model.settings.batches = 20
|
||||
|
||||
cyl_mesh = openmc.CylindricalMesh()
|
||||
cyl_mesh.r_grid = np.linspace(0.0, 5.0**3, 20)**(1/3)
|
||||
cyl_mesh.z_grid = [-5., 5.]
|
||||
cyl_mesh = openmc.CylindricalMesh(
|
||||
r_grid=np.linspace(0.0, 5.0**3, 20)**(1/3),
|
||||
z_grid=[-5., 5.]
|
||||
)
|
||||
tally1 = openmc.Tally()
|
||||
tally1.filters = [openmc.MeshFilter(cyl_mesh)]
|
||||
tally1.scores = ['flux']
|
||||
tally1.estimator = 'collision'
|
||||
|
||||
cyl_mesh = openmc.CylindricalMesh()
|
||||
cyl_mesh.r_grid = np.linspace(0.0, 5.0**3, 20)**(1/3)
|
||||
cyl_mesh.z_grid = [-5., 5.]
|
||||
cyl_mesh = openmc.CylindricalMesh(
|
||||
r_grid=np.linspace(0.0, 5.0**3, 20)**(1/3),
|
||||
z_grid=[-5., 5.]
|
||||
)
|
||||
tally2 = openmc.Tally()
|
||||
tally2.filters = [openmc.MeshFilter(cyl_mesh)]
|
||||
tally2.scores = ['flux']
|
||||
|
|
@ -133,10 +137,11 @@ def test_cylindrical_mesh_coincident(scale, run_in_tmpdir):
|
|||
model.settings.batches = 10
|
||||
model.settings.inactive = 0
|
||||
|
||||
cyl_mesh = openmc.CylindricalMesh()
|
||||
cyl_mesh.r_grid = [0., 1.25*scale]
|
||||
cyl_mesh.phi_grid = [0., 2*math.pi]
|
||||
cyl_mesh.z_grid = [-1e10, 1e10]
|
||||
cyl_mesh = openmc.CylindricalMesh(
|
||||
r_grid=[0., 1.25*scale],
|
||||
phi_grid=[0., 2*math.pi],
|
||||
z_grid=[-1e10, 1e10]
|
||||
)
|
||||
cyl_mesh_filter = openmc.MeshFilter(cyl_mesh)
|
||||
cell_filter = openmc.CellFilter([cell1])
|
||||
|
||||
|
|
@ -183,10 +188,12 @@ def test_spherical_mesh_coincident(scale, run_in_tmpdir):
|
|||
model.settings.batches = 10
|
||||
model.settings.inactive = 0
|
||||
|
||||
sph_mesh = openmc.SphericalMesh()
|
||||
sph_mesh.r_grid = [0., 1.25*scale]
|
||||
sph_mesh.phi_grid = [0., 2*math.pi]
|
||||
sph_mesh.theta_grid = [0., math.pi]
|
||||
sph_mesh = openmc.SphericalMesh(
|
||||
r_grid=[0., 1.25*scale],
|
||||
phi_grid=[0., 2*math.pi],
|
||||
theta_grid=[0., math.pi],
|
||||
)
|
||||
|
||||
sph_mesh_filter = openmc.MeshFilter(sph_mesh)
|
||||
cell_filter = openmc.CellFilter([cell1])
|
||||
|
||||
|
|
@ -227,10 +234,11 @@ def test_get_reshaped_data(run_in_tmpdir):
|
|||
model.settings.inactive = 10
|
||||
model.settings.batches = 20
|
||||
|
||||
sph_mesh = openmc.SphericalMesh()
|
||||
sph_mesh.r_grid = np.linspace(0.0, 5.0**3, 20)**(1/3)
|
||||
sph_mesh.theta_grid = np.linspace(0, math.pi, 4)
|
||||
sph_mesh.phi_grid = np.linspace(0, 2*math.pi, 3)
|
||||
sph_mesh = openmc.SphericalMesh(
|
||||
r_grid=np.linspace(0.0, 5.0**3, 20)**(1/3),
|
||||
theta_grid=np.linspace(0, math.pi, 4),
|
||||
phi_grid=np.linspace(0, 2*math.pi, 3)
|
||||
)
|
||||
tally1 = openmc.Tally()
|
||||
efilter = openmc.EnergyFilter([0, 1e5, 1e8])
|
||||
meshfilter = openmc.MeshFilter(sph_mesh)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import openmc
|
||||
import pytest
|
||||
from math import pi
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
import openmc
|
||||
|
||||
|
||||
@pytest.mark.parametrize("val_left,val_right", [(0, 0), (-1., -1.), (2.0, 2)])
|
||||
def test_raises_error_when_flat(val_left, val_right):
|
||||
|
|
@ -37,10 +40,63 @@ def test_raises_error_when_flat(val_left, val_right):
|
|||
|
||||
def test_mesh_bounding_box():
|
||||
mesh = openmc.RegularMesh()
|
||||
mesh.lower_left = [-2, -3 ,-5]
|
||||
mesh.lower_left = [-2, -3, -5]
|
||||
mesh.upper_right = [2, 3, 5]
|
||||
bb = mesh.bounding_box
|
||||
assert isinstance(bb, openmc.BoundingBox)
|
||||
np.testing.assert_array_equal(bb.lower_left, np.array([-2, -3 ,-5]))
|
||||
np.testing.assert_array_equal(bb.upper_right, np.array([2, 3, 5]))
|
||||
|
||||
|
||||
def test_SphericalMesh_initiation():
|
||||
|
||||
# test defaults
|
||||
mesh = openmc.SphericalMesh(r_grid=(0, 10))
|
||||
assert (mesh.origin == np.array([0, 0, 0])).all()
|
||||
assert mesh.r_grid == (0, 10)
|
||||
assert (mesh.theta_grid == np.array([0, pi])).all()
|
||||
assert (mesh.phi_grid == np.array([0, 2*pi])).all()
|
||||
|
||||
# test setting on creation
|
||||
mesh = openmc.SphericalMesh(
|
||||
origin=(1, 2, 3),
|
||||
r_grid=(0, 2),
|
||||
theta_grid=(1, 3),
|
||||
phi_grid=(2, 4)
|
||||
)
|
||||
assert (mesh.origin == np.array([1, 2, 3])).all()
|
||||
assert mesh.r_grid == (0., 2.)
|
||||
assert mesh.theta_grid == (1, 3)
|
||||
assert mesh.phi_grid == (2, 4)
|
||||
|
||||
# test attribute changing
|
||||
mesh.r_grid = (0, 11)
|
||||
assert (mesh.r_grid == np.array([0., 11.])).all()
|
||||
|
||||
|
||||
def test_CylindricalMesh_initiation():
|
||||
|
||||
# test defaults
|
||||
mesh = openmc.CylindricalMesh(r_grid=(0, 10), z_grid=(0, 10))
|
||||
assert (mesh.origin == np.array([0, 0, 0])).all()
|
||||
assert mesh.r_grid == (0, 10)
|
||||
assert mesh.phi_grid == (0, 2*pi)
|
||||
assert mesh.z_grid == (0, 10)
|
||||
|
||||
# test setting on creation
|
||||
mesh = openmc.CylindricalMesh(
|
||||
origin=(1, 2, 3),
|
||||
r_grid=(0, 2),
|
||||
z_grid=(1, 3),
|
||||
phi_grid=(2, 4)
|
||||
)
|
||||
assert (mesh.origin == np.array([1, 2, 3])).all()
|
||||
assert (mesh.r_grid == np.array([0., 2.])).all()
|
||||
assert mesh.z_grid == (1, 3)
|
||||
assert (mesh.phi_grid == np.array([2, 4])).all()
|
||||
|
||||
# test attribute changing
|
||||
mesh.r_grid = (0., 10.)
|
||||
assert (mesh.r_grid == np.array([0, 10.])).all()
|
||||
mesh.z_grid = (0., 4.)
|
||||
assert (mesh.z_grid == np.array([0, 4.])).all()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ def test_reg_mesh_from_cell():
|
|||
surface = openmc.Sphere(r=10, x0=2, y0=3, z0=5)
|
||||
cell = openmc.Cell(region=-surface)
|
||||
|
||||
mesh = openmc.RegularMesh.from_domain(cell, dimension=[7, 11, 13])
|
||||
mesh = openmc.RegularMesh.from_domain(domain=cell, dimension=[7, 11, 13])
|
||||
assert isinstance(mesh, openmc.RegularMesh)
|
||||
assert np.array_equal(mesh.dimension, (7, 11, 13))
|
||||
assert np.array_equal(mesh.lower_left, cell.bounding_box[0])
|
||||
|
|
@ -23,7 +23,7 @@ def test_cylindrical_mesh_from_cell():
|
|||
z_surface_1 = openmc.ZPlane(z0=30)
|
||||
z_surface_2 = openmc.ZPlane(z0=0)
|
||||
cell = openmc.Cell(region=-cy_surface & -z_surface_1 & +z_surface_2)
|
||||
mesh = openmc.CylindricalMesh.from_domain(cell, dimension=[2, 4, 3])
|
||||
mesh = openmc.CylindricalMesh.from_domain(domain=cell, dimension=[2, 4, 3])
|
||||
|
||||
assert isinstance(mesh, openmc.CylindricalMesh)
|
||||
assert np.array_equal(mesh.dimension, (2, 4, 3))
|
||||
|
|
@ -38,7 +38,7 @@ def test_reg_mesh_from_region():
|
|||
surface = openmc.Sphere(r=1, x0=-5, y0=-3, z0=-2)
|
||||
region = -surface
|
||||
|
||||
mesh = openmc.RegularMesh.from_domain(region)
|
||||
mesh = openmc.RegularMesh.from_domain(domain=region)
|
||||
assert isinstance(mesh, openmc.RegularMesh)
|
||||
assert np.array_equal(mesh.dimension, (10, 10, 10)) # default values
|
||||
assert np.array_equal(mesh.lower_left, region.bounding_box[0])
|
||||
|
|
@ -53,7 +53,7 @@ def test_cylindrical_mesh_from_region():
|
|||
z_surface_2 = openmc.ZPlane(z0=-30)
|
||||
cell = openmc.Cell(region=-cy_surface & -z_surface_1 & +z_surface_2)
|
||||
mesh = openmc.CylindricalMesh.from_domain(
|
||||
cell,
|
||||
domain=cell,
|
||||
dimension=(6, 2, 3),
|
||||
phi_grid_bounds=(0., np.pi)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ def model():
|
|||
settings.run_mode = 'fixed source'
|
||||
|
||||
# build
|
||||
mesh = openmc.SphericalMesh()
|
||||
mesh.phi_grid = np.linspace(0, 2*np.pi, 13)
|
||||
mesh.theta_grid = np.linspace(0, np.pi, 7)
|
||||
mesh.r_grid = np.linspace(0, geom_size, geom_size)
|
||||
|
||||
mesh = openmc.SphericalMesh(
|
||||
phi_grid=np.linspace(0, 2*np.pi, 13),
|
||||
theta_grid=np.linspace(0, np.pi, 7),
|
||||
r_grid=np.linspace(0, geom_size, geom_size),
|
||||
)
|
||||
tally = openmc.Tally()
|
||||
|
||||
mesh_filter = openmc.MeshFilter(mesh)
|
||||
|
|
@ -135,8 +135,7 @@ def void_coincident_geom_model():
|
|||
settings.particles = 5000
|
||||
model.settings = settings
|
||||
|
||||
mesh = openmc.SphericalMesh()
|
||||
mesh.r_grid = np.linspace(0, 250, 501)
|
||||
mesh = openmc.SphericalMesh(r_grid=np.linspace(0, 250, 501))
|
||||
mesh_filter = openmc.MeshFilter(mesh)
|
||||
|
||||
tally = openmc.Tally()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue