CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyamg

Algebraic Multigrid (AMG) solvers for large sparse linear systems with Python interface

Pending
Overview
Eval results
Files

multilevel-solver.mddocs/

MultilevelSolver Class

The core solver class that manages AMG hierarchies and provides solve methods with extensive control over the solution process. This class represents a complete multigrid hierarchy with operators, grids, and smoothers at each level.

Capabilities

Main Solver Class

The primary class for managing and executing AMG solvers.

class MultilevelSolver:
    """
    Multilevel AMG solver managing hierarchy of operators and grids.
    
    Manages the complete AMG hierarchy including:
    - Level operators (matrices)  
    - Prolongation and restriction operators
    - Pre and post smoothers
    - Coarse grid solver
    
    Provides methods for solving linear systems using multigrid cycles
    and accessing hierarchy information.
    
    Attributes:
    - levels: list of level dictionaries containing operators
    - A: list of matrices at each level
    - P: list of prolongation operators  
    - R: list of restriction operators
    - presmoother: list of pre-smoothing operators
    - postsmoother: list of post-smoothing operators
    """
    
    def solve(self, b, x0=None, tol=1e-5, maxiter=None, 
              cycle='V', accel=None, callback=None, residuals=None, **kwargs):
        """
        Solve Ax = b using multigrid cycles.
        
        Main solution method supporting various multigrid cycles,
        convergence criteria, and Krylov acceleration.
        
        Parameters:
        - b: array-like, right-hand side vector
        - x0: array-like, initial guess (default: zero vector)
        - tol: float, convergence tolerance (default 1e-5)
        - maxiter: int, maximum iterations (default: automatic)
        - cycle: str, multigrid cycle type:
            * 'V': V-cycle (default, most efficient)
            * 'W': W-cycle (more robust, higher cost)  
            * 'F': F-cycle (flexible cycle)
        - accel: str, Krylov acceleration method:
            * None: no acceleration (default)
            * 'cg': conjugate gradient acceleration
            * 'gmres': GMRES acceleration
            * 'bicgstab': BiCGSTAB acceleration
            * 'fgmres': flexible GMRES
        - callback: callable, function called after each iteration
        - residuals: list, stores residual norms if provided
        - return_residuals: bool, return residual history
        
        Returns:
        array: solution vector x such that ||b - Ax|| < tol * ||b||
        
        Raises:
        ValueError: if b has wrong dimensions or parameters are invalid
        RuntimeError: if solver fails to converge within maxiter
        """
    
    def aspreconditioner(self, cycle='V'):
        """
        Return linear operator for use as preconditioner.
        
        Creates scipy LinearOperator that applies one multigrid
        cycle, suitable for use with Krylov methods.
        
        Parameters:
        - cycle: str, multigrid cycle type ('V', 'W', 'F')
        
        Returns:
        scipy.sparse.linalg.LinearOperator: preconditioner operator
            with matvec method applying multigrid cycle
        
        Raises:
        ValueError: if cycle type is invalid
        """
    
    def __repr__(self):
        """
        String representation showing hierarchy information.
        
        Returns:
        str: formatted hierarchy summary including:
            - Number of levels
            - Grid complexity (total unknowns / fine grid unknowns)  
            - Operator complexity (total nonzeros / fine grid nonzeros)
            - Coarse solver information
            - Per-level statistics (unknowns, nonzeros, percentages)
        """
    
    def __len__(self):
        """
        Number of levels in the hierarchy.
        
        Returns:
        int: number of levels (fine grid is level 0)
        """

Usage Examples:

import pyamg
import numpy as np
from scipy.sparse.linalg import gmres

# Create solver and examine hierarchy
A = pyamg.gallery.poisson((100, 100))
ml = pyamg.ruge_stuben_solver(A)
print(ml)  # Display hierarchy information
print(f"Number of levels: {len(ml)}")

# Basic solve with V-cycle
b = np.random.rand(A.shape[0])
x = ml.solve(b)

# Solve with W-cycle and custom tolerance
x = ml.solve(b, cycle='W', tol=1e-8)

# Solve with initial guess
x0 = np.ones(A.shape[0])
x = ml.solve(b, x0=x0, maxiter=50)

# Use as preconditioner with Krylov method
M = ml.aspreconditioner()
x, info = gmres(A, b, M=M, tol=1e-8)

# Monitor convergence
residuals = []
x = ml.solve(b, residuals=residuals)
print(f"Convergence in {len(residuals)} iterations")

# Custom callback function
def callback(x):
    r = np.linalg.norm(b - A*x)
    print(f"Residual: {r:.2e}")

x = ml.solve(b, callback=callback)

Level Access and Hierarchy Information

Methods and attributes for inspecting the multigrid hierarchy.

class MultilevelSolver:
    
    @property 
    def A(self):
        """
        List of matrices at each level.
        
        Returns:
        list: sparse matrices [A0, A1, ..., A_{L-1}]
            where A0 is the fine grid matrix
        """
    
    @property
    def P(self):
        """  
        List of prolongation operators.
        
        Returns:
        list: prolongation matrices [P0, P1, ..., P_{L-2}]
            where Pi maps from level i+1 to level i
        """
    
    @property
    def R(self):
        """
        List of restriction operators.
        
        Returns: 
        list: restriction matrices [R0, R1, ..., R_{L-2}]
            where Ri maps from level i to level i+1
        """
    
    @property
    def levels(self):
        """
        Complete level information.
        
        Returns:
        list: level dictionaries containing:
            - 'A': operator matrix
            - 'P': prolongation operator (if not coarsest)
            - 'R': restriction operator (if not coarsest) 
            - 'presmoother': pre-smoothing operator
            - 'postsmoother': post-smoothing operator
            - Additional level-specific data
        """
        
    def grid_complexity(self):
        """
        Compute grid complexity of hierarchy.
        
        Grid complexity measures memory overhead as ratio of
        total unknowns across all levels to fine grid unknowns.
        
        Returns:
        float: grid complexity = sum(Ni) / N0
            where Ni is number of unknowns at level i
        """
    
    def operator_complexity(self):
        """
        Compute operator complexity of hierarchy.
        
        Operator complexity measures storage overhead as ratio of
        total nonzeros across all levels to fine grid nonzeros.
        
        Returns:
        float: operator complexity = sum(nnz(Ai)) / nnz(A0)
        """

Usage Examples:

# Examine hierarchy structure
A = pyamg.gallery.linear_elasticity((50, 50))
ml = pyamg.smoothed_aggregation_solver(A)

print(f"Grid complexity: {ml.grid_complexity():.2f}")
print(f"Operator complexity: {ml.operator_complexity():.2f}")

# Access level operators
print(f"Fine grid size: {ml.A[0].shape}")
print(f"Coarse grid size: {ml.A[-1].shape}")

# Examine prolongation operators
for i, P in enumerate(ml.P):
    print(f"P{i} maps {P.shape[1]} -> {P.shape[0]} points")

# Access complete level information
for i, level in enumerate(ml.levels):
    A_level = level['A']
    print(f"Level {i}: {A_level.shape[0]} unknowns, "
          f"{A_level.nnz} nonzeros")

Cycle Control and Advanced Solving

Methods for controlling multigrid cycle behavior and advanced solution strategies.

class MultilevelSolver:
    
    def cycle(self, level, x, b, cycle='V'):
        """
        Apply one multigrid cycle starting at given level.
        
        Low-level method for applying multigrid cycles with
        explicit level control. Used internally by solve().
        
        Parameters:
        - level: int, starting level (0 = fine grid)
        - x: array, solution vector (modified in-place)
        - b: array, right-hand side vector  
        - cycle: str, cycle type ('V', 'W', 'F')
        
        Returns:
        None (x is modified in-place)
        """
        
    def _solve_level0(self, x, b, **kwargs):
        """
        Apply smoothing at finest level.
        
        Internal method applying pre/post smoothing at level 0.
        
        Parameters:
        - x: array, solution vector (modified in-place)
        - b: array, right-hand side
        - **kwargs: smoothing parameters
        """

Solver Diagnostics and Utilities

Methods for analyzing solver performance and behavior.

def multilevel_solver(A, **kwargs):
    """
    Alias for MultilevelSolver constructor.
    
    Provided for backward compatibility and alternative naming.
    
    Parameters:
    - A: sparse matrix, coefficient matrix
    - **kwargs: solver construction parameters
    
    Returns:
    MultilevelSolver: AMG solver instance
    """

Performance and Usage Guidelines

Cycle Selection

  • V-cycle: Most efficient, suitable for most problems
  • W-cycle: More robust for difficult problems, higher computational cost
  • F-cycle: Flexible cycle, adaptive coarse grid correction

Memory Management

  • Grid complexity > 2.0 may indicate memory issues
  • Operator complexity > 3.0 suggests aggressive coarsening
  • Use max_levels and max_coarse to control hierarchy size

Convergence Monitoring

  • Default tolerance is relative: ||r|| < tol * ||b||
  • Use callback functions to monitor intermediate progress
  • Store residual history with residuals parameter
  • Set reasonable maxiter to prevent infinite loops

Preconditioner Usage

  • Single V-cycle typically effective for preconditioning
  • W-cycle may be needed for very difficult problems
  • Use with CG for SPD problems, GMRES for general problems
  • Combine with Krylov methods for optimal performance

Common Issues

  • Slow convergence: Try W-cycle or different solver method
  • Memory errors: Reduce max_levels or increase max_coarse
  • Poor scaling: Check operator and grid complexity ratios
  • Stagnation: May need better coarse grid solver or different method

Install with Tessl CLI

npx tessl i tessl/pypi-pyamg

docs

aggregation-methods.md

gallery.md

high-level-interface.md

index.md

krylov-methods.md

multilevel-solver.md

relaxation-methods.md

solver-constructors.md

strength-of-connection.md

utilities.md

tile.json