Skip to content

Commit 7d32251

Browse files
committed
First commit
0 parents  commit 7d32251

File tree

3 files changed

+459
-0
lines changed

3 files changed

+459
-0
lines changed

config.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"mgga_settings" :
3+
{
4+
"seed": 1283123901319,
5+
"population": 1000,
6+
"generations": 20,
7+
"crossover_prob": 0.7,
8+
"mutation_prob": 0.2,
9+
"copy_prob": 0.1,
10+
"chromosome_length": 100,
11+
"num_of_states": 6,
12+
"percentage_worst": 0.25,
13+
"tornament_size": 5
14+
}
15+
}

make_geom.py

+318
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
"""
2+
This script builds a simple geometry
3+
"""
4+
5+
import argparse
6+
from math import log10
7+
from mgga import MGGA
8+
9+
import numpy as np
10+
import openmc
11+
12+
import sys
13+
import json
14+
15+
def add_element(element,material,fraction,fraction_type):
16+
to_add = openmc.Element(element)
17+
to_add = to_add.expand(fraction,fraction_type)
18+
19+
for nuclide in to_add:
20+
material.add_nuclide(nuclide[0],nuclide[1],percent_type=nuclide[2])
21+
22+
class openmc_problem():
23+
def __init__(self):
24+
self.materials = {}
25+
self.model = None
26+
self.num_x = 0
27+
self.num_y = 0
28+
self.x_bounds = []
29+
self.y_bounds = []
30+
self.x_planes = []
31+
self.y_planes = []
32+
self.cells = []
33+
self.tallies = {}
34+
35+
def setup(self, num_x, x_bounds, num_y, y_bounds):
36+
self.num_x = num_x
37+
self.num_y = num_y
38+
39+
self.x_bounds = np.linspace(x_bounds[0], x_bounds[1], num_x)
40+
self.y_bounds = np.linspace(y_bounds[0], y_bounds[1], num_y)
41+
42+
for i,x in enumerate(self.x_bounds):
43+
plane = openmc.XPlane(x0=x, name = 'xplane_' + str(i))
44+
self.x_planes.append(plane)
45+
46+
for i,y in enumerate(self.y_bounds):
47+
plane = openmc.YPlane(y0=y, name = 'yplane_' + str(i))
48+
self.y_planes.append(plane)
49+
50+
self.__build_model()
51+
52+
def __build_materials(self):
53+
breeder = openmc.Material(name='Lithium')
54+
breeder.set_density('g/cm3', 0.534)
55+
add_element('Li',breeder,100,'ao')
56+
self.materials[0] = breeder
57+
58+
multiplier = openmc.Material(name="Lead")
59+
multiplier.set_density('g/cm3', 12.3)
60+
add_element('Pb', multiplier, 100, 'ao')
61+
self.materials[1] = multiplier
62+
63+
be = openmc.Material(name="Beryllium")
64+
be.set_density('g/cm3', 1.85)
65+
add_element('Be', be, 100, 'ao')
66+
self.materials[2] = be
67+
68+
lithium6 = openmc.Material(name="lithium-6")
69+
lithium6.set_density('g/cm3', 0.534)
70+
lithium6.add_nuclide('Li6',100,'ao')
71+
self.materials[3] = lithium6
72+
73+
lithium7 = openmc.Material(name="lithium-7")
74+
lithium7.set_density('g/cm3', 0.534)
75+
lithium7.add_nuclide('Li7',100,'ao')
76+
self.materials[4] = lithium7
77+
78+
bismuth = openmc.Material(name="Bismuth")
79+
bismuth.set_density('g/cm3', 9.747)
80+
add_element('Bi',bismuth,100,'ao')
81+
self.materials[5] = bismuth
82+
83+
def __build_tallies(self, flux_cells, tbr_cells):
84+
85+
neutron_filter = openmc.ParticleFilter('neutron', filter_id=1)
86+
cell_filter = openmc.CellFilter(flux_cells, filter_id=2)
87+
tbr_cell_filter = openmc.CellFilter(tbr_cells, filter_id=3)
88+
89+
tbr_tally = openmc.Tally(tally_id = 1, name="tbr")
90+
tbr_tally.scores = ['(n,t)']
91+
tbr_tally.estimator = 'tracklength'
92+
tbr_tally.filters = [tbr_cell_filter, neutron_filter]
93+
94+
flux_tally = openmc.Tally(tally_id = 2, name="flux")
95+
flux_tally.scores = ['flux']
96+
flux_tally.estimator = 'tracklength'
97+
flux_tally.filters = [cell_filter, neutron_filter]
98+
flux_tally.triggers = [openmc.Trigger('rel_err',0.05)]
99+
flux_tally.triggers[0].scores = ['flux']
100+
101+
tallies = openmc.Tallies([tbr_tally,flux_tally])
102+
self.model.tallies = tallies
103+
104+
# generate the fitness for the current generation and
105+
# index
106+
def generate_fitness(self, directory, sp_name = "statepoint.10.h5"):
107+
sp = openmc.StatePoint(directory + '/' + sp_name)
108+
tbr = sp.get_tally(name = 'tbr')
109+
cells = []
110+
[cells.append(x.id) for x in self.cells]
111+
tbr_data = tbr.get_slice(scores=['(n,t)'],filters=[openmc.CellFilter], filter_bins = [tuple(cells)])
112+
tbr_ave = tbr_data.mean
113+
114+
# maximise tbr
115+
fitness = sum(tbr_ave)[0][0]
116+
sp.close()
117+
return fitness
118+
119+
def assign_genome(self, genome):
120+
idx = 0
121+
for x in range(self.num_x-1):
122+
for y in range(self.num_y-1):
123+
# set the material given the position in genome
124+
mat = self.materials[genome[idx]]
125+
self.cells[idx].fill = mat
126+
idx = idx + 1
127+
128+
# given the genome build the region of geometry
129+
# to optimise
130+
def build_geometry(self):
131+
132+
univ = openmc.Universe(name='optimisation')
133+
cells = []
134+
idx = 0
135+
for x in range(self.num_x-1):
136+
for y in range(self.num_y-1):
137+
# set the material given the position in genome
138+
#mat = self.materials[genome[idx]]
139+
cell = openmc.Cell(region = +self.x_planes[x] & -self.x_planes[x+1] & +self.y_planes[y] & -self.y_planes[y+1])
140+
cells.append(cell)
141+
# increment index
142+
idx = idx + 1
143+
144+
univ.add_cells(cells)
145+
146+
self.cells = cells
147+
148+
# tally the cells in the last x row
149+
tally_cells = cells[-self.num_y:]
150+
151+
self.__build_tallies(tally_cells, cells)
152+
153+
return univ
154+
155+
# run specific settings
156+
def __set_settings(self):
157+
self.model.settings.run_mode = 'fixed source'
158+
self.model.settings.batches = 10
159+
self.model.settings.particles = 100000
160+
161+
# make the source spatial dist
162+
x_dist = openmc.stats.Discrete([0.0],[1.0])
163+
y_dist = openmc.stats.Uniform(a=self.y_planes[0].y0, b=self.y_planes[-1].y0)
164+
z_dist = openmc.stats.Discrete([0.0],[1.0])
165+
spatial = openmc.stats.multivariate.CartesianIndependent(x_dist, y_dist, z_dist)
166+
# make the angular dist
167+
angle_dist = openmc.stats.Monodirectional(reference_uvw = [1,0,0])
168+
# make the energy dist
169+
energy_dist = openmc.stats.Discrete([14.06e6],[1.0])
170+
source = openmc.Source(space = spatial, angle = angle_dist, energy = energy_dist)
171+
self.model.settings.source = source
172+
173+
# main build function
174+
def __build_model(self):
175+
176+
self.model = openmc.model.Model()
177+
178+
self.__build_materials()
179+
180+
# build the region to optimise
181+
optimisation = self.build_geometry()
182+
183+
# Create a cell filled with the lattice
184+
inside_boundary = -self.y_planes[-1] & +self.y_planes[0] & -self.x_planes[-1] & +self.x_planes[0]
185+
outside_boundary = +self.y_planes[-1] | -self.y_planes[0] | +self.x_planes[-1] | -self.x_planes[0]
186+
main_cell = openmc.Cell(fill=optimisation, region=inside_boundary)
187+
eou = openmc.Cell(region = outside_boundary)
188+
# Finally, create geometry by providing a list of cells that fill the root
189+
# universe
190+
self.model.geometry = openmc.Geometry([main_cell,eou])
191+
192+
self.x_planes[0].boundary_type = 'vacuum'
193+
self.x_planes[-1].boundary_type = 'vacuum'
194+
195+
self.y_planes[0].boundary_type = 'vacuum'
196+
self.y_planes[-1].boundary_type = 'vacuum'
197+
198+
self.__set_settings()
199+
200+
# using slurm array job build description
201+
def build_slurm(generation):
202+
contents = []
203+
contents.append('#!/bin/bash')
204+
contents.append('#')
205+
contents.append('#SBATCH --job-name=mgga')
206+
contents.append('#SBATCH -A UKAEA-AP001-CPU')
207+
contents.append('#SBATCH -p cclake')
208+
contents.append('#SBATCH --nodes=1')
209+
contents.append('#SBATCH --ntasks=56')
210+
contents.append('#SBATCH --time=36:00:00')
211+
contents.append('#SBATCH --output=array_%A-%a.out')
212+
contents.append('#SBATCH --array=1-1000')
213+
contents.append(' ')
214+
contents.append('module purge')
215+
contents.append('module load rhel7/default-ccl')
216+
contents.append('module load openmpi/gcc/9.2/4.0.1')
217+
contents.append(' ')
218+
contents.append('cd $WORKDIR')
219+
contents.append('# IDX should match the folders inside generation')
220+
contents.append('IDX=$(($SLURM_ARRAY_TASK_ID - 1))')
221+
contents.append('cd ' + str(generation) + '/$IDX')
222+
contents.append('export OPENMC_CROSS_SECTIONS=/home/dc-davi4/openmc-data/fendl-3.1d-hdf5/cross_sections.xml')
223+
contents.append('openmc')
224+
contents.append('cd ..')
225+
226+
with open('mgga_openmc.slurm','w') as f:
227+
f.writelines(s + '\n' for s in contents)
228+
229+
def write_population(population, generation):
230+
data = {"population": [population]}
231+
json_string = json.dumps(data)
232+
jsonfile = open("population_" + str(generation) + ".json",'w')
233+
jsonfile.write(json_string)
234+
jsonfile.close()
235+
236+
def read_population(generation):
237+
data = None
238+
239+
fileObject = open("population_" + str(generation) + ".json", "r")
240+
jsonContent = fileObject.read()
241+
data = json.loads(jsonContent)
242+
return data["population"][0]
243+
244+
if __name__ == '__main__':
245+
246+
# Set up command-line arguments for generating/running the model
247+
parser = argparse.ArgumentParser()
248+
parser.add_argument('--generate')
249+
parser.add_argument('--run', action='store_true')
250+
parser.add_argument('--initialise', action='store_true')
251+
parser.add_argument('--input')
252+
args = parser.parse_args()
253+
# MGGA class
254+
mgga = MGGA()
255+
256+
if args.input:
257+
f = open(args.input)
258+
data = json.load(f)
259+
mgga.seed = data["mgga_settings"]["seed"]
260+
mgga.population_size = data["mgga_settings"]["population"]
261+
mgga.generations = data["mgga_settings"]["generations"]
262+
mgga.crossover_prob = data["mgga_settings"]["crossover_prob"]
263+
mgga.mutation_prob = data["mgga_settings"]["mutation_prob"]
264+
mgga.copy_prob = data["mgga_settings"]["copy_prob"]
265+
mgga.chromosome_length = data["mgga_settings"]["chromosome_length"]
266+
mgga.num_genes = data["mgga_settings"]["num_of_states"]
267+
mgga.percentage_worst = data["mgga_settings"]["percentage_worst"]
268+
mgga.tornament_size = data["mgga_settings"]["tornament_size"]
269+
mgga.initialise()
270+
f.close()
271+
else:
272+
print('No input specified, use --input')
273+
sys.exit()
274+
275+
# initialise the first generation
276+
if args.initialise:
277+
mgga.fill_population()
278+
openmc_problem = openmc_problem()
279+
openmc_problem.setup(10,[0,100],10,[0,200])
280+
for idx,i in enumerate(mgga.population):
281+
openmc_problem.assign_genome(i)
282+
openmc_problem.model.export_to_xml(directory='0/'+str(idx))
283+
build_slurm(0)
284+
write_population(mgga.population, 0)
285+
286+
# need to write a filename dependent population file!!
287+
288+
# generate the next generation
289+
if args.generate:
290+
generation = int(args.generate)
291+
population = read_population(generation-1)
292+
mgga.population = population
293+
genomes = mgga.population
294+
openmc_problem = openmc_problem()
295+
openmc_problem.setup(10,[0,100],10,[0,200])
296+
# loop over each of the genomes
297+
fitness = []
298+
for idx,i in enumerate(genomes):
299+
# folder for the current problem
300+
directory = str(generation-1) + '/' + str(idx)
301+
fit = openmc_problem.generate_fitness(directory)
302+
fitness.append(fit)
303+
# set the fitness
304+
mgga.fitness = fitness
305+
print('max fitness: ' + str(max(fitness)))
306+
print('min fitness: ' + str(min(fitness)))
307+
308+
mgga.sample_population()
309+
for idx,i in enumerate(mgga.children):
310+
openmc_problem.assign_genome(i)
311+
openmc_problem.model.export_to_xml(directory=str(generation) + '/'+str(idx))
312+
write_population(mgga.children,generation)
313+
314+
"""
315+
# translate to a higher resolution
316+
if args.translate:
317+
genomes = mgga.population
318+
"""

0 commit comments

Comments
 (0)