Skip to content

Commit

Permalink
Merge pull request arfc#178 from yardasol/serpent-material-temps
Browse files Browse the repository at this point in the history
Serpent material temps
  • Loading branch information
samgdotson authored Jan 9, 2023
2 parents 6bac510 + 35cdb8d commit beb9b1d
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 21 deletions.
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
68 changes: 49 additions & 19 deletions saltproc/serpent_depcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class SerpentDepcode(Depcode):
inactive_cycles : int
Number of inactive cycles.
"""

def __init__(self,
Expand Down Expand Up @@ -95,7 +94,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 +107,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):
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 @@ -119,17 +132,30 @@ def create_runtime_matfile(self, file_lines):
absolute_path = (runtime_dir / burnable_materials_path)
else:
absolute_path = Path(burnable_materials_path)
with open(absolute_path) as f:
if 'mat ' not in f.read():
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]
with open(absolute_path) as f:
if 'mat ' not in f.read():
raise IOError('Template file '
f'{self.template_input_file_path} includes '
'no file with materials description')
return burnable_materials_path, absolute_path.resolve()

def _get_burnable_material_card_data(self, file_lines):
# 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 +546,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
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
47 changes: 47 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,53 @@ 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
33 changes: 33 additions & 0 deletions tests/unit_tests/test_serpent_depcode.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Test SerpentDepcode functions"""
import pytest
import numpy as np
import tempfile
from pathlib import Path

from saltproc import SerpentDepcode

Expand Down Expand Up @@ -35,6 +37,37 @@ def test_get_neutron_settings(serpent_depcode):
assert serpent_depcode.active_cycles == 20
assert serpent_depcode.inactive_cycles == 20

def test_get_burnable_materials_file(serpent_depcode):
err1 = (f'Template file {serpent_depcode.template_input_file_path}'
' has no <include "material_file"> statements')

with pytest.raises(IOError, match=err1):
lines_no_include = ['this line does not start with include']
serpent_depcode._get_burnable_materials_file(lines_no_include)

with tempfile.NamedTemporaryFile(mode='w+') as tf:
tf.write('some junk')
old_template = serpent_depcode.template_input_file_path
serpent_depcode.template_input_file_path = tf.name

err2 = (f'Template file {serpent_depcode.template_input_file_path}'
' includes no file with materials description')
with pytest.raises(IOError, match=err2):
lines_bad_matfile = [f'include "{tf.name}"']
serpent_depcode._get_burnable_materials_file(lines_bad_matfile)
serpent_depcode.template_input_file_path = old_template

def test_get_burnable_material_card_data(serpent_depcode):
bad_mat_cards = ['mat fuel -9.2 burn 1 fix 09c',
'mat blanket -9.1 burn 1']

err = ('"mat" card for burnable material "blanket" 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')
with pytest.raises(IOError, match=err):
serpent_depcode._get_burnable_material_card_data(bad_mat_cards)


def test_read_plaintext_file(serpent_depcode):
template_str = serpent_depcode.read_plaintext_file(
Expand Down

0 comments on commit beb9b1d

Please sign in to comment.