### Build and install Scarabée from source Source: https://scarabee.readthedocs.io/en/latest/install/index.html Compiles and installs Scarabée from the source code. This command launches the compilation sequence, which may take several minutes to complete. ```bash pip install --user -v . ``` -------------------------------- ### Install Linux prerequisites on Ubuntu Source: https://scarabee.readthedocs.io/en/latest/install/index.html Installs required system packages for building Scarabée on Ubuntu-based systems (including Debian and Linux Mint). These packages are necessary for the graphical plotting interface. ```bash sudo apt-get install -y python3-pip libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libomp-dev mesa-common-dev libgl1-mesa-dev libglu1-mesa-dev libwayland-dev libxkbcommon-dev xorg-dev ``` -------------------------------- ### Install Scarabée via pip Source: https://scarabee.readthedocs.io/en/latest/_sources/install/index.rst.txt Use this command to install the latest stable release of Scarabée using pre-built Python wheels. ```bash pip install --user scarabee ``` -------------------------------- ### Install Linux Build Dependencies (Fedora/RockyOS) Source: https://scarabee.readthedocs.io/en/latest/_sources/install/index.rst.txt Install required system packages for building the graphical plotting interface on Fedora or RockyOS. ```bash sudo dnf install -y python3-pip python3-devel wayland-devel libxkbcommon-devel libXcursor-devel libXi-devel libXinerama-devel libXrandr-devel mesa-libGL-devel ``` -------------------------------- ### Install Linux Build Dependencies (Ubuntu/Debian) Source: https://scarabee.readthedocs.io/en/latest/_sources/install/index.rst.txt Install required system packages for building the graphical plotting interface on Ubuntu, Debian, or Linux Mint. ```bash sudo apt-get install -y python3-pip libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libomp-dev mesa-common-dev libgl1-mesa-dev libglu1-mesa-dev libwayland-dev libxkbcommon-dev xorg-dev ``` -------------------------------- ### PWR assembly cell setup and volume fraction methods Source: https://scarabee.readthedocs.io/en/latest/_modules/scarabee/reseau/pwr_assembly.html These methods are part of the PWR assembly class in the scarabee.reseau.pwr_assembly module. _set_cells validates the cell grid shape, deep-copies each cell, and accumulates the initial heavy metal linear mass with symmetry corrections (quarter corner 0.25, side half 0.5, bottom half 0.5) before scaling for half/quarter symmetry and converting from grams to kilograms. _compute_fuel_volume_fraction sums fuel pin volumes with the same symmetry corrections and stores the fuel volume fraction relative to the assembly pitch area. _compute_moderator_volume_fraction starts by computing the moderator volume per pin cell, optionally reducing it when a spacer grid width is present. ```python def _set_cells(self, cells: List[List[Union[FuelPin, GuideTube]]]) -> None: if len(cells) != self._simulated_shape[1]: raise ValueError( "Shape along y of cells list does not agree with assembly shape and symmetry." ) for j in range(len(cells)): if len(cells[j]) != self._simulated_shape[0]: raise ValueError( "Shape along x of cells list does not agree with assembly shape and symmetry." ) # Make deep copies of all cells provided by the user. This makes sure # that each duplicate FuelPin or GuideTube instance is unique. self._cells = [] self._cells_set = False self._initial_heavy_metal_linear_mass = 0.0 for j in range(len(cells)): self._cells.append([]) for i in range(len(cells[j])): self._cells[-1].append(copy.deepcopy(cells[j][i])) if isinstance(cells[j][i], FuelPin): lfm = cells[j][i].initial_fissionable_linear_mass # First check for quarter symmetry and being corner pin if ( self.symmetry == Symmetry.Quarter and self.shape[0] % 2 == 1 and self.shape[1] % 2 == 1 and j == self._simulated_shape[1] - 1 and i == 0 ): lfm *= 0.25 # Next, check for being on the side with a half pin in quarter symmetry elif ( self.symmetry == Symmetry.Quarter and self.shape[0] % 2 == 1 and i == 0 ): lfm *= 0.5 # Next, check for being on the bottom row with a half pin elif ( self.symmetry != Symmetry.Full and self.shape[1] % 2 == 1 and j == self._simulated_shape[1] - 1 ): lfm *= 0.5 self._initial_heavy_metal_linear_mass += lfm self._cells_set = True if self.symmetry == Symmetry.Half: self._initial_heavy_metal_linear_mass *= 2.0 elif self.symmetry == Symmetry.Quarter: self._initial_heavy_metal_linear_mass *= 4.0 # Convert HM mass from g to kg self._initial_heavy_metal_linear_mass *= 1.0e-3 ``` ```python def _compute_fuel_volume_fraction(self) -> None: """ Computes the fraction of the assembly which is fuel. """ sum_volume = 0.0 for j in range(len(self.cells)): for i in range(len(self.cells[j])): cell = self.cells[j][i] if not isinstance(cell, FuelPin): continue pin_volume = np.pi * cell.fuel_radius * cell.fuel_radius # First check for quarter symmetry and being corner pin if ( self.symmetry == Symmetry.Quarter and self.shape[0] % 2 == 1 and self.shape[1] % 2 == 1 and j == self._simulated_shape[1] - 1 and i == 0 ): pin_volume *= 0.25 # Next, check for being on the side with a half pin in quarter symmetry elif ( self.symmetry == Symmetry.Quarter and self.shape[0] % 2 == 1 and i == 0 ): pin_volume *= 0.5 # Next, check for being on the bottom row with a half pin elif ( self.symmetry != Symmetry.Full and self.shape[1] % 2 == 1 and j == self._simulated_shape[1] - 1 ): pin_volume *= 0.5 sum_volume += pin_volume if self.symmetry == Symmetry.Quarter: sum_volume *= 4.0 elif self.symmetry == Symmetry.Half: sum_volume *= 2.0 self._fuel_volume_fraction = sum_volume / ( self.assembly_pitch * self.assembly_pitch ) ``` ```python def _compute_moderator_volume_fraction(self) -> None: """ Computes the fraction of the assembly which is moderator. """ sum_volume = 0.0 pin_cell_volume = self.pitch**2.0 if self.spacer_grid_width is not None: pin_cell_volume = (self.pitch - 2.0 * self.spacer_grid_width) ** 2.0 for j in range(len(self.cells)): for i in range(len(self.cells[j])): cell = self.cells[j][i] # Start with volume of moderator in a pin cell cell_mod_volume = pin_cell_volume ``` -------------------------------- ### Install Linux prerequisites on Fedora Source: https://scarabee.readthedocs.io/en/latest/install/index.html Installs required system packages for building Scarabée on Fedora-based systems (including RockyOS). These packages are necessary for the graphical plotting interface. ```bash sudo dnf install -y python3-pip python3-devel wayland-devel libxkbcommon-devel libXcursor-devel libXi-devel libXinerama-devel libXrandr-devel mesa-libGL-devel ``` -------------------------------- ### Simulation Iteration Output Source: https://scarabee.readthedocs.io/en/latest/_sources/examples/moc_c5g7.ipynb.txt Example log output showing the convergence of the keff and flux values over multiple iterations. ```text [info] Iteration 22 keff: 1.18673 [info] keff difference: 5.88778E-08 [info] max flux difference: 1.20878E-04 [info] iteration time: 7.09888E-01 s [info] CMFD solve time: 1.42580E-01 s [info] ------------------------------------- [info] Iteration 23 keff: 1.18673 [info] keff difference: 1.55472E-07 [info] max flux difference: 8.97403E-05 [info] iteration time: 7.04260E-01 s [info] CMFD solve time: 1.19236E-01 s [info] ------------------------------------- [info] Iteration 24 keff: 1.18673 [info] keff difference: 2.39317E-08 [info] max flux difference: 6.54081E-05 [info] iteration time: 6.67643E-01 s [info] CMFD solve time: 1.27304E-01 s [info] ------------------------------------- [info] Iteration 25 keff: 1.18673 [info] keff difference: 1.26680E-08 [info] max flux difference: 4.79790E-05 [info] iteration time: 6.91578E-01 s [info] CMFD solve time: 1.22305E-01 s [info] ------------------------------------- [info] Iteration 26 keff: 1.18673 [info] keff difference: 2.54890E-08 [info] max flux difference: 3.53072E-05 [info] iteration time: 6.76282E-01 s [info] CMFD solve time: 1.21425E-01 s [info] ------------------------------------- [info] Iteration 27 keff: 1.18673 [info] keff difference: 2.79617E-08 [info] max flux difference: 2.60287E-05 [info] iteration time: 6.95128E-01 s [info] CMFD solve time: 1.23611E-01 s [info] ------------------------------------- [info] Iteration 28 keff: 1.18673 [info] keff difference: 4.36046E-08 [info] max flux difference: 1.97460E-05 [info] iteration time: 6.71203E-01 s [info] CMFD solve time: 9.96425E-02 s [info] ------------------------------------- [info] Iteration 29 keff: 1.18673 [info] keff difference: 3.42624E-09 [info] max flux difference: 1.43451E-05 [info] iteration time: 6.63062E-01 s [info] CMFD solve time: 1.05476E-01 s [info] ------------------------------------- [info] Iteration 30 keff: 1.18673 [info] keff difference: 1.49671E-08 [info] max flux difference: 1.05024E-05 [info] iteration time: 6.72758E-01 s [info] CMFD solve time: 1.03482E-01 s [info] ------------------------------------- [info] Iteration 31 keff: 1.18673 [info] keff difference: 1.88816E-08 [info] max flux difference: 7.72313E-06 [info] iteration time: 7.07397E-01 s [info] CMFD solve time: 1.06156E-01 s [info] [info] Simulation Time: 2.68848E+01 s ``` -------------------------------- ### NodalFlux1D.__init__: 1D NEM nodal diffusion setup Source: https://scarabee.readthedocs.io/en/latest/_modules/scarabee/reseau/nodal_flux.html Initializes a 1D nodal diffusion calculation using the Nodal Expansion Method (NEM). Validates that x_min is less than x_max, keff lies in (0, 2), and that all flux and current arrays are 1D with lengths matching the number of energy groups. Builds the coefficient matrix A and right-hand side b for the nodal equations, referencing equations 2.54 and 2.55. ```python from .._scarabee import DiffusionCrossSection import numpy as np from typing import Optional, Union [docs]class NodalFlux1D: [docs] def __init__( self, x_min: float, x_max: float, keff: float, xs: DiffusionCrossSection, avg_flx: np.ndarray, j_neg: np.ndarray, j_pos: np.ndarray, ): """ Performs the 1D nodal diffusion calculation using the Nodal Expansion Method (NEM) with reference currents and average fluxes. This represents the transverse integrated homogeneous nodal flux solution. The primary use of this class is for computing the homogeneous flux that is required to define discontinuity factors for generalized equivalence theory. Parameters ---------- x_min : float Position of the negative surface of the node. x_max : float Position of the positive surface of the node. keff : float Multiplication factor from reference Sn calculation. xs : DiffusionCrossSection Diffusion cross sections homogenized for the node. avg_flx : np.ndarray Average flux in each group within the node from reference Sn calculation. j_neg : np.ndarray Reference net current in each group on the negative boundary from the reference calculation. j_pos : np.ndarray Reference net current in each group on the positive boundary from the reference calculation. """ if x_min >= x_max: raise ValueError("The value of x_min must be < x_max.") self.x_min = x_min self.x_max = x_max dx = x_max - x_min # Only needed locally to compute coefficients if keff <= 0.0 or 2.0 <= keff: raise ValueError("The value of keff must be in the interval (0, 2).") self.ngroups = xs.ngroups # Checks for all arrays if avg_flx.ndim != 1: raise ValueError("The array avg_flux must be 1D.") if j_neg.ndim != 1: raise ValueError("The array j_neg must be 1D.") if j_pos.ndim != 1: raise ValueError("The array j_pos must be 1D.") if avg_flx.size != xs.ngroups: raise ValueError( "The length of avg_flux does not agree with number of groups in xs." ) if j_neg.size != xs.ngroups: raise ValueError( "The length of j_neg does not agree with number of groups in xs." ) if j_pos.size != xs.ngroups: raise ValueError( "The length of j_neg does not agree with number of groups in xs." ) # Perform the static nodal calculation for all groups NG = self.ngroups Na = NG * 4 # number of a coefficients to solve for invs_dx = 1.0 / dx A = np.zeros((Na, Na)) # Matrix to hold all coefficients b = np.zeros((Na)) # Results array # Load the coefficient matrix and results array j = 0 # Matrix row for g in range(NG): Dg = xs.D(g) Dg_dx = Dg * invs_dx chi_g_keff = xs.chi(g) / keff # Each group has 4 equations. See reference [1]. # Eq 2.54 A[j, g * 4 + 0] += xs.Er(g) / 12.0 # a1 A[j, g * 4 + 2] -= xs.Er(g) / 120.0 # a3 A[j, g * 4 + 2] -= 0.5 * Dg_dx * invs_dx # a3 for gg in range(NG): A[j, gg * 4 + 0] -= chi_g_keff * xs.vEf(gg) / 12.0 # a1 A[j, gg * 4 + 2] += chi_g_keff * xs.vEf(gg) / 120.0 # a3 if gg == g: continue A[j, gg * 4 + 0] -= xs.Es(gg, g) / 12.0 # a1 A[j, gg * 4 + 2] += xs.Es(gg, g) / 120.0 # a3 b[j] = 0.0 j += 1 # Eq 2.55 A[j, g * 4 + 1] += xs.Er(g) / 20.0 # a2 A[j, g * 4 + 3] -= xs.Er(g) / 700.0 # a4 A[j, g * 4 + 3] -= 0.2 * Dg_dx * invs_dx # a4 for gg in range(NG): A[j, gg * 4 + 1] -= chi_g_keff * xs.vEf(gg) / 20.0 # a2 A[j, gg * 4 + 3] += chi_g_keff * xs.vEf(gg) / 700.0 # a4 if gg == g: continue A[j, gg * 4 + 1] -= xs.Es(gg, g) / 20.0 # a2 A[j, gg * 4 + 3] += xs.Es(gg, g) / 700.0 # a4 b[j] = 0.0 j += 1 ``` -------------------------------- ### Solver Output Source: https://scarabee.readthedocs.io/en/latest/examples/moc_c5g7.html Example output logs generated during the track generation process. ```text [info] Creating quadrature [info] Number of azimuthal angles: 64 [info] Maximum track spacing: 0.05 cm [info] Tracing tracks [info] Renormalizing segment lengths [info] Determining track connections [info] Time spent drawing tracks: 13.414 s. ``` -------------------------------- ### Nodal calculation and diffusion data setup Source: https://scarabee.readthedocs.io/en/latest/_modules/scarabee/reseau/reflector.html Performs nodal calculations to obtain homogeneous flux, computes discontinuity factors, and sets up diffusion data for a NEM k-eff calculation. ```python g_min = self.condensation_scheme[g][0] g_max = self.condensation_scheme[g][1] for gg in range(g_min, g_max + 1): j_0[g] += ref_sn.current(0, gg) j_mid[g] += ref_sn.current(s_mid, gg) j_max[g] += ref_sn.current(s_max, gg) # Do nodal calculation to obtain homogeneous flux x_fuel = np.sum(dx[:NF]) x_ref_end = np.sum(dx) fuel_node = NodalFlux1D( 0.0, x_fuel, ref_sn.keff, fuel_diffusion_xs, avg_flx_fuel, j_0, j_mid ) ref_node = NodalFlux1D( x_fuel, x_ref_end, ref_sn.keff, self.diffusion_xs, avg_flx_ref, j_mid, j_max ) # I noticed that the initial fixed-source claculation from above can result in # a negative flux next to the vacuum BC, which is of course non-physical. Here, # we iteratively bump up the diffusion coefficients until the fluxes are # positive at the far right boundary in all groups. xmax_homog_fluxes = ref_node.pos_surf_flux() while np.min(xmax_homog_fluxes) < 0.0: self.diffusion_xs = self._doctor_xs(self.diffusion_xs) ref_node = NodalFlux1D( x_fuel, x_ref_end, ref_sn.keff, self.diffusion_xs, avg_flx_ref, j_mid, j_max, ) xmax_homog_fluxes = ref_node.pos_surf_flux() # Compute DFs heter_flx = 0.5 * (few_group_flux[:, NF - 1] + few_group_flux[:, NF]) homog_flx_fuel = fuel_node.pos_surf_flux() homog_flx_ref = ref_node.neg_surf_flux() # Get DF for fuel and reflector sides f_fuel = heter_flx / homog_flx_fuel f_ref = heter_flx / homog_flx_ref # As outlined by Smith in [1], we should normalize the reflector DFs by # The fuel DFs from the reflector calculation. Then, in the nodal # calculation, we can multiply by the DF of the actual fuel next to the # node to get better results. f_ref /= f_fuel f_fuel /= f_fuel nodal_flux = np.zeros((len(self.condensation_scheme), len(x))) self.adf = np.ones((len(self.condensation_scheme), 6)) fuel_adf = np.ones((len(self.condensation_scheme), 6)) for g in range(len(self.condensation_scheme)): nodal_flux[g, :NF] = fuel_node(x[:NF], g) nodal_flux[g, NF:] = ref_node(x[NF:], g) self.adf[g, :] = f_ref[g] fuel_adf[g, :] = f_fuel[g] # Create the diffusion data self.diffusion_data = DiffusionData(self.diffusion_xs) self.diffusion_data.adf = self.adf self.diffusion_data.reflector = True self.form_factors = FormFactors( np.array([[0.0]]), np.array([self.assembly_width]), np.array([self.assembly_width]), ) # Do a nodal k-eff calulation fuel_diffision_data = DiffusionData(fuel_diffusion_xs) fuel_diffision_data.adf = fuel_adf dx = np.array([1 * self.assembly_width, self.assembly_width]) nx = np.array([1, 1]) dy = np.array([10.0]) ny = np.array([1]) nem_geom = DiffusionGeometry( [fuel_diffision_data, self.diffusion_data], dx, nx, dy, ny, dy, ny, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, ) nem_solver = NEM4DiffusionDriver(nem_geom) nem_solver.nonlinear_update_frequency = 1 nem_solver.source_extrapolation_frequency = 100 nem_solver.flux_tolerance = 1.0e-7 set_logging_level(LogLevel.Warning) nem_solver.solve() set_logging_level(LogLevel.Info) scarabee_log(LogLevel.Info, "NEM Keff: {:.5f}".format(nem_solver.keff)) nem_keff_flux = nem_solver.flux(x, [10.0], [10.0]) nem_keff_flux *= flux_norm / np.sum(nem_keff_flux[:, :NF]) ``` -------------------------------- ### Depletion and condensation data initialization Source: https://scarabee.readthedocs.io/en/latest/_modules/scarabee/reseau/pwr_assembly.html Initializes depletion-related data: exposure and time steps start as None (user must provide), arrays for exposures (MWd/kg) and times (days) are empty, corrector transport defaults to True (two transport calculations per time step), keff array is empty, and condensation scheme is taken from the nuclear data library. ```python self._depletion_exposure_steps: Optional[np.ndarray] = None self._depletion_time_steps: Optional[np.ndarray] = None ``` ```python self._exposures: np.ndarray = np.array([]) self._times: np.ndarray = np.array([]) ``` ```python self._corrector_transport: bool = True ``` ```python self._keff: np.ndarray = np.array([]) ``` ```python self._condensation_scheme: Optional[List[List[int]]] = ( self._ndl.condensation_scheme ) ``` -------------------------------- ### Define Guide Tube Cross-Sections Source: https://scarabee.readthedocs.io/en/latest/examples/moc_c5g7.html Initializes a CrossSection object for a guide tube using absorption and scattering data. ```python Ea = np.array([5.11320E-04, 7.58010E-05, 3.15720E-04, 1.15820E-03, 3.39750E-03, 9.18780E-03, 2.32420E-02]) Es = np.array([[6.61659E-02, 5.90700E-02, 2.83340E-04, 1.46220E-06, 2.06420E-08, 0.00000E+00, 0.00000E+00], [0.00000E+00, 2.40377E-01, 5.24350E-02, 2.49900E-04, 1.92390E-05, 2.98750E-06, 4.21400E-07], [0.00000E+00, 0.00000E+00, 1.83297E-01, 9.23970E-02, 6.94460E-03, 1.08030E-03, 2.05670E-04], [0.00000E+00, 0.00000E+00, 0.00000E+00, 7.88511E-02, 1.70140E-01, 2.58810E-02, 4.92970E-03], [0.00000E+00, 0.00000E+00, 0.00000E+00, 3.73330E-05, 9.97372E-02, 2.06790E-01, 2.44780E-02], [0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 9.17260E-04, 3.16765E-01, 2.38770E-01], [0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 4.97920E-02, 1.09912E+00]]) Et = Ea + np.sum(Es, 1) GTxs = scrb.CrossSection(Et, Ea, Es, name="Guide Tube") ``` -------------------------------- ### Configure MOCDriver and Boundary Conditions Source: https://scarabee.readthedocs.io/en/latest/examples/moc_c5g7.html Initialize the MOC solver and set vacuum boundary conditions for the water assembly sides. ```python moc = scrb.MOCDriver(core) moc.x_max_bc = scrb.BoundaryCondition.Vacuum moc.y_min_bc = scrb.BoundaryCondition.Vacuum ``` -------------------------------- ### Creating fuel pins and guide tubes Source: https://scarabee.readthedocs.io/en/latest/examples/pwr_assembly_depletion.html Define the fuel pin and guide tube components using the previously created materials. ```python # Create a fuel pin fp = FuelPin( fuel=Fuel31, fuel_radius=0.39218, gap=He, gap_radius=0.40005, clad=Clad, clad_radius=0.45720, ) # Create a guide tube gt = GuideTube(inner_radius=0.56134, outer_radius=0.60198, clad=Clad) ``` -------------------------------- ### Clone and Build Scarabée from Source Source: https://scarabee.readthedocs.io/en/latest/_sources/install/index.rst.txt Commands to download the source code, navigate to the directory, optionally switch to the development branch, and compile the package. ```bash git clone https://github.com/scarabee-dev/scarabee.git ``` ```bash cd scarabee ``` ```bash git switch develop ``` ```bash pip install --user -v . ``` -------------------------------- ### Define guide tube cross-sections Source: https://scarabee.readthedocs.io/en/latest/_sources/examples/moc_c5g7.ipynb.txt Sets up the guide tube cross-section data for the C5G7 benchmark. Uses scrb.CrossSection with total, absorption, and scattering arrays. ```python # Guide Tube Ea = np.array([5.11320E-04, 7.58010E-05, 3.15720E-04, 1.15820E-03, 3.39750E-03, 9.18780E-03, 2.32420E-02]) Es = np.array([[6.61659E-02, 5.90700E-02, 2.83340E-04, 1.46220E-06, 2.06420E-08, 0.00000E+00, 0.00000E+00], [0.00000E+00, 2.40377E-01, 5.24350E-02, 2.49900E-04, 1.92390E-05, 2.98750E-06, 4.21400E-07], [0.00000E+00, 0.00000E+00, 1.83297E-01, 9.23970E-02, 6.94460E-03, 1.08030E-03, 2.05670E-04], [0.00000E+00, 0.00000E+00, 0.00000E+00, 7.88511E-02, 1.70140E-01, 2.58810E-02, 4.92970E-03], [0.00000E+00, 0.00000E+00, 0.00000E+00, 3.73400E-05, 9.97570E-02, 2.06790E-01, 2.44780E-02], [0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 9.17420E-04, 3.16774E-01, 2.38760E-01], [0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 0.00000E+00, 4.97930E-02, 1.09910E+00]]) Et = Ea + np.sum(Es, 1) GTxs = scrb.CrossSection(Et, Ea, Es, name="Guide Tube") ``` -------------------------------- ### Initialize CMFD Acceleration Source: https://scarabee.readthedocs.io/en/latest/examples/moc_c5g7.html Set up CMFD acceleration at the pin cell level with energy condensation to 3 groups. ```python moc.cmfd = scrb.CMFD(3*17*[pitch], 3*17*[pitch], [[0,1], [2,4], [5,6]]) ``` -------------------------------- ### Run MOC Solver Source: https://scarabee.readthedocs.io/en/latest/examples/moc_c5g7.html Generate tracks with specified quadrature and spacing, set convergence tolerances, and execute the solver. ```python moc.generate_tracks(64, 0.05, scrb.YamamotoTabuchi6()) moc.keff_tolerance = 1.E-5 moc.flux_tolerance = 1.E-5 moc.solve() ``` -------------------------------- ### Execute simulation and view output Source: https://scarabee.readthedocs.io/en/latest/examples/pwr_assembly_depletion.html Launches the depletion simulation and displays the resulting log output. ```python asmbly.solve() ``` ```text [info] Running Time Step 0 [info] Exposure: 0.000E+00 MWd/kg [info] Time : 0.000E+00 days [info] [info] Predictor: [info] Initializing Dancoff correction calculation components. [info] Computing Dancoff corrections for the fuel. [info] Computing Dancoff corrections for the cladding. [info] Creating quadrature [info] Number of azimuthal angles: 64 [info] Maximum track spacing: 0.03 cm [info] Tracing tracks [info] Renormalizing segment lengths [info] Determining track connections [info] Time spent drawing tracks: 0.13736 s. [info] [info] Kinf: 1.21004 [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.21004 [info] Buckling: 0.00355 [info] [info] Corrector: [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.19074 [info] Buckling: 0.00325 [info] [info] ------------------------------------------------------------ [info] Running Time Step 1 [info] Exposure: 1.000E-02 MWd/kg [info] Time : 2.758E-01 days [info] [info] Predictor: [info] Computing Dancoff corrections for the fuel. [info] Computing Dancoff corrections for the cladding. [info] [info] Kinf: 1.19596 [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.19596 [info] Buckling: 0.00333 [info] [info] Corrector: [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.19262 [info] Buckling: 0.00328 [info] [info] ------------------------------------------------------------ [info] Running Time Step 2 [info] Exposure: 2.000E-02 MWd/kg [info] Time : 5.516E-01 days [info] [info] Predictor: [info] Computing Dancoff corrections for the fuel. [info] Computing Dancoff corrections for the cladding. [info] [info] Kinf: 1.18645 [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.18645 [info] Buckling: 0.00318 [info] [info] Corrector: [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.17929 [info] Buckling: 0.00307 [info] [info] ------------------------------------------------------------ [info] Running Time Step 3 [info] Exposure: 3.000E-02 MWd/kg [info] Time : 8.274E-01 days [info] [info] Predictor: [info] Computing Dancoff corrections for the fuel. [info] Computing Dancoff corrections for the cladding. [info] [info] Kinf: 1.17906 [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.17906 [info] Buckling: 0.00306 [info] [info] Corrector: [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.17555 [info] Buckling: 0.00301 [info] [info] ------------------------------------------------------------ [info] Running Time Step 4 [info] Exposure: 4.000E-02 MWd/kg [info] Time : 1.103E+00 days [info] [info] Predictor: [info] Computing Dancoff corrections for the fuel. [info] Computing Dancoff corrections for the cladding. [info] [info] Kinf: 1.17545 [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.17545 [info] Buckling: 0.00300 [info] [info] Corrector: [info] [info] Performing P1 criticality spectrum calculation [info] Kinf : 1.17357 [info] Buckling: 0.00297 [info] [info] ------------------------------------------------------------ [info] Running Time Step 5 [info] Exposure: 5.000E-02 MWd/kg [info] Time : 1.379E+00 days [info] [info] Predictor: ``` -------------------------------- ### Material.__init__ Source: https://scarabee.readthedocs.io/en/latest/api/materials.html Creates a new Material definition with specified temperature. The density is determined by computing the sum of fractions in the `MaterialCompositon`. ```APIDOC ## Material.__init__ ### Description Creates a new Material definition with specified temperature. The density is determined by computing the sum of fractions in the `MaterialCompositon`. If the fractions are atoms, then the density units are interpreted as atoms per barn-centimeter. If the fractions are weight, then the density units are interpreted as grams per cubic-centimeter. ### Method __init__ ### Parameters - **comp** (MaterialComposition) - Required - The material composition. - **temp** (float) - Required - Temperature. - **ndl** (NDLibrary) - Required - Nuclear data library. ### Request Example ```python material = Material(comp, temp, ndl) ``` ### Response No return value. ``` -------------------------------- ### scarabee.reseau.GuideTube Source: https://scarabee.readthedocs.io/en/latest/_sources/api/tool_chains.rst.txt Class representing a guide tube in a PWR assembly. ```APIDOC ## scarabee.reseau.GuideTube ### Description Class representing a guide tube in a PWR assembly. ### Class `scarabee.reseau.GuideTube` ### Module `scarabee.reseau` ``` -------------------------------- ### PWRAssembly.__init__ Source: https://scarabee.readthedocs.io/en/latest/_modules/scarabee/reseau/pwr_assembly.html Constructor for the PWRAssembly class. Initializes a new PWRAssembly instance with the given parameters for performing lattice calculations. ```APIDOC ## PWRAssembly.__init__ ### Description Initializes a PWRAssembly instance responsible for performing all lattice calculations necessary to produce few-group cross sections for a single PWR assembly. ### Method Constructor ### Parameters - **shape** (tuple of int) - Required - The number of pin cells in the full assembly along x and y. - **pitch** (float) - Required - The spacing between fuel pins. - **ndl** (NDLibrary) - Required - Nuclear data library used for the calculation. - **cells** (list of list of FuelPin or GuideTube) - Required - All of the cells which describe the assembly geometry. Should be consistent with the symmetry argument. - **moderator** (dict) - Optional - Parameters for defining the moderator. Acceptable keys: boron-ppm (float, default 800), temperature (float, default 570), pressure (float, default 15.5), legendre-order (int, default 1), material (scarabee.Material). Default is an empty dictionary. - **symmetry** (Symmetry) - Optional - Symmetry of the fuel assembly. Default is Symmetry.Quarter. - **independent_quadrant** (bool) - Optional - If symmetry is Symmetry.Quarter and true, the quarter assembly is treated as an independent assembly. Default is False. - **linear_power** (float) - Optional - Linear power density of the full assembly in kW/cm. Default is 42. - **assembly_pitch** (optional float) - Optional - Spacing between fuel assemblies. If None, calculated from shape and pitch. Default is None. - **spacer_grid_width** (optional float) - Optional - Width of the spacer grid material between pin cells. Default is None. - **spacer_grid** (optional Material) - Optional - Material defining the spacer grid between pin cells. - **grid_sleeve_width** (optional float) - Optional - Width of the grid sleeve around the assembly. Default is None. - **grid_sleeve** (optional Material) - Optional - Material defining the grid sleeve around the assembly. ### Attributes - **shape** (tuple of int) - The number of pin cells in the full assembly along x and y. - **pitch** (float) - The spacing between fuel pins. - **symmetry** (Symmetry) - Symmetry of the fuel assembly. - **independent_quadrant** (bool) - Whether the quarter assembly is treated as independent. - **assembly_pitch** (float) - Spacing between fuel assemblies. - **fuel_volume_fraction** (float) - Fraction of the assembly occupied by fuel. ``` -------------------------------- ### recompute_all_guide_tube_fill_xs: Recompute guide tube fill cross sections Source: https://scarabee.readthedocs.io/en/latest/_modules/scarabee/reseau/pwr_assembly.html Computes and applies all cross sections for the fill objects of guide tubes, which could be for burnable poison rods or control rods. Iterates over all cells and sets fill cross sections for depletion step -1 on GuideTube instances. ```python def recompute_all_guide_tube_fill_xs(self) -> None: """ Computes and applies all cross sections for the fill objects of guide tubes. These could be for burnable poison rods or control rods. """ for j in range(len(self.cells)): for i in range(len(self.cells[j])): cell = self.cells[j][i] if isinstance(cell, GuideTube): cell.set_fill_xs_for_depletion_step(-1, self._ndl) ``` -------------------------------- ### Legendre64.__init__ Source: https://scarabee.readthedocs.io/en/latest/api/moc.html Constructor for the Legendre64 polar quadrature class. Initializes a sixty-four point Legendre polar quadrature. ```APIDOC ## Legendre64.__init__ ### Description Constructor for the Legendre64 polar quadrature class. Initializes a sixty-four point Legendre polar quadrature. ### Method Constructor ### Signature __init__(_self : scarabee._scarabee.Legendre64_) → None ### Parameters - **_self** (Legendre64) - Required - The Legendre64 instance. ### Returns None ``` -------------------------------- ### Plot Geometry Source: https://scarabee.readthedocs.io/en/latest/examples/moc_c5g7.html Launch the graphical geometry plotter to verify the system setup. ```python moc.plot() ``` -------------------------------- ### SANMDiffusionDriver.__init__ Source: https://scarabee.readthedocs.io/en/latest/api/diffusion.html Initializes a nodal diffusion solver with a DiffusionGeometry instance. ```APIDOC ## __init__(geom) ### Description Initializes a nodal diffusion solver. ### Method Constructor ### Parameters - **geom** (DiffusionGeometry) - Required - Problem definition to solve. ### Returns None ### Example ```python driver = SANMDiffusionDriver(geom) ``` ``` -------------------------------- ### set_fill_xs_for_depletion_step method Source: https://scarabee.readthedocs.io/en/latest/_modules/scarabee/reseau/guide_tube.html Constructs the CrossSection objects for the fill of the guide tube at a specified depletion step. The depletion step changes the poison composition if filled with a burnable poison rod. Returns early if the guide tube is empty, otherwise sets the center, gap, clad, and poison cross sections for a BurnablePoisonRod fill. ```python def set_fill_xs_for_depletion_step(self, t: int, ndl: NDLibrary) -> None: """ Constructs the CrossSection objects for the fill of the guide tube at the specified depletion step. The depletion step changes the poison composition, if filled with a burnable poison rod. Parameters ---------- t : int Index for the depletion step. ndl : NDLibrary Nuclear data library to use for cross sections. """ if self.empty: return if isinstance(self.fill, BurnablePoisonRod): self.fill.set_center_xs(ndl) self.fill.set_gap_xs(ndl) self.fill.set_clad_xs(ndl) self.fill.set_poison_xs_for_depletion_step(t, ndl) ``` -------------------------------- ### FluxCalculator.__init__ Source: https://scarabee.readthedocs.io/en/latest/api/materials.html Creates a FluxCalculator instance for a resonant isotope. ```APIDOC ## FluxCalculator.__init__ ### Description Creates a FluxCalculator instance for a resonant isotope. ### Parameters - **energy_boundaries** (ndarray) - Boundaries of the energy groups from low to high energy. - **sig_t** (ndarray) - Microscopic total cross section of resonant isotope in each group. - **sig_s** (ndarray) - Microscopic scattering cross section of resonant isotope in each group. - **awr** (float) - Atomic weight ratio of the resonant isotope. ### Returns None ``` -------------------------------- ### flux(i, j, g) Source: https://scarabee.readthedocs.io/en/latest/api/moc.html Gets the CMFD scalar flux in a specified tile and energy group. ```APIDOC ## flux(i, j, g) ### Description Gets the CMFD flux in a desired tile and group. ### Method flux(i, j, g) ### Parameters - **i** (int) - Required - x index of tile. - **j** (int) - Required - y index of tile. - **g** (int) - Required - Energy group index. ### Returns float - The CMFD scalar flux at cell (i,j) in group g. ``` -------------------------------- ### Get and set moc_polar_quadrature Source: https://scarabee.readthedocs.io/en/latest/_modules/scarabee/reseau/pwr_assembly.html Property and setter for moc_polar_quadrature. The setter directly assigns the provided PolarQuadrature instance without validation. ```python @property def moc_polar_quadrature(self) -> Optional[PolarQuadrature]: return self._moc_polar_quadrature @moc_polar_quadrature.setter def moc_polar_quadrature(self, pq: PolarQuadrature) -> None: self._moc_polar_quadrature = pq ``` -------------------------------- ### Branch.__init__ Source: https://scarabee.readthedocs.io/en/latest/api/depletion.html Creates a Branch object. ```APIDOC ## Branch.__init__ ### Description Creates a Branch object. ```