You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Whereas Serpent2 uses plain text input files, OpenMC uses .xml files (settings.xml, materials.xml, geometry.xml). A user would typically create these .xml files using the Python API.
This issue can be closed when functions exist within the Depcode class that can work with the .xml files used by OpenMC -- specifically the .xml files that the OpenMC python API creates. These functions should utilize the OpenMC API where possible.
In particular, we want similar functionality as the following functions:
In my meeting with @munkm today we discussed some aspects of open development and having a discussion about implementation is one of them.
write_depcode_input
This function stores the lines of a "template" serpent input file in memory, and modifies parameters such as geometry, neutron population and number of batches, and reactor power based on the current depletion step. The flow for the current algorithm is as follows
To support OpenMC, I can think of two directions:
Create an entirely new function that utilizes the OpenMC API. This may require renaming write_depcode_input to write_serpent_input
defwrite_serpent_input(self, temp_file, inp_file, reactor, dts, restart):
""" Writes prepared data into the serpent code input file. Parameters ---------- temp_file : str Path to user template file for depletion code inp_file : str Path to input file for depletio ncod rerunning. . . . """#.#.#.defwrite_openmc_input(self, temp_dir, inp_dir, reactor, dts, restart):
""" Writes prepared data into the openmc code input files. Parameters ---------- temp_dir : str Path to parent directory of template input files for OpenMC. inp_dir : str Path to parent directory of input files for depletion code rerunning. . . . """
.
.
.
Add a keyword argument to the function to specify which depletion code we are using ('serpent' for Serpent, 'openmc' for OpenMC), and then refactor the current function into a series of if-statements OR a collection of helper functions for each depletion code option. Below I have shown the former.
defwrite_depcode_input(self, depcode_name, temp_file, inp_file, reactor, dts, restart):
""" Writes prepared data into the depletion code input file. Parameters ---------- depcode_name : str name for depletion code software. Options are 'openmc', 'serpent'. . . . """if (depcode_name=="serpent"):
# repeat body of current write_depcode_input code here
.
.
.
elseif (depcode_name=="openmc"):
# Use OpenMC API to write prepared data into OpenMC input files
.
.
.
In either case, the flow for the OpenMC algorithm could look like the following
read_depcode_template
This function stores the lines of the serpent template input file in memory. OpenMC uses a different xml file for geometry, materials, and settings each. I can think of the following implementation:
Utilize the OpenMC API to initialize these objects from template files
defread_openmc_templates(self, settings_fname, materials_fname):
""" reads prepared template input files for openmc fr further changes in the files to prepare input files for multiple runs Parameters ---------- settings_fname : str Path to user template settings file for OpenMC materials_fname : str Path to user template materials file for OpenMC Returns ------- settings_xml : openmc.Settings OpenMC Settings object materials_xml : openmc.Materials OpenMC Materials object geometry_xml : openmc.Geometry OpenMC Geometry object """settings_xml=openmc.Settings.from_xml(path=settings_fname)
materials_xml=openmc.Materials.from_xml(path=materials_fname)
geometry_xml=openmc.Geometry.from_xml(path=str(self.geo_file[0]), materials=materials_xml)
returnsettings_xml,materials_xml, geometry_xml
insert_path_to_geometry
This function inserts a path in the serpent input file pointing to a serpent geometry file. In OpenMC, geometry input file must be named geometry.xml. Because we don't need to pass the data parameter for the OpenMC case, I can only think of one option for OpenMC support here:
Create an entirely new function that utilizes the OpenMC API. This may require renaming insert_path_to_geometry to something else.
This function changes the neutron population and number of cycles in the serpent template file to the user-specified neutron population and number of cycles. In OpenMC, the settings.xml file stores these parameters. We can utilize the OpenMC API to create this settings file.
Because we don't need to pass the data parameter for the OpenMC case, I can only think of one option for OpenMC support here:
Create an entirely new function that utilizes the OpenMC API. This may require renaming change_sim_par to something else.
This function creates a rewritable iterative material file based on an initial material file for the SaltProc simulation. It is in serpent format. In OpenMC, the materials.xml file stores the material data. We can utilize the OpenMC API to create this material file.
Because we don't need to pass the data parameter for the OpenMC case, I can only think of one option for OpenMC support here:
Create an entirely new function that utilizes the OpenMC API. This may require renaming create_iter_matfile to something else.
This function updates the composition of materials in the serpent materials file after each depletion step. In OpenMC, we can utilize the OpenMC API to do this without having to fuss around with formatting strings and writing directly to files.
I can think of two ways to add OpenMC support for this function:
Create an entirely new function that utilizes the OpenMC API. This may require renaming write_mat_file to write_serpent_file
defwrite_openmc_mat_file(self, dep_dict, mat_file, cumulative_time_at_eds):
"""Writes the iteration material file containing burnable materials composition used in depletion runs and updated after each depletion step. Parameters ---------- . . . """matf=openmc.Materials()
forkey, valueindep_dict.items():
mat=openmc.Material(name=key)
mat.density=dep_dict[key].densitymat.temperature=dep_dict[key].tempmat.volume=dep_dict[key].volfornuc_code, wt_fracindep_dict[key].com.items():
mat.add_nuclide(nuc_code,wt_frac, 'wo')
matf.append(mat)
matf.export_to_xml(mat_file)
. Add an if-statement to the function to specify which depletion code we are using based on the codename field of the Depcode class ('serpent' for Serpent, 'openmc' for OpenMC), and then refactor the current function into the body of one of the if-statements OR a collection of helper functions for each depletion code option. Below I have shown the former.
defwrite_mat_file(self, dep_dict, mat_file, cumulative_time_at_eds):
"""Writes the iteration input file containing burnable materials composition used in depletion runs and updated after each depletion step. Parameters ---------- . . . """if (self.codename=="serpent"):
# repeat body of current write_mat_file here
.
.
.
elseif (self.codename=="openmc"):
# repeat body of proposed write_openmc_mat_file here
.
.
.
Given that Depcode already has the codename field built-in, I think approach 2 makes more sense for this function.
2. Add a keyword argument to the function to specify which depletion code we are using ('serpent' for Serpent, 'openmc' for OpenMC), and then refactor the current function into a series of `if`-statements OR a collection of helper functions for each depletion code option. Below I have shown the former.
defwrite_depcode_input(self, depcode_name, temp_file, inp_file, reactor, dts, restart):
""" Writes prepared data into the depletion code input file. Parameters ---------- depcode_name : str name for depletion code software. Options are 'openmc', 'serpent'. . . . """if (depcode_name=="serpent"):
# repeat body of current write_depcode_input code here
.
.
.
elseif (depcode_name=="openmc"):
# Use OpenMC API to write prepared data into OpenMC input files
.
.
.
I just realized that Depcode has a field codename, so the proposed key word argument is redundant. We can still use the if-statement structure though,
In my meeting with @katyhuff on Saturday, we discussed refactoring Depcode to be a parent class and create new classes -- SerpentDepcode and OpenMCDepcode -- as subclasses of Depcode that implement the respective versions of code-specific methods where necessary, and would inherit methods that are generalizable to either depletion code.
I have looked at the current methods in Depcode and all of them are specifically designed for use with Serpent. I see two ways that we could make Depcode a parent class:
Make Depcode contain only the current class parameters and no methods. Copy all current methods in Depcode to DepcodeSerpent. Perform the suggested implementations above for DepcodeOpenMC.
Make Depcode contain the current class parameters and make it a subclass of abc. We will create abstract methods wherever possible. This will enable a common API for the Depcode class than can be passed to both the DepcodeOpenMC and DepcodeSerpent. This would also mean we avoid having to completely refactor the Simulation class, as well as the other SaltProc classes**.
Below is an example of what an implementation of approach 2 could look like. Approach 1 would be similar, except we would not import anything from the abc module, nor use abstract classes.
fromabcimportABC, abstractmethod# I borrows this handy doc function from the OpenMC folks.# See https://docs.openmc.org/en/stable/_modules/openmc/deplete/abc.html#Integratordefadd_params(cls):
cls.__doc__+=cls._paramsreturncls@add_paramsclassDepcode(ABC):
r"""Abstract class for running depletion simulation code. """_params=r""" Parameters ---------- codename : str Name of depletion code. exec_path : str Path to depletion code executable. template_fname : str Path to user input file for depletion code. input_fname : str Name of input file for depletion code rerunning. iter_matfile : str Name of iterative, rewritable material file for depletion code rerunning. This file is being modified during simulation. geo_file : str or list Path to file that contains the reactor geometry. List of `str` if reactivity control by switching geometry is `On` or just `str` otherwise. npop : int Size of neutron population per cycle for Monte Carlo. active_cycles : int Number of active cycles. inactive_cycles : int Number of inactive cycles. """def__init__(self, ...):
.
.
.
@abstractmethoddefwrite_depcode_input(self, ...):
""" Writes prepared data into the depletion code input file. . . . """@abstractmethoddefrun_depcode(self, cores, nodes):
"""Runs depletion code as subprocess with the given parameters. Parameters ---------- cores : int Number of cores to use for depletion code run. nodes : int Number of nodes to use for depletion code run. """
.
.
.
@add_paramsdefDepcodeSerpent(Depcode):
r"""Class contains contains information about input, output, geometry, and template file for for running Serpent depletion simulation. """self.codename="Serpent"
.
.
.
@add_paramsdefDepcodeOpenMC(Depcode):
r"""Class contains information about input, output, geometry, and template file for running OpenMC depletion simulation """
.
.
.
Activity
yardasol commentedon Jun 18, 2021
DepcodeDiscussion:In my meeting with @munkm today we discussed some aspects of open development and having a discussion about implementation is one of them.
write_depcode_inputThis function stores the lines of a "template" serpent input file in memory, and modifies parameters such as geometry, neutron population and number of batches, and reactor power based on the current depletion step. The flow for the current algorithm is as follows

To support OpenMC, I can think of two directions:
write_depcode_inputtowrite_serpent_inputif-statements OR a collection of helper functions for each depletion code option. Below I have shown the former.In either case, the flow for the OpenMC algorithm could look like the following

read_depcode_templateThis function stores the lines of the serpent template input file in memory. OpenMC uses a different
xmlfile for geometry, materials, and settings each. I can think of the following implementation:insert_path_to_geometryThis function inserts a path in the serpent input file pointing to a serpent geometry file. In OpenMC, geometry input file must be named
geometry.xml. Because we don't need to pass thedataparameter for the OpenMC case, I can only think of one option for OpenMC support here:insert_path_to_geometryto something else.change_sim_parThis function changes the neutron population and number of cycles in the serpent template file to the user-specified neutron population and number of cycles. In OpenMC, the
settings.xmlfile stores these parameters. We can utilize the OpenMC API to create this settings file.Because we don't need to pass the
dataparameter for the OpenMC case, I can only think of one option for OpenMC support here:change_sim_parto something else.create_iter_matfileThis function creates a rewritable iterative material file based on an initial material file for the SaltProc simulation. It is in serpent format. In OpenMC, the
materials.xmlfile stores the material data. We can utilize the OpenMC API to create this material file.Because we don't need to pass the
dataparameter for the OpenMC case, I can only think of one option for OpenMC support here:create_iter_matfileto something else.write_mat_fileThis function updates the composition of materials in the serpent materials file after each depletion step. In OpenMC, we can utilize the OpenMC API to do this without having to fuss around with formatting strings and writing directly to files.
I can think of two ways to add OpenMC support for this function:
write_mat_filetowrite_serpent_fileif-statement to the function to specify which depletion code we are using based on thecodenamefield of theDepcodeclass ('serpent' for Serpent, 'openmc' for OpenMC), and then refactor the current function into the body of one of theif-statements OR a collection of helper functions for each depletion code option. Below I have shown the former.Given that
Depcodealready has thecodenamefield built-in, I think approach 2 makes more sense for this function.1 remaining item
yardasol commentedon Jun 22, 2021
@LukeSeifert @munkm @andrewryh please see the above discussion.
yardasol commentedon Jun 22, 2021
I just realized that
Depcodehas a fieldcodename, so the proposed key word argument is redundant. We can still use theif-statement structure though,yardasol commentedon Jun 30, 2021
Refactor
DepcodeIn my meeting with @katyhuff on Saturday, we discussed refactoring
Depcodeto be a parent class and create new classes --SerpentDepcodeandOpenMCDepcode-- as subclasses ofDepcodethat implement the respective versions of code-specific methods where necessary, and would inherit methods that are generalizable to either depletion code.I have looked at the current methods in
Depcodeand all of them are specifically designed for use with Serpent. I see two ways that we could makeDepcodea parent class:Make
Depcodecontain only the current class parameters and no methods. Copy all current methods inDepcodetoDepcodeSerpent. Perform the suggested implementations above forDepcodeOpenMC.Make
Depcodecontain the current class parameters and make it a subclass ofabc. We will create abstract methods wherever possible. This will enable a common API for theDepcodeclass than can be passed to both theDepcodeOpenMCandDepcodeSerpent. This would also mean we avoid having to completely refactor theSimulationclass, as well as the other SaltProc classes**.Below is an example of what an implementation of approach 2 could look like. Approach 1 would be similar, except we would not import anything from the
abcmodule, nor use abstract classes.**I am not 100% sure that this is true.
[-]OpenMC .xml file support[/-][+]Discussion: OpenMC .xml file support[/+]