replaced batchwise nomenclature with reactivity_control one

This commit is contained in:
church89 2024-03-15 13:37:44 +01:00
parent a4b44edd3c
commit 0a2933ce53
8 changed files with 108 additions and 98 deletions

View file

@ -17,7 +17,7 @@ from .stepresult import *
from .results import *
from .integrators import *
from .transfer_rates import *
from .batchwise import *
from .reactivity_control import *
from . import abc
from . import cram
from . import helpers

View file

@ -26,8 +26,11 @@ from .results import Results
from .pool import deplete
from .transfer_rates import TransferRates
from openmc import Material, Cell
from .batchwise import (BatchwiseCellGeometrical, BatchwiseCellTemperature,
BatchwiseMaterialRefuel)
from .reactivity_control import (
GeometricalCellReactivityController,
TemperatureCellReactivityController,
RefuelMaterialReactivityController
)
__all__ = [
"OperatorResult", "TransportOperator",
@ -556,8 +559,8 @@ class Integrator(ABC):
transfer_rates : openmc.deplete.TransferRates
Instance of TransferRates class to perform continuous transfer during depletion
batchwise : openmc.deplete.Batchwise
Instance of Batchwise class to perform batch-wise scheme during
reactivity_control : openmc.deplete.ReactivityController
Instance of ReactivityController class to perform reactivity control during
transport-depletion simulation.
.. versionadded:: 0.14.0
@ -641,7 +644,7 @@ class Integrator(ABC):
self.source_rates = asarray(source_rates)
self.transfer_rates = None
self._batchwise = None
self._reactivity_control = None
if isinstance(solver, str):
# Delay importing of cram module, which requires this file
@ -691,8 +694,8 @@ class Integrator(ABC):
self._solver = func
@property
def batchwise(self):
return self._batchwise
def reactivity_control(self):
return self._reactivity_control
def _timed_deplete(self, n, rates, dt, matrix_func=None):
start = time.time()
@ -773,11 +776,11 @@ class Integrator(ABC):
return (self.operator.prev_res[-1].time[-1],
len(self.operator.prev_res) - 1)
def _get_bos_from_batchwise(self, step_index, bos_conc):
"""Get BOS from criticality batch-wise control."""
def _get_bos_from_reactivity_control(self, step_index, bos_conc):
"""Get BOS from reactivity control."""
x = deepcopy(bos_conc)
# Get new vector after keff criticality control
x, root = self._batchwise.search_for_keff(x, step_index)
x, root = self._reactivity_control.search_for_keff(x, step_index)
return x, root
def integrate(
@ -814,9 +817,9 @@ class Integrator(ABC):
# Solve transport equation (or obtain result from restart)
if i > 0 or self.operator.prev_res is None:
# Update geometry/material according to batchwise definition
if self._batchwise is not None and source_rate != 0.0:
n, root = self._get_bos_from_batchwise(i, n)
# Update geometry/material according to reactivity control
if self._reactivity_control is not None and source_rate != 0.0:
n, root = self._get_bos_from_reactivity_control(i, n)
else:
root = None
n, res = self._get_bos_data_from_operator(i, source_rate, n)
@ -843,8 +846,8 @@ class Integrator(ABC):
# solve)
if output and final_step and comm.rank == 0:
print(f"[openmc.deplete] t={t} (final operator evaluation)")
if self._batchwise is not None and source_rate != 0.0:
n, root = self._get_bos_from_batchwise(i+1, n)
if self._reactivity_control is not None and source_rate != 0.0:
n, root = self._get_bos_from_reactivity_control(i+1, n)
else:
root = None
res_list = [self.operator(n, source_rate if final_step else 0.0)]
@ -882,31 +885,32 @@ class Integrator(ABC):
self.transfer_rates.set_transfer_rate(material, components, transfer_rate,
transfer_rate_units, destination_material)
def add_batchwise(self, obj, attr, **kwargs):
"""Add batchwise operation to integrator scheme.
def add_reactivity_control(self, obj, attr, **kwargs):
"""Add reactivity control to integrator scheme.
Parameters
----------
obj : openmc.Cell or openmc.Material object or id or str name
Cell or Materials identifier to where add batchwise scheme
Cell or Materials identifier to where add reactivity control
attr : str
Attribute to specify the type of batchwise scheme. Accepted values
Attribute to specify the type of reactivity control. Accepted values
are: 'translation', 'rotation', 'temperature' for an openmc.Cell
object; 'refuel' for an openmc.Material object.
**kwargs
keyword arguments that are passed to the batchwise class.
keyword arguments that are passed to ReactivityController.
"""
check_value('attribute', attr, ('translation', 'rotation',
'temperature', 'refuel'))
if attr in ('translation', 'rotation'):
batchwise = BatchwiseCellGeometrical
reactivity_control = GeometricalCellReactivityController
elif attr == 'temperature':
batchwise = BatchwiseCellTemperature
reactivity_control = TemperatureCellReactivityController
elif attr == 'refuel':
batchwise = BatchwiseMaterialRefuel
reactivity_control = RefuelMaterialReactivityController
self._batchwise = batchwise.from_params(obj, attr, self.operator,**kwargs)
self._reactivity_control = reactivity_control.from_params(obj, attr,
self.operator,**kwargs)
@add_params
class SIIntegrator(Integrator):

View file

@ -19,20 +19,20 @@ from openmc.checkvalue import (
)
class Batchwise(ABC):
"""Abstract class defining a generalized batch wise scheme.
class ReactivityController(ABC):
"""Abstract class defining a generalized reactivity control.
Batchwise schemes, such as control rod adjustment or material refuelling to
control reactivity and maintain keff constant and equal to a desired value,
usually one.
Reactivity control schemes, such as control rod adjustment or material
refuelling to control reactivity and maintain keff constant and equal to a
desired value, usually one.
A batch wise scheme can be added here to an integrator instance,
A reactivity control scheme can be added here to an integrator instance,
such as :class:`openmc.deplete.CECMIntegrator`, to parametrize one system
variable with the aim of satisfy certain design criteria, such as keeping
keff equal to one, while running transport-depletion calculations.
Specific classes for running batch wise depletion calculations are
implemented as derived class of Batchwise.
Specific classes for running reactivity control depletion calculations are
implemented as derived class of ReactivityController.
.. versionadded:: 0.14.1
@ -348,7 +348,7 @@ class Batchwise(ABC):
"""Update number density and material compositions in OpenMC on all processes.
If density_treatment is set to 'constant-density'
:meth:`openmc.deplete.batchwise._update_volumes` is called to update
:meth:`openmc.deplete.reactivity_control._update_volumes` is called to update
material volumes in AtomNumber, keeping the material total density
constant, before re-normalizing the atom densities and assigning them
to the model in memory.
@ -430,11 +430,11 @@ class Batchwise(ABC):
return x
class BatchwiseCell(Batchwise):
"""Abstract class holding batch wise cell-based functions.
class CellReactivityController(ReactivityController):
"""Abstract class holding reactivity control cell-based functions.
Specific classes for running batch wise depletion calculations are
implemented as derived class of BatchwiseCell.
Specific classes for running reactivity control depletion calculations are
implemented as derived class of CellReactivityController.
.. versionadded:: 0.14.1
@ -674,13 +674,13 @@ class BatchwiseCell(Batchwise):
return x, root
class BatchwiseCellGeometrical(BatchwiseCell):
"""Batch wise cell-based with geometrical-attribute class.
class GeometricalCellReactivityController(CellReactivityController):
"""Reactivity control cell-based with geometrical-attribute class.
A user doesn't need to call this class directly.
Instead an instance of this class is automatically created by calling
:meth:`openmc.deplete.Integrator.add_batchwise` method from an integrator
class, such as :class:`openmc.deplete.CECMIntegrator`.
:meth:`openmc.deplete.Integrator.add_reactivity_control` method from an
integrator class, such as :class:`openmc.deplete.CECMIntegrator`.
.. versionadded:: 0.14.1
@ -850,13 +850,13 @@ class BatchwiseCellGeometrical(BatchwiseCell):
return volumes
class BatchwiseCellTemperature(BatchwiseCell):
"""Batch wise cell-based with temperature-attribute class.
class TemperatureCellReactivityController(CellReactivityController):
"""Reactivity control cell-based with temperature-attribute class.
A user doesn't need to call this class directly.
Instead an instance of this class is automatically created by calling
:meth:`openmc.deplete.Integrator.add_batchwise` method from an integrator
class, such as :class:`openmc.deplete.CECMIntegrator`.
:meth:`openmc.deplete.Integrator.add_reactivity_control` method from an
integrator class, such as :class:`openmc.deplete.CECMIntegrator`.
.. versionadded:: 0.14.1
@ -972,11 +972,11 @@ class BatchwiseCellTemperature(BatchwiseCell):
self.lib_cell.set_temperature(val)
class BatchwiseMaterial(Batchwise):
"""Abstract class holding batch wise material-based functions.
class MaterialReactivityController(ReactivityController):
"""Abstract class holding reactivity control material-based functions.
Specific classes for running batch wise depletion calculations are
implemented as derived class of BatchwiseMaterial.
Specific classes for running reactivity control depletion calculations are
implemented as derived class of MaterialReactivityController.
.. versionadded:: 0.14.1
@ -1140,13 +1140,14 @@ class BatchwiseMaterial(Batchwise):
return x, root
class BatchwiseMaterialRefuel(BatchwiseMaterial):
"""Batch wise material-based class for refuelling (addition or removal) scheme.
class RefuelMaterialReactivityController(MaterialReactivityController):
"""Reactivity control material-based class for refuelling (addition or
removal) scheme.
A user doesn't need to call this class directly.
Instead an instance of this class is automatically created by calling
:meth:`openmc.deplete.Integrator.add_batchwise` method from an integrator
class, such as :class:`openmc.deplete.CECMIntegrator`.
:meth:`openmc.deplete.Integrator.add_reactivity_control` method from an
integrator class, such as :class:`openmc.deplete.CECMIntegrator`.
.. versionadded:: 0.14.1
@ -1315,14 +1316,15 @@ class BatchwiseMaterialRefuel(BatchwiseMaterial):
return self.model
def _calculate_volumes(self, res):
"""Uses :meth:`openmc.batchwise._search_for_keff` solution as grams of
material to add or remove to calculate new material volume.
"""Uses :meth:`openmc.deplete.reactivity_control._search_for_keff`
solution as grams of material to add or remove to calculate new material
volume.
Parameters
----------
res : float
Solution in grams of material, coming from
:meth:`openmc.batchwise._search_for_keff`
:meth:`openmc.deplete.reactivity_control._search_for_keff`
Returns
-------

View file

@ -56,7 +56,7 @@ class StepResult:
Number of stages in simulation.
data : numpy.ndarray
Atom quantity, stored by stage, mat, then by nuclide.
batchwise : float
reac_cont : float
The root returned by the reactivity controller.
proc_time : int
Average time spent depleting a material across all
@ -76,7 +76,7 @@ class StepResult:
self.mat_to_hdf5_ind = None
self.data = None
self.batchwise = None
self.reac_cont = None
def __repr__(self):
t = self.time[0]
@ -353,7 +353,7 @@ class StepResult:
dtype="float64")
handle.create_dataset(
"batchwise_root", (1,), maxshape=(None,),
"reac_cont_root", (1,), maxshape=(None,),
dtype="float64")
def _to_hdf5(self, handle, index, parallel=False):
@ -386,7 +386,7 @@ class StepResult:
time_dset = handle["/time"]
source_rate_dset = handle["/source_rate"]
proc_time_dset = handle["/depletion time"]
root_dset = handle["/batchwise_root"]
root_dset = handle["/reac_cont_root"]
# Get number of results stored
number_shape = list(number_dset.shape)
@ -447,7 +447,7 @@ class StepResult:
proc_time_dset[index] = (
self.proc_time / (comm.size * self.n_hdf5_mats)
)
root_dset[index] = self.batchwise
root_dset[index] = self.reac_cont
@classmethod
def from_hdf5(cls, handle, step):
@ -482,9 +482,9 @@ class StepResult:
if step < proc_time_dset.shape[0]:
results.proc_time = proc_time_dset[step]
if "batchwise_root" in handle:
root_dset = handle["/batchwise_root"]
results.batchwise = root_dset[step]
if "reac_cont_root" in handle:
root_dset = handle["/reac_cont_root"]
results.reac_cont = root_dset[step]
if results.proc_time is None:
results.proc_time = np.array([np.nan])
@ -582,7 +582,7 @@ class StepResult:
results.proc_time = proc_time
if results.proc_time is not None:
results.proc_time = comm.reduce(proc_time, op=MPI.SUM)
results.batchwise = root
results.reac_cont = root
if not Path(path).is_file():
Path(path).parent.mkdir(parents=True, exist_ok=True)

View file

@ -223,5 +223,5 @@ def search_for_keff(model_builder, initial_guess=None, target=1.0,
return guesses, results
# In case the root finder is not successful
except Exception as e:
warn(f'{e})
warn(f'{e}')
return guesses, results

View file

@ -1,4 +1,4 @@
""" Tests for Batchwise class """
""" Tests for ReactivityController class """
from pathlib import Path
import shutil
@ -83,8 +83,9 @@ def model():
('rot_cell', 'rotation', [-90,90], 2, None, 'depletion_with_rotation'),
('f', 'refuel', [-100,100], None, {'U235':1}, 'depletion_with_refuel')
])
def test_batchwise(run_in_tmpdir, model, obj, attribute, bracket_limit, axis,
vec, ref_result):
def test_reactivity_control(run_in_tmpdir, model, obj, attribute, bracket_limit,
axis, vec, ref_result):
chain_file = Path(__file__).parents[2] / 'chain_simple.xml'
op = CoupledOperator(model, chain_file)
@ -100,7 +101,7 @@ def test_batchwise(run_in_tmpdir, model, obj, attribute, bracket_limit, axis,
if axis is not None:
kwargs['axis'] = axis
integrator.add_batchwise(obj, attribute, **kwargs)
integrator.add_reactivity_control(obj, attribute, **kwargs)
integrator.integrate()
# Get path to test and reference results
@ -117,5 +118,5 @@ def test_batchwise(run_in_tmpdir, model, obj, attribute, bracket_limit, axis,
res_ref = openmc.deplete.Results(path_reference)
# Use high tolerance here
assert [res.batchwise for res in res_test] == pytest.approx(
[res.batchwise for res in res_ref], rel=2)
assert [res.reac_cont for res in res_test] == pytest.approx(
[res.reac_cont for res in res_ref], rel=2)

View file

@ -1,4 +1,4 @@
""" Tests for Batchwise class """
""" Tests for ReactivityController class """
from pathlib import Path
@ -8,8 +8,11 @@ import numpy as np
import openmc
import openmc.lib
from openmc.deplete import CoupledOperator
from openmc.deplete import (BatchwiseCellGeometrical, BatchwiseCellTemperature,
BatchwiseMaterialRefuel)
from openmc.deplete import (
GeometricalCellReactivityController,
TemperatureCellReactivityController,
RefuelMaterialReactivityController
)
CHAIN_PATH = Path(__file__).parents[1] / "chain_simple.xml"
@ -97,36 +100,36 @@ def test_attributes(case_name, model, operator, integrator, obj, attribute,
if case_name == "invalid_1":
with pytest.raises(ValueError) as e:
integrator.add_batchwise(obj, attribute, **kwargs)
integrator.add_reactivity_control(obj, attribute, **kwargs)
assert str(e.value) == 'Unable to set "Material name" to "universe_cell" '\
'since it is not in "[\'fuel\', \'water\']"'
elif case_name == "invalid_2":
with pytest.raises(ValueError) as e:
integrator.add_batchwise(obj, attribute, **kwargs)
integrator.add_reactivity_control(obj, attribute, **kwargs)
assert str(e.value) == 'Unable to set "Cell name exists" to "fuel" since '\
'it is not in "[\'fuel_cell\', \'universe_cell\', \'\', \'\']"'
elif case_name == "invalid_3":
with pytest.raises(ValueError) as e:
integrator.add_batchwise(obj, attribute, **kwargs)
integrator.add_reactivity_control(obj, attribute, **kwargs)
assert str(e.value) == 'Unable to set "Cell name exists" to "fuel" since '\
'it is not in "[\'fuel_cell\', \'universe_cell\', \'\', \'\']"'
else:
integrator.add_batchwise(obj, attribute, **kwargs)
integrator.add_reactivity_control(obj, attribute, **kwargs)
if attribute in ('translation','rotation'):
assert integrator.batchwise.universe_cells == [cell for cell in \
assert integrator.reactivity_control.universe_cells == [cell for cell in \
model.geometry.get_cells_by_name(obj)[0].fill.cells.values() \
if cell.fill.depletable]
assert integrator.batchwise.axis == axis
assert integrator.reactivity_control.axis == axis
elif attribute == 'refuel':
assert integrator.batchwise.mat_vector == vec
assert integrator.reactivity_control.mat_vector == vec
assert integrator.batchwise.attrib_name == attribute
assert integrator.batchwise.bracket == bracket
assert integrator.batchwise.bracket_limit == limit
assert integrator.batchwise.burn_mats == operator.burnable_mats
assert integrator.batchwise.local_mats == operator.local_mats
assert integrator.reactivity_control.attrib_name == attribute
assert integrator.reactivity_control.bracket == bracket
assert integrator.reactivity_control.bracket_limit == limit
assert integrator.reactivity_control.burn_mats == operator.burnable_mats
assert integrator.reactivity_control.local_mats == operator.local_mats
@pytest.mark.parametrize("obj, attribute, value_to_set", [
('universe_cell', 'translation', 0),
@ -139,15 +142,15 @@ def test_cell_methods(run_in_tmpdir, model, operator, integrator, obj, attribute
"""
kwargs = {'bracket':[-1,1], 'bracket_limit':[-10,10], 'axis':2, 'tol':0.1}
integrator.add_batchwise(obj, attribute, **kwargs)
integrator.add_reactivity_control(obj, attribute, **kwargs)
model.export_to_xml()
openmc.lib.init()
integrator.batchwise._set_cell_attrib(value_to_set)
assert integrator.batchwise._get_cell_attrib() == value_to_set
integrator.reactivity_control._set_cell_attrib(value_to_set)
assert integrator.reactivity_control._get_cell_attrib() == value_to_set
vol = integrator.batchwise._calculate_volumes()
for cell in integrator.batchwise.universe_cells:
vol = integrator.reactivity_control._calculate_volumes()
for cell in integrator.reactivity_control.universe_cells:
assert vol[str(cell.id)] == pytest.approx([
mat.volume for mat in model.materials \
if mat.id == cell.id][0], rel=tolerance)
@ -167,7 +170,7 @@ def test_internal_methods(run_in_tmpdir, model, operator, integrator, nuclide,
kwargs = {'bracket':[-1,1], 'bracket_limit':[-10,10], 'mat_vector':{}}
integrator.add_batchwise('fuel', 'refuel', **kwargs)
integrator.add_reactivity_control('fuel', 'refuel', **kwargs)
model.export_to_xml()
openmc.lib.init()
@ -175,12 +178,12 @@ def test_internal_methods(run_in_tmpdir, model, operator, integrator, nuclide,
#Increase number of atoms of U238 in fuel by fix amount and check the
# volume increase at constant-density
#extract fuel material from model materials
mat = integrator.batchwise.material
mat = integrator.reactivity_control.material
mat_index = operator.number.index_mat[str(mat.id)]
nuc_index = operator.number.index_nuc[nuclide]
vol = operator.number.get_mat_volume(str(mat.id))
operator.number.number[mat_index][nuc_index] += atoms_to_add
integrator.batchwise._update_volumes()
integrator.reactivity_control._update_volumes()
vol_to_compare = vol + (atoms_to_add * openmc.data.atomic_mass(nuclide) /\
openmc.data.AVOGADRO / mat.density)
@ -188,14 +191,14 @@ def test_internal_methods(run_in_tmpdir, model, operator, integrator, nuclide,
assert operator.number.get_mat_volume(str(mat.id)) == pytest.approx(vol_to_compare)
x = [i[:operator.number.n_nuc_burn] for i in operator.number.number]
integrator.batchwise._update_materials(x)
integrator.reactivity_control._update_materials(x)
nuc_index_lib = openmc.lib.materials[mat.id].nuclides.index(nuclide)
dens_to_compare = 1.0e-24 * operator.number.get_atom_density(str(mat.id), nuclide)
assert openmc.lib.materials[mat.id].densities[nuc_index_lib] == pytest.approx(dens_to_compare)
volumes = {str(mat.id): vol + 1}
new_x = integrator.batchwise._update_x_and_set_volumes(x, volumes)
new_x = integrator.reactivity_control._update_x_and_set_volumes(x, volumes)
dens_to_compare = 1.0e24 * volumes[str(mat.id)] *\
openmc.lib.materials[mat.id].densities[nuc_index_lib]
assert new_x[mat_index][nuc_index] == pytest.approx(dens_to_compare)