Python package for solving partial differential equations with a focus on ease of use and performance
npx @tessl/cli install tessl/pypi-py-pde@0.45.0A comprehensive Python library for solving partial differential equations (PDEs) with a focus on ease of use and performance. Provides classes for defining grids on which scalar and tensor fields can be represented, with differential operators computed using numba-compiled finite difference methods for high performance.
pip install py-pdeimport pdeCommon usage imports:
from pde import ScalarField, UnitGrid, CartesianGrid, DiffusionPDE, ExplicitSolverimport pde
# Create a simple 1D grid
grid = pde.UnitGrid([64], periodic=False)
# Initialize a scalar field with random data
field = pde.ScalarField.random_uniform(grid)
# Define a simple diffusion PDE
eq = pde.DiffusionPDE(diffusivity=0.1)
# Set up boundary conditions
bc = {"derivative": 0} # Neumann boundary conditions
# Solve the PDE using explicit time stepping
result = eq.solve(field, t_range=10, bc=bc)
print(f"Final field statistics: mean={result.average:.3f}, std={result.std:.3f}")py-pde is built around several key components that work together:
The numba compilation system provides high-performance finite difference operators, while the modular design allows easy customization and extension for specialized applications.
Define and manipulate scalar, vector, and tensor fields on discrete grids with automatic differentiation and mathematical operations.
class ScalarField:
def __init__(self, grid, data=None, *, label=None): ...
@classmethod
def random_uniform(cls, grid, vmin=0, vmax=1, **kwargs): ...
def laplace(self, bc, **kwargs): ...
def gradient(self, bc): ...
class VectorField:
def __init__(self, grid, data=None, *, label=None): ...
def divergence(self, bc): ...
def curl(self, bc): ...
class Tensor2Field:
def __init__(self, grid, data=None, *, label=None): ...Create spatial domains with various coordinate systems including Cartesian, polar, spherical, and cylindrical grids.
class UnitGrid:
def __init__(self, shape, periodic=True): ...
class CartesianGrid:
def __init__(self, bounds, shape, periodic=False): ...
class PolarSymGrid:
def __init__(self, radius, shape, periodic=True): ...
class SphericalSymGrid:
def __init__(self, radius, shape): ...
class CylindricalSymGrid:
def __init__(self, radius, bounds, shape, periodic_z=True): ...Built-in partial differential equations and tools for defining custom PDEs with automatic operator compilation.
class PDE:
def __init__(self, rhs, *, noise=None, is_sde_value=None): ...
class DiffusionPDE:
def __init__(self, diffusivity=1, *, noise=None, bc=None): ...
class AllenCahnPDE:
def __init__(self, a=1, b=1, *, noise=None, bc=None): ...
class WavePDE:
def __init__(self, speed=1, *, noise=None, bc=None): ...
def solve_laplace_equation(grid, bc, *, solver="auto"): ...
def solve_poisson_equation(grid, rhs, bc, *, solver="auto"): ...Time integration algorithms for evolving PDE systems with adaptive time stepping and parallel computing support.
class Controller:
def __init__(self, sol_class, *, t_range, tracker=None): ...
class ExplicitSolver:
def __init__(self, pde, *, scheme="euler", adaptive=False): ...
class ImplicitSolver:
def __init__(self, pde, *, scheme="backward_euler"): ...
class CrankNicolsonSolver:
def __init__(self, pde): ...
class ScipySolver:
def __init__(self, pde, *, method="RK45"): ...Comprehensive boundary condition system supporting Dirichlet, Neumann, mixed, and periodic conditions with expression-based inhomogeneous boundaries.
class DirichletBC:
def __init__(self, value, *, rank=0): ...
class NeumannBC:
def __init__(self, value, *, rank=0): ...
class MixedBC:
def __init__(self, value, const, *, rank=0): ...
def set_default_bc(bc): ...Monitor simulation progress, collect data, create visualizations, and implement custom analysis during time evolution.
class DataTracker:
def __init__(self, interrupts=1, *, filename=None): ...
class PlotTracker:
def __init__(self, interrupts=1, *, filename=None): ...
class ProgressTracker:
def __init__(self, interrupts="0:10"): ...
class SteadyStateTracker:
def __init__(self, atol=1e-8, rtol=1e-5, interrupts=1): ...Manage simulation data with support for various storage backends including memory, files, and movie generation.
class MemoryStorage:
def __init__(self, *, write_mode="truncate_once"): ...
class FileStorage:
def __init__(self, filename, *, info=None, write_mode="truncate_once"): ...
class MovieStorage:
def __init__(self, filename, *, movie_writer="auto"): ...Create movies and interactive plots from field data with automatic scaling and customizable styling.
def movie(storage, filename=None, *, progress=True, **kwargs): ...
def plot_kymograph(storage, *, field_index=0, transpose=False): ...
def plot_interactive(field, title=None, *, fig_num=1): ...# Common type aliases used throughout the API
Real = Union[int, float]
ArrayLike = Union[np.ndarray, list, tuple]
GridAxes = Union[int, Sequence[int]]
BoundaryData = Union[str, dict, Callable]
InterruptData = Union[Real, str, Sequence]