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

Update defaults #15

Merged
merged 30 commits into from
Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 26 additions & 0 deletions examples/critical-sphere/critical_sphere.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import openmc
import numpy as np

pu = openmc.Material()
pu.set_density("g/cm3", 19.84)
pu.add_nuclide("Pu239", 1)
mats = openmc.Materials([pu])

radius = {{radius}}

fuel_sphere = openmc.Sphere(r=radius, boundary_type='vacuum')
fuel_cell = openmc.Cell(fill=pu, region=-fuel_sphere)
univ = openmc.Universe(cells=[fuel_cell])
geom = openmc.Geometry(univ)

settings = openmc.Settings()
settings.batches = 100
settings.inactive = 20
settings.particles = 20000
settings.temperature = {"multipole": True, "method": "interpolation"}


mats.export_to_xml()
geom.export_to_xml()
settings.export_to_xml()
openmc.run()
Binary file not shown.
124 changes: 124 additions & 0 deletions examples/critical-sphere/critical_sphere_results_analysis.ipynb

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions examples/critical-sphere/rollo_critical_sphere.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"control_variables": {
"radius": {"min": 1.0, "max": 8.0}
},
"evaluators": {
"openmc": {
"input_script": "critical_sphere.py",
"inputs": ["radius"],
"outputs": ["keff", "radius"],
"keep_files": false
}
},
"constraints": {"keff": {"operator": [">="], "constrained_val": [1.0]}},
"algorithm": {
"parallel": "multiprocessing",
"objective": ["min"],
"optimized_variable": ["radius"],
"pop_size": 80,
"generations": 10,
"mutation_probability": 0.23,
"mating_probability": 0.46,
"selection_operator": {"operator": "selTournament", "inds": 15, "tournsize": 5},
"mutation_operator": {
"operator": "mutPolynomialBounded",
"eta": 0.23,
"indpb": 0.23
},
"mating_operator": {"operator": "cxBlend", "alpha": 0.46}
}
}
15 changes: 2 additions & 13 deletions examples/fhr-slab/rollo_input.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"evaluators": {
"openmc": {
"input_script": "openmcinp.py",
"input_script": "openmc_input.py",
"inputs": ["sine_a", "sine_b", "sine_c"],
"outputs": ["keff"],
"keep_files": false
Expand All @@ -16,17 +16,6 @@
"algorithm": {
"parallel": "multiprocessing",
"objective": ["max"],
"optimized_variable": ["keff"],
"pop_size": 4,
"generations": 10,
"mutation_probability": 0.2374127402121101,
"mating_probability": 0.4699131568275016,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain these deletions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

From this PR, ROLLO will add default values for these parameters.

"selection_operator": {"operator": "selTournament", "inds": 1, "tournsize": 5},
"mutation_operator": {
"operator": "mutPolynomialBounded",
"eta": 0.2374127402121101,
"indpb": 0.2374127402121101
},
"mating_operator": {"operator": "cxBlend", "alpha": 0.4699131568275016}
"optimized_variable": ["keff"]
}
}
3 changes: 2 additions & 1 deletion rollo/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ def execute(self):
t0 = time.time()
input_dict = self.read_input_file()
iv = InputValidation(input_dict)
iv.add_all_defaults()
iv.validate()
complete_input_dict = iv.add_all_defaults(input_dict)
complete_input_dict = iv.input
# organize control variables and output dict
control_dict, output_dict = self.organize_input_output(complete_input_dict)
# generate evaluator function
Expand Down
87 changes: 50 additions & 37 deletions rollo/input_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

class InputValidation:
"""The InputValidation class contains methods to read and validate the JSON
ROLLO input file to ensure the user defined all key parameters. If the user
did not, ROLLO raises an exception to tell the user which parameters are
missing.
ROLLO input file to ensure the user defined all key parameters. If the
user did not, ROLLO raises an exception to tell the user which
parameters are missing.

Attributes
----------
Copy link
Contributor

Choose a reason for hiding this comment

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

Naming the variable for this class as input could be confusing for folks reading the documentation. Consider adding a quantifier to differentiate this variable from the general concept of an input. Off the top of my head, rollo_input seems like it could be a good option.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll address this in #20

Expand All @@ -18,8 +18,8 @@ class InputValidation:
def __init__(self, input_dict):
self.input = input_dict

def add_all_defaults(self, input_dict):
""" Goes through the entire input_dict and adds default inputs if they
def add_all_defaults(self):
"""Goes through the entire input_dict and adds default inputs if they
are missing from the input_dict

Parameters
Expand All @@ -33,6 +33,7 @@ def add_all_defaults(self, input_dict):
input file dict with additional missing default inputs

"""
input_dict = self.input.copy()
Copy link
Contributor

Choose a reason for hiding this comment

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

If you go ahead and rename the class variable input, perhaps think about if you need to change the variable name for input_dict as well. That would go for all the other files that also use input_dict. I personally don't think this change is strictly necessary, but maybe you'll find it useful.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll address this in #20

input_evaluators = {}
for solver in input_dict["evaluators"]:
input_evaluators[solver] = input_dict["evaluators"][solver]
Expand All @@ -41,26 +42,37 @@ def add_all_defaults(self, input_dict):
)
input_algorithm = input_dict["algorithm"]
input_algorithm = self.default_check(input_algorithm, "objective", "min")
input_algorithm = self.default_check(input_algorithm, "pop_size", 100)
input_algorithm = self.default_check(input_algorithm, "pop_size", 60)
input_algorithm = self.default_check(input_algorithm, "generations", 10)
input_algorithm = self.default_check(
input_algorithm, "selection_operator", {"operator": "selBest", "inds": 1}
input_algorithm, "mutation_probability", 0.23
Copy link
Contributor

Choose a reason for hiding this comment

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

Sanity check: You're adding more checks for the input file, yes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What do you mean? All the checks are in the input_validation.py file.

)
input_algorithm = self.default_check(
input_algorithm, "mating_probability", 0.47
)
input_algorithm = self.default_check(
input_algorithm,
"selection_operator",
{"operator": "selTournament", "inds": 15, "tournsize": 5},
)
input_algorithm = self.default_check(
input_algorithm,
"mutation_operator",
{"operator": "mutGaussian", "indpb": 0.5, "mu": 0.5, "sigma": 0.5},
{"operator": "mutPolynomialBounded", "eta": 0.23, "indpb": 0.23},
)
input_algorithm = self.default_check(
input_algorithm, "mating_operator", {"operator": "cxOnePoint"}
input_algorithm,
"mating_operator",
{"operator": "cxBlend", "alpha": 0.46},
)
reloaded_input_dict = input_dict.copy()
reloaded_input_dict["evaluators"] = input_evaluators
reloaded_input_dict["algorithm"] = input_algorithm
return reloaded_input_dict
self.input = reloaded_input_dict.copy()
return

def default_check(self, input_dict, variable, default_val):
"""Checks if a single variable is missing from a dict, and adds a
"""Checks if a single variable is missing from a dict, and adds a
default value if it is

Parameters
Expand Down Expand Up @@ -217,8 +229,8 @@ def validate_algorithm(self, input_algorithm, input_evaluators):
# k value cannot be larger than pop size
if input_algorithm["selection_operator"]["operator"] == "selTournament":
if (
input_algorithm["selection_operator"]["inds"] >
input_algorithm["pop_size"]
input_algorithm["selection_operator"]["inds"]
> input_algorithm["pop_size"]
):
raise Exception("Population size must be larger than inds.")
return
Expand Down Expand Up @@ -257,9 +269,9 @@ def validate_algorithm_operators(self, operator_type, input_algorithm):
op_op = op["operator"]
except KeyError:
print(
"<Input Validation Error> You must define an operator for the " +
operator_type +
"_operator"
"<Input Validation Error> You must define an operator for "
+ operator_type
+ "_operator"
)
raise
else:
Expand Down Expand Up @@ -461,11 +473,12 @@ def validate_evaluators(self, input_evaluators):
a = input_evaluators[evaluator]["output_script"]
except KeyError:
print(
"<Input Validation Error> You must define an output_script for evaluator: " +
evaluator +
" since the outputs: " +
str(which_strings) +
" are not inputs or pre-defined outputs."
"<Input Validation Error>"
Copy link
Contributor

Choose a reason for hiding this comment

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

Ooh yeah the way these plus signs are is much better :)

+ "You must define an output_script for evaluator: "
+ evaluator
+ " since the outputs: "
+ str(which_strings)
+ " are not inputs or pre-defined outputs."
)
raise
return
Expand Down Expand Up @@ -511,12 +524,12 @@ def validate_in_list(self, variable, accepted_variables, name):

"""
assert variable in accepted_variables, (
"<Input Validation Error> variable: " +
name +
", only accepts: " +
str(accepted_variables) +
" not variable: " +
variable
"<Input Validation Error> variable: "
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

+ name
+ ", only accepts: "
+ str(accepted_variables)
+ " not variable: "
+ variable
)
return

Expand Down Expand Up @@ -544,19 +557,19 @@ def validate_correct_keys(
a = dict_to_validate[key]
for key in dict_to_validate:
assert key in combined_key_names, (
"<Input Validation Error> Only " +
str(combined_key_names) +
" are accepted for " +
variable_type +
", not variable: " +
key
"<Input Validation Error> Only "
+ str(combined_key_names)
+ " are accepted for "
+ variable_type
+ ", not variable: "
+ key
)
except KeyError:
print(
"<Input Validation Error> " +
str(key_names) +
" variables must be defined for " +
variable_type
"<Input Validation Error> "
+ str(key_names)
+ " variables must be defined for "
+ variable_type
)
raise
except AssertionError as error:
Expand Down