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 @@
-
+