Move tally derivatives into their own header file and add from_xml()

This commit is contained in:
Paul Romano 2017-09-01 14:59:15 -05:00
parent 311d291a8f
commit 4af186cd13
5 changed files with 96 additions and 86 deletions

View file

@ -378,6 +378,7 @@ set(LIBOPENMC_FORTRAN_SRC
src/volume_header.F90
src/xml_interface.F90
src/tallies/tally.F90
src/tallies/tally_derivative_header.F90
src/tallies/tally_filter.F90
src/tallies/tally_filter_header.F90
src/tallies/tally_filter_azimuthal.F90

View file

@ -16,6 +16,7 @@ module global
use surface_header
use tally_filter_header
use tally_header
use tally_derivative_header
use timer_header
use trigger_header
use volume_header

View file

@ -2493,7 +2493,6 @@ contains
type(XMLNode) :: node_tal
type(XMLNode) :: node_filt
type(XMLNode) :: node_trigger
type(XMLNode) :: node_deriv
type(XMLNode), allocatable :: node_mesh_list(:)
type(XMLNode), allocatable :: node_tal_list(:)
type(XMLNode), allocatable :: node_filt_list(:)
@ -2582,75 +2581,10 @@ contains
! Read derivative attributes.
do i = 1, size(node_deriv_list)
associate(deriv => tally_derivs(i))
! Get pointer to derivative node.
node_deriv = node_deriv_list(i)
call tally_derivs(i) % from_xml(node_deriv_list(i))
! Copy the derivative id.
if (check_for_node(node_deriv, "id")) then
call get_node_value(node_deriv, "id", deriv % id)
else
call fatal_error("Must specify an ID for <derivative> elements in the&
& tally XML file")
end if
! Make sure the id is > 0.
if (deriv % id <= 0) then
call fatal_error("<derivative> IDs must be an integer greater than &
&zero")
end if
! Make sure this id has not already been used.
do j = 1, i-1
if (tally_derivs(j) % id == deriv % id) then
call fatal_error("Two or more <derivative>'s use the same unique &
&ID: " // trim(to_str(deriv % id)))
end if
end do
! Read the independent variable name.
temp_str = ""
call get_node_value(node_deriv, "variable", temp_str)
temp_str = to_lower(temp_str)
select case(temp_str)
case("density")
deriv % variable = DIFF_DENSITY
call get_node_value(node_deriv, "material", deriv % diff_material)
case("nuclide_density")
deriv % variable = DIFF_NUCLIDE_DENSITY
call get_node_value(node_deriv, "material", deriv % diff_material)
call get_node_value(node_deriv, "nuclide", word)
word = trim(to_lower(word))
pair_list => nuclide_dict % keys()
do while (associated(pair_list))
if (starts_with(pair_list % key, word)) then
word = pair_list % key(1:150)
exit
end if
! Advance to next
pair_list => pair_list % next
end do
! Check if no nuclide was found
if (.not. associated(pair_list)) then
call fatal_error("Could not find the nuclide " &
// trim(word) // " specified in derivative " &
// trim(to_str(deriv % id)) // " in any material.")
end if
deallocate(pair_list)
deriv % diff_nuclide = nuclide_dict % get_key(word)
case("temperature")
deriv % variable = DIFF_TEMPERATURE
call get_node_value(node_deriv, "material", deriv % diff_material)
end select
end associate
! Update tally derivative dictionary
call tally_deriv_dict % add_key(tally_derivs(i) % id, i)
end do
! ==========================================================================
@ -2693,13 +2627,11 @@ contains
if (.not. check_for_node(node_filt, "bins")) then
call fatal_error("Bins not set in filter " // trim(to_str(filter_id)))
end if
n_words = node_word_count(node_filt, "bins")
case ("mesh", "universe", "material", "cell", "distribcell", &
"cellborn", "cellfrom", "surface", "delayedgroup")
if (.not. check_for_node(node_filt, "bins")) then
call fatal_error("Bins not set in filter " // trim(to_str(filter_id)))
end if
n_words = node_word_count(node_filt, "bins")
end select
! Allocate according to the filter type

View file

@ -0,0 +1,91 @@
module tally_derivative_header
use constants
use dict_header, only: DictIntInt
use error, only: fatal_error
use nuclide_header, only: nuclide_dict
use string, only: to_str, to_lower
use xml_interface
implicit none
private
!===============================================================================
! TALLYDERIVATIVE describes a first-order derivative that can be applied to
! tallies.
!===============================================================================
type, public :: TallyDerivative
integer :: id
integer :: variable
integer :: diff_material
integer :: diff_nuclide
real(8) :: flux_deriv
contains
procedure :: from_xml
end type TallyDerivative
type(TallyDerivative), public, allocatable :: tally_derivs(:)
!$omp threadprivate(tally_derivs)
! Dictionary that maps user IDs to indices in 'tally_derivs'
type(DictIntInt), public :: tally_deriv_dict
contains
subroutine from_xml(this, node)
class(TallyDerivative), intent(inout) :: this
type(XMLNode), intent(in) :: node
character(MAX_WORD_LEN) :: temp_str
character(MAX_WORD_LEN) :: word
! Copy the derivative id.
if (check_for_node(node, "id")) then
call get_node_value(node, "id", this % id)
else
call fatal_error("Must specify an ID for <derivative> elements in the&
& tally XML file")
end if
! Make sure the id is > 0.
if (this % id <= 0) then
call fatal_error("<derivative> IDs must be an integer greater than &
&zero")
end if
! Make sure this id has not already been used.
if (tally_deriv_dict % has_key(this % id)) then
call fatal_error("Two or more <derivative>'s use the same unique &
&ID: " // trim(to_str(this % id)))
end if
! Read the independent variable name.
call get_node_value(node, "variable", temp_str)
temp_str = to_lower(temp_str)
select case(temp_str)
case("density")
this % variable = DIFF_DENSITY
case("nuclide_density")
this % variable = DIFF_NUCLIDE_DENSITY
call get_node_value(node, "nuclide", word)
word = trim(to_lower(word))
if (.not. nuclide_dict % has_key(word)) then
call fatal_error("Could not find the nuclide " &
// trim(word) // " specified in derivative " &
// trim(to_str(this % id)) // " in any material.")
end if
this % diff_nuclide = nuclide_dict % get_key(word)
case("temperature")
this % variable = DIFF_TEMPERATURE
end select
call get_node_value(node, "material", this % diff_material)
end subroutine from_xml
end module tally_derivative_header

View file

@ -30,19 +30,6 @@ module tally_header
public :: openmc_tally_set_nuclides
public :: openmc_tally_set_scores
!===============================================================================
! TALLYDERIVATIVE describes a first-order derivative that can be applied to
! tallies.
!===============================================================================
type, public :: TallyDerivative
integer :: id
integer :: variable
integer :: diff_material
integer :: diff_nuclide
real(8) :: flux_deriv
end type TallyDerivative
!===============================================================================
! TALLYOBJECT describes a user-specified tally. The region of phase space to
! tally in is given by the TallyFilters and the results are stored in a
@ -124,8 +111,6 @@ module tally_header
integer(C_INT32_T), public, bind(C) :: n_tallies = 0 ! # of tallies
type(TallyContainer), public, allocatable, target :: tallies(:)
type(TallyDerivative), public, allocatable :: tally_derivs(:)
!$omp threadprivate(tally_derivs)
! Dictionary that maps user IDs to indices in 'tallies'
type(DictIntInt), public :: tally_dict