Skip to content

Commit b20311a

Browse files
authored
Merge pull request #189 from yardasol/openmc-file-io
Implement file and database IO functions in `OpenMCDepcode`
2 parents 1af46aa + 31cbef5 commit b20311a

77 files changed

Lines changed: 35230 additions & 3784 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test-saltproc.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ on:
1414
workflow_dispatch:
1515

1616
env:
17-
CACHE_NUMBER: 0 #change to manually reset cache
17+
CACHE_NUMBER: 6 #change to manually reset cache
1818

1919
jobs:
2020
test-saltproc:
@@ -57,6 +57,7 @@ jobs:
5757
path: |
5858
/usr/share/miniconda3/envs/saltproc-env
5959
~/openmc_src
60+
~/mcpl_src
6061
~/endfb71_hdf5
6162
~/.cache/pip
6263
key: depcache-${{ hashFiles('environment.yml') }}-${{ env.DATE }}-${{ env.CACHE_NUMBER }}
@@ -94,7 +95,10 @@ jobs:
9495
- name: Install SaltProc
9596
run: pip install .
9697

97-
- name: Test SaltProc
98+
- name: Environment variables
9899
run: |
99100
echo "OPENMC_CROSS_SECTIONS=$HOME/endfb71_hdf5/cross_sections.xml" >> $GITHUB_ENV
100-
pytest --ignore tests/integration_tests/run_no_reprocessing --ignore tests/integration_tests/run_constant_reprocessing tests/
101+
102+
- name: Test SaltProc
103+
run: |
104+
pytest --ignore tests/integration_tests/run_no_reprocessing_serpent --ignore tests/integration_tests/run_no_reprocessing_openmc --ignore tests/integration_tests/run_constant_reprocessing_serpent --ignore tests/integration_tests/run_constant_reprocessing_openmc tests/

doc/releasenotes/v0.5.0.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,15 @@ Python API Changes
173173
- (new function) → ``get_neutron_settings()``
174174
- (new function) → ``_get_burnable_materials_file()``
175175
- (new function) → ``_get_burnable_material_card_data()``
176+
- (new function) → ``resolve_include_paths()``
177+
- (new function) → ``_convert_name_to_nuccode()``
176178
- (new parameter) → ``zaid_convention``
177179

178180

179181
- ``OpenMCDepcode`` is a ``Depcode`` subclass that interfaces with ``openmc``. This class implements the following functions
180182
- ``run_depletion_step()``
183+
- ``write_saltproc_openmc_tallies()``
184+
- ``convert_nuclide_code_to_name()``
181185
- ``switch_to_next_geometry()``
182186
- ``write_runtime_input()``
183187
- ``write_depletion_settings()``
@@ -206,6 +210,7 @@ Python API Changes
206210

207211
- ``core_number`` → (removed)
208212
- ``node_number`` → (removed)
213+
- (new function) → ``_add_missing_nuclides()``
209214

210215
- ``Sparger``
211216

examples/msbr/msbr_endfb71.serpent

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ set sfylib "endfb71.sfy"
5858

5959
% --- Neutron population and criticality cycles:
6060

61-
set pop 300 400 10
61+
set pop 60000 120 80
6262
set gcu -1
6363
%set usym 0 3 2 0.0 0.0 0 90
6464

examples/msbr/msbr_endfb71_main.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
{
22
"proc_input_file": "msbr_objects.json",
33
"dot_input_file": "msbr.dot",
4-
"n_depletion_steps": 12,
4+
"n_depletion_steps": 122,
5+
"output_path": "serpent_msbr_test",
56
"depcode": {
67
"codename": "serpent",
78
"exec_path": "sss2",
89
"template_input_file_path": "./msbr_endfb71.serpent",
910
"geo_file_paths": ["./geometry/msbr_full.ini"]
1011
},
1112
"simulation": {
12-
"sim_name": "msbr_example_simulation",
13-
"db_name": "msbr_kl_100_saltproc.h5",
14-
"restart_flag": false,
15-
"adjust_geo": false
13+
"sim_name": "msbr_serpent_test"
1614
},
1715
"reactor": {
1816
"volume": 1.0,

examples/msbr/msbr_openmc.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"proc_input_file": "msbr_objects.json",
3+
"dot_input_file": "msbr.dot",
4+
"n_depletion_steps": 122,
5+
"output_path": "openmc_msbr_test",
6+
"depcode": {
7+
"codename": "openmc",
8+
"template_input_file_path": {
9+
"materials": "materials.xml",
10+
"settings": "settings.xml"},
11+
"geo_file_paths": ["geometry.xml"],
12+
"chain_file_path": "chain_endfb71_pwr.xml",
13+
"depletion_settings": {
14+
"operator_kwargs": {
15+
"fission_q": "serpent_fissq.json"
16+
}
17+
}
18+
},
19+
"simulation": {
20+
"sim_name": "msbr_openmc_test"
21+
},
22+
"reactor": {
23+
"volume": 1.0,
24+
"mass_flowrate": 9920000,
25+
"power_levels": [ 2250000000 ],
26+
"depletion_timesteps": [ 3 ],
27+
"timestep_units": "d"
28+
}
29+
}

examples/msbr/openmc_msbr_model.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,29 @@ def parse_arguments():
5151
-------
5252
deplete : bool
5353
Flag indicated whether or not to run a depletion simulation.
54+
volume_calculation : bool
55+
Flag indicating whether or not to run a stochastic volume calcuation.
56+
entropy : bool
57+
Flag indicating whether or not to calculate Shannon entropy.
5458
"""
5559
parser = argparse.ArgumentParser()
5660
parser.add_argument('--deplete',
5761
type=bool,
5862
default=False,
5963
help='flag for running depletion')
64+
parser.add_argument('--volume_calculation',
65+
type=bool,
66+
default=False,
67+
help='flag for running stochastic volume calculation')
68+
parser.add_argument('--entropy',
69+
type=bool,
70+
default=False,
71+
help='flag for including entropy mesh')
72+
73+
6074

6175
args = parser.parse_args()
62-
return bool(args.deplete)
76+
return bool(args.deplete), bool(args.volume_calculation), bool(args.entropy)
6377

6478
def shared_elem_geometry(elem_type='core',
6579
gr_sq_d=4.953,
@@ -372,7 +386,7 @@ def plot_geometry(name,
372386
return plot
373387

374388

375-
deplete = parse_arguments()
389+
deplete, volume_calculation, entropy = parse_arguments()
376390

377391
(zone_bounds,
378392
core_bounds,
@@ -450,18 +464,25 @@ def plot_geometry(name,
450464

451465
# Settings
452466
settings = openmc.Settings()
453-
settings.particles = 10000
454-
settings.batches = 150
455-
settings.inactive = 25
467+
settings.particles = 60000
468+
settings.batches = 200
469+
settings.inactive = 80
456470
settings.temperature = {'default': 900,
457471
'method': 'interpolation',
458472
'range': (800, 1000)}
459473

460474
ll, ur = geo.root_universe.bounding_box
461-
msbr_volume_calc = openmc.VolumeCalculation([fuel, moder], 1000000000, ll, ur)
462-
#msbr_volume_calc.set_trigger(1e-03, 'rel_err')
463-
settings.volume_calculations = [msbr_volume_calc]
464-
settings.run_mode = 'volume'
475+
if volume_calculation:
476+
msbr_volume_calc = openmc.VolumeCalculation([fuel, moder], int(1e10), ll, ur)
477+
#msbr_volume_calc.set_trigger(1e-03, 'rel_err')
478+
settings.volume_calculations = [msbr_volume_calc]
479+
settings.run_mode = 'volume'
480+
if entropy:
481+
entropy_mesh = openmc.RegularMesh()
482+
entropy_mesh.lower_left = ll
483+
entropy_mesh.upper_right = ur
484+
entropy_mesh.dimension = (20, 20, 20)
485+
settings.entropy_mesh = entropy_mesh
465486
settings.export_to_xml()
466487

467488
## Slice plots

saltproc/abc.py

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import sys
2+
import subprocess
3+
14
from abc import ABC, abstractmethod
25

36
class Depcode(ABC):
@@ -99,21 +102,37 @@ def read_depleted_materials(self, read_at_end=False):
99102
:class:`Materialflow` object holding material composition and properties.
100103
101104
"""
102-
103-
@abstractmethod
104-
def run_depletion_step(self, mpi_args, threads):
105+
def run_depletion_step(self, mpi_args, args):
105106
"""Runs a depletion step as a subprocess with the given parameters.
106107
107108
Parameters
108109
----------
109110
mpi_args : list of str
110111
Arguments for running simulations on supercomputers using
111112
``mpiexec`` or similar programs.
112-
threads : int
113-
Threads to use for shared-memory parallelism
113+
args : list of str
114+
Arguments for running depletion step.
114115
115116
"""
116117

118+
print('Running %s' % (self.codename))
119+
try:
120+
if mpi_args is None:
121+
stdout = sys.stdout
122+
else:
123+
stdout = None
124+
subprocess.run(
125+
args,
126+
check=True,
127+
cwd=self.output_path,
128+
stdout=stdout,
129+
stderr=subprocess.STDOUT)
130+
print(f'Finished {self.codename.upper()} Run')
131+
except subprocess.CalledProcessError as error:
132+
print(error.output.decode("utf-8"))
133+
raise RuntimeError('\n %s RUN FAILED\n see error message above'
134+
% (self.codename))
135+
117136
@abstractmethod
118137
def switch_to_next_geometry(self):
119138
"""Changes the geometry used in the depletion code simulation to the
@@ -153,5 +172,76 @@ def update_depletable_materials(self, mats, dep_end_time):
153172
154173
"""
155174

175+
def read_plaintext_file(self, file_path):
176+
"""Reads the content of a plaintext file for use by other methods.
177+
178+
Parameters
179+
----------
180+
file_path : str
181+
Path to file.
182+
183+
Returns
184+
-------
185+
file_lines : list of str
186+
File lines.
187+
188+
"""
189+
file_lines = []
190+
with open(file_path, 'r') as file:
191+
file_lines = file.readlines()
192+
return file_lines
193+
194+
@abstractmethod
195+
def convert_nuclide_code_to_name(self, nuc_code):
196+
"""Converts depcode nuclide code to symbolic nuclide name.
197+
198+
Parameters
199+
----------
200+
nuc_code : str
201+
Nuclide code
202+
203+
Returns
204+
-------
205+
nuc_name : str
206+
Symbolic nuclide name (`Am242m1`).
207+
208+
"""
209+
210+
@abstractmethod
211+
def _convert_name_to_nuccode(self, nucname):
212+
"""Converts depcode nuclide name to ZA nuclide code
213+
214+
Parameters
215+
----------
216+
nucname : str
217+
Nuclide namce
218+
219+
Returns
220+
-------
221+
nuc_name : str
222+
ZA nuclide code
223+
224+
"""
225+
226+
def preserve_simulation_files(self, step_idx):
227+
"""Move simulation input and output files
228+
to unique a directory
156229
230+
Parameters
231+
----------
232+
step_idx : int
157233
234+
"""
235+
step_results_dir = self.output_path / f'step_{step_idx}_data'
236+
step_results_dir.mkdir(exist_ok=True)
237+
238+
file_path = lambda file : self.output_path / file
239+
output_paths = list(map(file_path, self._OUTPUTFILE_NAMES))
240+
input_paths = list(map(file_path, self._INPUTFILE_NAMES))
241+
for file_path, fname in zip(output_paths, self._OUTPUTFILE_NAMES):
242+
file_path.rename(step_results_dir / fname)
243+
244+
for file_path, fname in zip(input_paths, self._INPUTFILE_NAMES):
245+
lines = self.read_plaintext_file(file_path)
246+
with open(step_results_dir / fname, 'w') as out_file:
247+
out_file.writelines(lines)

0 commit comments

Comments
 (0)