Source code for watts.plugin_openmc

# SPDX-FileCopyrightText: 2022-2023 UChicago Argonne, LLC
# SPDX-License-Identifier: MIT

from functools import lru_cache
from pathlib import Path
from typing import Callable, Mapping, List, Optional

from uncertainties import ufloat

from .fileutils import PathLike
from .parameters import Parameters
from .plugin import Plugin
from .results import Results, ExecInfo


[docs] class ResultsOpenMC(Results): """OpenMC simulation results Parameters ---------- params Parameters used to generate inputs exec_info Execution information (job ID, plugin name, timestamp, etc.) inputs List of input files outputs List of output files Attributes ---------- keff K-effective value from the final statepoint statepoints List of statepoint files stdout Standard output from OpenMC run tallies List of OpenMC tally objects """ def __init__(self, params: Parameters, exec_info: ExecInfo, inputs: List[Path], outputs: List[Path]): super().__init__(params, exec_info, inputs, outputs) @property def statepoints(self) -> List[Path]: return [p for p in self.outputs if p.name.startswith('statepoint')] @property @lru_cache() def keff(self) -> ufloat: import openmc # Get k-effective from last statepoint last_statepoint = self.statepoints[-1] with openmc.StatePoint(last_statepoint) as sp: if hasattr(sp, 'keff'): return sp.keff else: return sp.k_combined @property @lru_cache() def tallies(self) -> List: import openmc # Get k-effective from last statepoint last_statepoint = self.statepoints[-1] with openmc.StatePoint(last_statepoint) as sp: return list(sp.tallies.values())
[docs] class PluginOpenMC(Plugin): """Plugin for running OpenMC Parameters ---------- model_builder Function that generates an OpenMC model extra_inputs Extra (non-templated) input files show_stdout Whether to display output from stdout when OpenMC is run show_stderr Whether to display output from stderr when OpenMC is run """ def __init__(self, model_builder: Optional[Callable[[Parameters], None]] = None, extra_inputs: Optional[List[PathLike]] = None, show_stdout: bool = False, show_stderr: bool = False): super().__init__(extra_inputs, show_stdout, show_stderr) self.model_builder = model_builder self.unit_system = 'cgs' self.plugin_name = 'OpenMC'
[docs] def prerun(self, params: Parameters) -> None: """Generate OpenMC input files Parameters ---------- params Parameters used by the OpenMC template """ # Convert quantities in parameters to CGS system params_copy = params.convert_units(system=self.unit_system) if self.model_builder is not None: self.model_builder(params_copy)
[docs] def run(self, function: Optional[Callable] = None, **kwargs: Mapping): """Run OpenMC Parameters ---------- function Function to execute. If not passed, defaults to only calling :func:`openmc.run`. **kwargs Keyword arguments passed on to ``function`` See also -------- openmc.run, openmc.plot_geometry, openmc.calculate_volumes """ import openmc if function: function(**kwargs) else: openmc.run(**kwargs)
[docs] def postrun(self, params: Parameters, exec_info: ExecInfo) -> ResultsOpenMC: """Collect information from OpenMC simulation and create results object Parameters ---------- params Parameters used to create OpenMC model exec_info Execution information Returns ------- OpenMC results object """ def files_since(pattern, timestamp): matches = [] for p in Path.cwd().glob(pattern): # Because of limited time resolution, we rely on access time to # determine input files mtime = p.stat().st_atime_ns if mtime >= timestamp: matches.append(p) matches.sort(key=lambda x: x.stat().st_mtime_ns) return matches # Start with non-templated input files inputs = [Path.cwd() / p.name for p in self.extra_inputs] # Get generated input files for path in files_since('*.xml', exec_info.timestamp): if path not in inputs: inputs.append(path) # Get list of all output files outputs = ['OpenMC_log.txt'] outputs.extend(files_since('tallies.out', exec_info.timestamp)) outputs.extend(files_since('source.*.h5', exec_info.timestamp)) outputs.extend(files_since('particle*.h5', exec_info.timestamp)) outputs.extend(files_since('statepoint.*.h5', exec_info.timestamp)) outputs.extend(files_since('volume*.h5', exec_info.timestamp)) outputs.extend(files_since('*.png', exec_info.timestamp)) outputs.extend(files_since('*.ppm', exec_info.timestamp)) return ResultsOpenMC(params, exec_info, inputs, outputs)