Move CppTallyFilter functionality to TallyFilter

This commit is contained in:
Sterling Harper 2018-10-28 20:51:36 -04:00
parent a65ea4cce8
commit 89bf3a6afb
12 changed files with 190 additions and 293 deletions

View file

@ -373,7 +373,6 @@ add_library(libopenmc SHARED
src/tallies/tally_derivative_header.F90
src/tallies/tally_filter.F90
src/tallies/tally_filter_header.F90
src/tallies/tally_filter_cpp.F90
src/tallies/tally_filter_delayedgroup.F90
src/tallies/tally_filter_distribcell.F90
src/tallies/tally_filter_energy.F90

View file

@ -170,14 +170,11 @@ contains
call set_errmsg("Unknown filter type: " // trim(type_))
end select
select type(filt => filters(index) % obj)
class is (CppTallyFilter)
filt % ptr = allocate_filter(type)
if (.not. c_associated(filt % ptr)) then
err = E_UNASSIGNED
call set_errmsg("Could not allocate C++ tally filter")
end if
end select
filters(index) % obj % ptr = allocate_filter(type)
if (.not. c_associated(filters(index) % obj % ptr)) then
err = E_UNASSIGNED
call set_errmsg("Could not allocate C++ tally filter")
end if
end if
else

View file

@ -1,211 +0,0 @@
module tally_filter_cpp
use, intrinsic :: ISO_C_BINDING
use constants, only: MAX_LINE_LEN
use hdf5_interface, only: HID_T
use particle_header, only: Particle
use tally_filter_header
use xml_interface, only: XMLNode
implicit none
!===============================================================================
! CPPTALLYFILTER is a TallyFilter that is at least partially implemented in C++.
!
! Moving a tally to C++ is easier if done piece-by-piece, so this filter has
! *_cpp_inner procedures that allows the Fortran code to override e.g.
! get_all_bins and still call the C++ implementation for side-by-side comparison
!===============================================================================
type, abstract, extends(TallyFilter) :: CppTallyFilter
type(C_PTR) :: ptr
contains
procedure :: n_bins_cpp
procedure :: from_xml_cpp_inner
procedure :: initialize_cpp_inner
procedure :: from_xml => from_xml_cpp_default
procedure :: get_all_bins => get_all_bins_cpp
procedure :: to_statepoint => to_statepoint_cpp
procedure :: text_label => text_label_cpp
procedure :: initialize => initialize_cpp_default
end type CppTallyFilter
!===============================================================================
! Pure C++ filters
!===============================================================================
type, extends(CppTallyFilter) :: AzimuthalFilter
end type
type, extends(CppTallyFilter) :: CellFilter
end type
type, extends(CppTallyFilter) :: CellbornFilter
end type
type, extends(CellFilter) :: CellFromFilter
end type
type, extends(CppTallyFilter) :: EnergyFunctionFilter
end type
type, extends(CppTallyFilter) :: MaterialFilter
end type
type, extends(CppTallyFilter) :: MuFilter
end type
type, extends(CppTallyFilter) :: PolarFilter
end type
type, extends(CppTallyFilter) :: SpatialLegendreFilter
end type
type, extends(CppTallyFilter) :: SurfaceFilter
! True if this filter is used for surface currents
logical :: current = .false.
end type
type, extends(CppTallyFilter) :: UniverseFilter
end type
type, extends(CppTallyFilter) :: ZernikeFilter
end type
type, extends(ZernikeFilter) :: ZernikeRadialFilter
end type
contains
!===============================================================================
! CppTallyFilter implementation
!===============================================================================
function n_bins_cpp(this) result(n_bins)
class(CppTallyFilter), intent(inout) :: this
integer :: n_bins
interface
function filter_n_bins(filt) result(n_bins) bind(C)
import C_PTR, C_INT
type(C_PTR), value :: filt
integer(C_INT) :: n_bins
end function filter_n_bins
end interface
n_bins = filter_n_bins(this % ptr)
end function n_bins_cpp
subroutine from_xml_cpp_inner(this, node)
class(CppTallyFilter), intent(inout) :: this
class(XMLNode), intent(in) :: node
interface
subroutine filter_from_xml(filt, node) bind(C)
import C_PTR
type(C_PTR), value :: filt
type(C_PTR) :: node
end subroutine filter_from_xml
end interface
call filter_from_xml(this % ptr, node % ptr)
end subroutine from_xml_cpp_inner
subroutine initialize_cpp_inner(this)
class(CppTallyFilter), intent(inout) :: this
interface
subroutine filter_initialize(filt) bind(C)
import C_PTR
type(C_PTR), value :: filt
end subroutine filter_initialize
end interface
call filter_initialize(this % ptr)
end subroutine initialize_cpp_inner
subroutine from_xml_cpp_default(this, node)
class(CppTallyFilter), intent(inout) :: this
type(XMLNode), intent(in) :: node
call this % from_xml_cpp_inner(node)
this % n_bins = this % n_bins_cpp()
end subroutine from_xml_cpp_default
subroutine get_all_bins_cpp(this, p, estimator, match)
class(CppTallyFilter), intent(in) :: this
type(Particle), intent(in) :: p
integer, intent(in) :: estimator
type(TallyFilterMatch), intent(inout) :: match
interface
subroutine filter_get_all_bins(filt, p, estimator, match) bind(C)
import C_PTR, Particle, C_INT
type(C_PTR), value :: filt
type(Particle), intent(in) :: p
integer(C_INT), intent(in), value :: estimator
type(C_PTR), value :: match
end subroutine filter_get_all_bins
end interface
call filter_get_all_bins(this % ptr, p, estimator, match % ptr)
end subroutine get_all_bins_cpp
subroutine to_statepoint_cpp(this, filter_group)
class(CppTallyFilter), intent(in) :: this
integer(HID_T), intent(in) :: filter_group
interface
subroutine filter_to_statepoint(filt, filter_group) bind(C)
import C_PTR, HID_T
type(C_PTR), value :: filt
integer(HID_T), intent(in), value :: filter_group
end subroutine filter_to_statepoint
end interface
call filter_to_statepoint(this % ptr, filter_group)
end subroutine to_statepoint_cpp
function text_label_cpp(this, bin) result(label)
class(CppTallyFilter), intent(in) :: this
integer, intent(in) :: bin
character(MAX_LINE_LEN) :: label
character(kind=C_CHAR) :: label_(MAX_LINE_LEN+1)
integer :: i
interface
subroutine filter_text_label(filt, bin, label) bind(C)
import C_PTR, C_INT, C_CHAR
type(C_PTR), value :: filt
integer(C_INT), value :: bin
character(kind=C_CHAR) :: label(*)
end subroutine filter_text_label
end interface
call filter_text_label(this % ptr, bin, label_)
label = " "
do i = 1, MAX_LINE_LEN
if (label_(i) == C_NULL_CHAR) exit
label(i:i) = label_(i)
end do
end function text_label_cpp
subroutine initialize_cpp_default(this)
class(CppTallyFilter), intent(inout) :: this
call this % initialize_cpp_inner()
end subroutine initialize_cpp_default
!===============================================================================
! FILTER_FROM_F given a Fortran index, return a pointer to a C++ filter.
!===============================================================================
function filter_from_f(index) result(filt) bind(C)
integer(C_INT32_T), intent(in), value :: index
type(C_PTR) :: filt
filt = C_NULL_PTR
select type(f => filters(index) % obj)
class is (CppTallyFilter)
filt = f % ptr
end select
end function
!===============================================================================
! FILTER_UPDATE_N_BINS given a Fortran index, updates filt % n_bins using C++.
!===============================================================================
subroutine filter_update_n_bins(index) bind(C)
integer(C_INT32_T), intent(in), value :: index
select type(f => filters(index) % obj)
class is (CppTallyFilter)
f % n_bins = f % n_bins_cpp()
end select
end subroutine
end module tally_filter_cpp

View file

@ -2,7 +2,7 @@ module tally_filter_delayedgroup
use, intrinsic :: ISO_C_BINDING
use tally_filter_cpp
use tally_filter_header
implicit none
private
@ -13,7 +13,7 @@ module tally_filter_delayedgroup
! iterated over in the scoring subroutines.
!===============================================================================
type, public, extends(CppTallyFilter) :: DelayedGroupFilter
type, public, extends(TallyFilter) :: DelayedGroupFilter
contains
procedure :: groups
end type DelayedGroupFilter

View file

@ -1,11 +1,11 @@
module tally_filter_distribcell
use tally_filter_cpp
use tally_filter_header
implicit none
private
type, public, extends(CppTallyFilter) :: DistribcellFilter
type, public, extends(TallyFilter) :: DistribcellFilter
contains
procedure :: initialize => initialize_distribcell
end type DistribcellFilter
@ -14,7 +14,7 @@ contains
subroutine initialize_distribcell(this)
class(DistribcellFilter), intent(inout) :: this
call this % initialize_cpp_inner()
call this % initialize_cpp()
this % n_bins = this % n_bins_cpp()
end subroutine initialize_distribcell

View file

@ -2,7 +2,7 @@ module tally_filter_energy
use, intrinsic :: ISO_C_BINDING
use tally_filter_cpp
use tally_filter_header
use xml_interface
implicit none
@ -31,7 +31,7 @@ module tally_filter_energy
! ENERGYFILTER bins the incident neutron energy.
!===============================================================================
type, public, extends(CppTallyFilter) :: EnergyFilter
type, public, extends(TallyFilter) :: EnergyFilter
! True if transport group number can be used directly to get bin number
logical :: matches_transport_groups = .false.
contains
@ -67,7 +67,7 @@ contains
end function
end interface
call this % from_xml_cpp_inner(node)
call this % from_xml_cpp(node)
this % n_bins = this % n_bins_cpp()
this % matches_transport_groups = &
energy_filter_matches_transport_groups(this % ptr)

View file

@ -62,66 +62,62 @@ module tally_filter_header
type, public, abstract :: TallyFilter
integer :: id
integer :: n_bins = 0
type(C_PTR) :: ptr
contains
procedure(from_xml_), deferred :: from_xml
procedure(get_all_bins_), deferred :: get_all_bins
procedure(to_statepoint_), deferred :: to_statepoint
procedure(text_label_), deferred :: text_label
procedure :: initialize => filter_initialize
procedure :: from_xml
procedure :: get_all_bins
procedure :: to_statepoint
procedure :: text_label
procedure :: initialize
procedure :: n_bins_cpp
procedure :: from_xml_cpp
procedure :: initialize_cpp
end type TallyFilter
abstract interface
subroutine from_xml_(this, node)
import TallyFilter, XMLNode
class(TallyFilter), intent(inout) :: this
type(XMLNode), intent(in) :: node
end subroutine from_xml_
!===============================================================================
! GET_NEXT_BIN gives the index for the next valid filter bin and a weight that
! will be applied to the flux.
!
! In principle, a filter can have multiple valid bins. If current_bin =
! NO_BIN_FOUND, then this method should give the first valid bin. Providing the
! first valid bin should then give the second valid bin, and so on. When there
! are no valid bins left, the next_bin should be NO_VALID_BIN.
subroutine get_all_bins_(this, p, estimator, match)
import TallyFilter
import Particle
import TallyFilterMatch
class(TallyFilter), intent(in) :: this
type(Particle), intent(in) :: p
integer, intent(in) :: estimator
type(TallyFilterMatch), intent(inout) :: match
end subroutine get_all_bins_
! Pure C++ filters
!===============================================================================
! TO_STATEPOINT writes all the information needed to reconstruct the filter to
! the given filter_group.
subroutine to_statepoint_(this, filter_group)
import TallyFilter
import HID_T
class(TallyFilter), intent(in) :: this
integer(HID_T), intent(in) :: filter_group
end subroutine to_statepoint_
type, public, extends(TallyFilter) :: AzimuthalFilter
end type
!===============================================================================
! TEXT_LABEL returns a string describing the given filter bin. For example, an
! energy filter might return the string "Incoming Energy [0.625E-6, 20.0)".
! This is used to write the tallies.out file.
type, public, extends(TallyFilter) :: CellFilter
end type
function text_label_(this, bin) result(label)
import TallyFilter
import MAX_LINE_LEN
class(TallyFilter), intent(in) :: this
integer, intent(in) :: bin
character(MAX_LINE_LEN) :: label
end function text_label_
type, public, extends(TallyFilter) :: CellbornFilter
end type
end interface
type, public, extends(CellFilter) :: CellFromFilter
end type
type, public, extends(TallyFilter) :: EnergyFunctionFilter
end type
type, public, extends(TallyFilter) :: MaterialFilter
end type
type, public, extends(TallyFilter) :: MuFilter
end type
type, public, extends(TallyFilter) :: PolarFilter
end type
type, public, extends(TallyFilter) :: SpatialLegendreFilter
end type
type, public, extends(TallyFilter) :: SurfaceFilter
! True if this filter is used for surface currents
logical :: current = .false.
end type
type, public, extends(TallyFilter) :: UniverseFilter
end type
type, public, extends(TallyFilter) :: ZernikeFilter
end type
type, public, extends(ZernikeFilter) :: ZernikeRadialFilter
end type
!===============================================================================
! TALLYFILTERCONTAINER contains an allocatable TallyFilter object for arrays of
@ -258,12 +254,128 @@ contains
end subroutine bins_set_data
!===============================================================================
! INITIALIZE sets up any internal data, as necessary. If this procedure is not
! overriden by the derived class, then it will do nothing by default.
! TallyFilter implementation
!===============================================================================
subroutine filter_initialize(this)
subroutine from_xml(this, node)
class(TallyFilter), intent(inout) :: this
end subroutine filter_initialize
type(XMLNode), intent(in) :: node
call this % from_xml_cpp(node)
this % n_bins = this % n_bins_cpp()
end subroutine from_xml
subroutine get_all_bins(this, p, estimator, match)
class(TallyFilter), intent(in) :: this
type(Particle), intent(in) :: p
integer, intent(in) :: estimator
type(TallyFilterMatch), intent(inout) :: match
interface
subroutine filter_get_all_bins(filt, p, estimator, match) bind(C)
import C_PTR, Particle, C_INT
type(C_PTR), value :: filt
type(Particle), intent(in) :: p
integer(C_INT), intent(in), value :: estimator
type(C_PTR), value :: match
end subroutine filter_get_all_bins
end interface
call filter_get_all_bins(this % ptr, p, estimator, match % ptr)
end subroutine get_all_bins
subroutine to_statepoint(this, filter_group)
class(TallyFilter), intent(in) :: this
integer(HID_T), intent(in) :: filter_group
interface
subroutine filter_to_statepoint(filt, filter_group) bind(C)
import C_PTR, HID_T
type(C_PTR), value :: filt
integer(HID_T), intent(in), value :: filter_group
end subroutine filter_to_statepoint
end interface
call filter_to_statepoint(this % ptr, filter_group)
end subroutine to_statepoint
function text_label(this, bin) result(label)
class(TallyFilter), intent(in) :: this
integer, intent(in) :: bin
character(MAX_LINE_LEN) :: label
character(kind=C_CHAR) :: label_(MAX_LINE_LEN+1)
integer :: i
interface
subroutine filter_text_label(filt, bin, label) bind(C)
import C_PTR, C_INT, C_CHAR
type(C_PTR), value :: filt
integer(C_INT), value :: bin
character(kind=C_CHAR) :: label(*)
end subroutine filter_text_label
end interface
call filter_text_label(this % ptr, bin, label_)
label = " "
do i = 1, MAX_LINE_LEN
if (label_(i) == C_NULL_CHAR) exit
label(i:i) = label_(i)
end do
end function text_label
subroutine initialize(this)
class(TallyFilter), intent(inout) :: this
call this % initialize_cpp()
end subroutine initialize
function n_bins_cpp(this) result(n_bins)
class(TallyFilter), intent(in) :: this
integer :: n_bins
interface
function filter_n_bins(filt) result(n_bins) bind(C)
import C_PTR, C_INT
type(C_PTR), value :: filt
integer(C_INT) :: n_bins
end function filter_n_bins
end interface
n_bins = filter_n_bins(this % ptr)
end function n_bins_cpp
subroutine from_xml_cpp(this, node)
class(TallyFilter), intent(inout) :: this
class(XMLNode), intent(in) :: node
interface
subroutine filter_from_xml(filt, node) bind(C)
import C_PTR
type(C_PTR), value :: filt
type(C_PTR) :: node
end subroutine filter_from_xml
end interface
call filter_from_xml(this % ptr, node % ptr)
end subroutine from_xml_cpp
subroutine initialize_cpp(this)
class(TallyFilter), intent(inout) :: this
interface
subroutine filter_initialize(filt) bind(C)
import C_PTR
type(C_PTR), value :: filt
end subroutine filter_initialize
end interface
call filter_initialize(this % ptr)
end subroutine initialize_cpp
!===============================================================================
! FILTER_FROM_F given a Fortran index, return a pointer to a C++ filter.
!===============================================================================
function filter_from_f(index) result(filt) bind(C)
integer(C_INT32_T), intent(in), value :: index
type(C_PTR) :: filt
filt = filters(index) % obj % ptr
end function
!===============================================================================
! FILTER_UPDATE_N_BINS given a Fortran index, updates filt % n_bins using C++.
!===============================================================================
subroutine filter_update_n_bins(index) bind(C)
integer(C_INT32_T), intent(in), value :: index
filters(index) % obj % n_bins = filters(index) % obj % n_bins_cpp()
end subroutine
!===============================================================================
! FREE_MEMORY_TALLY_FILTER deallocates global arrays defined in this module

View file

@ -2,7 +2,7 @@ module tally_filter_legendre
use, intrinsic :: ISO_C_BINDING
use tally_filter_cpp
use tally_filter_header
implicit none
@ -15,7 +15,7 @@ module tally_filter_legendre
end function
end interface
type, extends(CppTallyFilter) :: LegendreFilter
type, extends(TallyFilter) :: LegendreFilter
end type LegendreFilter
end module tally_filter_legendre

View file

@ -2,7 +2,7 @@ module tally_filter_mesh
use, intrinsic :: ISO_C_BINDING
use tally_filter_cpp
use tally_filter_header
implicit none
@ -15,7 +15,7 @@ module tally_filter_mesh
end function
end interface
type, public, extends(CppTallyFilter) :: MeshFilter
type, public, extends(TallyFilter) :: MeshFilter
contains
procedure :: mesh => get_mesh
end type MeshFilter

View file

@ -2,7 +2,7 @@ module tally_filter_meshsurface
use, intrinsic :: ISO_C_BINDING
use tally_filter_cpp
use tally_filter_header
implicit none
@ -16,7 +16,7 @@ module tally_filter_meshsurface
end function
end interface
type, extends(CppTallyFilter) :: MeshSurfaceFilter
type, extends(TallyFilter) :: MeshSurfaceFilter
end type MeshSurfaceFilter
end module tally_filter_meshsurface

View file

@ -2,7 +2,7 @@ module tally_filter_particle
use, intrinsic :: ISO_C_BINDING
use tally_filter_cpp
use tally_filter_header
implicit none
private
@ -11,7 +11,7 @@ module tally_filter_particle
! PARTICLEFILTER specifies what particles can score to a tally
!===============================================================================
type, public, extends(CppTallyFilter) :: ParticleFilter
type, public, extends(TallyFilter) :: ParticleFilter
contains
procedure :: particles
end type ParticleFilter

View file

@ -2,7 +2,7 @@ module tally_filter_sph_harm
use, intrinsic :: ISO_C_BINDING
use tally_filter_cpp
use tally_filter_header
implicit none
private
@ -10,7 +10,7 @@ module tally_filter_sph_harm
integer, public, parameter :: COSINE_SCATTER = 1
integer, public, parameter :: COSINE_PARTICLE = 2
type, public, extends(CppTallyFilter) :: SphericalHarmonicsFilter
type, public, extends(TallyFilter) :: SphericalHarmonicsFilter
contains
procedure :: cosine
end type SphericalHarmonicsFilter