RadCluster
Graph-based cluster dynamics for irradiated materials
Loading...
Searching...
No Matches
Functions
py_utils.materials.eurofer97.declaration Namespace Reference

Functions

np.ndarray _xi (np.ndarray n)
 
np.ndarray _coalescence_kernel (np.ndarray D_eff, float A_pref)
 
np.ndarray _absorb_kernel (np.ndarray D_partner, float A_pref)
 
np.ndarray _annihilation_kernel (np.ndarray D_v, np.ndarray D_i, float A_pref)
 
np.ndarray _source_array (np.ndarray P_indexed)
 
np.ndarray _trap_mutation_kernel (int V, float T)
 
np.ndarray _resolution_kernel (int V, float phi_dot, float b0)
 
 build_eurofer_rag (input_data, reaction_rates, *str equations="discrete", str cascade="fission")
 

Detailed Description

materials/eurofer97/declaration.py — EUROFER-97 RAG declaration (Layer 2).

Builds the host-specific reaction admissibility graph G_Eur and its
contiguous ODE-index :class:`StateLayout` for the reduced-activation
ferritic-martensitic steel EUROFER-97, following Ghoniem (2026),
*A Generalized Graph-Based Cluster Dynamics Framework for Irradiated
Materials*, Section 4.

This module is a *declaration*, not an integrator.  It

  * declares the EUROFER-97 populations (Eqs. 42-46): one bulk SIA
    population and one bulk vacancy population, plus helium as the single
    resolved gas (Eq. 41);
  * adds one :class:`Edge` family per EUROFER process class P1-P8
    (Section 4.3), each mapped to one of the ten abstract
    :class:`EdgeClass` values;
  * registers, for every edge, the size-resolved rate kernel as the
    *precomputed numpy array* already built by :class:`ReactionRates`
    (the abstract core never re-derives a rate); and
  * builds the :class:`StateLayout` that packs the SIA ladder, the
    vacancy ladder, the helium block, and a small conservation-accounting
    aux block into one flat ODE state vector.

The production solver (C++/CVODE) remains the engine; this layer is the
"subclass" in the paper's abstract-base-class analogy — it says *what*
EUROFER-97 is, never *how* to integrate it.

Function Documentation

◆ _absorb_kernel()

np.ndarray py_utils.materials.eurofer97.declaration._absorb_kernel ( np.ndarray  D_partner,
float  A_pref 
)
protected
Cross-character absorption kernel K[m-1, n-1] (Marian growth, P3-like).

For ``<100>_m + <111>_n -> <100>_{m+n}`` (paper Eqs. 79/81 form):

  K_{m,n} = 8 pi (xi_m + xi_n) (D^{100}_m + D^{111}_n) / Omega^(2/3)

The sessile ⟨100⟩ primary contributes zero diffusivity, so only the mobile
½⟨111⟩ partner ``D_partner = D_SIA_eff`` drives the capture.  Primary axis
m = ⟨100⟩ size, partner axis n = ½⟨111⟩ size (both span 1..I).

Definition at line 82 of file declaration.py.

◆ _annihilation_kernel()

np.ndarray py_utils.materials.eurofer97.declaration._annihilation_kernel ( np.ndarray  D_v,
np.ndarray  D_i,
float  A_pref 
)
protected
Cross-polarity V-I annihilation kernel K[m-1, n-1] (paper Eq. 81).

K_{m,n} = 8 pi (xi_m + xi_n) (D_m^v + D_n^i) / Omega^(2/3)

The primary axis is the vacancy population (size m), the partner axis
is the SIA population (size n), matching the EUROFER ANNIHILATION edge
declared below (vacancy population as ``population``, SIA population as
``partner_population``).

Definition at line 99 of file declaration.py.

◆ _coalescence_kernel()

np.ndarray py_utils.materials.eurofer97.declaration._coalescence_kernel ( np.ndarray  D_eff,
float  A_pref 
)
protected
Same-polarity binary-growth kernel K[n-1, n'-1] (paper Eqs. 79-80).

K_{n,n'} = 8 pi (xi_n + xi_n') (D_n + D_n') / Omega^(2/3)

``D_eff`` is the precomputed effective 3-D diffusivity array (mobile
sizes non-zero, sessile sizes zero) from :class:`ReactionRates`;
``A_pref`` is ``8 pi / Omega^(2/3)`` assembled from the precomputed
``A_sph_inv_O23`` geometric prefactor.  Sessile-sessile pairs vanish
automatically because their diffusivities are zero.

Definition at line 64 of file declaration.py.

◆ _resolution_kernel()

np.ndarray py_utils.materials.eurofer97.declaration._resolution_kernel ( int  V,
float  phi_dot,
float  b0 
)
protected
Size-resolved radiation re-solution rate kernel Gamma_res[m-1] (P8).

Radiation re-solution He_ell V_m -> He_{ell-1} V_m + He detraps one
helium atom per displacement event; its rate ``Gamma_res(ell) = b0 *
ell * phi_dot`` (binding_energies, paper Eq. 75 / Section 5.3) is
proportional to the helium loading ``ell``, not the vacancy size ``m``.

Without an explicit (m, ell) occupancy axis the per-``ell`` factor
cannot be resolved here; we register the *per-He-atom* re-solution
coefficient ``b0 * phi_dot`` broadcast over the vacancy size axis (so
the C++ kernel arithmetic multiplies it by the local loading ell when
P8 is implemented).  If the displacement rate or b0 is unavailable the
array degrades to all-zero, which cleanly disables P8.

Definition at line 153 of file declaration.py.

◆ _source_array()

np.ndarray py_utils.materials.eurofer97.declaration._source_array ( np.ndarray  P_indexed)
protected
Convert a 1-indexed production array P[size] to a 0-indexed size array.

:func:`production_rates` returns arrays of length ``n_max + 1`` whose
index 0 is unused and index k holds the size-k production rate.  The
SOURCE edge class consumes a 0-indexed size array (size n -> [n-1]).

Definition at line 117 of file declaration.py.

◆ _trap_mutation_kernel()

np.ndarray py_utils.materials.eurofer97.declaration._trap_mutation_kernel ( int  V,
float  T 
)
protected
Size-resolved trap-mutation rate kernel Gamma_TM[m-1] (paper Eq. 75 / P7).

Trap mutation V_m(He) -> V_{m+1} + I_1 is gas-pressure-driven; its rate
``Gamma_TM(m, ell)`` (binding_energies, paper Eq. 75) depends on both the
vacancy size ``m`` and the helium loading ``ell``.  This declaration layer
carries one bulk vacancy population without an explicit (m, ell)
occupancy axis, so the loading-resolved barrier table cannot be collapsed
to a 1-D size array without picking a representative ``ell`` per ``m``.

We register the *spontaneous-mutation envelope*: for each vacancy size m
we evaluate ``Gamma_TM`` at the maximum admissible helium loading
``ell = ell_max(m)`` (the trap-mutation limit, paper Table 27).  Where
that (m, ell) pair is absent from the barrier table (``E_TM`` table only
populates the small over-pressurized bubbles He5-7V1 / He4-6), the rate
is exactly zero — so the returned array is non-zero only on the handful
of sizes for which an atomistic trap-mutation barrier is known and zero
elsewhere.  This is a faithful placeholder: the C++ solver does not yet
evaluate P7 (Stage-2 review), so no run consumes a non-zero value here;
the array documents *where* trap mutation is admissible.

Definition at line 127 of file declaration.py.

◆ _xi()

np.ndarray py_utils.materials.eurofer97.declaration._xi ( np.ndarray  n)
protected
Capture radius in lattice units, xi_n = (3 n / 8 pi)^(1/3) (paper Eq. 79).

Definition at line 59 of file declaration.py.

◆ build_eurofer_rag()

py_utils.materials.eurofer97.declaration.build_eurofer_rag (   input_data,
  reaction_rates,
*str   equations = "discrete",
str   cascade = "fission" 
)
Build the EUROFER-97 reaction admissibility graph and state layout.

Parameters
----------
input_data : InputData
    The loaded EUROFER-97 parameter set (sizes ``I``/``V``, mobility
    cutoffs ``i_mobile``/``v_mobile``, derived physics).
reaction_rates : ReactionRates
    The precomputed rate-constant arrays built from ``input_data``.
    Its attributes are registered verbatim as the RAG kernel library.
equations : {'discrete', 'bin_moment'}
    Selects the SIA / vacancy state-space representation: one ODE per
    size (``discrete``) or the logarithmic bin-moment reduction
    (``bin_moment``, paper Section 5.4).
cascade : {'fission', 'fusion'}
    Selects the cascade production spectrum and, through
    :meth:`HeReductionMode.from_cascade`, the helium reduction
    (fission -> Case 2 decoupled; fusion -> Case 1 mean-field).

Returns
-------
(ReactionAdmissibilityGraph, StateLayout)
    The host-specific graph G_Eur with all kernels registered, and the
    contiguous ODE-index layout that packs it.

Definition at line 176 of file declaration.py.