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

Rewriting SS Model as a Set of Functions #18

Open
wants to merge 72 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
3e4b3ad
Add files via upload
anu1217 Aug 26, 2024
af78b20
Update and rename OpenMC_xml.py to OpenMCSphericalShellFunctions/Open…
anu1217 Aug 26, 2024
4091d8a
Update OpenMCSphericalShellFunctions/OpenMC_xml.py
anu1217 Aug 27, 2024
e737ae4
Remove print statement
anu1217 Nov 20, 2024
f22bdfa
Delete OpenMCSphericalShellFunctions/OpenMC_xml.py
anu1217 Nov 29, 2024
f9de25d
Merge branch 'cnerg:main' into xml_split
anu1217 Nov 29, 2024
3922b2d
Add files via upload
anu1217 Nov 29, 2024
3ffca9e
Update and rename OpenMC_SS_Geometry.py to SphericalShell/Split_into_…
anu1217 Nov 29, 2024
799689b
Update and rename OpenMC_SS_YAML.yaml to SphericalShell/Split_into_Fu…
anu1217 Nov 29, 2024
cd6bb50
Update and rename OpenMC_SS_Material.py to SphericalShell/Split_into_…
anu1217 Nov 29, 2024
9d63d57
Update and rename OpenMC_Source_Tallies_Model.py to SphericalShell/Sp…
anu1217 Nov 29, 2024
f580d7f
Add files via upload
anu1217 Dec 5, 2024
bb63601
Update and rename SS_Depletion.py to SphericalShell/Split_into_Functi…
anu1217 Dec 5, 2024
f11cd2a
Update and rename SphericalShell/Split_into_Functions/OpenMC_Model/Op…
anu1217 Dec 5, 2024
1df6e73
Update OpenMC_SS_YAML.yaml with depletion parameters
anu1217 Dec 5, 2024
4011bd7
Delete SphericalShell/OpenMC_Input/SS_Activation_OpenMC.py
anu1217 Dec 5, 2024
ce4526b
Update and rename SphericalShell/Split_into_Functions/OpenMC_Depletio…
anu1217 Dec 5, 2024
ed30a23
Update and rename SphericalShell/Split_into_Functions/OpenMC_Model/Op…
anu1217 Dec 5, 2024
1cb6b94
Update and rename SphericalShell/OpenMC_Input/Depletion to SphericalS…
anu1217 Dec 5, 2024
cbeb7b2
Update and rename SphericalShell/OpenMC_Input/Model to SphericalShell…
anu1217 Dec 5, 2024
9efebeb
Update and rename SphericalShell/Split_into_Functions/OpenMC_Model/Op…
anu1217 Dec 5, 2024
dfd7bd5
Update and rename SS_Depletion to SS_Depletion.py
anu1217 Dec 5, 2024
583304c
Update and rename SS_Geometry to SS_Geometry.py
anu1217 Dec 5, 2024
3da5017
Update and rename SphericalShell/OpenMC_Input/SS_Material.py to Spher…
anu1217 Dec 5, 2024
d86b3e5
Update and rename OpenMC_Source_Tallies_Model.py to SS_Source_Tallies…
anu1217 Dec 5, 2024
30e30e2
Update and rename OpenMC_SS_YAML.yaml to OpenMC_SS_YAML.yaml
anu1217 Dec 5, 2024
c274709
Delete SphericalShell/OpenMC_Input/SphericalShell.py
anu1217 Dec 5, 2024
826f74c
Delete reference to YAML file
anu1217 Dec 6, 2024
50cc384
Update inputs and outputs to SS_Material.py
anu1217 Dec 13, 2024
8bfe889
Update SS_Source_Tallies_Model.py - assign particle filter to tallies
anu1217 Dec 13, 2024
aa53685
Update OpenMC_SS_YAML.yaml
anu1217 Dec 13, 2024
ad99831
Remove material volume assignment
anu1217 Dec 13, 2024
121b1e5
Update SS_Material.py
anu1217 Dec 13, 2024
a2bfe82
Add files via upload
anu1217 Dec 13, 2024
136ec2c
Update and rename SS_Depletion_PostProcessing.py to SphericalShell/Op…
anu1217 Dec 13, 2024
ce07336
Update and rename SS_Model_to_xml.py to SphericalShell/OpenMC_Input/S…
anu1217 Dec 13, 2024
1c0ba75
Update and rename SS_Post_Processing_YAML.yaml to SphericalShell/Open…
anu1217 Dec 13, 2024
de55c19
Update and rename SS_Run_Depletion.py to SphericalShell/OpenMC_Input/…
anu1217 Dec 13, 2024
96e7417
Update and rename SS_Run_Depletion.py to SS_Run_Depletion.py
anu1217 Dec 13, 2024
1344136
Update and rename SS_Tally_PostProcessing.py to SphericalShell/OpenMC…
anu1217 Dec 13, 2024
136a761
Update and rename SS_all_PostProcessing.py to SphericalShell/OpenMC_O…
anu1217 Dec 13, 2024
8fe0d17
Update SphericalShell/OpenMC_Input/SS_Model_to_xml.py
anu1217 Dec 15, 2024
ad28c6a
Update SphericalShell/OpenMC_Input/SS_Model_to_xml.py
anu1217 Dec 15, 2024
ae9f9f6
Compile helper functions using main function
anu1217 Dec 15, 2024
27f8b62
Change function names to make_settings and make_tallies
anu1217 Dec 15, 2024
de7ef12
Compile helper functions using main function
anu1217 Dec 15, 2024
51d86fa
Compile post-processing scripts into main()
anu1217 Dec 23, 2024
795a83b
Delete SphericalShell/OpenMC_Input/OpenMC_Depletion/SS_Run_Depletion.py
anu1217 Dec 23, 2024
87b1d05
Update SS_Tally_PostProcessing.py
anu1217 Dec 23, 2024
25ef83b
Update SS_Depletion_PostProcessing.py
anu1217 Dec 23, 2024
0923847
Initiate depletion from main() function
anu1217 Dec 23, 2024
cbfe285
Remove commented line
anu1217 Dec 23, 2024
84df5ba
Add model.xml as input
anu1217 Dec 23, 2024
724e870
Remove returned variables
anu1217 Dec 23, 2024
eba557d
Update SphericalShell/OpenMC_Output_Processing/SS_Depletion_PostProce…
anu1217 Dec 24, 2024
dc0e796
Change nuclide_array to nuclide_set
anu1217 Dec 24, 2024
62f7232
Rename make_element as make_materials
anu1217 Dec 24, 2024
a4ebe46
Rename element as materials & update references
anu1217 Dec 24, 2024
26e2e02
Change output of make_source
anu1217 Dec 24, 2024
144e90b
Update SphericalShell/OpenMC_Input/OpenMC_Model/SS_Source_Tallies_Mod…
anu1217 Dec 24, 2024
c3a4fb2
Remove volume calculation from make_materials
anu1217 Dec 24, 2024
e86672f
Calculate volume of depletable material
anu1217 Dec 24, 2024
f7bce21
Update SphericalShell/OpenMC_Input/SS_Model_to_xml.py
anu1217 Dec 24, 2024
0891158
Break main() up into smaller functions
anu1217 Dec 24, 2024
ba5f199
Remove create_openmc_model()
anu1217 Dec 24, 2024
d0f8db0
Apply suggestions from code review
anu1217 Dec 24, 2024
80b36db
Fix indentation and plot_flux_spectrum input
anu1217 Dec 25, 2024
6cc6b12
Break main() function up into smaller functions
anu1217 Dec 25, 2024
2e921fe
Add nested functions inside main()
anu1217 Dec 25, 2024
fd19ab1
Update SS_Depletion.py
anu1217 Dec 25, 2024
0ef732e
Update SS_Material.py docstring
anu1217 Jan 10, 2025
192ba37
Update SS_all_PostProcessing.py
anu1217 Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions SphericalShell/OpenMC_Input/OpenMC_Depletion/SS_Depletion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import openmc
import openmc.deplete
import numpy as np
import argparse
import yaml

def deplete_ss(chain_file_path, model, inner_radius, thickness, times_post_boc, particle_source_rates, norm_mode, timestep_units):
material = model.materials[0]
chain_file = chain_file_path
material.depletable = True
timesteps = times_post_boc
source_rates = particle_source_rates
operator = openmc.deplete.CoupledOperator(model, chain_file, normalization_mode = norm_mode)
integrator = openmc.deplete.PredictorIntegrator(operator, timesteps, source_rates = source_rates, timestep_units = timestep_units)
integrator.integrate()
return integrator

def main():
parser = argparse.ArgumentParser()
parser.add_argument('--yaml_filepath', default = 'OpenMC_SS_YAML.yaml', help="Path to YAML file containing required inputs (str)")
args = parser.parse_args()
yaml_filepath = args.yaml_filepath
with open(yaml_filepath, 'r') as yaml_dep:
dep_inputs = yaml.safe_load(yaml_dep)
geom_info = dep_inputs['geom_info']
dep_params = dep_inputs['depletion_params']

chain_file_path = dep_params['chain_file']
model_file = dep_params['model_file']
model = openmc.model.Model.from_model_xml(path=model_file)
inner_radius = geom_info['inner_radius']
thickness = geom_info['thickness']
times_post_boc = dep_params['times_post_boc']
particle_source_rates = dep_params['source_rates']
norm_mode = dep_params['norm_mode']
timestep_units = dep_params['timestep_units']

dss = deplete_ss(chain_file_path, model, inner_radius, thickness, times_post_boc, particle_source_rates, norm_mode, timestep_units)
dss.integrate()

if __name__ == "__main__":
main()
22 changes: 22 additions & 0 deletions SphericalShell/OpenMC_Input/OpenMC_Model/SS_Geometry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import openmc

def make_spherical_shell(material, thickness, inner_radius):
'''
Creates a spherical shell with its own material and inner/outer radius.

inputs:
material: OpenMC Material object/iterable of OpenMC Material
thickness: radial thickness (float) of material
inner_radius : inner radius of material

outputs:
geometry: OpenMC Geometry object
'''
inner_sphere = openmc.Sphere(r = inner_radius)
cells = [openmc.Cell(fill = None, region = -inner_sphere)]
outer_radius = inner_radius + thickness
outer_sphere = openmc.Sphere(r = outer_radius, boundary_type = 'vacuum')
cells.append(openmc.Cell(fill = material, region = +inner_sphere & -outer_sphere))
cells.append(openmc.Cell(fill = None, region = +outer_sphere))
geometry = openmc.Geometry(cells)
return geometry
40 changes: 40 additions & 0 deletions SphericalShell/OpenMC_Input/OpenMC_Model/SS_Material.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import openmc
import numpy as np

def alara_element_densities(elelib_fp):
'''
Create a dictionary of element names and their corresponding densities using the ALARA element library.

inputs:
filepath: path to file containing ALARA element library (str)

'''
with open(elelib_fp) as ALARA_Lib:
libLines = ALARA_Lib.readlines()
num_lines = len(libLines)
density_dict = {}
line_num = 0
while line_num < num_lines:
element_data = libLines[line_num].strip().split()
element_name = element_data[0].lower()
density_dict[element_name] = float(element_data[3])
line_num += int(element_data[4]) + 1
return density_dict

def make_element(element, density_dict, inner_radius, thickness):
'''
inputs:
element: elemental symbol of chosen element (str)
density_dict: dictionary with key = elemental symbol & value = density [g/cm^3]
Copy link
Member

Choose a reason for hiding this comment

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

Your docstring doesn't include the geometry info.... but I wonder if that should be done elsewhere. I am guessing this is only necessary for the depletion/activation calculation. Should we do it in a different way to keep the separation of concerns of just making a new material?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The volume is used for depletion and during post-processing, where flux data is normalized by volume. Calculating the volume separately for both of these might be best for separation of concerns...I think I was trying to avoid having to import the thickness/radius on each occasion


outputs:
mats : OpenMC Materials object
volume : volume (float) of material in cm3
'''
mat = openmc.Material(material_id=1, name=element)
mat.add_element(element, 1.00)
mat.set_density('g/cm3', density_dict.get(element.lower()))
volume = 4.0/3.0 * np.pi * ((inner_radius+thickness)**3 - inner_radius**3)
mat.volume = volume
mats = openmc.Materials([mat])
return mats, volume
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import openmc

def make_source(energy):
anu1217 marked this conversation as resolved.
Show resolved Hide resolved
point_source = openmc.stats.Point(xyz=(0.0, 0.0, 0.0))
energy_dist = openmc.stats.Discrete(energy, 1.0)
return point_source, energy_dist

def make_settings(point_source, energy_dist, total_batches, inactive_batches, num_particles, run_mode):
sets = openmc.Settings()
sets.batches = total_batches
sets.inactive = inactive_batches
sets.particles = num_particles
sets.source = openmc.Source(space = point_source, energy = energy_dist, strength = 1.0, particle = 'neutron')
sets.run_mode = run_mode
return sets

def make_tallies(tallied_cells):
particle_filter = openmc.ParticleFilter('neutron')
cell_filter = openmc.CellFilter(tallied_cells)
energy_filter_flux = openmc.EnergyFilter.from_group_structure("VITAMIN-J-175")

neutron_tally = openmc.Tally(name="Neutron tally")
neutron_tally.scores = ['flux', 'elastic', 'absorption']
neutron_tally.filters = [cell_filter, particle_filter]

spectrum_tally = openmc.Tally(name="Neutron flux spectrum")
spectrum_tally.filters = [energy_filter_flux, cell_filter, particle_filter]
spectrum_tally.scores = ['flux']

talls = openmc.Tallies([neutron_tally, spectrum_tally])
return talls
anu1217 marked this conversation as resolved.
Show resolved Hide resolved

def create_openmc_model(mats_object, geom_object, tallies_object, settings_object):
Copy link
Member

Choose a reason for hiding this comment

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

Not sure this needs its own method since it does nothing other than what the openmc method already does

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would it be better to make this model object in SS_Model_to_xml instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The Model object is now being made in SS_Model_to_xml

model = openmc.model.Model(geometry = geom_object, materials = mats_object, settings = settings_object, tallies = tallies_object)
return model
29 changes: 29 additions & 0 deletions SphericalShell/OpenMC_Input/OpenMC_SS_YAML.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
elelib_fp : elelib.std
element : W

geom_info :
thickness : 5
inner_radius : 1000
outer_boundary_type : vacuum

particle_energy : 14.0E+06

settings_info :
total_batches : 10
inactive_batches : 1
num_particles : 10000
run_mode : fixed source

depletion_params :
chain_file : chain_endfb71_sfr.xml
model_file : model.xml
times_post_boc : #sequence of timesteps following the beginning of operation (not cumulative)
- 3.0E+8
- 86400
- 2.6E+6
source_rates :
- 1.0E+18
- 0
- 0
norm_mode : source_rate
timestep_units : s
170 changes: 0 additions & 170 deletions SphericalShell/OpenMC_Input/SS_Activation_OpenMC.py

This file was deleted.

41 changes: 41 additions & 0 deletions SphericalShell/OpenMC_Input/SS_Model_to_xml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import openmc
import yaml
import argparse
from OpenMC_SS_Material import alara_element_densities, make_element
from OpenMC_SS_Geometry import make_spherical_shell
from OpenMC_Source_Tallies_Model import make_source, settings, tallies, create_openmc_model

def main():
Copy link
Member

Choose a reason for hiding this comment

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

For separation of concerns, you might think of a main function that was:

def main():
    args = parse_args() # this is a short method comprised of your first 3 lines

    input_data = read_yaml(args[yaml_filepath])  # this is a short method comprised of the next 3 lines

    model = build_model(input_data)  # this is a method that holds most of your code

    model.export_to_model_xml()

Although testing may not seem critical, this means that you can easily test that build_model() does what you want with a given input_data dictionary without having to make a YAML input file for each variation.

parser = argparse.ArgumentParser()
parser.add_argument('--yaml_filepath', required=True, help="Path to YAML file containing required inputs (str)")
args = parser.parse_args()
Copy link
Member

Choose a reason for hiding this comment

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

Its common to put these in a different function for separation of concerns. By separating file input in its different forms from action it helps make testing a little simpler.

yaml_filepath = args.yaml_filepath
with open(yaml_filepath, 'r') as file:
inputs = yaml.safe_load(file)
Copy link
Member

Choose a reason for hiding this comment

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

These lines might also go in a separate method for separation of concerns.

geometry = inputs['geom_info']
settings_info = inputs['settings_info']
# for OpenMC_SS_Material
aed = alara_element_densities(inputs['elelib_fp'])
element = make_element(inputs['element'],
anu1217 marked this conversation as resolved.
Show resolved Hide resolved
aed,
geometry['inner_radius'],
geometry['thickness'])
# for OpenMC_SS_Geometry
mss = make_spherical_shell(element[0][0],
anu1217 marked this conversation as resolved.
Show resolved Hide resolved
geometry['thickness'],
geometry['inner_radius'])
# for OpenMC_Source_Tallies_Model
ms = make_source(inputs['particle_energy'])
anu1217 marked this conversation as resolved.
Show resolved Hide resolved
sets = make_settings(ms[0], ms[1],
settings_info['total_batches'],
settings_info['inactive_batches'],
settings_info['num_particles'],
settings_info['run_mode'])
# tallied cells = all cells with non-void material
tallied_cells = list(mss.get_all_material_cells().values())
talls = make_tallies(tallied_cells)
com = create_openmc_model(element[0], mss, talls, sets)
Copy link
Member

Choose a reason for hiding this comment

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

I recommend just calling this model (and probably just calling the openmc function directly - see related comment)

Suggested change
com = create_openmc_model(element[0], mss, talls, sets)
model = create_openmc_model(element[0], mss, talls, sets)

com.export_to_model_xml()

if __name__ == "__main__":
main()
Loading