LinearPDE¶
LinearPDE assembles linear rectangular-domain PDE rows using a
GBMSCApproximation.
from gbmsc_pde import LinearPDE
pde = LinearPDE(approximation)
Equation Form¶
The assembled equation is:
div(D grad u) + v . grad u + r u = f
where:
Dis diagonal diffusion,vis convection velocity,ris reaction,fis the source term.
Boundary conditions are applied later by BoundaryConditions and LinearSolver.
Diffusion¶
pde.add_diffusion_term(-1.0)
Accepted forms:
- scalar: same coefficient in both directions,
- tuple of two scalars:
(D_x, D_y), - callable: reused for both directions,
- tuple of two callables:
(D_x_fn, D_y_fn).
Callables must have signature:
fn(x: np.ndarray, y: np.ndarray) -> np.ndarray
The implementation assembles the product-rule form:
partial_x(D_x partial_x u) + partial_y(D_y partial_y u)
Convection¶
pde.add_convection_term((vx, vy))
Accepted forms are the same as diffusion:
- scalar,
- pair of scalars,
- callable,
- pair of callables.
The assembled term is:
v_x partial_x u + v_y partial_y u
Reaction¶
pde.add_reaction_term(1.0)
Accepted forms:
- scalar,
- callable
(x, y) -> values.
Source¶
pde.add_source_term(lambda x, y: np.ones_like(x))
Accepted forms:
- scalar,
- callable
(x, y) -> values.
Assembly¶
A, b, Mx, My, Mxx, Myy = pde.assemble()
Returns:
A: sparse LinearPDE matrix before boundary conditions,b: right-hand side,Mx,My: first-derivative matrices used by boundary rows.
The solver normally calls assemble() for you.
Example¶
For:
-Delta u = 2 pi^2 sin(pi x) sin(pi y)
use:
pde = LinearPDE(approximation)
pde.add_diffusion_term(-1.0)
pde.add_source_term(
lambda x, y: 2.0 * np.pi**2 * np.sin(np.pi * x) * np.sin(np.pi * y)
)