-
Notifications
You must be signed in to change notification settings - Fork 2
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
base: main
Are you sure you want to change the base?
Changes from 54 commits
3e4b3ad
af78b20
4091d8a
e737ae4
f22bdfa
f9de25d
3922b2d
3ffca9e
799689b
cd6bb50
9d63d57
f580d7f
bb63601
f11cd2a
1df6e73
4011bd7
ce4526b
ed30a23
1cb6b94
cbeb7b2
9efebeb
dfd7bd5
583304c
3da5017
d86b3e5
30e30e2
c274709
826f74c
50cc384
8bfe889
aa53685
ad99831
121b1e5
a2bfe82
136ec2c
ce07336
1c0ba75
de55c19
96e7417
1344136
136a761
8fe0d17
ad28c6a
ae9f9f6
27f8b62
de7ef12
51d86fa
795a83b
87b1d05
25ef83b
0923847
cbfe285
84df5ba
724e870
eba557d
dc0e796
62f7232
a4ebe46
26e2e02
144e90b
c3a4fb2
e86672f
f7bce21
0891158
ba5f199
d0f8db0
80b36db
6cc6b12
2e921fe
fd19ab1
0ef732e
192ba37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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() |
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 |
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] | ||
|
||
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): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
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 |
This file was deleted.
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(): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
Although testing may not seem critical, this means that you can easily test that |
||||||
parser = argparse.ArgumentParser() | ||||||
parser.add_argument('--yaml_filepath', required=True, help="Path to YAML file containing required inputs (str)") | ||||||
args = parser.parse_args() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I recommend just calling this
Suggested change
|
||||||
com.export_to_model_xml() | ||||||
|
||||||
if __name__ == "__main__": | ||||||
main() |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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