openmc-dev / openmc

OpenMC Monte Carlo Code
https://docs.openmc.org
Other
764 stars 492 forks source link

`Materials.cross_sections` handles elements differently than OPENMC_CROSS_SECTIONS #2542

Open kkiesling opened 1 year ago

kkiesling commented 1 year ago

I noticed a discrepancy in how add_element() is handled depending on how the cross sections path is set. This became apparent with specifically adding elemental carbon and using the ENDF/B-7.1 data. When using the Material.cross_sections property to set the XS path, carbon is expanded into C12 and C13 first, which causes an error with ENDF/B-7.1 when running (ERROR: Could not find nuclide C12 in the nuclear data library.). In the case where the XS path is set as an environment variable first (OPENMC_CROSS_SECTIONS), it is not expanded into the individual nuclides and instead added as C0 (which is how 7.1 handles this nuclide). Adding the nuclide as C0 seems to be fine.

I can understand why this treatment differs, but ideally, the treatment of the elemental carbon would be handled identically regardless of how and when the XS library is set.

Here are some example scripts/steps that can be run to generate the materials.xml file to view this difference:

Using OPENMC_CROSS_SECTIONS environment variable

Script:

bash:

export OPENMC_CROSS_SECTIONS=/path/to/endf7.1/cross_sections.xml

Python script:

import openmc

# make a material with elemental carbon
c_mat = openmc.Material()
c_mat.set_density('atom/b-cm', 1.0)
c_mat.add_element('C', 1.0, 'ao')

# make material library
mats = openmc.Materials([c_mat])

# export w/out setting the XS path (rely on environment variable):
mats.export_to_xml('materials_env_eleC.xml')

########################################################################
# make a material with nuclide C0
c0_mat = openmc.Material()
c0_mat.set_density('atom/b-cm', 1.0)
c0_mat.add_nuclide('C0', 1.0, 'ao')

# make material library
mats0 = openmc.Materials([c0_mat])

# export w/out setting the XS path (rely on environment variable):
mats0.export_to_xml('materials_env_c0.xml')

XML output:

materials_env_eleC.xml (adding elemental carbon):

<?xml version='1.0' encoding='utf-8'?>
<materials>
  <material id="1">
    <density units="atom/b-cm" value="1.0" />
    <nuclide ao="1.0" name="C0" />
  </material>
</materials>

materials_env_c0.xml (adding nuclide C0):

<?xml version='1.0' encoding='utf-8'?>
<materials>
  <material id="2">
    <density units="atom/b-cm" value="1.0" />
    <nuclide ao="1.0" name="C0" />
  </material>
</materials>

setting Materials.cross_sections before exporting

Script:

bash:

unset OPENMC_CROSS_SECTIONS

Python script:

import openmc

# make a material with elemental carbon
c_mat = openmc.Material()
c_mat.set_density('atom/b-cm', 1.0)
c_mat.add_element('C', 1.0, 'ao')

# make material library
mats = openmc.Materials([c_mat])

# set path on material library and export
# MAKE SURE OPENMC_CROSS_SECTIONS IS NOT SET
mats.cross_sections = "/path/to/endf7.1/cross_sections.xml"
mats.export_to_xml('materials_withpath_eleC.xml')

########################################################################
# make a material with nuclide C0
c0_mat = openmc.Material()
c0_mat.set_density('atom/b-cm', 1.0)
c0_mat.add_nuclide('C0', 1.0, 'ao')

# make material library
mats0 = openmc.Materials([c0_mat])

# set path on material library and export
# MAKE SURE OPENMC_CROSS_SECTIONS IS NOT SET
mats0.cross_sections = "/path/to/endf7.1/cross_sections.xml"
mats0.export_to_xml('materials_withpath_c0.xml')

XML output:

materials_withpath_eleC.xml (adding elemental carbon): This behavior to expand the element when it is is added makes sense to me and I think should be the behavior regardless of how the XS path is set, even though it causes an error when running later.

<?xml version='1.0' encoding='utf-8'?>
<materials>
  <cross_sections>/path/to/endf7.1/cross_sections.xml</cross_sections>
  <material id="1">
    <density units="atom/b-cm" value="1.0" />
    <nuclide ao="0.988922" name="C12" />
    <nuclide ao="0.011078" name="C13" />
  </material>
</materials>

materials_withpath_c0.xml (adding nuclide C0):

<?xml version='1.0' encoding='utf-8'?>
<materials>
  <cross_sections>/path/to/endf7.1/cross_sections.xml</cross_sections>
  <material id="2">
    <density units="atom/b-cm" value="1.0" />
    <nuclide ao="1.0" name="C0" />
  </material>
</materials>

Like I said, I understand why this is happening- in the case where the XS path is set as an environment variable, the knowledge of how elemental carbon should be handled for this particular data library is known. Whereas in the case where it is set as a materials attribute, that info on how to handle it isn't available. I don't know if this happens with other nuclides/elements too.

Ideally, add_element('C') would be how it expands the nuclides, regardless of how and when the cross sections are set. IMO the correct handling to expand all elements into the individual nuclides, like is done for the materials_withpath_eleC.xml file (meaning materials_env_eleC.xml shows the "incorrect" handling even though this file is what ultimately works for running).

kkiesling commented 1 year ago

We discussed this issue in the OpenMC Monthly Drop-in and came up with a few solutions to address the inconsistencies or at least notify users of possible inconsistencies.

  1. to ensure consistent behavior, instead of expanding elements at the time of adding them to a material, expand them at the time of exporting. This will ensure they can be checked against the library no matter which way it is set because the library will be known before exporting. The draw back of this solution is that is more of an intermediate bandaid fix that will require some heavy lifting infrastructure change.
  2. Add a warning in the case that the data library is set using the attribute but material objects have already been generated. (ie "material library data is being set after construction of materials, there is no guarantee that the data is consistent with how those materials were constructed"). Or perhaps the warning is invoked when add_element is called but no cross section library is present OR if the attribute is set later and it differs from the environment variable. There are probably a few options to trigger the warning but a warning should be added regardless I think.

I think implementing option 1 is best for consistency but probably not doable for me personally in the near term, but at least implementing the warning will be helpful for other users.

paulromano commented 1 year ago

At this point I would say that using Materials.cross_sections is not recommended. Once we introduced the openmc.config variable for setting data sources, it provided a better way of indicating data without the need for environment variables. Moving forward, I suggest that we deprecate and then eventually remove the option to set Materials.cross_sections.