Move cell/tally functionality into View/Mapping classes

This commit is contained in:
Paul Romano 2017-07-29 09:04:41 -05:00
parent 692765ef4a
commit 050cb6e016
4 changed files with 247 additions and 88 deletions

View file

@ -38,8 +38,6 @@ except OSError:
_available = False
_int3 = c_int*3
_double3 = c_double*3
class GeometryError(Exception):
@ -97,22 +95,6 @@ def calculate_volumes():
_dll.openmc_calculate_volumes()
def cell_set_temperature(cell_id, T, instance=None):
"""Set the temperature of a cell
Parameters
----------
cell_id : int
ID of the cell
T : float
Temperature in K
instance : int or None
Which instance of the cell
"""
_dll.openmc_cell_set_temperature(cell_id, T, instance)
def finalize():
"""Finalize simulation and free memory"""
_dll.openmc_finalize()
@ -149,7 +131,7 @@ def find(xyz, rtype='cell'):
# Call openmc_find
uid = c_int32()
instance = c_int32()
_dll.openmc_find(_double3(*xyz), r_int, uid, instance)
_dll.openmc_find((c_double*3)(*xyz), r_int, uid, instance)
return (uid.value if uid != 0 else None), instance.value
@ -203,25 +185,6 @@ def run():
_dll.openmc_run()
def tally_results(tally_id):
"""Get tally results array
Parameters
----------
tally_id : int
ID of tally
Returns
-------
numpy.ndarray
Array that exposes the internal tally results array
"""
data = POINTER(c_double)()
shape = _int3()
_dll.openmc_tally_results(tally_id, data, shape)
return as_array(data, tuple(shape[::-1]))
@contextmanager
def run_in_memory(intracomm=None):
@ -254,7 +217,7 @@ if _available:
_dll.openmc_calculate_volumes.restype = None
_dll.openmc_finalize.restype = None
_dll.openmc_find.argtypes = [
POINTER(_double3), c_int, POINTER(c_int32), POINTER(c_int32)]
POINTER(c_double*3), c_int, POINTER(c_int32), POINTER(c_int32)]
_dll.openmc_find.restype = c_int
_dll.openmc_find.errcheck = _error_handler
_dll.openmc_init.argtypes = [POINTER(c_int)]
@ -262,22 +225,11 @@ if _available:
_dll.openmc_get_keff.argtypes = [POINTER(c_double*2)]
_dll.openmc_get_keff.restype = c_int
_dll.openmc_get_keff.errcheck = _error_handler
# Cell functions
_dll.openmc_cell_set_temperature.argtypes = [
c_int32, c_double, POINTER(c_int32)]
_dll.openmc_cell_set_temperature.restype = c_int
_dll.openmc_cell_set_temperature.errcheck = _error_handler
_dll.openmc_plot_geometry.restype = None
_dll.openmc_run.restype = None
_dll.openmc_reset.restype = None
# Tally functions
_dll.openmc_tally_results.argtypes = [
c_int32, _double_array, POINTER(_int3)]
_dll.openmc_tally_results.restype = c_int
_dll.openmc_tally_results.errcheck = _error_handler
from .nuclide import *
from .material import *
from .cell import *
from .tally import *

68
openmc/capi/cell.py Normal file
View file

@ -0,0 +1,68 @@
from collections import Mapping
from ctypes import c_int, c_int32, c_double, c_char_p, POINTER
from weakref import WeakValueDictionary
import numpy as np
from openmc.capi import _dll, _error_handler
__all__ = ['CellView', 'cells']
# Cell functions
_dll.openmc_cell_id.argtypes = [c_int32, POINTER(c_int32)]
_dll.openmc_cell_id.restype = c_int
_dll.openmc_cell_id.errcheck = _error_handler
_dll.openmc_cell_set_temperature.argtypes = [
c_int32, c_double, POINTER(c_int32)]
_dll.openmc_cell_set_temperature.restype = c_int
_dll.openmc_cell_set_temperature.errcheck = _error_handler
_dll.openmc_get_cell.argtypes = [c_int32, POINTER(c_int32)]
_dll.openmc_get_cell.restype = c_int
_dll.openmc_get_cell.errcheck = _error_handler
class CellView(object):
__instances = WeakValueDictionary()
def __new__(cls, *args):
if args not in cls.__instances:
instance = super().__new__(cls)
cls.__instances[args] = instance
return cls.__instances[args]
def __init__(self, index):
self._index = index
@property
def id(self):
cell_id = c_int32()
_dll.openmc_cell_id(self._index, cell_id)
return cell_id.value
def set_temperature(self, T, instance=None):
"""Set the temperature of a cell
Parameters
----------
T : float
Temperature in K
instance : int or None
Which instance of the cell
"""
_dll.openmc_cell_set_temperature(self._index, T, instance)
class _CellMapping(Mapping):
def __getitem__(self, key):
index = c_int32()
_dll.openmc_get_cell(key, index)
return CellView(index.value)
def __iter__(self):
for i in range(len(self)):
yield CellView(i + 1).id
def __len__(self):
return c_int32.in_dll(_dll, 'n_cells').value
cells = _CellMapping()

71
openmc/capi/tally.py Normal file
View file

@ -0,0 +1,71 @@
from collections import Mapping
from ctypes import c_int, c_int32, c_double, c_char_p, POINTER
from weakref import WeakValueDictionary
from numpy.ctypeslib import as_array
from openmc.capi import _dll, _error_handler, NuclideView
__all__ = ['TallyView', 'tallies']
# Tally functions
_dll.openmc_get_tally.argtypes = [c_int32, POINTER(c_int32)]
_dll.openmc_get_tally.restype = c_int
_dll.openmc_get_tally.errcheck = _error_handler
_dll.openmc_tally_id.argtypes = [c_int32, POINTER(c_int32)]
_dll.openmc_tally_id.restype = c_int
_dll.openmc_tally_id.errcheck = _error_handler
_dll.openmc_tally_results.argtypes = [
c_int32, POINTER(POINTER(c_double)), POINTER(c_int*3)]
_dll.openmc_tally_results.restype = c_int
_dll.openmc_tally_results.errcheck = _error_handler
class TallyView(object):
__instances = WeakValueDictionary()
def __new__(cls, *args):
if args not in cls.__instances:
instance = super().__new__(cls)
cls.__instances[args] = instance
return cls.__instances[args]
def __init__(self, index):
self._index = index
@property
def id(self):
tally_id = c_int32()
_dll.openmc_tally_id(self._index, tally_id)
return tally_id.value
@property
def results(self):
"""Get tally results array
Returns
-------
numpy.ndarray
Array that exposes the internal tally results array
"""
data = POINTER(c_double)()
shape = (c_int*3)()
_dll.openmc_tally_results(self._index, data, shape)
return as_array(data, tuple(shape[::-1]))
class _TallyMapping(Mapping):
def __getitem__(self, key):
index = c_int32()
_dll.openmc_get_tally(key, index)
return TallyView(index.value)
def __iter__(self):
for i in range(len(self)):
yield TallyView(i + 1).id
def __len__(self):
return c_int32.in_dll(_dll, 'n_tallies').value
tallies = _TallyMapping()

View file

@ -23,12 +23,15 @@ module openmc_api
private
public :: openmc_calculate_volumes
public :: openmc_cell_id
public :: openmc_cell_set_temperature
public :: openmc_finalize
public :: openmc_find
public :: openmc_get_cell
public :: openmc_get_keff
public :: openmc_get_material
public :: openmc_get_nuclide
public :: openmc_get_tally
public :: openmc_init
public :: openmc_load_nuclide
public :: openmc_material_id
@ -40,6 +43,7 @@ module openmc_api
public :: openmc_plot_geometry
public :: openmc_reset
public :: openmc_run
public :: openmc_tally_id
public :: openmc_tally_results
! Error codes
@ -58,12 +62,29 @@ module openmc_api
contains
!===============================================================================
! OPENMC_CELL_ID returns the ID of a cell
!===============================================================================
function openmc_cell_id(index, id) result(err) bind(C)
integer(C_INT32_T), value :: index
integer(C_INT32_T), intent(out) :: id
integer(C_INT) :: err
if (index >= 1 .and. index <= size(cells)) then
id = cells(index) % id
err = 0
else
err = E_OUT_OF_BOUNDS
end if
end function openmc_cell_id
!===============================================================================
! OPENMC_CELL_SET_TEMPERATURE sets the temperature of a cell
!===============================================================================
function openmc_cell_set_temperature(id, T, instance) result(err) bind(C)
integer(C_INT32_T), value, intent(in) :: id ! id of cell
function openmc_cell_set_temperature(index, T, instance) result(err) bind(C)
integer(C_INT32_T), value, intent(in) :: index
real(C_DOUBLE), value, intent(in) :: T
integer(C_INT32_T), optional, intent(in) :: instance
integer(C_INT) :: err
@ -71,28 +92,23 @@ contains
integer :: i, n
err = E_UNASSIGNED
if (allocated(cells)) then
if (cell_dict % has_key(id)) then
i = cell_dict % get_key(id)
associate (c => cells(i))
if (allocated(c % sqrtkT)) then
n = size(c % sqrtkT)
if (present(instance) .and. n > 1) then
if (instance >= 0 .and. instance < n) then
c % sqrtkT(instance + 1) = sqrt(K_BOLTZMANN * T)
err = 0
end if
else
c % sqrtkT(:) = sqrt(K_BOLTZMANN * T)
if (index >= 1 .and. index <= size(cells)) then
associate (c => cells(i))
if (allocated(c % sqrtkT)) then
n = size(c % sqrtkT)
if (present(instance) .and. n > 1) then
if (instance >= 0 .and. instance < n) then
c % sqrtkT(instance + 1) = sqrt(K_BOLTZMANN * T)
err = 0
end if
else
c % sqrtkT(:) = sqrt(K_BOLTZMANN * T)
err = 0
end if
end associate
else
err = E_CELL_INVALID_ID
end if
end if
end associate
else
err = E_CELL_NOT_ALLOCATED
err = E_OUT_OF_BOUNDS
end if
end function openmc_cell_set_temperature
@ -226,6 +242,27 @@ contains
end function openmc_find
!===============================================================================
! OPENMC_GET_CELL returns the index in the cells array of a cell with a given ID
!===============================================================================
function openmc_get_cell(id, index) result(err) bind(C)
integer(C_INT32_T), value :: id
integer(C_INT32_T), intent(out) :: index
integer(C_INT) :: err
if (allocated(cells)) then
if (cell_dict % has_key(id)) then
index = cell_dict % get_key(id)
err = 0
else
err = E_CELL_INVALID_ID
end if
else
err = E_CELL_NOT_ALLOCATED
end if
end function openmc_get_cell
!===============================================================================
! OPENMC_GET_MATERIAL returns the index in the materials array of a material
! with a given ID
@ -275,6 +312,28 @@ contains
end if
end function openmc_get_nuclide
!===============================================================================
! OPENMC_GET_TALLY returns the index in the tallies array of a tally
! with a given ID
!===============================================================================
function openmc_get_tally(id, index) result(err) bind(C)
integer(C_INT32_T), value :: id
integer(C_INT32_T), intent(out) :: index
integer(C_INT) :: err
if (allocated(tallies)) then
if (tally_dict % has_key(id)) then
index = tally_dict % get_key(id)
err = 0
else
err = E_TALLY_INVALID_ID
end if
else
err = E_TALLY_NOT_ALLOCATED
end if
end function openmc_get_tally
!===============================================================================
! OPENMC_LOAD_LOAD loads a nuclide from the cross section library
!===============================================================================
@ -581,35 +640,44 @@ contains
end subroutine openmc_reset
!===============================================================================
! OPENMC_TALLY_ID returns the ID of a tally
!===============================================================================
function openmc_tally_id(index, id) result(err) bind(C)
integer(C_INT32_T), value :: index
integer(C_INT32_T), intent(out) :: id
integer(C_INT) :: err
if (index >= 1 .and. index <= size(tallies)) then
id = tallies(index) % id
err = 0
else
err = E_OUT_OF_BOUNDS
end if
end function openmc_tally_id
!===============================================================================
! OPENMC_TALLY_RESULTS returns a pointer to a tally results array along with its
! shape. This allows a user to obtain in-memory tally results from Python
! directly.
!===============================================================================
function openmc_tally_results(id, ptr, shape_) result(err) bind(C)
integer(C_INT32_T), intent(in), value :: id
function openmc_tally_results(index, ptr, shape_) result(err) bind(C)
integer(C_INT32_T), intent(in), value :: index
type(C_PTR), intent(out) :: ptr
integer(C_INT), intent(out) :: shape_(3)
integer(C_INT) :: err
integer :: i
ptr = C_NULL_PTR
err = E_UNASSIGNED
if (allocated(tallies)) then
if (tally_dict % has_key(id)) then
i = tally_dict % get_key(id)
if (allocated(tallies(i) % results)) then
ptr = C_LOC(tallies(i) % results(1,1,1))
shape_(:) = shape(tallies(i) % results)
err = 0
end if
else
err = E_TALLY_INVALID_ID
if (index >= 1 .and. index <= size(tallies)) then
if (allocated(tallies(index) % results)) then
ptr = C_LOC(tallies(index) % results(1,1,1))
shape_(:) = shape(tallies(index) % results)
err = 0
end if
else
err = E_TALLY_NOT_ALLOCATED
err = E_OUT_OF_BOUNDS
end if
end function openmc_tally_results