Skip to content

Support for a single model.xml file#2291

Merged
paulromano merged 54 commits intoopenmc-dev:developfrom
pshriwise:model-xml
Dec 24, 2022
Merged

Support for a single model.xml file#2291
paulromano merged 54 commits intoopenmc-dev:developfrom
pshriwise:model-xml

Conversation

@pshriwise
Copy link
Copy Markdown
Contributor

This PR adds the ability to read a single input XML, model.xml as input.

If this file is present, OpenMC will read the settings, materials, geometry, tallies, and plots from this file and ignore any other XML files present in the directory -- a warning will be displayed if those additional XMLs are present. If a model.xml file is absent, OpenMC will fall back to using the current set of separate XML files we rely on for input.

In the Python API, a separate_xmls keyword argument has been added to the openmc.Model export_to_xml and from_xml methods to support both reading and writing a single XML file or separate XML files. This should make it easy to either stick with the current workflow for input generation with multiple XML files or convert old inputs into a single model.xml file.

This PR is still a little rough (needs a fresh look in the morning and several tests), so I'm marking it as a draft for now.

@pshriwise pshriwise marked this pull request as ready for review November 10, 2022 16:32
@shimwell
Copy link
Copy Markdown
Member

This looks like the way to go, nice work Patrick. Perhaps this closes #1906?

Copy link
Copy Markdown
Contributor

@paulromano paulromano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together @pshriwise!

@pshriwise
Copy link
Copy Markdown
Contributor Author

With the additional changes to exec.py to support custom file names, I’d like to add a couple more tests to ensure that works correctly.

Copy link
Copy Markdown
Contributor

@paulromano paulromano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates @pshriwise! Another round of comments:

Comment on lines +451 to +453
directory : str
Directory to write XML files to. If it doesn't exist already, it
will be created.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than having separate directory and filename arguments, perhaps we should have a single path argument. When exporting separate XMLs, it would expect a directory. When exporting a single model.xml, the path could either be a directory (in which case 'model.xml' will be appended) or an explicit filename.

auto other_inputs = {"materials.xml", "geometry.xml", "settings.xml", "tallies.xml", "plots.xml"};
for (const auto& input : other_inputs) {
if (file_exists(settings::path_input + input)) {
warning(("Other XML file input(s) are present. These file will be ignored in favor of the model.xml file."));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment remains about need for clang-formatting

pshriwise and others added 23 commits December 6, 2022 13:03
Incorporating suggestions from @paulromano

Co-authored-by: Paul Romano <paul.k.romano@gmail.com>

def export_to_xml(self, directory='.', remove_surfs=False):
"""Export model to XML files.
def export_to_xml(self, directory='.', remove_surfs=False, separate_xmls=True, path='model.xml'):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulromano I'm wondering if we should take the same approach here as we did for from_xml (i.e. maintain the current export_to_xml method and add an export_to_model_xml method alongside it for now). Thoughts?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, in light of the changes for from_xml, I think it would make sense to keep this as two separate methods as well. Thanks!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do!

@pshriwise
Copy link
Copy Markdown
Contributor Author

A couple of changes related to filesystem functions are worth noting in the latest set of updates:

  • A dir_exists function was added to file_utils.h. It uses the C lib system calls and flags to check whether or not a path is a directory. Once we switch to C++17, we can use the std::filesystem component there instead.
  • Our file_exists method in file_utils.h will return true for existing directories as well as files. A dir_exists call for the input filepath has been added to this method so it returns false for directories.

Comment on lines +264 to +265
if model.settings.entropy_mesh is not None:
meshes[model.settings.entropy_mesh.id] = model.settings.entropy_mesh
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also the UFS mesh (this feels a little brittle -- wondering if there's a better way we can capture all the meshes from settings.xml)

Suggested change
if model.settings.entropy_mesh is not None:
meshes[model.settings.entropy_mesh.id] = model.settings.entropy_mesh
if model.settings.entropy_mesh is not None:
meshes[model.settings.entropy_mesh.id] = model.settings.entropy_mesh
if model.settings.ufs_mesh is not None:
meshes[model.settings.ufs_mesh.id] = model.settings.ufs_mesh

Copy link
Copy Markdown
Contributor Author

@pshriwise pshriwise Dec 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah maybe we should consolidate all of the mesh writing into a single method?

☝🏻 misunderstanding on my part

How about an internal attribute on the class that tracks meshes used (updated inside the property setters). Then this would become:

meshes = {mesh.id: for mesh in model.settings._meshes}

subelement.text = str(value)

def _create_entropy_mesh_subelement(self, root):
def _create_entropy_mesh_subelement(self, root, mesh_memo=None):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need similar changes for _create_ufs_mesh_subelement

@paulromano paulromano merged commit 3f8f8f6 into openmc-dev:develop Dec 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants