diff --git a/benchmarks/cullen-sab/problem1/settings.xml b/benchmarks/cullen-sab/problem1/settings.xml index 5aa8a4c02..c50c7b011 100644 --- a/benchmarks/cullen-sab/problem1/settings.xml +++ b/benchmarks/cullen-sab/problem1/settings.xml @@ -10,7 +10,9 @@ ==================================================== --> - + + /home/paulromano/openmc/cross_sections_serpent.xml + 500 diff --git a/benchmarks/cullen-sab/problem2/settings.xml b/benchmarks/cullen-sab/problem2/settings.xml index c3b33399b..0d998cf81 100644 --- a/benchmarks/cullen-sab/problem2/settings.xml +++ b/benchmarks/cullen-sab/problem2/settings.xml @@ -10,7 +10,9 @@ ==================================================== --> - + + /home/paulromano/openmc/cross_sections_serpent.xml + 500 diff --git a/benchmarks/cullen-sab/problem3/settings.xml b/benchmarks/cullen-sab/problem3/settings.xml index b483f3e38..b21f29396 100644 --- a/benchmarks/cullen-sab/problem3/settings.xml +++ b/benchmarks/cullen-sab/problem3/settings.xml @@ -10,7 +10,9 @@ ==================================================== --> - + + /home/paulromano/openmc/cross_sections_serpent.xml + 500 diff --git a/benchmarks/pu-met-fast-001/settings.xml b/benchmarks/pu-met-fast-001/settings.xml index aa5b251ca..eee43cff0 100644 --- a/benchmarks/pu-met-fast-001/settings.xml +++ b/benchmarks/pu-met-fast-001/settings.xml @@ -9,8 +9,10 @@ Date: 9/1/2011 ========================================== --> - - + + + /home/paulromano/openmc/cross_sections_serpent.xml + 3000 diff --git a/benchmarks/pu-met-fast-002/settings.xml b/benchmarks/pu-met-fast-002/settings.xml index 74e4e2b8e..9f4da2dd6 100644 --- a/benchmarks/pu-met-fast-002/settings.xml +++ b/benchmarks/pu-met-fast-002/settings.xml @@ -10,7 +10,9 @@ ========================================== --> - + + /home/paulromano/openmc/cross_sections_serpent.xml + 3000 diff --git a/benchmarks/pu-met-fast-005/settings.xml b/benchmarks/pu-met-fast-005/settings.xml index 831fbafbe..e5594b37e 100644 --- a/benchmarks/pu-met-fast-005/settings.xml +++ b/benchmarks/pu-met-fast-005/settings.xml @@ -10,7 +10,9 @@ =============================================================== --> - + + /home/paulromano/openmc/cross_sections_serpent.xml + 3000 diff --git a/cross_sections_serpent.xml b/cross_sections_serpent.xml new file mode 100644 index 000000000..d61e95a16 --- /dev/null +++ b/cross_sections_serpent.xml @@ -0,0 +1,2705 @@ + + + + /opt/serpent/xsdata/endfb7/acedata + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/basic/settings.xml b/examples/basic/settings.xml index b59a0de03..d3f63c7aa 100644 --- a/examples/basic/settings.xml +++ b/examples/basic/settings.xml @@ -2,7 +2,9 @@ - + + /home/paulromano/openmc/cross_sections_serpent.xml + diff --git a/examples/lattice/settings.xml b/examples/lattice/settings.xml index beb7193fa..81b0a9d97 100644 --- a/examples/lattice/settings.xml +++ b/examples/lattice/settings.xml @@ -2,7 +2,9 @@ - + + /home/paulromano/openmc/cross_sections_serpent.xml + diff --git a/examples/reflective/settings.xml b/examples/reflective/settings.xml index 40da741d7..f1a00aafe 100644 --- a/examples/reflective/settings.xml +++ b/examples/reflective/settings.xml @@ -2,7 +2,9 @@ - + + /home/paulromano/openmc/cross_sections_serpent.xml + diff --git a/src/DEPENDENCIES b/src/DEPENDENCIES index 71fb70c0b..4d5a798a8 100644 --- a/src/DEPENDENCIES +++ b/src/DEPENDENCIES @@ -10,6 +10,8 @@ cross_section.o: material_header.o cross_section.o: output.o cross_section.o: string.o +cross_section_header.o: constants.o + datatypes.o: datatypes_header.o doppler.o: constants.o @@ -86,6 +88,7 @@ input_xml.o: mesh_header.o input_xml.o: output.o input_xml.o: string.o input_xml.o: tally_header.o +input_xml.o: xml-fortran/templates/cross_sections_t.o input_xml.o: xml-fortran/templates/geometry_t.o input_xml.o: xml-fortran/templates/materials_t.o input_xml.o: xml-fortran/templates/settings_t.o diff --git a/src/constants.f90 b/src/constants.f90 index ad0f0bc62..6ae68440d 100644 --- a/src/constants.f90 +++ b/src/constants.f90 @@ -166,6 +166,12 @@ module constants N_PT = 116, & N_DA = 117 + ! ACE table types + integer, parameter :: & + ACE_NEUTRON = 1, & ! continuous-energy neutron + ACE_THERMAL = 2, & ! thermal S(a,b) scattering data + ACE_DOSIMETRY = 3 ! dosimetry cross sections + ! Tally macro reactions integer, parameter :: N_MACRO_TYPES = 15 integer, parameter :: & @@ -223,6 +229,7 @@ module constants integer, parameter :: MAX_WORDS = 500 integer, parameter :: MAX_LINE_LEN = 250 integer, parameter :: MAX_WORD_LEN = 150 + integer, parameter :: MAX_FILE_LEN = 255 ! Unit numbers integer, parameter :: UNIT_LOG = 11 ! unit # for writing log file diff --git a/src/cross_section.f90 b/src/cross_section.f90 index de240e666..023f980b9 100644 --- a/src/cross_section.f90 +++ b/src/cross_section.f90 @@ -1,7 +1,7 @@ module cross_section use constants - use cross_section_header, only: Nuclide, Reaction, SAB_Table, xsData + use cross_section_header, only: Nuclide, Reaction, SAB_Table, XsListing use datatypes, only: dict_create, dict_add_key, dict_get_key, & dict_has_key, dict_delete use datatypes_header, only: DictionaryCI @@ -36,7 +36,7 @@ contains integer :: i ! index in materials array integer :: j ! index over nuclides in material - integer :: index ! index in xsdatas array + integer :: index ! index in xs_listings array integer :: index_nuclides ! index in nuclides integer :: index_sab ! index in sab_tables character(10) :: key ! name of isotope, e.g. 92235.03c @@ -105,8 +105,8 @@ contains do i = 1, n_materials mat => materials(i) do j = 1, mat % n_nuclides - ! Get index in xsdatas array for this nuclide - index = mat % xsdata(j) + ! Get index in xs_listings array for this nuclide + index = mat % xs_listing(j) ! Get name of nuclide key = mat % names(j) @@ -126,12 +126,12 @@ contains key = mat % sab_name if (.not. dict_has_key(temp_dict, key)) then - ! Find the entry in xsdatas for this table - if (dict_has_key(xsdata_dict, key)) then - index = dict_get_key(xsdata_dict, key) + ! Find the entry in xs_listings for this table + if (dict_has_key(xs_listing_dict, key)) then + index = dict_get_key(xs_listing_dict, key) else message = "Cannot find cross-section " // trim(key) // & - " in specified xsdata file." + " in specified cross_sections.xml file." call fatal_error() end if @@ -176,7 +176,7 @@ contains subroutine read_ACE_continuous(index_table, index) integer, intent(in) :: index_table ! index in nuclides array - integer, intent(in) :: index ! index in xsdatas array + integer, intent(in) :: index ! index in xs_listings array integer :: in = 7 ! unit to read from integer :: ioError ! error status for file access @@ -189,21 +189,23 @@ contains character(7) :: readable ! is ACE library readable? character(MAX_LINE_LEN) :: line ! single line to read character(MAX_WORD_LEN) :: words(MAX_WORDS) ! words on a line - character(MAX_WORD_LEN) :: filename ! name of ACE library file + character(MAX_FILE_LEN) :: filename ! name of ACE library file character(10) :: tablename ! name of cross section table type(Nuclide), pointer :: nuc => null() - ! Check to make sure index in nuclides array and xsdata arrays are valid + ! Check to make sure index in nuclides array and xs_listings arrays are + ! valid if (index_table > size(nuclides)) then message = "Index of table to read is greater than length of nuclides." call fatal_error() - elseif (index > size(xsdatas)) then - message = "Index of xsdata entry is greater than length of xsdatas." + elseif (index > size(xs_listings)) then + message = "Index of xs_listing entry is greater than length of " // & + "xs_listings." call fatal_error() end if - filename = xsdatas(index)%path - tablename = xsdatas(index)%id + filename = xs_listings(index) % path + tablename = xs_listings(index) % name nuc => nuclides(index_table) @@ -1071,7 +1073,7 @@ contains subroutine read_ACE_thermal(index_table, index) integer, intent(in) :: index_table ! index in sab_tables array - integer, intent(in) :: index ! index in xsdatas array + integer, intent(in) :: index ! index in xs_listings array integer :: in = 7 ! unit to read from integer :: ioError ! error status for file access @@ -1088,8 +1090,8 @@ contains character(10) :: tablename ! name of cross section table type(SAB_Table), pointer :: table => null() - filename = xsdatas(index)%path - tablename = xsdatas(index)%id + filename = xs_listings(index) % path + tablename = xs_listings(index) % name table => sab_tables(index_table) @@ -1319,104 +1321,4 @@ contains end function get_real -!=============================================================================== -! READ_XSDATA reads the data in a SERPENT xsdata file and builds a dictionary to -! find cross-section information later on. -!=============================================================================== - - subroutine read_xsdata(path) - - character(*), intent(in) :: path - - type(xsData), pointer :: iso => null() - character(MAX_LINE_LEN) :: line - character(MAX_WORD_LEN) :: words(MAX_WORDS) - character(MAX_WORD_LEN) :: filename - integer :: n - integer :: in = 7 - logical :: file_exists - character(7) :: readable - integer :: count - integer :: index - integer :: ioError - - message = "Reading cross-section summary file..." - call write_message(5) - - ! Construct filename - filename = trim(path) - - ! Check if xsdata exists and is readable - inquire(FILE=filename, EXIST=file_exists, READ=readable) - if (.not. file_exists) then - message = "Cross section summary '" // trim(filename) // "' does not exist!" - call fatal_error() - elseif (readable(1:3) == 'NO') then - message = "Cross section summary '" // trim(filename) // "' is not " & - & // "readable! Change file permissions with chmod command." - call fatal_error() - end if - - ! open xsdata file - open(FILE=filename, UNIT=in, STATUS='old', & - & ACTION='read', IOSTAT=ioError) - if (ioError /= 0) then - message = "Error while opening file: " // filename - call fatal_error() - end if - - ! determine how many lines - count = 0 - do - read(UNIT=in, FMT='(A)', IOSTAT=ioError) line - if (ioError < 0) then - ! reached end of file - exit - elseif (ioError > 0) then - message = "Unknown error while reading file: " // filename - close(UNIT=in) - call fatal_error() - end if - count = count + 1 - end do - allocate(xsdatas(count)) - - ! read actual lines - index = 0 - rewind(in) - do - read(UNIT=in, FMT='(A)', IOSTAT=ioError) line - if (ioError < 0) exit - index = index + 1 - call split_string(line, words, n) - if (n == 0) cycle ! skip blank line - - ! Check to make sure there are enough arguments - if (n < 9) then - message = "Not enough arguments on xsdata line: " // line - close(UNIT=in) - call fatal_error() - end if - - iso => xsdatas(index) - - ! store data - iso%alias = words(1) - iso%id = words(2) - iso%type = str_to_int(words(3)) - iso%zaid = str_to_int(words(4)) - iso%isomeric = str_to_int(words(5)) - iso%awr = str_to_real(words(6)) - iso%temp = str_to_real(words(7)) - iso%binary = str_to_int(words(8)) - iso%path = words(9) - - ! create dictionary entry - call dict_add_key(xsdata_dict, iso%alias, index) - end do - - close(UNIT=in) - - end subroutine read_xsdata - end module cross_section diff --git a/src/cross_section_header.f90 b/src/cross_section_header.f90 index ba6df0526..4698d1c2a 100644 --- a/src/cross_section_header.f90 +++ b/src/cross_section_header.f90 @@ -1,5 +1,7 @@ module cross_section_header + use constants, only: MAX_FILE_LEN + implicit none !=============================================================================== @@ -148,20 +150,20 @@ module cross_section_header end type SAB_Table !=============================================================================== -! XSDATA contains data read in from a SERPENT xsdata file +! XSLISTING contains data read from a cross_sections.xml file !=============================================================================== - type xsData + type XsListing + character(10) :: name character(10) :: alias - character(10) :: id integer :: type integer :: zaid - integer :: isomeric real(8) :: awr real(8) :: temp - integer :: binary - character(150) :: path - end type xsData + logical :: metastable + logical :: binary + character(MAX_FILE_LEN) :: path + end type XsListing !=============================================================================== ! NUCLIDEMICROXS contains cached microscopic cross sections for a diff --git a/src/global.f90 b/src/global.f90 index 9107a09f1..110780619 100644 --- a/src/global.f90 +++ b/src/global.f90 @@ -2,8 +2,8 @@ module global use bank_header, only: Bank use constants - use cross_section_header, only: Nuclide, SAB_Table, xsData, NuclideMicroXS, & - MaterialMacroXS + use cross_section_header, only: Nuclide, SAB_Table, xsListing, & + NuclideMicroXS, MaterialMacroXS use datatypes_header, only: DictionaryII, DictionaryCI use geometry_header, only: Cell, Universe, Lattice, Surface use material_header, only: Material @@ -52,9 +52,9 @@ module global ! CROSS SECTION RELATED VARIABLES ! Cross section arrays - type(Nuclide), allocatable, target :: nuclides(:) ! Nuclide cross-sections - type(SAB_Table), allocatable, target :: sab_tables(:) ! S(a,b) tables - type(xsData), allocatable, target :: xsdatas(:) ! xsdata listings + type(Nuclide), allocatable, target :: nuclides(:) ! Nuclide cross-sections + type(SAB_Table), allocatable, target :: sab_tables(:) ! S(a,b) tables + type(XsListing), allocatable, target :: xs_listings(:) ! cross_sections.xml listings ! Cross section caches type(NuclideMicroXS), allocatable :: micro_xs(:) ! Cache for each nuclide @@ -63,10 +63,10 @@ module global integer :: n_nuclides_total ! Number of nuclide cross section tables integer :: n_sab_tables ! Number of S(a,b) thermal scattering tables - ! Dictionaries to look up cross sections and xsdata - type(DictionaryCI), pointer :: nuclide_dict => null() - type(DictionaryCI), pointer :: sab_dict => null() - type(DictionaryCI), pointer :: xsdata_dict => null() + ! Dictionaries to look up cross sections and listings + type(DictionaryCI), pointer :: nuclide_dict => null() + type(DictionaryCI), pointer :: sab_dict => null() + type(DictionaryCI), pointer :: xs_listing_dict => null() ! Unionized energy grid integer :: n_grid ! number of points on unionized grid @@ -146,8 +146,8 @@ module global ! ============================================================================ ! MISCELLANEOUS VARIABLES - character(MAX_WORD_LEN) :: path_input ! Path to input file - character(MAX_WORD_LEN) :: path_xsdata ! Path to xsdata file + character(MAX_WORD_LEN) :: path_input ! Path to input file + character(MAX_FILE_LEN) :: path_cross_sections ! Path to cross_sections.xml ! Message used in message/warning/fatal_error character(MAX_LINE_LEN) :: message @@ -178,10 +178,10 @@ contains if (allocated(materials)) deallocate(materials) if (allocated(lattices)) deallocate(lattices) - ! Deallocate cross section data - if (allocated(xsdatas)) deallocate(xsdatas) + ! Deallocate cross section data and listings if (allocated(nuclides)) deallocate(nuclides) if (allocated(sab_tables)) deallocate(sab_tables) + if (allocated(xs_listings)) deallocate(xs_listings) ! Deallocate energy grid if (allocated(e_grid)) deallocate(e_grid) diff --git a/src/initialize.f90 b/src/initialize.f90 index 45283238c..fbb9707cd 100644 --- a/src/initialize.f90 +++ b/src/initialize.f90 @@ -1,7 +1,7 @@ module initialize use constants - use cross_section, only: read_xs, read_xsdata + use cross_section, only: read_xs use datatypes, only: dict_create, dict_add_key, dict_get_key, & dict_has_key, dict_keys use datatypes_header, only: ListKeyValueII, DictionaryII @@ -10,7 +10,8 @@ module initialize use geometry, only: neighbor_lists use geometry_header, only: Cell, Surface, Universe, Lattice, BASE_UNIVERSE use global - use input_xml, only: read_input_xml, cells_in_univ_dict + use input_xml, only: read_input_xml, read_cross_sections_xml, & + cells_in_univ_dict use logging, only: create_log use mcnp_random, only: RN_init_problem use mpi_routines, only: setup_mpi @@ -78,10 +79,10 @@ contains if (.not. plotting) then ! Read cross section summary file to determine what files contain ! cross-sections - call read_xsdata(path_xsdata) + call read_cross_sections_xml() - ! With the AWRs from the xsdata, change all material specifications so that - ! they contain atom percents summing to 1 + ! With the AWRs from the xs_listings, change all material specifications + ! so that they contain atom percents summing to 1 call normalize_ao() ! Read ACE-format cross sections @@ -182,7 +183,7 @@ contains call dict_create(material_dict) call dict_create(mesh_dict) call dict_create(tally_dict) - call dict_create(xsdata_dict) + call dict_create(xs_listing_dict) call dict_create(nuclide_dict) call dict_create(sab_dict) @@ -532,7 +533,8 @@ contains character(10) :: key ! name of nuclide, e.g. 92235.03c type(Material), pointer :: mat => null() - ! first find the index in the xsdata array for each nuclide in each material + ! first find the index in the xs_listings array for each nuclide in each + ! material do i = 1, n_materials mat => materials(i) @@ -561,17 +563,17 @@ contains call fatal_error() end if - if (dict_has_key(xsdata_dict, key)) then - index = dict_get_key(xsdata_dict, key) - mat % xsdata(j) = index + if (dict_has_key(xs_listing_dict, key)) then + index = dict_get_key(xs_listing_dict, key) + mat % xs_listing(j) = index else message = "Cannot find cross-section " // trim(key) // & - " in specified xsdata file." + " in specified cross_sections.xml file." call fatal_error() end if ! determine atomic weight ratio - awr = xsdatas(index) % awr + awr = xs_listings(index) % awr ! if given weight percent, convert all values so that they are divided ! by awr. thus, when a sum is done over the values, it's actually @@ -592,8 +594,8 @@ contains if (.not. density_in_atom) then sum_percent = ZERO do j = 1, mat % n_nuclides - index = mat % xsdata(j) - awr = xsdatas(index) % awr + index = mat % xs_listing(j) + awr = xs_listings(index) % awr x = mat % atom_percent(j) sum_percent = sum_percent + x*awr end do diff --git a/src/input_xml.f90 b/src/input_xml.f90 index 316ae489b..56b33e768 100644 --- a/src/input_xml.f90 +++ b/src/input_xml.f90 @@ -9,7 +9,7 @@ module input_xml use mesh_header, only: StructuredMesh use output, only: write_message use string, only: lower_case, int_to_str, str_to_int, str_to_real, & - split_string + split_string, starts_with, ends_with use tally_header, only: TallyObject implicit none @@ -64,8 +64,8 @@ contains ! Parse settings.xml file call read_xml_file_settings_t(filename) - ! Cross-section library path - path_xsdata = trim(xslibrary % path) + ! Path for cross_sections.xml file + path_cross_sections = trim(cross_sections_) ! Criticality information if (criticality % cycles > 0) then @@ -466,7 +466,7 @@ contains m % n_nuclides = n allocate(m % names(n)) allocate(m % nuclide(n)) - allocate(m % xsdata(n)) + allocate(m % xs_listing(n)) allocate(m % atom_density(n)) allocate(m % atom_percent(n)) @@ -904,4 +904,102 @@ contains end subroutine read_plot_xml +!=============================================================================== +! READ_CROSS_SECTIONS_XML reads information from a cross_sections.xml file. This +! file contains a listing of the ACE cross sections that may be used. +!=============================================================================== + + subroutine read_cross_sections_xml() + + use xml_data_cross_sections_t + + integer :: i ! loop index + integer :: n_listings ! number of listings in cross_sections.xml + logical :: file_exists ! does cross_sections.xml exist? + character(MAX_WORD_LEN) :: directory + type(XsListing), pointer :: listing => null() + + ! Check if cross_sections.xml exists + inquire(FILE=path_cross_sections, EXIST=file_exists) + if (.not. file_exists) then + ! Could not find cross_sections.xml file + message = "Cross sections XML file '" // trim(path_cross_sections) // & + "' does not exist!" + call fatal_error() + end if + + message = "Reading cross sections XML file..." + call write_message(5) + + ! Initialize directory_ variable + directory_ = "" + + ! Parse cross_sections.xml file + call read_xml_file_cross_sections_t(path_cross_sections) + + ! Copy directory information if present + directory = trim(directory_) + + ! Allocate xs_listings array + if (.not. associated(ace_tables_)) then + message = "No ACE table listings present in cross_sections.xml file!" + call fatal_error() + else + n_listings = size(ace_tables_) + allocate(xs_listings(n_listings)) + end if + + + do i = 1, n_listings + listing => xs_listings(i) + + ! copy a number of attributes + listing % name = trim(ace_tables_(i) % name) + listing % alias = trim(ace_tables_(i) % alias) + listing % zaid = ace_tables_(i) % zaid + listing % awr = ace_tables_(i) % awr + listing % temp = ace_tables_(i) % temperature + + ! determine type of cross section + select case(ace_tables_(i) % type) + case ('neutron') + listing % type = ACE_NEUTRON + case ('thermal') + listing % type = ACE_THERMAL + case ('dosimetry') + listing % type = ACE_DOSIMETRY + end select + + ! determine metastable state + if (ace_tables_(i) % metastable == 0) then + listing % metastable = .false. + else + listing % metastable = .true. + end if + + ! determine whether binary/ascii + if (ace_tables_(i) % binary == 0) then + listing % binary = .false. + else + listing % binary = .true. + end if + + ! determine path of cross section table + if (starts_with(ace_tables_(i) % path, '/')) then + listing % path = ace_tables_(i) % path + else + if (ends_with(directory,'/')) then + listing % path = trim(directory) // trim(ace_tables_(i) % path) + else + listing % path = trim(directory) // '/' // trim(ace_tables_(i) % path) + end if + end if + + ! create dictionary entry for both name and alias + call dict_add_key(xs_listing_dict, listing % name, i) + call dict_add_key(xs_listing_dict, listing % alias, i) + end do + + end subroutine read_cross_sections_xml + end module input_xml diff --git a/src/material_header.f90 b/src/material_header.f90 index 5a4899653..c95c2ced0 100644 --- a/src/material_header.f90 +++ b/src/material_header.f90 @@ -10,7 +10,7 @@ module material_header integer :: uid ! unique identifier integer :: n_nuclides ! number of nuclides character(10), allocatable :: names(:) ! isotope names - integer, allocatable :: xsdata(:) ! index in xsdata list + integer, allocatable :: xs_listing(:) ! index in xs_listings list integer, allocatable :: nuclide(:) ! index in nuclides array real(8) :: density ! total atom density in atom/b-cm real(8), allocatable :: atom_density(:) ! nuclide atom density in atom/b-cm diff --git a/src/utils/convert_xsdata.py b/src/utils/convert_xsdata.py new file mode 100755 index 000000000..c5f02f22a --- /dev/null +++ b/src/utils/convert_xsdata.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python + +import os +import sys +from xml.dom.minidom import getDOMImplementation + +types = {1: "neutron", 2: "dosimetry", 3: "thermal"} + +class Xsdata(object): + + def __init__(self, filename): + self._table_dict = {} + self.tables = [] + + for line in open(filename, 'r'): + words = line.split() + + # If this listing is just an alias listing, only assign the alias + # attribute + name = words[1] + alias = words[0] + table = self.find_table(name) + if table: + if name not in table.alias: + table.alias.append(alias) + continue + + table = XsdataTable() + table.name = name + table.type = types[int(words[2])] + table.zaid = int(words[3]) + table.metastable = int(words[4]) + table.awr = float(words[5]) + table.temperature = 8.6173423e-11 * float(words[6]) + table.binary = int(words[7]) + table.path = words[8] + + self.tables.append(table) + self._table_dict[name] = table + + # Check for common directory + self.directory = os.path.dirname(self.tables[0].path) + for table in self.tables: + if not table.path.startswith(self.directory): + self.directory = None + break + + def to_xml(self): + # Create XML document + impl = getDOMImplementation() + doc = impl.createDocument(None, "cross_sections", None) + + # Get root element + root = doc.documentElement + + # Add a directory node + if self.directory: + directoryNode = doc.createElement("directory") + text = doc.createTextNode(self.directory) + directoryNode.appendChild(text) + root.appendChild(directoryNode) + + for table in self.tables: + table.path = os.path.basename(table.path) + + # Add a node for each table + for table in self.tables: + node = table.to_xml_node(doc) + root.appendChild(node) + + return doc + + def find_table(self, name): + if name in self._table_dict: + return self._table_dict[name] + else: + return None + + +class XsdataTable(object): + + def __init__(self): + self.alias = [] + + def to_xml_node(self, doc): + node = doc.createElement("ace_table") + node.setAttribute("name", self.name) + for attribute in ["alias", "zaid", "type", "metastable", + "awr", "temperature", "binary", "path"]: + if hasattr(self, attribute): + # Join string for alias attribute + if attribute == "alias": + if not self.alias: + continue + string = " ".join(self.alias) + else: + string = "{0}".format(getattr(self,attribute)) + + # Skip metastable and binary if 0 + if attribute == "metastable" and self.metastable == 0: + continue + if attribute == "binary" and self.binary == 0: + continue + + # Create attribute node + # nodeAttr = doc.createElement(attribute) + # text = doc.createTextNode(string) + # nodeAttr.appendChild(text) + # node.appendChild(nodeAttr) + node.setAttribute(attribute, string) + return node + + +if __name__ == '__main__': + # Read command line arguments + if len(sys.argv) < 3: + sys.exit("Usage: convert_xsdata.py xsdataFile xmlFile") + xsdataFile = sys.argv[1] + xmlFile = sys.argv[2] + + # Read xsdata and create XML document object + xsdataObject = Xsdata(xsdataFile) + doc = xsdataObject.to_xml() + + # Reduce number of lines + lines = doc.toprettyxml(indent=' ') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + lines = lines.replace('\n ','') + + # Write document in pretty XML to specified file + f = open(xmlFile, 'w') + f.write(lines) + f.close() diff --git a/src/xml-fortran/templates/cross_sections_t.xml b/src/xml-fortran/templates/cross_sections_t.xml new file mode 100644 index 000000000..d49d79862 --- /dev/null +++ b/src/xml-fortran/templates/cross_sections_t.xml @@ -0,0 +1,23 @@ + + diff --git a/src/xml-fortran/templates/settings_t.xml b/src/xml-fortran/templates/settings_t.xml index 7309eb039..167ff0d63 100644 --- a/src/xml-fortran/templates/settings_t.xml +++ b/src/xml-fortran/templates/settings_t.xml @@ -3,10 +3,6 @@ - - - - @@ -23,11 +19,11 @@ - +