Source code for matrix_toolkit.pde.equations.heat

"""
Heat equation: ∂u/∂t = α∇²u
"""

import numpy as np
from scipy import sparse
from typing import Dict, Any

from matrix_toolkit.pde.base import BasePDEEquation
from matrix_toolkit.pde.config import PDEConfig  # 添加这行


[docs] class HeatEquation(BasePDEEquation): """ The heat/diffusion equation: .. math:: \frac{\partial u}{\partial t} = \alpha \nabla^2 u Time discretization using the theta-method: - :math:`\theta = 0`: Forward Euler (explicit) - :math:`\theta = 0.5`: Crank-Nicolson - :math:`\theta = 1`: Backward Euler (implicit) Examples: >>> config = PDEConfig( ... dimension=2, ... mesh_size=32, ... coefficients={'dt': 0.01, 'theta': 0.5} ... ) >>> eq = HeatEquation(config) >>> M = eq.generate_matrix() # System matrix """
[docs] def get_operator_name(self) -> str: return "Heat"
[docs] def get_default_coefficients(self) -> Dict[str, Any]: return { 'diffusion': 1.0, # Thermal diffusivity α 'dt': 0.01, # Time step 'theta': 0.5, # Theta parameter (0.5 = Crank-Nicolson) }
[docs] def generate_matrix(self) -> sparse.spmatrix: """ Generate system matrix for heat equation Returns matrix M such that: M u^{n+1} = RHS(u^n) """ coeffs = self.config.coefficients or self.get_default_coefficients() if self.config.random_params: coeffs = self.randomize_coefficients(self.config.random_seed) alpha = coeffs.get('diffusion', 1.0) dt = coeffs.get('dt', 0.01) theta = coeffs.get('theta', 0.5) # Get spatial discretization (Laplacian) from matrix_toolkit.pde.equations.poisson import PoissonEquation # Create temporary config for Laplacian laplacian_config = PDEConfig( dimension=self.config.dimension, domain=self.config.domain, mesh_size=self.config.mesh_size, boundary_condition=self.config.boundary_condition ) poisson = PoissonEquation(laplacian_config) L = poisson.generate_matrix() # Identity matrix n = self.config.total_dofs() I = sparse.eye(n, format='csr') # Theta-method: (I - θ dt α L) u^{n+1} = (I + (1-θ) dt α L) u^n M = I - theta * dt * alpha * L return M
[docs] def generate_rhs_matrix(self) -> sparse.spmatrix: """Generate RHS matrix for explicit part""" coeffs = self.config.coefficients or self.get_default_coefficients() alpha = coeffs.get('diffusion', 1.0) dt = coeffs.get('dt', 0.01) theta = coeffs.get('theta', 0.5) from matrix_toolkit.pde.equations.poisson import PoissonEquation laplacian_config = PDEConfig( dimension=self.config.dimension, domain=self.config.domain, mesh_size=self.config.mesh_size, boundary_condition=self.config.boundary_condition ) poisson = PoissonEquation(laplacian_config) L = poisson.generate_matrix() n = self.config.total_dofs() I = sparse.eye(n, format='csr') R = I + (1 - theta) * dt * alpha * L return R