mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-26 21:25:36 -04:00
Move cell/tally functionality into View/Mapping classes
This commit is contained in:
parent
692765ef4a
commit
050cb6e016
4 changed files with 247 additions and 88 deletions
|
|
@ -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
68
openmc/capi/cell.py
Normal 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
71
openmc/capi/tally.py
Normal 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()
|
||||
140
src/api.F90
140
src/api.F90
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue