Updated BEAVRS to work with MPI. Fixed errors in 'RectangularPrism' conversion

This commit is contained in:
Adam Parler 2024-02-02 01:06:22 -08:00
parent ff50c1f1d2
commit 06300aefe3
9 changed files with 246 additions and 156 deletions

View file

@ -49,7 +49,7 @@ class Assemblies(object):
# Rectangular prism around the edge of the pinlattice
self.lattice_surfs = \
openmc.model.rectangular_prism(17*c.pinPitch, 17*c.pinPitch)
openmc.model.RectangularPrism(17*c.pinPitch, 17*c.pinPitch)
def _add_assembly_surfs(self,c):
@ -57,7 +57,7 @@ class Assemblies(object):
# Rectangular prism around the edge of the pinlattice
self.assem_surfs = \
openmc.model.rectangular_prism(c.latticePitch, c.latticePitch)
openmc.model.RectangularPrism(c.latticePitch, c.latticePitch)
def _add_bpra_layouts(self):

View file

@ -23,12 +23,12 @@ warnings.simplefilter('once', DeprecationWarning)
class BEAVRS(object):
""" Main BEAVRS class"""
def __init__(self, S=None, SS=None, boron_ppm=None, is_symmetric=False, is_2d=False):
def __init__(self, rank, S:int=-3, SS:int=-3, boron_ppm:float=-3.1, is_symmetric:bool=False, is_2d=False):
""" We build the entire geometry in memory in the constructor """
self.c = Constants(S,SS)
self.c = Constants(rank,S,SS)
if boron_ppm == None:
if boron_ppm < 0:
boron_ppm = self.c.nominalBoronPPM
self.is_symmetric = is_symmetric
@ -113,17 +113,19 @@ class BEAVRS(object):
self.depletion_nuclides = nuclides
def set_boron_ppm(self, ppm):
self.mats = openmc_materials(ppm=ppm)
self.mats = openmc_materials(self.c, ppm=ppm)
def write_openmc_geometry(self):
self.openmc_geometry.export_to_xml()
def write_openmc_geometry(self, rank):
if rank == 0:
self.openmc_geometry.export_to_xml()
@property
def materials(self):
return openmc.Materials(self.mats.values())
def write_openmc_materials(self):
self.materials.export_to_xml()
def write_openmc_materials(self, rank):
if rank == 0:
self.materials.export_to_xml()
@property
def plots(self):
@ -131,14 +133,16 @@ class BEAVRS(object):
plot_file = openmc.Plots(plots.plots)
return plot_file
def write_openmc_plots(self):
self.plots.export_to_xml()
def write_openmc_plots(self, rank):
if rank == 0:
self.plots.export_to_xml()
@property
def settings(self):
settings_file = openmc.Settings()
settings_file.batches = self.settings_batches
settings_file.inactive = self.settings_inactive
# settings_file.verbosity = 6
settings_file.particles = self.settings_particles
settings_file.confidence_intervals = self.settings_confidence
if self.settings_volumes:
@ -151,7 +155,7 @@ class BEAVRS(object):
settings_file.dd_nodemap = self.dd_nodemap
settings_file.dd_allow_leakage = self.dd_truncate
settings_file.dd_count_interactions = self.dd_interactions
settings_file.source = openmc.Source(space=openmc.stats.Box(
settings_file.source = openmc.IndependentSource(space=openmc.stats.Box(
self.settings_sourcebox[:3], self.settings_sourcebox[3:]))
output = {'tallies': self.settings_output_tallies,
'summary': self.settings_summary}
@ -163,8 +167,9 @@ class BEAVRS(object):
settings_file.seed = np.random.randint(1e14, dtype=np.uint64)
return settings_file
def write_openmc_settings(self):
self.settings.export_to_xml()
def write_openmc_settings(self, rank):
if rank == 0:
self.settings.export_to_xml()
@property
def common_tallies(self):
@ -176,13 +181,14 @@ class BEAVRS(object):
tallies_file.append(tally)
return tallies_file
def write_openmc_tallies(self):
self.common_tallies.export_to_xml()
def write_openmc_tallies(self, rank):
if rank == 0:
self.common_tallies.export_to_xml()
def set_S(self,val):
def set_S(self,rank,val):
openmc.reset_auto_ids()
self.c.set_S(val)
self.c.set_S(rank,val)
self.pincells = Pincells(self.mats, self.c)
self.assemblies = Assemblies(self.pincells, self.mats, self.c)
@ -192,10 +198,10 @@ class BEAVRS(object):
self.openmc_geometry = openmc.Geometry(self.main_universe)
def set_SS(self,val):
def set_SS(self,rank,val):
openmc.reset_auto_ids()
self.c.set_SS(val)
self.c.set_SS(rank,val)
self.pincells = Pincells(self.mats, self.c)
self.assemblies = Assemblies(self.pincells, self.mats, self.c)
@ -211,10 +217,10 @@ class BEAVRS(object):
return model
def export_xml(self,as_model:bool=False):
if as_model:
def export_xml(self,rank, as_model:bool=False):
if as_model and rank == 0:
self.export_model().export_to_model_xml()
else:
elif rank == 0:
self.export_model().export_to_xml()
def set_volumes(self, samples:int=100000) -> None:
@ -354,8 +360,9 @@ class BEAVRS(object):
""" Adds 207 depletion nuclides to fuel materials
"""
for name,mat in self.mats.items():
if not name in ['Fuel 1.6%', 'Fuel 2.4%', 'Fuel 3.1%', 'Fuel 3.2%', 'Fuel 3.4%']: continue
for nme,mat in self.mats.items():
if not nme in ['Fuel 1.6%', 'Fuel 2.4%', 'Fuel 3.1%', 'Fuel 3.2%', 'Fuel 3.4%']:
continue
for nuc in self.depletion_nuclides:
if not nuc.name in mat._nuclides:
mat.add_nuclide(nuc, 1e-14)
mat.add_nuclide(nuc, 1e-14)

View file

@ -143,7 +143,7 @@ class Constants(object):
neutronShield_NEbot_SWtop = {'a': 1, 'b': math.tan(-math.pi/3 - math.pi/180), 'c': 0, 'd': 0}
neutronShield_NEtop_SWbot = {'a': 1, 'b': math.tan(-math.pi/6 + math.pi/180), 'c': 0, 'd': 0}
def __init__(self, S:int=15, SS:int=0) -> None:
def __init__(self, rank, S:int=15, SS:int=0) -> None:
self.first_thru = True
@ -153,28 +153,31 @@ class Constants(object):
self.rcca_banks = self.rcca_bank_steps_withdrawn.keys()
## Keff=1 at approximately S 298
self.set_S(S)
self.set_SS(SS)
self.set_S(rank, S)
self.set_SS(rank, SS)
self.update_dict()
def set_S(self, _S, print_data=True):
def set_S(self, rank, _S, print_data=True):
if isinstance(_S,(float,int)):
if _S < 0:
print("Cannot have a negative S position. S set to 0")
self._S = 0
if rank == 0:
print("Cannot have a negative S position. S set to 0")
elif _S > 573:
print("Cannot have a S position greater than 573. S set to 573")
self._S = 573
if rank == 0:
print("Cannot have a S position greater than 573. S set to 573")
else:
self._S = int(_S)
elif _S == None:
self._S = 15
print(f"Value supplied was 'None'. S Value set to default value of {self._S}")
if rank == 0:
print(f"Value supplied was 'None'. S Value set to default value of {self._S}")
else:
raise ValueError
if print_data and not self.first_thru:
if print_data and not self.first_thru and rank == 0:
print(" RCCA Positions")
print(f" A: {self._A:3d} B: {self._B:3d} C: {self._C:3d} D: {self._D:3d}")
print(f" SA: {self._SA:3d} SB: {self._SB:3d} SC: {self._SC:3d} SD: {self._SD:3d} SE: {self._SE:3d}")
@ -200,23 +203,26 @@ class Constants(object):
def _D(self):
return max(0,228-self._S)
def set_SS(self, _SS, print_data=True):
def set_SS(self, rank, _SS, print_data=True):
if isinstance(_SS,(float,int)):
if _SS < 0:
print("Cannot have a negative SS position. SS set to 0")
self._SS = 0
if rank == 0:
print("Cannot have a negative SS position. SS set to 0")
elif _SS > 228:
print("Cannot have a SS position greater than 228. SS set to 228")
self._SS = 228
if rank == 0:
print("Cannot have a SS position greater than 228. SS set to 228")
else:
self._SS = int(_SS)
elif _SS == None:
self._SS = 0
print(f"Value supplied was 'None'. SS Value set to default value of {self._SS}")
if rank == 0:
print(f"Value supplied was 'None'. SS Value set to default value of {self._SS}")
else:
raise ValueError
if print_data and not self.first_thru:
if print_data and not self.first_thru and rank == 0:
print(" RCCA Positions")
print(f" A: {self._A:3d} B: {self._B:3d} C: {self._C:3d} D: {self._D:3d}")
print(f" SA: {self._SA:3d} SB: {self._SB:3d} SC: {self._SC:3d} SD: {self._SD:3d} SE: {self._SE:3d}")

View file

@ -113,21 +113,10 @@ class InfinitePinCell(openmc.Universe):
if i == 0:
# this is the first ring
if box:
# this first ring is a box ring
cell = openmc.Cell(name=label, fill=fill)
cell.region = radius
if not rot is None: cell.rotation = rot
self.add_cell(cell)
else:
# this first ring is a regular cylinder
cell = openmc.Cell(name=label, fill=fill)
cell.region = -radius
if not rot is None: cell.rotation = rot
self.add_cell(cell)
cell = openmc.Cell(name=label, fill=fill)
cell.region = -radius
if not rot is None: cell.rotation = rot
self.add_cell(cell)
else:
# this is not the first ring
@ -174,7 +163,7 @@ class InfinitePinCell(openmc.Universe):
if self.box[-1]:
# the last one is a box, we need 4 outer cells to infinity
cell = openmc.Cell(name=label, fill=self.fills[-1])
cell.region = ~radius
cell.region = +radius
if not self.rot[-1] is None: cell.rotation = self.rot[-1]
self.add_cell(cell)
@ -251,13 +240,13 @@ class AxialPinCell(openmc.Universe):
current = self.outermost.radii[-1].coefficients['r']
else:
# current is a box
current = self.outermost.radii[-1][-1]._surface.y0
current = self.outermost.radii[-1].max_x2.y0
if isinstance(pincell.radii[-1], openmc.ZCylinder):
# new one is a cylinder
new = pincell.radii[-1].coefficients['r']
else:
# new one is a box
new = self.outermost.radii[-1][-1]._surface.y0
new = self.outermost.radii[-1].max_x2.y0
if new > current:
self.outermost = pincell

View file

@ -48,13 +48,13 @@ class Pincells(object):
# Rectangular prisms for grid spacers
grid_surfs_tb = \
openmc.model.rectangular_prism(c.rodGridSide_tb, c.rodGridSide_tb)
openmc.model.RectangularPrism(c.rodGridSide_tb, c.rodGridSide_tb)
grid_surfs_i = \
openmc.model.rectangular_prism(c.rodGridSide_i, c.rodGridSide_i)
openmc.model.RectangularPrism(c.rodGridSide_i, c.rodGridSide_i)
# Rectangular prisms for lattice grid sleeves
grid_surfs_ass = \
openmc.model.rectangular_prism(c.gridstrapSide, c.gridstrapSide)
openmc.model.RectangularPrism(c.gridstrapSide, c.gridstrapSide)
# Grids axial surfaces

View file

@ -19,7 +19,7 @@ class UniverseZero(openmc.Universe):
self._add_outer_rings(constants)
self._add_shield_panels(constants)
self._add_core_barrel(constants)
self._create_main_universe()
self._create_main_universe(constants)
def _add_outer_rings(self,c):
@ -140,7 +140,7 @@ class UniverseZero(openmc.Universe):
(-self.s_coreBarrelIR & -self.s_upperBound & +self.s_lowerBound)
def _create_main_universe(self):
def _create_main_universe(self,c):
""" Creates the main BEAVRS universe """
# For 3D problem, add full core to main universe

File diff suppressed because one or more lines are too long

View file

@ -48,14 +48,17 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Value supplied was 'None'. S Value set to default value of 15\n",
"Value supplied was 'None'. SS Value set to default value of 0\n"
"Cannot have a negative S position. S set to 0\n",
"Cannot have a negative SS position. SS set to 0\n",
" RCCA Positions\n",
" A: 228 B: 228 C: 228 D: 228\n",
" SA: 228 SB: 228 SC: 228 SD: 228 SE: 228\n"
]
}
],
"source": [
"# Instantiate a BEAVRS object from the mit-crpg/PWR_benchmarks repository\n",
"b = beavrs.builder.BEAVRS()"
"b = beavrs.builder.BEAVRS(0)"
]
},
{
@ -144,7 +147,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"OrderedDict([(52, Cell\n",
"{52: Cell\n",
"\tID =\t52\n",
"\tName =\tFuel rod active region - 1.6% enr radial 0: Fuel 1.6%\n",
"\tFill =\tMaterial 9\n",
@ -153,7 +156,7 @@
"\tTemperature =\tNone\n",
"\tTranslation =\tNone\n",
"\tVolume =\tNone\n",
"), (53, Cell\n",
", 53: Cell\n",
"\tID =\t53\n",
"\tName =\tFuel rod active region - 1.6% enr radial 1: Helium\n",
"\tFill =\tMaterial 5\n",
@ -162,7 +165,7 @@
"\tTemperature =\tNone\n",
"\tTranslation =\tNone\n",
"\tVolume =\tNone\n",
"), (54, Cell\n",
", 54: Cell\n",
"\tID =\t54\n",
"\tName =\tFuel rod active region - 1.6% enr radial outer: Zircaloy 4\n",
"\tFill =\tMaterial 7\n",
@ -171,7 +174,7 @@
"\tTemperature =\tNone\n",
"\tTranslation =\tNone\n",
"\tVolume =\tNone\n",
")])\n"
"}\n"
]
}
],
@ -203,7 +206,7 @@
" )\n",
"water_cell = openmc.Cell(name='Water',\n",
" fill=b.mats['Borated Water'],\n",
" region=+fuel_clad_OR & pin_sides\n",
" region=+fuel_clad_OR & -pin_sides\n",
" )"
]
},
@ -394,7 +397,7 @@
"outputs": [
{
"data": {
"image/png": "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",
"image/png": "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",
"text/plain": [
"<IPython.core.display.Image object>"
]
@ -548,10 +551,11 @@
" | The OpenMC Monte Carlo Code\n",
" Copyright | 2011-2023 MIT, UChicago Argonne LLC, and contributors\n",
" License | https://docs.openmc.org/en/latest/license.html\n",
" Version | 0.13.3\n",
" Git SHA1 | 50e39a4e20dc9e0f3d7ccf07333f6a5e6c797c8c\n",
" Date/Time | 2023-11-16 00:00:00\n",
" OpenMP Threads | 4\n",
" Version | 0.14.0\n",
" Git SHA1 | e1a8ee7794b441c992426f17fafe216391cbba83\n",
" Date/Time | 2024-02-02 00:48:52\n",
" MPI Processes | 2\n",
" OpenMP Threads | 2\n",
"\n",
" Reading settings XML file...\n",
" Reading cross sections XML file...\n",
@ -760,21 +764,21 @@
"\n",
" =======================> TIMING STATISTICS <=======================\n",
"\n",
" Total time for initialization = 2.0384e+00 seconds\n",
" Reading cross sections = 2.0227e+00 seconds\n",
" Total time in simulation = 9.1420e+00 seconds\n",
" Time in transport only = 9.0999e+00 seconds\n",
" Time in inactive batches = 5.5386e-01 seconds\n",
" Time in active batches = 8.5882e+00 seconds\n",
" Time synchronizing fission bank = 1.1552e-02 seconds\n",
" Sampling source sites = 1.0190e-02 seconds\n",
" SEND/RECV source sites = 1.2995e-03 seconds\n",
" Time accumulating tallies = 3.2846e-03 seconds\n",
" Time writing statepoints = 7.0253e-03 seconds\n",
" Total time for finalization = 2.1724e-04 seconds\n",
" Total time elapsed = 1.1191e+01 seconds\n",
" Calculation Rate (inactive) = 18055.2 particles/second\n",
" Calculation Rate (active) = 16301.5 particles/second\n",
" Total time for initialization = 2.3583e+00 seconds\n",
" Reading cross sections = 2.3309e+00 seconds\n",
" Total time in simulation = 1.0739e+01 seconds\n",
" Time in transport only = 1.0461e+01 seconds\n",
" Time in inactive batches = 6.4227e-01 seconds\n",
" Time in active batches = 1.0096e+01 seconds\n",
" Time synchronizing fission bank = 2.4140e-01 seconds\n",
" Sampling source sites = 6.2924e-03 seconds\n",
" SEND/RECV source sites = 1.6094e-03 seconds\n",
" Time accumulating tallies = 1.4377e-02 seconds\n",
" Time writing statepoints = 9.8511e-03 seconds\n",
" Total time for finalization = 1.9690e-04 seconds\n",
" Total time elapsed = 1.3108e+01 seconds\n",
" Calculation Rate (inactive) = 15569.8 particles/second\n",
" Calculation Rate (active) = 13866.5 particles/second\n",
"\n",
" ============================> RESULTS <============================\n",
"\n",
@ -789,7 +793,7 @@
],
"source": [
"# Run OpenMC with 2 MPI processes\n",
"openmc.run()"
"openmc.run(mpi_args=['mpiexec', '-n', '2'], threads=2)"
]
},
{
@ -827,7 +831,8 @@
" \tFilters =\tCellFilter, EnergyFilter\n",
" \tNuclides =\tO16 O17 U234 U235 U238 U236\n",
" \tScores =\t['scatter', 'absorption']\n",
" \tEstimator =\ttracklength}"
" \tEstimator =\ttracklength\n",
" \tMultiply dens. =\tTrue}"
]
},
"execution_count": 21,
@ -1209,7 +1214,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.12.1"
}
},
"nbformat": 4,

View file

@ -5,6 +5,17 @@ import openmc.deplete
from beavrs.builder import BEAVRS
import argparse, json, openmc, os, shutil, sys
import matplotlib.pyplot as plt
try:
from mpi4py import MPI
except ModuleNotFoundError:
print("Cannot use MPI")
try:
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
except NameError:
comm = None
rank = 0
parser = argparse.ArgumentParser(description="Program to make BEAVRS reactor and run" \
" simulations with resulting geometry")
@ -24,13 +35,16 @@ parser.add_argument('--shutdown', action='store_true', default=False,
help='Set reactor to be in shutdown, all control rods fully inserted.')
args = parser.parse_args()
try:
os.mkdir(os.path.dirname(os.path.realpath(__file__)) + '/build')
except OSError: pass
if rank == 0:
try:
os.mkdir(os.path.dirname(os.path.realpath(__file__)) + '/build')
except OSError: pass
comm.Barrier()
os.chdir(os.path.dirname(os.path.realpath(__file__)) + '/build')
def no_overwrite(filename):
if os.path.isfile(filename):
def no_overwrite(rank, filename):
if os.path.isfile(filename) and rank == 0:
j = 0
new_filepath = filename*1
path, new_name = os.path.split(new_filepath)
@ -47,14 +61,16 @@ def no_overwrite(filename):
print(f"Backed up file {filename} to {new_filepath}")
os.replace(filename, new_filepath)
def run_loop(val):
b.set_S(val)
comm.Barrier()
def run_loop(rank, val):
b.set_S(rank, val)
return b.export_model()
if args.shutdown:
b = BEAVRS(573, 228, is_symmetric=args.is_symmetric, is_2d=args.is_2d)
b = BEAVRS(rank, 573, 228, is_symmetric=args.is_symmetric, is_2d=args.is_2d)
else:
b = BEAVRS(args.rod_loc, 0, is_symmetric=args.is_symmetric, is_2d=args.is_2d)
b = BEAVRS(rank, args.rod_loc, 0, is_symmetric=args.is_symmetric, is_2d=args.is_2d)
# openmc.calculate_volumes()
# openmc.plot_geometry()
@ -68,11 +84,13 @@ if args.optimal:
for p in particles:
for i in inactive:
for a in active:
print(f"Particles: {p} Inactive Cycles: {i} Active Cycles: {a}\n\n")
if rank == 0:
print(f"Particles: {p} Inactive Cycles: {i} Active Cycles: {a}\n\n")
b.set_params(batches=i+a,inactive=i,particles=p)
b.export_xml()
b.export_xml(rank)
openmc.run()
print("\n\n\n")
if rank == 0:
print("\n\n\n")
sys.stdout.flush()
###############################################################################
@ -93,10 +111,11 @@ elif args.run_deplete:
chain_file = "/opt/xdata/endfb-vii.1-hdf5/chain_endfb71_pwr.xml"
try:
os.makedirs('depletion_results')
except FileExistsError:
pass
if rank == 0:
try:
os.makedirs('depletion_results')
except FileExistsError:
pass
## setting the system linear power [W]
"""powers = [45.50,91.01,136.51,182.02,227.52,273.03,324.45,324.45,273.03,273.03,227.52,182.02,136.51,91.01,45.50]
@ -114,7 +133,8 @@ elif args.run_deplete:
## setting the transport operator
model = b.export_model()
openmc.plot_geometry()
comm.Barrier()
# openmc.plot_geometry()
operator = openmc.deplete.CoupledOperator(model, chain_file,
#diff_burnable_mats=False, normalization_mode='fission-q',
fission_q=serpent_fission_q, fission_yield_mode="average")
@ -124,56 +144,114 @@ elif args.run_deplete:
integrator = openmc.deplete.SILEQIIntegrator(operator, time_steps, powers, timestep_units='d')
integrator.integrate()
model.materials = openmc.deplete.Results('depletion_results.h5').export_to_materials(1)
model.export_to_xml()
"""
print(time_steps)
if rank == 0:
print(time_steps)
i = 0
for power, time_step in zip(powers, time_steps):
print(f'Current loop info: {power} {time_step}')
if rank == 0:
print(f'Current loop info: {power} {time_step}')
## setting the transport operator
model = b.export_model()
comm.Barrier()
openmc.plot_geometry()
operator = openmc.deplete.CoupledOperator(model, chain_file,
#diff_burnable_mats=False, normalization_mode='fission-q',
fission_q=serpent_fission_q, fission_yield_mode="average")
## depleting using a first-order predictor algorithm
integrator = openmc.deplete.PredictorIntegrator(operator, [time_step], [power], timestep_units='d')
## Working algorithms: CELI, CECM, SILEQI
integrator = openmc.deplete.SILEQIIntegrator(operator, time_steps, powers, timestep_units='d')
integrator.integrate()
results = openmc.deplete.Results('depletion_results.h5')
time, n_Xe135 = results.get_atoms('1', 'Xe135')
print(n_Xe135)
days = 24*60*60
plt.plot(time/days, n_Xe135)
plt.xlabel('Time [d]')
plt.ylabel('Xe135 [atoms]')
filename = f'depletion_results/depletion_results_t{i}.h5'
no_overwrite(filename)
no_overwrite(rank, filename)
os.replace('depletion_results.h5', filename)
shutil.copy2('materials.xml', f'depletion_results/materials_{i}.xml')
i += 1
# Get materials at the end of the last simulation
model.materials = results.export_to_materials(len(time_steps))
"""
results = openmc.deplete.Results('depletion_results.h5')
# Get materials at the end of the last simulation
if rank == 0:
model.materials = results.export_to_materials(len(time_steps))
model.export_to_xml()
comm.Barrier()
# Obtain K_eff as a function of time
time, keff = results.get_keff(time_units='d')
n_U235 = 0
Xe_capture = 0
n_Xe135 = 0
tmp = [[],[],[]]
# ['Fuel 1.6%' 'Fuel 2.4%' 'Fuel 3.1%' 'Fuel 3.2%' 'Fuel 3.4%']
for mat in b.mats:
# Obtain U235 concentration as a function of time
_, tmp[0] = results.get_atoms(mat, 'U235')
# Obtain Xe135 capture reaction rate as a function of time
_, tmp[1] = results.get_reaction_rate(mat, 'Xe135', '(n,gamma)')
# Obtain U235 concentration as a function of time
_, tmp[2] = results.get_atoms(mat, 'Xe135')
n_U235 += tmp[0]
Xe_capture += tmp[1]
n_Xe135 += tmp[2]
#######################################################################
# Generate plots
#######################################################################
fig, ax = plt.subplots()
ax.errorbar(time,keff[:,0], keff[:,1], label="k-effective")
ax.set_xlabel("Time [d]")
ax.set_ylabel("Keff")
if rank == 0:
plt.savefig("k-effective.png", dpi=150)
plt.draw()
fig, ax = plt.subplots()
ax.plot(time, n_U235, label="U235")
ax.set_xlabel("Time [d]")
ax.set_ylabel("U235 atoms")
if rank == 0:
plt.savefig("U235", dpi=150)
plt.draw()
fig, ax = plt.subplots()
ax.plot(time, Xe_capture, label="Xe135 capture")
ax.set_xlabel("Time [d]")
ax.set_ylabel("Xe135 capture rate")
if rank == 0:
plt.savefig("Xe135_capture", dpi=150)
plt.draw()
fig, ax = plt.subplots()
ax.plot(time, n_Xe135, label="Xe135")
ax.set_xlabel("Time [d]")
ax.set_ylabel("Xe135 atoms")
if rank == 0:
plt.savefig("Xe135", dpi=150)
plt.draw()
elif args.run:
b.set_params(batches=350,inactive=50,particles=20000)
"""rod_loc, guess_list, result = openmc.search_for_keff(run_loop, initial_guess=10, target=1.0,
tol=6e-4, print_iterations=True)"""
tol=6e-4, print_iterations=True, run_args=(rank))"""
b.export_xml()
b.export_xml(rank)
openmc.run()
else:
b.set_params(batches=350,inactive=50,particles=20000)
b.export_xml()
b.export_xml(rank)