mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-21 14:35:27 -04:00
Materials name persist when running depletion simulation (#3738)
Co-authored-by: GuySten <guyste@post.bgu.ac.il> Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com> Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
This commit is contained in:
parent
5c502ddb3e
commit
db426b66ca
8 changed files with 41 additions and 10 deletions
|
|
@ -34,6 +34,7 @@ The current version of the depletion results file format is 1.2.
|
|||
|
||||
:Attributes: - **index** (*int*) -- Index used in results for this material
|
||||
- **volume** (*double*) -- Volume of this material in [cm^3]
|
||||
- **name** (*char[]*) -- Name of this material
|
||||
|
||||
**/nuclides/<name>/**
|
||||
|
||||
|
|
|
|||
|
|
@ -209,6 +209,8 @@ class TransportOperator(ABC):
|
|||
simulation.
|
||||
full_burn_list : list of int
|
||||
All burnable materials in the geometry.
|
||||
name_list : list of str
|
||||
Material names corresponding to materials in burn_list
|
||||
"""
|
||||
|
||||
def finalize(self):
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ class OpenMCOperator(TransportOperator):
|
|||
"section data.")
|
||||
warn(msg)
|
||||
if mat.depletable:
|
||||
burnable_mats.add(str(mat.id))
|
||||
burnable_mats.add((str(mat.id), mat.name))
|
||||
if mat.volume is None:
|
||||
if mat.name is None:
|
||||
msg = ("Volume not specified for depletable material "
|
||||
|
|
@ -229,9 +229,12 @@ class OpenMCOperator(TransportOperator):
|
|||
"No depletable materials were found in the model.")
|
||||
|
||||
# Sort the sets
|
||||
burnable_mats = sorted(burnable_mats, key=int)
|
||||
burnable_mats = sorted(burnable_mats, key=lambda x: int(x[0]))
|
||||
model_nuclides = sorted(model_nuclides)
|
||||
|
||||
# Store material names for later use
|
||||
burnable_mats, self.name_list = zip(*burnable_mats)
|
||||
|
||||
# Construct a global nuclide dictionary, burned first
|
||||
nuclides = list(self.chain.nuclide_dict)
|
||||
for nuc in model_nuclides:
|
||||
|
|
@ -541,6 +544,8 @@ class OpenMCOperator(TransportOperator):
|
|||
A list of all material IDs to be burned. Used for sorting the simulation.
|
||||
full_burn_list : list
|
||||
List of all burnable material IDs
|
||||
name_list : list of str
|
||||
Material names corresponding to materials in burn_list
|
||||
|
||||
"""
|
||||
nuc_list = self.number.burnable_nuclides
|
||||
|
|
@ -554,4 +559,4 @@ class OpenMCOperator(TransportOperator):
|
|||
volume_list = comm.allgather(volume)
|
||||
volume = {k: v for d in volume_list for k, v in d.items()}
|
||||
|
||||
return volume, nuc_list, burn_list, self.burnable_mats
|
||||
return volume, nuc_list, burn_list, self.burnable_mats, self.name_list
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class StepResult:
|
|||
self.index_mat = None
|
||||
self.index_nuc = None
|
||||
self.mat_to_hdf5_ind = None
|
||||
self.name_list = None
|
||||
|
||||
self.data = None
|
||||
|
||||
|
|
@ -138,7 +139,7 @@ class StepResult:
|
|||
def n_hdf5_mats(self):
|
||||
return len(self.mat_to_hdf5_ind)
|
||||
|
||||
def allocate(self, volume, nuc_list, burn_list, full_burn_list):
|
||||
def allocate(self, volume, nuc_list, burn_list, full_burn_list, name_list=None):
|
||||
"""Allocate memory for depletion step data
|
||||
|
||||
Parameters
|
||||
|
|
@ -151,12 +152,15 @@ class StepResult:
|
|||
A list of all mat IDs to be burned. Used for sorting the simulation.
|
||||
full_burn_list : list of str
|
||||
List of all burnable material IDs
|
||||
name_list : list of str, optional
|
||||
Material names corresponding to materials in burn_list
|
||||
|
||||
"""
|
||||
self.volume = copy.deepcopy(volume)
|
||||
self.index_nuc = {nuc: i for i, nuc in enumerate(nuc_list)}
|
||||
self.index_mat = {mat: i for i, mat in enumerate(burn_list)}
|
||||
self.mat_to_hdf5_ind = {mat: i for i, mat in enumerate(full_burn_list)}
|
||||
self.mat_to_name = dict(zip(burn_list, name_list)) if name_list is not None else {}
|
||||
|
||||
# Create storage array
|
||||
self.data = np.zeros((self.n_mat, self.n_nuc))
|
||||
|
|
@ -184,7 +188,7 @@ class StepResult:
|
|||
|
||||
# Direct transfer
|
||||
direct_attrs = ("time", "k", "source_rate", "index_nuc",
|
||||
"mat_to_hdf5_ind", "proc_time")
|
||||
"mat_to_hdf5_ind", "mat_to_name", "proc_time")
|
||||
for attr in direct_attrs:
|
||||
setattr(new, attr, getattr(self, attr))
|
||||
# Get applicable slice of data
|
||||
|
|
@ -223,6 +227,8 @@ class StepResult:
|
|||
f'mat_id {mat_id} not found in StepResult. Available mat_id '
|
||||
f'values are {list(self.volume.keys())}'
|
||||
) from e
|
||||
if mat_id in self.mat_to_name:
|
||||
material.name = self.mat_to_name[mat_id]
|
||||
for nuc, _ in sorted(self.index_nuc.items(), key=lambda x: x[1]):
|
||||
atoms = self[mat_id, nuc]
|
||||
if atoms <= 0.0:
|
||||
|
|
@ -313,6 +319,8 @@ class StepResult:
|
|||
mat_single_group = mat_group.create_group(mat)
|
||||
mat_single_group.attrs["index"] = self.mat_to_hdf5_ind[mat]
|
||||
mat_single_group.attrs["volume"] = self.volume[mat]
|
||||
if mat in self.mat_to_name:
|
||||
mat_single_group.attrs["name"] = self.mat_to_name[mat]
|
||||
|
||||
nuc_group = handle.create_group("nuclides")
|
||||
|
||||
|
|
@ -495,6 +503,7 @@ class StepResult:
|
|||
results.volume = {}
|
||||
results.index_mat = {}
|
||||
results.index_nuc = {}
|
||||
results.mat_to_name = {}
|
||||
rxn_nuc_to_ind = {}
|
||||
rxn_to_ind = {}
|
||||
|
||||
|
|
@ -504,6 +513,8 @@ class StepResult:
|
|||
|
||||
results.volume[mat] = vol
|
||||
results.index_mat[mat] = ind
|
||||
if "name" in mat_handle.attrs:
|
||||
results.mat_to_name[mat] = mat_handle.attrs["name"]
|
||||
|
||||
for nuc, nuc_handle in handle["/nuclides"].items():
|
||||
ind_atom = nuc_handle.attrs["atom number index"]
|
||||
|
|
@ -569,11 +580,11 @@ class StepResult:
|
|||
.. versionadded:: 0.14.0
|
||||
"""
|
||||
# Get indexing terms
|
||||
vol_dict, nuc_list, burn_list, full_burn_list = op.get_results_info()
|
||||
vol_dict, nuc_list, burn_list, full_burn_list, name_list = op.get_results_info()
|
||||
|
||||
# Create results
|
||||
results = StepResult()
|
||||
results.allocate(vol_dict, nuc_list, burn_list, full_burn_list)
|
||||
results.allocate(vol_dict, nuc_list, burn_list, full_burn_list, name_list)
|
||||
|
||||
n_mat = len(burn_list)
|
||||
|
||||
|
|
|
|||
|
|
@ -243,4 +243,4 @@ class DummyOperator(TransportOperator):
|
|||
Maps cell name to index in global geometry.
|
||||
|
||||
"""
|
||||
return self.volume, self.nuc_list, self.local_mats, self.burnable_mats
|
||||
return self.volume, self.nuc_list, self.local_mats, self.burnable_mats, {"1": ""}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,11 @@ def test_activation(run_in_tmpdir, model, reaction_rate_mode, reaction_rate_opts
|
|||
assert atoms[0] == pytest.approx(n0)
|
||||
assert atoms[1] / atoms[0] == pytest.approx(0.5, rel=tolerance)
|
||||
|
||||
# Check that material name is preserved in depletion results
|
||||
step_result = results[0]
|
||||
mat_from_results = step_result.get_material(f"{w.id}")
|
||||
assert mat_from_results.name == 'tungsten'
|
||||
|
||||
|
||||
def test_decay(run_in_tmpdir):
|
||||
"""Test decay-only timesteps where no transport solve is performed"""
|
||||
|
|
|
|||
|
|
@ -82,3 +82,8 @@ def test_deplete_decay_step_fissionable(run_in_tmpdir):
|
|||
_, u238 = results.get_atoms(f"{mat.id}", "U238")
|
||||
|
||||
assert u238[1] == pytest.approx(original_atoms)
|
||||
|
||||
# Check that material name is preserved in depletion results
|
||||
step_result = results[0]
|
||||
mat_from_results = step_result.get_material(f"{mat.id}")
|
||||
assert mat_from_results.name == 'I do not decay.'
|
||||
|
|
|
|||
|
|
@ -59,8 +59,9 @@ def test_results_save(run_in_tmpdir):
|
|||
burn_list = full_burn_list[2*comm.rank: 2*comm.rank + 2]
|
||||
nuc_list = ["na", "nb"]
|
||||
|
||||
name_list = {mat: "" for mat in full_burn_list}
|
||||
op.get_results_info.return_value = (
|
||||
vol_dict, nuc_list, burn_list, full_burn_list)
|
||||
vol_dict, nuc_list, burn_list, full_burn_list, name_list)
|
||||
|
||||
# Construct end-of-step concentrations
|
||||
x1 = [rng.random(2), rng.random(2)]
|
||||
|
|
@ -130,7 +131,8 @@ def test_results_save_without_rates(run_in_tmpdir):
|
|||
vol_dict = {"0": 1.0}
|
||||
nuc_list = ["na"]
|
||||
burn_list = ["0"]
|
||||
op.get_results_info.return_value = (vol_dict, nuc_list, burn_list, burn_list)
|
||||
name_list = {mat: "" for mat in burn_list}
|
||||
op.get_results_info.return_value = (vol_dict, nuc_list, burn_list, burn_list, name_list)
|
||||
|
||||
x = [np.array([1.0])]
|
||||
rates = ReactionRates(burn_list, nuc_list, ["ra"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue