schr.utils.absorbing_boundary module

Absorbing boundary conditions for quantum simulations.

This module provides various implementations of absorbing boundary conditions to prevent artificial reflections from domain edges in quantum dynamics simulations.

Available implementations:

  • Polynomial masks (\(\cos^n\) profiles)

  • Exponential decay masks

  • Complex absorbing potentials (CAP)

  • Perfectly matched layers (PML-like)

schr.utils.absorbing_boundary.complex_absorbing_potential(coords: ~jax.Array | tuple[~jax.Array, ...], domain: tuple[float, float] | tuple[tuple[float, float], ...], width: float | tuple[float, ...], strength: float = 1.0, order: int = 2, dtype: ~numpy.dtype = <class 'jax.numpy.complex64'>) Array[source]

Create complex absorbing potential (CAP).

Generates an imaginary potential -i*η*f(x) that acts as an absorber when added to the Hamiltonian. The negative imaginary part causes exponential decay of the wavefunction amplitude.

The CAP method is more sophisticated than simple masks as it properly absorbs incoming waves while minimizing reflections.

Parameters:
  • coords – Grid coordinates (see polynomial_absorbing_mask).

  • domain – Domain boundaries (see polynomial_absorbing_mask).

  • width – CAP layer width.

  • strength – CAP strength parameter η. Typical: 0.1-2.0.

  • order – Polynomial order for CAP profile. Typical: 2-4.

  • dtype – JAX complex dtype for the potential.

Returns:

Complex absorbing potential (purely imaginary, negative values). Returns 0 in interior and -i*η*f(x) in absorption layer.

Example

>>> # Use in Hamiltonian: V_total = V_physical + CAP
>>> X, Y = jnp.meshgrid(jnp.linspace(-5, 5, 256), jnp.linspace(-3, 3, 128))
>>> cap = complex_absorbing_potential((X, Y), ((-5, 5), (-3, 3)), 1.0, strength=0.5)
>>> V_total = V_physical + cap
schr.utils.absorbing_boundary.create_absorbing_boundary(coords: Array | tuple[Array, ...], domain: tuple[float, float] | tuple[tuple[float, float], ...], width: float | tuple[float, ...], method: Literal['polynomial', 'exponential', 'cap', 'mask_potential'] = 'polynomial', **kwargs) Array[source]

Create absorbing boundary using specified method.

Convenience function that dispatches to the appropriate absorbing boundary implementation.

Parameters:
  • coords – Grid coordinates.

  • domain – Domain boundaries.

  • width – Absorption layer width.

  • method – Absorbing boundary method: - “polynomial”: Polynomial mask (cos^n profile) - “exponential”: Exponential mask - “cap”: Complex absorbing potential - “mask_potential”: Real absorbing potential

  • **kwargs – Additional method-specific parameters: - order: Polynomial order (polynomial, cap, mask_potential) - strength: Absorption strength (exponential, cap, mask_potential) - dtype: Data type

Returns:

Absorbing boundary (mask or potential depending on method).

Example

>>> # Polynomial mask (default)
>>> X, Y = jnp.meshgrid(jnp.linspace(-5, 5, 256), jnp.linspace(-3, 3, 128))
>>> mask = create_absorbing_boundary((X, Y), ((-5, 5), (-3, 3)), 1.0)
>>>
>>> # Complex absorbing potential
>>> cap = create_absorbing_boundary(
...     (X, Y), ((-5, 5), (-3, 3)), 1.0,
...     method="cap", strength=0.5
... )
schr.utils.absorbing_boundary.create_absorption_mask(X: Array, Y: Array, x_range: tuple[float, float], y_range: tuple[float, float], width: float = 1000.0, strength: float = 1.0, order: int = 4) Array[source]

Legacy interface for 2D polynomial absorbing mask.

Provided for backward compatibility with existing code.

Parameters:
  • X – 2D coordinate grids.

  • Y – 2D coordinate grids.

  • x_range – (x_min, x_max) tuple.

  • y_range – (y_min, y_max) tuple.

  • width – Absorption region width.

  • strength – Unused (kept for compatibility).

  • order – Polynomial order.

Returns:

2D absorption mask.

Example

>>> X, Y = jnp.meshgrid(jnp.linspace(-5, 5, 256), jnp.linspace(-3, 3, 128))
>>> mask = create_absorption_mask(X, Y, (-5, 5), (-3, 3), width=1.0)
schr.utils.absorbing_boundary.exponential_absorbing_mask(coords: ~jax.Array | tuple[~jax.Array, ...], domain: tuple[float, float] | tuple[tuple[float, float], ...], width: float | tuple[float, ...], strength: float = 5.0, dtype: ~numpy.dtype = <class 'jax.numpy.float32'>) Array[source]

Create exponential absorbing boundary mask.

Uses exponential decay profile: exp(-strength * (1 - t)^2) where t is the normalized distance from boundary. Provides very strong absorption near edges.

Parameters:
  • coords – Grid coordinates (see polynomial_absorbing_mask).

  • domain – Domain boundaries (see polynomial_absorbing_mask).

  • width – Absorption layer width.

  • strength – Absorption strength parameter (higher = stronger). Typical: 3-10.

  • dtype – JAX dtype for the mask.

Returns:

Absorption mask (0 to 1).

Example

>>> X, Y = jnp.meshgrid(jnp.linspace(-5, 5, 256), jnp.linspace(-3, 3, 128))
>>> mask = exponential_absorbing_mask((X, Y), ((-5, 5), (-3, 3)), 1.0, strength=7.0)
schr.utils.absorbing_boundary.mask_absorbing_potential(coords: ~jax.Array | tuple[~jax.Array, ...], domain: tuple[float, float] | tuple[tuple[float, float], ...], width: float | tuple[float, ...], strength: float = 100.0, order: int = 2, dtype: ~numpy.dtype = <class 'jax.numpy.float32'>) Array[source]

Create real-valued absorbing potential (mask potential).

Similar to CAP but uses a large positive real potential instead of imaginary. This creates a “soft wall” that exponentially suppresses the wavefunction. Simpler than CAP but may cause more reflections.

Parameters:
  • coords – Grid coordinates.

  • domain – Domain boundaries.

  • width – Absorption layer width.

  • strength – Potential height. Very large values (50-1000) recommended.

  • order – Polynomial order for potential profile.

  • dtype – JAX dtype for the potential.

Returns:

Real absorbing potential (positive values in absorption layer).

Example

>>> x = jnp.linspace(-10, 10, 512)
>>> V_absorb = mask_absorbing_potential(x, (-10, 10), width=2.0, strength=500.0)
>>> V_total = V_physical + V_absorb
schr.utils.absorbing_boundary.polynomial_absorbing_mask(coords: ~jax.Array | tuple[~jax.Array, ...], domain: tuple[float, float] | tuple[tuple[float, float], ...], width: float | tuple[float, ...], order: int = 4, dtype: ~numpy.dtype = <class 'jax.numpy.float32'>) Array[source]

Create polynomial absorbing boundary mask using \(\cos^n\) profile.

Uses a smooth polynomial profile based on \(\cos(\pi t/2)^n\) where \(t\) is the normalized distance from the boundary. Higher orders provide stronger absorption.

Parameters:
  • coords – Grid coordinates. Single 1D array or tuple of arrays for 2D/3D.

  • domain – Domain boundaries. (min, max) for 1D or tuple of tuples for 2D/3D.

  • width – Absorption layer width (uniform float or per-dimension tuple).

  • order – Polynomial order (higher = stronger absorption). Typical: 2-8.

  • dtype – JAX dtype for the mask.

Returns:

Absorption mask (multiplicative factor from 0 to 1). Returns 1.0 in interior and smoothly decreases to 0 near boundaries.

Raises:

ValueError – If dimensions are inconsistent.

Example

>>> x = jnp.linspace(-10, 10, 512)
>>> mask = polynomial_absorbing_mask(x, (-10, 10), width=2.0, order=4)
>>>
>>> X, Y = jnp.meshgrid(jnp.linspace(-5, 5, 256), jnp.linspace(-3, 3, 128))
>>> mask = polynomial_absorbing_mask(
...     (X, Y),
...     ((-5, 5), (-3, 3)),
...     width=1.0,
...     order=6
... )