CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-py-pde

Python package for solving partial differential equations with a focus on ease of use and performance

Pending
Overview
Eval results
Files

solvers.mddocs/

Solvers

Solver classes provide time integration algorithms for evolving PDE systems with adaptive time stepping, stability control, and parallel computing support through MPI.

Capabilities

Controller

High-level solver controller that manages time integration with automatic solver selection and progress tracking.

class Controller:
    def __init__(self, sol_class, *, t_range, tracker=None):
        """
        Initialize solver controller.
        
        Parameters:
        - sol_class: SolverBase class or instance, time integration solver
        - t_range: float or array-like, time integration range
        - tracker: TrackerBase or list, progress tracking
        """

    def run(self, initial_state, dt=None, **kwargs):
        """
        Run the simulation.
        
        Parameters:
        - initial_state: FieldBase, initial field configuration
        - dt: float, time step (auto-determined if None)
        - kwargs: additional solver parameters
        
        Returns:
        FieldBase: Final field state
        """

    @property
    def solver(self):
        """SolverBase: The underlying solver instance"""

    @property
    def tracker(self):
        """TrackerCollection: Collection of trackers"""

ExplicitSolver

Explicit time stepping methods with adaptive time step control.

class ExplicitSolver:
    def __init__(self, pde, scheme="euler", *, backend="auto", adaptive=False, tolerance=1e-4):
        """
        Initialize explicit solver.
        
        Parameters:
        - pde: PDEBase, the PDE to solve
        - scheme: str, integration scheme ("euler", "runge-kutta", "rk", "rk45")
        - backend: str, computation backend ("auto", "numpy", "numba")
        - adaptive: bool, enable adaptive time stepping
        - tolerance: float, error tolerance for adaptive stepping
        """

    def make_stepper(self, state, dt):
        """
        Create compiled stepper function.
        
        Parameters:
        - state: FieldBase, example state for compilation
        - dt: float, time step
        
        Returns:
        Callable: Compiled stepper function
        """

    @property
    def pde(self):
        """PDEBase: The PDE being solved"""

    @property
    def info(self):
        """dict: Solver information and statistics"""

ImplicitSolver

Implicit time stepping methods for stiff PDEs requiring large time steps.

class ImplicitSolver:
    def __init__(self, pde, *, scheme="backward_euler"):
        """
        Initialize implicit solver.
        
        Parameters:
        - pde: PDEBase, the PDE to solve
        - scheme: str, integration scheme ("backward_euler")
        """

    def solve_newton(self, state, dt, *, newton_options=None):
        """
        Solve nonlinear system using Newton's method.
        
        Parameters:
        - state: FieldBase, current state
        - dt: float, time step
        - newton_options: dict, Newton solver options
        
        Returns:
        FieldBase: Updated state
        """

CrankNicolsonSolver

Crank-Nicolson scheme providing second-order accuracy in time.

class CrankNicolsonSolver:
    def __init__(self, pde):
        """
        Initialize Crank-Nicolson solver for linear PDEs.
        
        Parameters:
        - pde: PDEBase, the PDE to solve (must be linear)
        """

    def make_stepper(self, state, dt):
        """
        Create stepper for Crank-Nicolson scheme.
        
        Parameters:
        - state: FieldBase, example state
        - dt: float, time step
        
        Returns:
        Callable: Stepper function
        """

AdamsBashforthSolver

Adams-Bashforth multi-step method with higher-order accuracy.

class AdamsBashforthSolver:
    def __init__(self, pde, *, order=2):
        """
        Initialize Adams-Bashforth solver.
        
        Parameters:
        - pde: PDEBase, the PDE to solve
        - order: int, order of the method (1-4)
        """

    @property
    def order(self):
        """int: Order of the Adams-Bashforth method"""

    def make_stepper(self, state, dt):
        """
        Create multi-step stepper function.
        
        Parameters:
        - state: FieldBase, example state  
        - dt: float, time step
        
        Returns:
        Callable: Multi-step stepper function
        """

ScipySolver

Interface to SciPy's ODE integration methods with automatic stiffness detection.

class ScipySolver:
    def __init__(self, pde, *, method="RK45"):
        """
        Initialize SciPy solver wrapper.
        
        Parameters:
        - pde: PDEBase, the PDE to solve
        - method: str, SciPy integration method 
                 ("RK45", "RK23", "DOP853", "Radau", "BDF", "LSODA")
        """

    @property
    def method(self):
        """str: SciPy integration method being used"""

    def solve(self, initial_state, t_span, **kwargs):
        """
        Solve using SciPy integration.
        
        Parameters:
        - initial_state: FieldBase, initial condition
        - t_span: tuple, (t_start, t_end)
        - kwargs: additional SciPy solver options
        
        Returns:
        FieldBase: Final state
        """

ExplicitMPISolver

MPI-parallel explicit solver for distributed computing (requires MPI installation).

class ExplicitMPISolver:
    def __init__(self, pde, *, scheme="euler"):
        """
        Initialize MPI parallel explicit solver.
        
        Parameters:
        - pde: PDEBase, the PDE to solve
        - scheme: str, integration scheme
        
        Note:
        Only available if MPI dependencies are installed
        """

    @property
    def is_mpi_root(self):
        """bool: True if this is the root MPI process"""

    def make_stepper(self, state, dt):
        """
        Create MPI-parallel stepper.
        
        Parameters:
        - state: FieldBase, example state
        - dt: float, time step
        
        Returns:
        Callable: MPI-parallel stepper function
        """

Solver Registry

Functions for managing and discovering available solvers.

def registered_solvers():
    """
    Get list of all registered solver names.
    
    Returns:
    list of str: Names of available solvers
    """

SolverBase

Base class providing common solver functionality.

class SolverBase:
    @classmethod
    def from_name(cls, name, pde, **kwargs):
        """
        Create solver instance by name.
        
        Parameters:
        - name: str, solver name
        - pde: PDEBase, PDE to solve
        - kwargs: additional solver parameters
        
        Returns:
        SolverBase: Solver instance
        """

    @classmethod
    def registered_solvers(cls):
        """
        Get list of registered solver names.
        
        Returns:
        list of str: Available solver names
        """

    def make_stepper(self, state, dt=None):
        """
        Create time stepping function (abstract method).
        
        Parameters:
        - state: FieldBase, example state for compilation
        - dt: float, time step
        
        Returns:
        Callable: Compiled stepper function
        """
    @property
    def supports_adaptive_stepping(self):
        """bool: Whether solver supports adaptive time steps"""

    def diagnose_performance(self, steps=100, *, state=None):
        """
        Analyze solver performance characteristics.
        
        Parameters:
        - steps: int, number of test steps
        - state: FieldBase, test state (created if None)
        
        Returns:
        dict: Performance diagnostics
        """

    def check_state_compatibility(self, state):
        """
        Check if state is compatible with solver.
        
        Parameters:
        - state: FieldBase, state to check
        
        Raises:
        ValueError: If incompatible
        """

Usage Examples

Basic Solver Usage

import pde

# Set up problem
grid = pde.UnitGrid([64, 64], periodic=False)
state = pde.ScalarField.random_uniform(grid, 0.2, 0.3)
eq = pde.DiffusionPDE(diffusivity=0.1)

# Use explicit solver
solver = pde.ExplicitSolver(eq, adaptive=True)
result = eq.solve(state, t_range=10.0, solver=solver)

print(f"Solver info: {solver.info}")

Comparing Solver Performance

import pde
import time

# Set up test problem
grid = pde.UnitGrid([32, 32], periodic=True)
state = pde.ScalarField.random_uniform(grid)
eq = pde.AllenCahnPDE()

solvers = {
    "explicit": pde.ExplicitSolver(eq),
    "implicit": pde.ImplicitSolver(eq), 
    "crank_nicolson": pde.CrankNicolsonSolver(eq),
    "scipy_rk45": pde.ScipySolver(eq, method="RK45")
}

# Time each solver
for name, solver in solvers.items():
    start_time = time.time()
    result = eq.solve(state.copy(), t_range=1.0, solver=solver)
    elapsed = time.time() - start_time
    print(f"{name}: {elapsed:.3f}s")

Advanced Solver Configuration

import pde

# Set up stiff PDE requiring implicit methods
grid = pde.CartesianGrid([[0, 10]], [128])
eq = pde.DiffusionPDE(diffusivity=100)  # High diffusivity = stiff

# Configure implicit solver with Newton options
newton_opts = {
    "maxiter": 10,
    "atol": 1e-8,
    "rtol": 1e-6
}

solver = pde.ImplicitSolver(eq)
state = pde.ScalarField.random_uniform(grid)

# Use controller for automatic management
controller = pde.Controller(
    solver, 
    t_range=1.0,
    tracker=pde.ProgressTracker()
)

result = controller.run(state, dt=0.1)
print(f"Simulation completed successfully")

Adaptive Time Stepping

import pde

# Problem with varying time scales
grid = pde.UnitGrid([64])
eq = pde.KuramotoSivashinskyPDE()
state = eq.get_initial_condition(grid)

# Enable adaptive stepping
solver = pde.ExplicitSolver(eq, adaptive=True)

# Set up detailed tracking
tracker = [
    pde.DataTracker(interrupts=0.1),
    pde.RuntimeTracker(interrupts=1.0)
]

result = eq.solve(
    state, 
    t_range=100.0,
    solver=solver,
    tracker=tracker,
    dt=0.01,  # Initial time step
    adaptive={"atol": 1e-4, "rtol": 1e-3}  # Tolerance for adaptation
)

print(f"Adaptive stepping completed")

Solver Registry

Function for discovering available solver types.

def registered_solvers():
    """
    Get list of all registered solver names.
    
    Returns:
    list of str: Names of available solver classes
    """

Install with Tessl CLI

npx tessl i tessl/pypi-py-pde

docs

boundaries.md

fields.md

grids.md

index.md

pdes.md

solvers.md

storage.md

trackers.md

visualization.md

tile.json