Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serpent material temps #178

Merged
merged 14 commits into from
Jan 9, 2023
6 changes: 4 additions & 2 deletions doc/releasenotes/v0.5.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,15 @@ Python API Changes
- ``write_mat_file()`` → ``update_depletable_materials()``
- ``get_nuc_name()`` → ``convert_nuclide_code_to_name()``
- ``convert_nuclide_name_serpent_to_zam()`` → ``convert_nuclide_code_to_zam()``
- ``change_sim_par()`` → (deleted)
- (new function) → ``get_neutron_settings()``
- ``create_iter_matfile()`` → ``create_runtime_matfile()``
- ``replace_burnup_parameters()`` → ``set_power_load()``
- ``write_depcode_input()`` → ``write_runtime_input()``
- ``iter_inputfile`` → ``runtime_inputfile``
- ``iter_matfile`` → ``runtime_matfile``
- ``change_sim_par()`` → (deleted)
- (new function) → ``get_neutron_settings()``
- (new function) → ``get_burnable_materials_file()``
- (new function) → ``get_burnable_material_card_data()``


- ``OpenMCDepcode`` is a ``Depcode`` subclass that interfaces with ``openmc``. This class implements the following functions
Expand Down
61 changes: 47 additions & 14 deletions saltproc/serpent_depcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ class SerpentDepcode(Depcode):
Number of active cycles.
inactive_cycles : int
Number of inactive cycles.

burnable_material_card_data : dict of str to tuple
Dictionary containing burnable material cards
and the index of the `vol` option.

"""

Expand Down Expand Up @@ -95,7 +97,7 @@ def get_neutron_settings(self, file_lines):

def create_runtime_matfile(self, file_lines):
"""Creates the runtime material file tracking burnable materials
ans inserts the path to this file in the Serpent2 runtime input file
and inserts the path to this file in the Serpent2 runtime input file

Parameters
----------
Expand All @@ -108,6 +110,20 @@ def create_runtime_matfile(self, file_lines):
Serpent2 runtime input file with updated material file path.

"""
burnable_materials_path, absolute_path = self.get_burnable_materials_file(file_lines)

# Create data directory
Path.mkdir(Path(self.runtime_matfile).parents[0], exist_ok=True)

# Get material cards
flines = self.read_plaintext_file(absolute_path)
self.get_burnable_material_card_data(flines)

# Create file with path for SaltProc rewritable iterative material file
shutil.copy2(absolute_path, self.runtime_matfile)
return [line.replace(burnable_materials_path, self.runtime_matfile) for line in file_lines]

def get_burnable_materials_file(self, file_lines):
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you need a docstring for this function?

Copy link
Contributor

Choose a reason for hiding this comment

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

If this is a private function, I will accept not having a docstring. Since users should never interact with it. In this case, the code is documentation. However, if it is a private function it should have a single underscore at the beginning of the method name.

runtime_dir = Path(self.template_input_file_path).parents[0]
include_card = [line for line in file_lines if line.startswith("include ")]
if not include_card:
Expand All @@ -124,12 +140,25 @@ def create_runtime_matfile(self, file_lines):
raise IOError('Template file '
f'{self.template_input_file_path} includes '
'no file with materials description')
# Create data directory
Path.mkdir(Path(self.runtime_matfile).parents[0], exist_ok=True)

# Create file with path for SaltProc rewritable iterative material file
shutil.copy2(absolute_path, self.runtime_matfile)
return [line.replace(burnable_materials_path, self.runtime_matfile) for line in file_lines]
return burnable_materials_path, absolute_path.resolve()

def get_burnable_material_card_data(self, file_lines):
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you need a docstring for this function?

Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above.

# Get data for matfile
mat_cards = \
[line.split() for line in file_lines if line.startswith("mat ")]

for card in mat_cards:
if 'fix' not in card:
raise IOError(f'"mat" card for burnable material "{card[1]}'
'does not have a "fix" option. Burnable materials'
'in SaltProc must include the "fix" option. See'
'the serpent wiki for more information: '
'https://serpent.vtt.fi/mediawiki/index.php/Input_syntax_manual#mat')
# Get volume indices
card_volume_idx = [(card.index('vol') + 1) for card in mat_cards]
mat_names = [card[1] for card in mat_cards]
mat_data = zip(mat_cards, card_volume_idx)#, mat_extensions)
self.burnable_material_card_data = dict(zip(mat_names, mat_data))

def convert_nuclide_code_to_name(self, nuc_code):
"""Converts Serpent2 nuclide code to symbolic nuclide name.
Expand Down Expand Up @@ -520,13 +549,17 @@ def update_depletable_materials(self, mats, dep_end_time):
f.write('%% Material compositions (after %f days)\n\n'
% dep_end_time)
nuc_code_map = self.map_nuclide_code_zam_to_serpent()
if not(hasattr(self, 'burnable_material_card_data')):
lines = self.read_plaintext_file(self.template_input_file_path)
_, abs_src_matfile = self.get_burnable_materials_file(lines)
file_lines = self.read_plaintext_file(abs_src_matfile)
self.get_burnable_material_card_data(file_lines)
for name, mat in mats.items():
f.write('mat %s %5.9E burn 1 fix %3s %4i vol %7.5E\n' %
(name,
-mat.density,
'09c',
mat.temp,
mat.vol))
mat_card, card_volume_idx = self.burnable_material_card_data[name]
mat_card[2] = str(-mat.density)
mat_card[card_volume_idx] = "%7.5E" % mat.vol
Copy link
Contributor

Choose a reason for hiding this comment

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

This feels like a hardcoded value. Is this the case?

Copy link
Contributor

Choose a reason for hiding this comment

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

No this is string formatting

Copy link
Contributor

Choose a reason for hiding this comment

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

That's what I was thinking. Just wanted to make sure it wasn't hard coding any values.

f.write(" ".join(mat_card))
f.write("\n")
for nuc_code, mass_fraction in mat.comp.items():
zam_code = pyname.zzaaam(nuc_code)
f.write(' %9s %7.14E\n' %
Expand Down
48 changes: 48 additions & 0 deletions tests/integration_tests/file_interface_serpent/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,54 @@ def test_runtime_input_from_template(serpent_depcode, msr):
file_data = serpent_depcode.create_runtime_matfile(file_data)
assert file_data[0].split()[-1] == '\"' + \
serpent_depcode.runtime_matfile + '\"'

# get_burnable_material_card_data
burnable_material_card_data = {'fuel':
(['mat',
'fuel',
'-4.960200000E+00',
'rgb',
'253',
'231',
'37',
'burn',
'1',
'fix',
'09c',
'900',
'vol',
'4.435305E+7',
'%',
'just',
'core',
'volume',
'2.27175E+07'], 13),
'ctrlPois':
(['mat',
'ctrlPois',
'-2.52',
'burn',
'1',
'fix',
'09c',
'900',
'rgb',
'255',
'128',
'0',
'vol',
'1.11635E+04'], 13)}


for ref_key, test_key in \
zip(serpent_depcode.burnable_material_card_data.keys(),
burnable_material_card_data.keys()):
assert ref_key == test_key
ref_data = serpent_depcode.burnable_material_card_data[ref_key]
test_data = burnable_material_card_data[test_key]
np.testing.assert_array_equal(np.array(ref_data, dtype=object),
np.array(test_data, dtype=object))

remove(serpent_depcode.runtime_matfile)

# set_power_load
Expand Down