Source code for WaveBlocksND.KineticOperator
"""The WaveBlocks Project
This file contains code for the representation of the kinetic
operator :math:`-\frac{1}{2} \Delta` in the Fourier space.
@author: R. Bourquin
@copyright: Copyright (C) 2012, 2014 R. Bourquin
@license: Modified BSD License
"""
from functools import reduce
from numpy import roll, exp, pi, square, add
from numpy.fft import fftfreq
__all__ = ["KineticOperator"]
[docs]class KineticOperator(object):
"""This class represents the kinetic operator :math:`T` in Fourier space.
"""
[docs] def __init__(self, grid, eps=None):
r"""Compute the Fourier transformation of the position space representation
of the kinetic operator :math:`T`.
:param grid: The position space grid :math:`\Gamma` of which we compute
its Fourier transform :math:`\Omega`.
:param eps: The semi-classical scaling parameter :math:`\varepsilon`. (optional)
"""
# Cache the value of eps if given
self._eps = eps
# TODO: Consider class "FourierSpaceGrid"
D = grid.get_dimension()
N = grid.get_number_nodes()
T = grid.get_extensions()
# Fourier domain nodes
prefactors = [t / (2.0 * pi) for t in T]
omega = [fftfreq(n, d=1.0 / n) for n in N]
omega = [o / p for o, p in zip(omega, prefactors)]
# Reshape properly
shape = [-1] + (D - 1) * [1]
omega = [o.reshape(roll(shape, i)) for i, o in enumerate(omega)]
# Compute the dot product of omega with itself
omega_sqr = reduce(add, map(square, omega))
# Fourier space grid axes
self._omega = omega
# Omega dot Omega
self._omega_sqr = omega_sqr
[docs] def get_fourier_grid_axes(self):
r"""Return the grid axes of the Fourier space grid :math:`\Omega`.
"""
return tuple([o.copy() for o in self._omega])
[docs] def calculate_operator(self, eps=None):
r"""Calculate the kinetic operator :math:`\hat{T} = \frac{\varepsilon^4}{2} \underline{\omega} \cdot \underline{\omega}`
in Fourier space.
:param eps: The semi-classical scaling parameter :math:`\varepsilon`. It has to
be given here or during the initialization of the current instance.
"""
if eps is None:
eps = self._eps
if eps is None:
# The value was not cached at initialization
raise AttributeError("Parameter eps not given")
self._OpT = 0.5 * eps**4 * self._omega_sqr
[docs] def calculate_exponential(self, factor=1.0):
r"""Calculate the exponential :math:`\exp(\alpha \underline{\omega} \cdot \underline{\omega})`
used in the Strang splitting.
:param factor: The prefactor :math:`\alpha`. It defaults to 1 but is
usually set to :math:`-\frac{i}{2} \varepsilon^2 \tau`
by the caller.
"""
self._expOpT = exp(factor * self._omega_sqr)
[docs] def evaluate_at(self, grid=None):
r"""Evaluate the kinetic operator :math:`\hat{T} = \frac{\varepsilon^4}{2} \underline{\omega} \cdot \underline{\omega}`
in Fourier space. This returns an numpy ``ndarray`` by using a specific :math:`\underline{\omega}`.
:param grid: Unused dummy parameter.
"""
return self._OpT.copy()
[docs] def evaluate_exponential_at(self, grid=None):
r"""Evaluate the exponential :math:`\exp(\alpha \hat{T})` in Fourier space.
This returns a numpy ``ndarray`` by using a specific :math:`\underline{\omega}`.
The factor :math:`\alpha` can be set by the corresponding method.
:param grid: Unused dummy parameter.
"""
return self._expOpT.copy()