Source code for openmc.lib.mesh

from collections.abc import Mapping, Iterable
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 . import _dll
from .core import _FortranObjectWithID
from .error import _error_handler
from .material import Material

__all__ = ['RegularMesh', 'meshes']

# Mesh functions
_dll.openmc_extend_meshes.argtypes = [c_int32, POINTER(c_int32), POINTER(c_int32)]
_dll.openmc_extend_meshes.restype = c_int
_dll.openmc_extend_meshes.errcheck = _error_handler
_dll.openmc_mesh_get_id.argtypes = [c_int32, POINTER(c_int32)]
_dll.openmc_mesh_get_id.restype = c_int
_dll.openmc_mesh_get_id.errcheck = _error_handler
_dll.openmc_mesh_get_dimension.argtypes = [c_int32, POINTER(POINTER(c_int)), POINTER(c_int)]
_dll.openmc_mesh_get_dimension.restype = c_int
_dll.openmc_mesh_get_dimension.errcheck = _error_handler
_dll.openmc_mesh_get_params.argtypes = [
    c_int32, POINTER(POINTER(c_double)), POINTER(POINTER(c_double)),
    POINTER(POINTER(c_double)), POINTER(c_int)]
_dll.openmc_mesh_get_params.restype = c_int
_dll.openmc_mesh_get_params.errcheck = _error_handler
_dll.openmc_mesh_set_id.argtypes = [c_int32, c_int32]
_dll.openmc_mesh_set_id.restype = c_int
_dll.openmc_mesh_set_id.errcheck = _error_handler
_dll.openmc_mesh_set_dimension.argtypes = [c_int32, c_int, POINTER(c_int)]
_dll.openmc_mesh_set_dimension.restype = c_int
_dll.openmc_mesh_set_dimension.errcheck = _error_handler
_dll.openmc_mesh_set_params.argtypes = [
    c_int32, c_int, POINTER(c_double), POINTER(c_double), POINTER(c_double)]
_dll.openmc_mesh_set_params.restype = c_int
_dll.openmc_mesh_set_params.errcheck = _error_handler
_dll.openmc_get_mesh_index.argtypes = [c_int32, POINTER(c_int32)]
_dll.openmc_get_mesh_index.restype = c_int
_dll.openmc_get_mesh_index.errcheck = _error_handler
_dll.n_meshes.argtypes = []
_dll.n_meshes.restype = c_int


[docs]class RegularMesh(_FortranObjectWithID): """RegularMesh stored internally. This class exposes a mesh that is stored internally in the OpenMC library. To obtain a view of a mesh with a given ID, use the :data:`openmc.lib.meshes` mapping. Parameters ---------- index : int Index in the `meshes` array. Attributes ---------- id : int ID of the mesh dimension : iterable of int The number of mesh cells in each direction. lower_left : numpy.ndarray The lower-left corner of the structured mesh. If only two coordinate are given, it is assumed that the mesh is an x-y mesh. upper_right : numpy.ndarray The upper-right corner of the structrued mesh. If only two coordinate are given, it is assumed that the mesh is an x-y mesh. width : numpy.ndarray The width of mesh cells in each direction. """ __instances = WeakValueDictionary() def __new__(cls, uid=None, new=True, index=None): mapping = meshes if index is None: if new: # Determine ID to assign if uid is None: uid = max(mapping, default=0) + 1 else: if uid in mapping: raise AllocationError('A mesh with ID={} has already ' 'been allocated.'.format(uid)) index = c_int32() _dll.openmc_extend_meshes(1, index, None) index = index.value else: index = mapping[uid]._index if index not in cls.__instances: instance = super().__new__(cls) instance._index = index if uid is not None: instance.id = uid cls.__instances[index] = instance return cls.__instances[index] @property def id(self): mesh_id = c_int32() _dll.openmc_mesh_get_id(self._index, mesh_id) return mesh_id.value @id.setter def id(self, mesh_id): _dll.openmc_mesh_set_id(self._index, mesh_id) @property def dimension(self): dims = POINTER(c_int)() n = c_int() _dll.openmc_mesh_get_dimension(self._index, dims, n) return tuple(as_array(dims, (n.value,))) @dimension.setter def dimension(self, dimension): n = len(dimension) dimension = (c_int*n)(*dimension) _dll.openmc_mesh_set_dimension(self._index, n, dimension) @property def lower_left(self): return self._get_parameters()[0] @property def upper_right(self): return self._get_parameters()[1] @property def width(self): return self._get_parameters()[2] def _get_parameters(self): ll = POINTER(c_double)() ur = POINTER(c_double)() w = POINTER(c_double)() n = c_int() _dll.openmc_mesh_get_params(self._index, ll, ur, w, n) return ( as_array(ll, (n.value,)), as_array(ur, (n.value,)), as_array(w, (n.value,)) ) def set_parameters(self, lower_left=None, upper_right=None, width=None): if lower_left is not None: n = len(lower_left) lower_left = (c_double*n)(*lower_left) if upper_right is not None: n = len(upper_right) upper_right = (c_double*n)(*upper_right) if width is not None: n = len(width) width = (c_double*n)(*width) _dll.openmc_mesh_set_params(self._index, n, lower_left, upper_right, width)
class _MeshMapping(Mapping): def __getitem__(self, key): index = c_int32() try: _dll.openmc_get_mesh_index(key, index) except (AllocationError, InvalidIDError) as e: # __contains__ expects a KeyError to work correctly raise KeyError(str(e)) return RegularMesh(index=index.value) def __iter__(self): for i in range(len(self)): yield RegularMesh(index=i).id def __len__(self): return _dll.n_meshes() def __repr__(self): return repr(dict(self)) meshes = _MeshMapping()