-
Notifications
You must be signed in to change notification settings - Fork 8
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
Latin Hypercube Neutronic Sampling #10
base: main
Are you sure you want to change the base?
Changes from 31 commits
5352233
b1f3e4e
5fb7b85
f995797
a9ca809
f6797df
71d51d4
30bba7e
d89deca
b0e8814
786c062
50be3ad
a44887c
abe77b5
ebb7296
2e17eb6
677fa4e
2f53046
667a118
1a5e34a
39216a6
d0101a6
162d809
47cfb2a
88839e8
e2d25cb
a860836
2f3ac24
0d1e51e
c3f6ffc
22d0077
4e511cd
4681c38
202f162
73d4418
7cd54b2
390aec9
49a450e
c73d6c7
af30af4
f0c4c66
82d4db7
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,147 @@ | ||
"""This module contains functions to sweep parameter-space, creating MCNP | ||
depletion inputs to calculate keff at EOL. | ||
* AR | ||
* core_z | ||
* cool_r | ||
* PD | ||
* power | ||
* enrich | ||
""" | ||
from pyDOE import lhs | ||
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. PEP8: missing blank line |
||
import os | ||
import glob | ||
import numpy as np | ||
import tarfile | ||
|
||
from mcnp_inputs import HomogeneousInput, build_pyne_matlib | ||
|
||
_dimensions = ['AR', 'core_r', 'cool_r', 'PD', 'power', 'enrich'] | ||
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. doctoring to explain what those variables are. |
||
|
||
# number of samples for each sampled dimension | ||
nsamples = 100 | ||
|
||
dims = {'core_r' : (20, 50), | ||
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. Shouldn't |
||
'AR' : (0.7, 1.3), | ||
'PD' : (1.4, 1.6), | ||
'enrich' : (0.3, 0.9), | ||
'cool_r' : 0.5, | ||
'power' : 150 | ||
} | ||
|
||
def get_sampling_params(): | ||
"""Decide which parameters are constants and which are ranges to be sampled. | ||
|
||
Returns: | ||
-------- | ||
sampled (list): list of keys for sampled parameters | ||
const (list): keys for constant parameters | ||
dim (float): length of sampled parameters for LHS sampling function. | ||
""" | ||
const = list(filter(lambda x: type(dims[x]) != tuple, dims.keys())) | ||
sampled = [x for x in dims.keys() if x not in const] | ||
|
||
dim = len(sampled) | ||
|
||
return sampled, const, dim | ||
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. why returning len(sampled) when you actually have sampled? |
||
|
||
|
||
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. 2 lines there |
||
def gen_hypercube(samples, N): | ||
"""Generate N-dimensional latin hypercube to sample dimensional reactor | ||
space. | ||
|
||
Arguments: | ||
---------- | ||
samples (int): number of test cases to try | ||
N (int): number of dimensions to test | ||
|
||
Returns: | ||
-------- | ||
cube (ndarray): normalized, N-D latin hypercube | ||
""" | ||
|
||
np.random.seed(4654562) | ||
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. why always the same seed ? 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. If I do the analysis again, I want to be able to generate the same input files. |
||
hypercube = lhs(N, samples=samples) | ||
|
||
return hypercube | ||
|
||
def fill_data_array(swept, const, cube): | ||
"""Fill an ndarray with the sampling set generated by lhs and bounded by the | ||
ranges provided for each sampled dimension. | ||
|
||
Arguments: | ||
---------- | ||
swept (list): keys for sampled dimensions | ||
const (list): keys for constant dimensions | ||
cube (ndarray): latin hypercube | ||
|
||
Returns: | ||
-------- | ||
rxt_confs (ndarray): array of data for every reactor configuration. This | ||
data is used to build MCNP6 input files. | ||
""" | ||
# initialize array | ||
rxt_confs = np.zeros(nsamples, dtype={'names' : list(dims.keys()), | ||
'formats' : ['f8']*len(dims)}) | ||
# for all samples in latin hypercube | ||
for sample_idx, sample in enumerate(cube): | ||
# set values for every sampled dimension | ||
for dim_idx, dim in enumerate(swept): | ||
# skip constants | ||
l_limit = dims[dim][0] | ||
u_limit = dims[dim][1] | ||
# uniform distribution | ||
a = u_limit - l_limit | ||
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. better variable name: |
||
b = l_limit | ||
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. why not just use |
||
# save to ndarray | ||
rxt_confs[sample_idx][dim] = b + cube[sample_idx][dim_idx] * a | ||
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. seems like there is probably a matrix-vector implementation of this? This won't work as is, but with a little thought on data structures, this whole inner loop can probably be replaced by something like this: |
||
# set constant value dimensions | ||
for dim in const: | ||
rxt_confs[sample_idx][dim] = dims[dim] | ||
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. What if you defined the upper and lower limit of these dimensions to be the same as each other and then used the same math as above? |
||
|
||
return rxt_confs | ||
|
||
def write_inputs(sampling_data): | ||
"""Write MCNP depletion inputs for each reactor configuration. | ||
|
||
Arguments: | ||
---------- | ||
sampling_data (ndarray): array of reactor configurations, one for each | ||
MCNP6 input file. | ||
""" | ||
# build PyNE material library | ||
pyne_mats = build_pyne_matlib() | ||
# initialize tarball to save input files | ||
tarputs = tarfile.open('smpl_mcnp_depl_inps.tar', 'w') | ||
# generate inputs | ||
for num, sample in enumerate(sampling_data): | ||
input = HomogeneousInput(sample['core_r'], | ||
sample['core_r']*sample['AR'], | ||
sample['power'], pyne_mats) | ||
homog_comp = input.homog_core(sample['enrich'], | ||
sample['cool_r'], | ||
sample['PD']) | ||
input.write_mat_string() | ||
|
||
# identifying header string for post-processing | ||
header_str = '' | ||
for param in _dimensions: | ||
header_str += str(round(sample[param], 5)) + ',' | ||
# write the input and tar it | ||
filename = input.write_input(num, header_str) | ||
tarputs.add(filename) | ||
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. It would be cleanest to delete the file as soon as possible after you add it to the tarfile. |
||
|
||
# write HTC input list | ||
htc_inputs = open('input_list.txt', 'w') | ||
htc_inputs.write('\n'.join(glob.glob("*.i"))) | ||
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. If this is the list of files you've just created, can't you generate it without a glob. Isn't it safer?
|
||
htc_inputs.close() | ||
|
||
tarputs.add('input_list.txt') | ||
tarputs.close() | ||
|
||
if __name__=='__main__': | ||
swept, const, dim = get_sampling_params() | ||
cube = gen_hypercube(nsamples, dim) | ||
data = fill_data_array(swept, const, cube) | ||
write_inputs(data) | ||
# cleanup | ||
os.system('rm *.i input_list.txt') | ||
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. There are modules to manipulate files without having to make https://stackoverflow.com/questions/6996603/how-to-delete-a-file-or-folder |
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.
Add arguments to docstring....
Not sure what
file_num
is: is it actually just a number? If so, then not sure about the filename below