@@ -618,11 +618,6 @@ class Integrator(ABC):
618618 External source rates for the depletion system.
619619
620620 .. versionadded:: 0.15.3
621- keff_search_control : openmc.deplete._KeffSearchControl
622- Instance of _KeffSearchControl class to perform keff search during
623- transport-depletion simulation.
624-
625- .. versionadded:: 0.15.4
626621
627622 """ )
628623
@@ -736,15 +731,6 @@ def solver(self, func):
736731
737732 self ._solver = func
738733
739- @property
740- def keff_search_control (self ):
741- return self ._keff_search_control
742-
743- @keff_search_control .setter
744- def keff_search_control (self , keff_search_control ):
745- check_type ('keff search control' , keff_search_control , _KeffSearchControl )
746- self ._keff_search_control = keff_search_control
747-
748734 def _timed_deplete (self , n , rates , dt , i = None , matrix_func = None ):
749735 start = time .time ()
750736 results = deplete (
@@ -853,12 +839,36 @@ def _get_start_data(self) -> tuple[float, int]:
853839 return (self .operator .prev_res [- 1 ].time [0 ],
854840 len (self .operator .prev_res ) - 1 )
855841
856- def _get_bos_from_keff_search_control (self , step_index , bos_conc ):
857- """Get BOS from keff search control."""
858- x = deepcopy (bos_conc )
859- # Get new vector after keff criticality control
860- x , keff_search_root = self ._keff_search_control .search_for_keff (x , step_index )
861- return x , keff_search_root
842+ def _restore_keff_search_control (self , res ):
843+ """Restore keff search control from restart results."""
844+ keff_search_root = res .keff_search_root
845+ if keff_search_root is None :
846+ raise ValueError (
847+ "Cannot restore keff search control from restart "
848+ "results because no stored keff_search_root is "
849+ "available."
850+ )
851+ self ._keff_search_control .function (keff_search_root )
852+ return keff_search_root
853+
854+ def _get_bos_data (self , step_index , source_rate , bos_conc ):
855+ """Get beginning-of-step concentrations, rates, and control state."""
856+ if step_index > 0 or self .operator .prev_res is None :
857+ if self ._keff_search_control is not None and source_rate != 0.0 :
858+ keff_search_root = self ._keff_search_control .run (bos_conc )
859+ else :
860+ keff_search_root = None
861+ bos_conc , res = self ._get_bos_data_from_operator (
862+ step_index , source_rate , bos_conc )
863+ else :
864+ bos_conc , res = self ._get_bos_data_from_restart (
865+ source_rate , bos_conc )
866+ if self ._keff_search_control is not None and source_rate != 0.0 :
867+ keff_search_root = self ._restore_keff_search_control (res )
868+ else :
869+ keff_search_root = None
870+
871+ return bos_conc , res , keff_search_root
862872
863873 def integrate (
864874 self ,
@@ -898,21 +908,9 @@ def integrate(
898908 if output and comm .rank == 0 :
899909 print (f"[openmc.deplete] t={ t } s, dt={ dt } s, source={ source_rate } " )
900910
901- # Solve transport equation (or obtain result from restart)
902- if i > 0 or self .operator .prev_res is None :
903- # Update geometry/material according to keff search control
904- if self ._keff_search_control is not None and source_rate != 0.0 :
905- n , keff_search_root = self ._get_bos_from_keff_search_control (i , n )
906- else :
907- keff_search_root = None
908- n , res = self ._get_bos_data_from_operator (i , source_rate , n )
909- else :
910- n , res = self ._get_bos_data_from_restart (source_rate , n )
911- # Get keff search root from keff search control
912- if self ._keff_search_control :
913- n , keff_search_root = self ._get_bos_from_keff_search_control (i , n )
914- else :
915- keff_search_root = None
911+ # Get beginning-of-step data from operator or restart results
912+ n , res , keff_search_root = self ._get_bos_data (i , source_rate , n )
913+
916914 # Solve Bateman equations over time interval
917915 proc_time , n_end = self (n , res .rates , dt , source_rate , i )
918916
@@ -940,7 +938,7 @@ def integrate(
940938 if output and final_step and comm .rank == 0 :
941939 print (f"[openmc.deplete] t={ t } (final operator evaluation)" )
942940 if self ._keff_search_control is not None and source_rate != 0.0 :
943- n , keff_search_root = self ._get_bos_from_keff_search_control ( i + 1 , n )
941+ keff_search_root = self ._keff_search_control . run ( n )
944942 else :
945943 keff_search_root = None
946944 res_final = self .operator (n , source_rate if final_step else 0.0 )
@@ -1091,40 +1089,34 @@ def add_keff_search_control(
10911089 function : Callable ,
10921090 x0 : float ,
10931091 x1 : float ,
1094- bracket : list [float ],
1092+ bracket : Sequence [float ],
10951093 ** search_kwargs
10961094 ):
10971095 """Add keff search to the integrator scheme.
10981096
1099- This method creates a :class:`openmc.deplete._KeffSearchControl` that
1100- performs keff searches during depletion to maintain a target keff
1101- by adjusting a model parameter through the provided function.
1097+ This method causes OpenMC to perform a keff search during depletion to
1098+ maintain a target keff by adjusting a model parameter through the
1099+ provided function.
11021100
11031101 .. important::
11041102 The function **must** modify the model through ``openmc.lib`` (e.g.,
11051103 ``openmc.lib.cells``, ``openmc.lib.materials``) and **NOT** through
1106- ``openmc.model ``. The function is called within a
1104+ ``openmc.Model ``. The function is called within a
11071105 :class:`openmc.lib.TemporarySession` context where only the C API
11081106 (``openmc.lib``) is available for modifications.
11091107
11101108 Parameters
11111109 ----------
11121110 function : Callable
1113- Function that modifies the model through ``openmc.lib`` based on a
1114- parameter value. The function should take a single float parameter
1115- and modify ``openmc.lib`` objects accordingly (e.g., adjust control
1116- rod position via ``openmc.lib.cells[...].translation``, material
1117- density via ``openmc.lib.materials[...].set_densities(...)``, etc.).
1118-
1119- **Important**: The function must modify ``openmc.lib`` objects, not
1120- ``openmc.model`` objects.
1121- x0: float
1111+ Function that takes a single float argument and modifies the model
1112+ through :mod:`openmc.lib`.
1113+ x0 : float
11221114 Initial lower bound for the keff search.
1123- x1: float
1115+ x1 : float
11241116 Initial upper bound for the keff search.
1125- bracket : list[ float]
1117+ bracket : sequence of float
11261118 Bracket interval [x_min, x_max] that constrains the allowed parameter
1127- values during the keff search. This is a required parameter
1119+ values during the keff search. This is a required parameter
11281120 that defines the absolute bounds for the search. The bracket must contain
11291121 exactly 2 elements with bracket[0] < bracket[1]. These values are passed
11301122 directly to the ``x_min`` and ``x_max`` optional arguments in
@@ -1162,36 +1154,30 @@ def add_keff_search_control(
11621154 ... k_tol=1e-4
11631155 ... )
11641156
1165- Add keff search that adjusts material density:
1157+ Add keff search that adjusts the U235 density:
11661158
1167- >>> def adjust_material_density(density_factor ):
1159+ >>> def set_u235_density(u235_density ):
11681160 ... # Get the material from openmc.lib
11691161 ... lib_mat = openmc.lib.materials[material_id]
11701162 ... # Get current nuclides and densities
11711163 ... nuclides = lib_mat.nuclides
1172- ... current_densities = lib_mat.densities
1173- ... # Scale all densities by the factor
1174- ... new_densities = densities * density_factor
1175- ... # Update the material densities
1176- ... lib_mat.set_densities(nuclides, new_densities)
1164+ ... densities = lib_mat.densities
1165+ ... u235_idx = nuclides.index('U235')
1166+ ... densities[u235_idx] = u235_density
1167+ ... lib_mat.set_densities(nuclides, densities)
11771168 >>> integrator.add_keff_search_control(
1178- ... adjust_material_density ,
1179- ... x0=0.8 ,
1180- ... x1=1.2 ,
1181- ... bracket=[0.2, 1.5 ],
1169+ ... set_u235_density ,
1170+ ... x0=5.0e-4 ,
1171+ ... x1=1.0e-3 ,
1172+ ... bracket=[1.0e-4, 2.0e-3 ],
11821173 ... target=1.0
11831174 ... )
11841175
11851176 .. versionadded:: 0.15.4
11861177
11871178 """
11881179 self ._keff_search_control = _KeffSearchControl (
1189- self .operator ,
1190- function ,
1191- x0 ,
1192- x1 ,
1193- bracket ,
1194- ** search_kwargs )
1180+ self .operator , function , x0 , x1 , bracket , ** search_kwargs )
11951181
11961182@add_params
11971183class SIIntegrator (Integrator ):
0 commit comments