spectral_galerkin_heat.physics.spectral_state ============================================= .. py:module:: spectral_galerkin_heat.physics.spectral_state .. autoapi-nested-parse:: Backend-parametrized spectral-solver state (shared by CPU and GPU kernels). These classes hold the precomputed grid, fine-mesh bases, working buffers and spectral propagators for :class:`~spectral_galerkin_heat.solvers.spectral.SpectralSolver`, parametrized by the array module ``xp`` (NumPy or CuPy). Each kernel module exposes a thin :class:`SpectralSolverState` subclass that binds its own ``xp``, so callers construct it as ``SpectralSolverState(phys, geom, num, fine)`` regardless of backend. The state is built at the Python layer only: a dataclass cannot enter the ``@njit`` / ``@cuda.jit`` kernels, so values are unpacked to scalars/arrays at the kernel boundary. Classes ------- .. autoapisummary:: spectral_galerkin_heat.physics.spectral_state.SpectralGrid spectral_galerkin_heat.physics.spectral_state.FineMeshState spectral_galerkin_heat.physics.spectral_state.SolverBuffers spectral_galerkin_heat.physics.spectral_state.BackendHooks spectral_galerkin_heat.physics.spectral_state.SpectralSolverState Functions --------- .. autoapisummary:: spectral_galerkin_heat.physics.spectral_state.precompute_K_KK Module Contents --------------- .. py:class:: SpectralGrid(geom, xp, dtype=np.float32) Immutable grid definitions and reconstruction bases. Plain class (not a ``@dataclass``): the fields are computed from ``(geom, xp)`` in :meth:`__init__`, not passed in, so the generated dataclass ``__init__`` would not fit. The annotated declarations below document the schema and provide defaults for the lazily-built fields (``B_recon`` / ``coords_rec``). .. py:method:: prepare_full_reconstruction(geom) Compute node-centered grids and full-domain reconstruction bases on demand. The bases are kept on the host (NumPy) on both backends: they are used only for final output, so this avoids spending GPU memory when full reconstruction is never requested. .. py:class:: FineMeshState(geom, grid, fine, xp, dtype=np.float32) Handles the moving fine mesh for latent heat/nonlinearities. Plain class (not a ``@dataclass``): fields are computed in :meth:`__init__`. The annotated declarations document the schema and default the late-set ``T_prev`` / ``Q_prev`` to ``None``. .. py:method:: update(laser_state) Update fine mesh basis subsets for x and y axes. .. py:class:: SolverBuffers(num, fine_mesh, xp, dtype=np.float32) Reusable working arrays. Plain class (not a ``@dataclass``): all buffers are allocated from ``(num, fine_mesh, xp)`` in :meth:`__init__`. .. py:class:: BackendHooks Backend primitives that the shared free functions in :mod:`spectral_ops` need but cannot express with ``xp`` alone. Each kernel module builds one and attaches it to its :class:`SpectralSolverState` subclass, so a function like ``reconstruct_surface_temperature(a, SsState)`` reaches the right FFT / ndimage / source-term implementation through ``SsState.hooks``. :ivar idct: Inverse (type-III, ortho) DCT, ``IDCT_II`` in the kernel modules. :vartype idct: callable :ivar ndshift: ``(field, shift_pixels, order, mode, cval) -> shifted_field``: scipy.ndimage on CPU, cupyx.scipy.ndimage on GPU. :vartype ndshift: callable :ivar source_term: Latent-heat source kernel with signature ``(T_curr, T_prev, T_S, T_L, rho, L, dt, out)``. A plain numba ``@njit`` call on CPU, a ``@cuda.jit`` launch on GPU. :vartype source_term: callable :ivar dct: Forward (type-II, ortho) DCT over **all** axes, ``DCT_II`` in the kernel modules. Used by the property-correction volume projection. :vartype dct: callable, optional :ivar corr_source: ``(T, k', a', T_prev, dt, dx, dy, dz) -> f`` fused property-correction forcing ``f = ∇·(k'∇T) - a'∂_tT``. CPU/GPU fast path replacing the six ``xp.gradient`` calls; ``None`` falls back to the ``xp`` finite differences in :func:`spectral_ops.assemble_property_correction`. :vartype corr_source: callable, optional .. py:class:: SpectralSolverState(phys, geom, num, fine, xp) Coordinator class for the spectral method state. Backend-parametrized: pass ``xp=numpy`` or ``xp=cupy``. The kernel modules expose thin subclasses that bind their own ``xp`` (and attach :class:`BackendHooks`) so callers use the ``SpectralSolverState(phys, geom, num, fine)`` signature. Plain class (not a ``@dataclass``): the sub-components are built in :meth:`__init__`. The annotated declarations document the schema and default the late-set ``a`` / ``hooks`` (the latter attached by the per-backend subclass) to ``None``. .. py:function:: precompute_K_KK(phys, num, geom, xp, dtype=np.float32) Compute spectral Propagators (K, KK) based on grid and time step. K = exp(-alpha * k^2 * dt) for ETD1 (Exact integration of linear part) KK = phi_1 / (rho * Cp), where phi_1(z) = (exp(z) - 1) / z, z = -alpha * k^2 * dt