Ability to create tallies from Python bindings to C API

This commit is contained in:
Paul Romano 2017-08-22 15:44:30 -05:00
parent e5869597cd
commit 23159d0c3b
6 changed files with 73 additions and 15 deletions

View file

@ -145,6 +145,16 @@ class MaterialFilterView(FilterView):
_dll.openmc_material_filter_set_bins(self._index, n, bins)
@classmethod
def new(cls, bins=None):
index = c_int32()
_dll.openmc_extend_filters(1, index, None)
_dll.openmc_filter_set_type(index, b'material')
f = cls(index.value)
if bins is not None:
f.bins = bins
return f
class MeshFilterView(FilterView):
pass

View file

@ -36,12 +36,18 @@ _dll.openmc_tally_results.errcheck = _error_handler
_dll.openmc_tally_set_filters.argtypes = [c_int32, c_int, POINTER(c_int32)]
_dll.openmc_tally_set_filters.restype = c_int
_dll.openmc_tally_set_filters.errcheck = _error_handler
_dll.openmc_tally_set_id.argtypes = [c_int32, c_int32]
_dll.openmc_tally_set_id.restype = c_int
_dll.openmc_tally_set_id.errcheck = _error_handler
_dll.openmc_tally_set_nuclides.argtypes = [c_int32, c_int, POINTER(c_char_p)]
_dll.openmc_tally_set_nuclides.restype = c_int
_dll.openmc_tally_set_nuclides.errcheck = _error_handler
_dll.openmc_tally_set_scores.argtypes = [c_int32, c_int, POINTER(c_char_p)]
_dll.openmc_tally_set_scores.restype = c_int
_dll.openmc_tally_set_scores.errcheck = _error_handler
_dll.openmc_tally_set_type.argtypes = [c_int32, c_char_p]
_dll.openmc_tally_set_type.restype = c_int
_dll.openmc_tally_set_type.errcheck = _error_handler
class TallyView(object):
@ -85,6 +91,10 @@ class TallyView(object):
_dll.openmc_tally_get_id(self._index, tally_id)
return tally_id.value
@id.setter
def id(self, tally_id):
_dll.openmc_tally_set_id(self._index, tally_id)
@property
def filters(self):
filt_idx = POINTER(c_int32)()
@ -121,6 +131,23 @@ class TallyView(object):
nucs[:] = [x.encode() for x in nuclides]
_dll.openmc_tally_set_nuclides(self._index, len(nuclides), nucs)
@property
def scores(self):
pass
@scores.setter
def scores(self, scores):
scores_ = (c_char_p * len(scores))()
scores_[:] = [x.encode() for x in scores]
_dll.openmc_tally_set_scores(self._index, len(scores), scores_)
@classmethod
def new(cls):
index = c_int32()
_dll.openmc_extend_tallies(1, index, None)
_dll.openmc_tally_set_type(index, b'generic')
return cls(index.value)
class _TallyMapping(Mapping):
def __getitem__(self, key):

View file

@ -66,6 +66,7 @@ module openmc_api
public :: openmc_tally_get_nuclides
public :: openmc_tally_results
public :: openmc_tally_set_filters
public :: openmc_tally_set_id
public :: openmc_tally_set_nuclides
public :: openmc_tally_set_scores
public :: openmc_tally_set_type

View file

@ -3249,17 +3249,6 @@ contains
! Get pointer to tally xml node
node_tal = node_tal_list(i)
! Set tally type to volume by default
t % type = TALLY_VOLUME
! It's desirable to use a track-length esimator for tallies since
! generally more events will score to the tally, reducing the
! variance. However, for tallies that require information on
! post-collision parameters (e.g. tally with an energyout filter) the
! analog esimator must be used.
t % estimator = ESTIMATOR_TRACKLENGTH
! Copy tally id
if (check_for_node(node_tal, "id")) then
call get_node_value(node_tal, "id", t % id)
@ -3318,8 +3307,6 @@ contains
! Set the filters
err = openmc_tally_set_filters(i_start + i - 1, n_filter, temp_filter)
else
allocate(t % filter(n_filter))
end if
deallocate(temp_filter)

View file

@ -4429,6 +4429,7 @@ contains
character(kind=C_CHAR), intent(in) :: type(*)
integer(C_INT) :: err
integer(C_INT32_T) :: empty(0)
character(:), allocatable :: type_
! Convert C string to Fortran string
@ -4445,6 +4446,9 @@ contains
case default
err = E_UNASSIGNED
end select
! When a tally is allocated, set it to have 0 filters
err = tallies(index) % obj % set_filters(empty)
end if
else
err = E_OUT_OF_BOUNDS

View file

@ -24,6 +24,7 @@ module tally_header
public :: openmc_tally_get_nuclides
public :: openmc_tally_results
public :: openmc_tally_set_filters
public :: openmc_tally_set_id
public :: openmc_tally_set_nuclides
public :: openmc_tally_set_scores
@ -51,8 +52,8 @@ module tally_header
integer :: id ! user-defined identifier
character(len=104) :: name = "" ! user-defined name
integer :: type ! volume, surface current
integer :: estimator ! collision, track-length
integer :: type = TALLY_VOLUME ! volume, surface current
integer :: estimator = ESTIMATOR_TRACKLENGTH ! collision, track-length
real(8) :: volume ! volume of region
logical :: active = .false.
integer, allocatable :: filter(:) ! index in filters array
@ -235,6 +236,13 @@ contains
subroutine tally_allocate_results(this)
class(TallyObject), intent(inout) :: this
! If no nuclides were specified, add a single bin for total material
if (.not. allocated(this % nuclide_bins)) then
allocate(this % nuclide_bins(1))
this % nuclide_bins(1) = -1
this % n_nuclide_bins = 1
end if
! Set total number of filter and scoring bins
this % total_score_bins = this % n_score_bins * this % n_nuclide_bins
@ -520,6 +528,27 @@ contains
end function openmc_tally_set_filters
function openmc_tally_set_id(index, id) result(err) bind(C)
! Set the ID of a tally
integer(C_INT32_T), value, intent(in) :: index
integer(C_INT32_T), value, intent(in) :: id
integer(C_INT) :: err
if (index >= 1 .and. index <= n_tallies) then
if (allocated(tallies(index) % obj)) then
tallies(index) % obj % id = id
call tally_dict % add_key(id, index)
err = 0
else
err = E_FILTER_NOT_ALLOCATED
end if
else
err = E_OUT_OF_BOUNDS
end if
end function openmc_tally_set_id
function openmc_tally_set_nuclides(index, n, nuclides) result(err) bind(C)
! Sets the nuclides in the tally which results should be scored for
integer(C_INT32_T), value :: index