Separate material filter into its own module

This commit is contained in:
Paul Romano 2017-08-16 10:39:14 -05:00
parent 35a69a4434
commit 2a14926661
6 changed files with 190 additions and 78 deletions

View file

@ -379,6 +379,7 @@ set(LIBOPENMC_FORTRAN_SRC
src/tallies/tally_filter.F90
src/tallies/tally_filter_header.F90
src/tallies/tally_filter_energy.F90
src/tallies/tally_filter_material.F90
src/tallies/tally_filter_mesh.F90
src/tallies/tally_header.F90
src/tallies/trigger.F90

View file

@ -8,6 +8,7 @@ from numpy.ctypeslib import as_array
from . import _dll
from .error import _error_handler
from .material import MaterialView
__all__ = ['FilterView', 'AzimuthalFilterView', 'CellFilterView',
@ -43,6 +44,13 @@ _dll.openmc_filter_set_type.errcheck = _error_handler
_dll.openmc_get_filter.argtypes = [c_int32, POINTER(c_int32)]
_dll.openmc_get_filter.restype = c_int
_dll.openmc_get_filter.errcheck = _error_handler
_dll.openmc_material_filter_get_bins.argtypes = [
c_int32, POINTER(POINTER(c_int32)), POINTER(c_int32)]
_dll.openmc_material_filter_get_bins.restype = c_int
_dll.openmc_material_filter_get_bins.errcheck = _error_handler
_dll.openmc_material_filter_set_bins.argtypes = [c_int32, c_int32, POINTER(c_int32)]
_dll.openmc_material_filter_set_bins.restype = c_int
_dll.openmc_material_filter_set_bins.errcheck = _error_handler
_dll.openmc_mesh_filter_set_mesh.argtypes = [c_int32, c_int32]
_dll.openmc_mesh_filter_set_mesh.restype = c_int
_dll.openmc_mesh_filter_set_mesh.errcheck = _error_handler
@ -122,7 +130,20 @@ class EnergyFunctionFilterView(FilterView):
class MaterialFilterView(FilterView):
pass
@property
def bins(self):
materials = POINTER(c_int32)()
n = c_int32()
_dll.openmc_material_filter_get_bins(self._index, materials, n)
return [MaterialView(materials[i]) for i in range(n.value)]
@bins.setter
def bins(self, materials):
# Get material indices as int32_t[]
n = len(materials)
bins = (c_int32*n)(*(m._index for m in materials))
_dll.openmc_material_filter_set_bins(self._index, n, bins)
class MeshFilterView(FilterView):

View file

@ -53,6 +53,8 @@ module openmc_api
public :: openmc_material_get_densities
public :: openmc_material_set_density
public :: openmc_material_set_densities
public :: openmc_material_filter_get_bins
public :: openmc_material_filter_set_bins
public :: openmc_mesh_filter_set_mesh
public :: openmc_nuclide_name
public :: openmc_plot_geometry

View file

@ -15,6 +15,7 @@ module tally_filter
! Inherit other filters
use tally_filter_energy
use tally_filter_material
use tally_filter_mesh
implicit none
@ -32,19 +33,6 @@ module tally_filter
procedure :: initialize => initialize_universe
end type UniverseFilter
!===============================================================================
! MATERIAL specifies which material tally events reside in.
!===============================================================================
type, extends(TallyFilter) :: MaterialFilter
integer, allocatable :: materials(:)
type(DictIntInt) :: map
contains
procedure :: get_all_bins => get_all_bins_material
procedure :: to_statepoint => to_statepoint_material
procedure :: text_label => text_label_material
procedure :: initialize => initialize_material
end type MaterialFilter
!===============================================================================
! CELLFILTER specifies which geometric cells tally events reside in.
!===============================================================================
@ -249,69 +237,6 @@ contains
label = "Universe " // to_str(universes(this % universes(bin)) % id)
end function text_label_universe
!===============================================================================
! MaterialFilter methods
!===============================================================================
subroutine get_all_bins_material(this, p, estimator, match)
class(MaterialFilter), intent(in) :: this
type(Particle), intent(in) :: p
integer, intent(in) :: estimator
type(TallyFilterMatch), intent(inout) :: match
if (this % map % has_key(p % material)) then
call match % bins % push_back(this % map % get_key(p % material))
call match % weights % push_back(ONE)
end if
end subroutine get_all_bins_material
subroutine to_statepoint_material(this, filter_group)
class(MaterialFilter), intent(in) :: this
integer(HID_T), intent(in) :: filter_group
integer :: i
integer, allocatable :: material_ids(:)
call write_dataset(filter_group, "type", "material")
call write_dataset(filter_group, "n_bins", this % n_bins)
allocate(material_ids(size(this % materials)))
do i = 1, size(this % materials)
material_ids(i) = materials(this % materials(i)) % id
end do
call write_dataset(filter_group, "bins", material_ids)
end subroutine to_statepoint_material
subroutine initialize_material(this)
class(MaterialFilter), intent(inout) :: this
integer :: i, id
! Convert ids to indices.
do i = 1, this % n_bins
id = this % materials(i)
if (material_dict % has_key(id)) then
this % materials(i) = material_dict % get_key(id)
else
call fatal_error("Could not find material " // trim(to_str(id)) &
&// " specified on a tally filter.")
end if
end do
! Generate mapping from material indices to filter bins.
do i = 1, this % n_bins
call this % map % add_key(this % materials(i), i)
end do
end subroutine initialize_material
function text_label_material(this, bin) result(label)
class(MaterialFilter), intent(in) :: this
integer, intent(in) :: bin
character(MAX_LINE_LEN) :: label
label = "Material " // to_str(materials(this % materials(bin)) % id)
end function text_label_material
!===============================================================================
! CellFilter methods
!===============================================================================

View file

@ -208,7 +208,7 @@ contains
if (allocated(f % bins)) deallocate(f % bins)
allocate(f % bins(n))
f % bins(:) = energies
class default
class default
err = E_WRONG_TYPE
end select
else

View file

@ -0,0 +1,163 @@
module tally_filter_material
use, intrinsic :: ISO_C_BINDING
use hdf5, only: HID_T
use constants
use dict_header, only: DictIntInt
use error
use hdf5_interface
use material_header, only: materials, material_dict
use particle_header, only: Particle
use string, only: to_str
use tally_filter_header
implicit none
private
public :: openmc_material_filter_get_bins
public :: openmc_material_filter_set_bins
!===============================================================================
! MATERIAL specifies which material tally events reside in.
!===============================================================================
type, public, extends(TallyFilter) :: MaterialFilter
integer, allocatable :: materials(:)
type(DictIntInt) :: map
contains
procedure :: get_all_bins => get_all_bins_material
procedure :: to_statepoint => to_statepoint_material
procedure :: text_label => text_label_material
procedure :: initialize => initialize_material
end type MaterialFilter
contains
subroutine get_all_bins_material(this, p, estimator, match)
class(MaterialFilter), intent(in) :: this
type(Particle), intent(in) :: p
integer, intent(in) :: estimator
type(TallyFilterMatch), intent(inout) :: match
if (this % map % has_key(p % material)) then
call match % bins % push_back(this % map % get_key(p % material))
call match % weights % push_back(ONE)
end if
end subroutine get_all_bins_material
subroutine to_statepoint_material(this, filter_group)
class(MaterialFilter), intent(in) :: this
integer(HID_T), intent(in) :: filter_group
integer :: i
integer, allocatable :: material_ids(:)
call write_dataset(filter_group, "type", "material")
call write_dataset(filter_group, "n_bins", this % n_bins)
allocate(material_ids(size(this % materials)))
do i = 1, size(this % materials)
material_ids(i) = materials(this % materials(i)) % id
end do
call write_dataset(filter_group, "bins", material_ids)
end subroutine to_statepoint_material
subroutine initialize_material(this)
class(MaterialFilter), intent(inout) :: this
integer :: i, id
! Convert ids to indices.
do i = 1, this % n_bins
id = this % materials(i)
if (material_dict % has_key(id)) then
this % materials(i) = material_dict % get_key(id)
else
call fatal_error("Could not find material " // trim(to_str(id)) &
&// " specified on a tally filter.")
end if
end do
! Generate mapping from material indices to filter bins.
do i = 1, this % n_bins
call this % map % add_key(this % materials(i), i)
end do
end subroutine initialize_material
function text_label_material(this, bin) result(label)
class(MaterialFilter), intent(in) :: this
integer, intent(in) :: bin
character(MAX_LINE_LEN) :: label
label = "Material " // to_str(materials(this % materials(bin)) % id)
end function text_label_material
!===============================================================================
! C API FUNCTIONS
!===============================================================================
function openmc_material_filter_get_bins(index, bins, n) result(err) bind(C)
! Return the bins for a material filter
integer(C_INT32_T), value :: index
type(C_PTR), intent(out) :: bins
integer(C_INT32_T), intent(out) :: n
integer(C_INT) :: err
if (index >= 1 .and. index <= n_filters) then
if (allocated(filters(index) % obj)) then
select type (f => filters(index) % obj)
type is (MaterialFilter)
bins = C_LOC(f % materials)
n = size(f % materials)
err = 0
class default
err = E_WRONG_TYPE
end select
else
err = E_FILTER_NOT_ALLOCATED
end if
else
err = E_OUT_OF_BOUNDS
end if
end function openmc_material_filter_get_bins
function openmc_material_filter_set_bins(index, n, bins) result(err) bind(C)
! Set the materials for the filter
integer(C_INT32_T), value, intent(in) :: index
integer(C_INT32_T), value, intent(in) :: n
integer(C_INT32_T), intent(in) :: bins(n)
integer(C_INT) :: err
integer :: i
err = 0
if (index >= 1 .and. index <= n_filters) then
if (allocated(filters(index) % obj)) then
select type (f => filters(index) % obj)
type is (MaterialFilter)
f % n_bins = n
if (allocated(f % materials)) deallocate(f % materials)
allocate(f % materials(n))
f % materials(:) = bins
! Generate mapping from material indices to filter bins.
call f % map % clear()
do i = 1, n
call f % map % add_key(f % materials(i), i)
end do
class default
err = E_WRONG_TYPE
end select
else
err = E_FILTER_NOT_ALLOCATED
end if
else
err = E_OUT_OF_BOUNDS
end if
end function openmc_material_filter_set_bins
end module tally_filter_material