Source code for rhodent.response.numpy

from __future__ import annotations

from typing import Collection

import numpy as np

from gpaw.lcaotddft.ksdecomposition import KohnShamDecomposition

from .base import BaseResponse
from ..perturbation import DeltaKick, PerturbationLike, NoPerturbation
from ..density_matrices.frequency import (FrequencyDensityMatrices,
                                          FrequencyDensityMatricesFromDisk)
from ..density_matrices.time import (ConvolutionDensityMatricesFromDisk,
                                     ConvolutionDensityMatricesFromFrequency,
                                     ConvolutionDensityMatrices)
from ..utils import Logger
from ..typing import Array1D


[docs] class ResponseFromDensityMatrices(BaseResponse): """ Response from density matrices saved on disk. Parameters ---------- pulserho_fmt Formatting string for the density matrices saved to disk. The formatting string should be a plain string containing variable placeholders within curly brackets ``{}``. It should not be confused with a formatted string literal (f-string). Example: * pulserho_fmt = ``pulserho/t{time:09.1f}{tag}.npy``. Accepts variables * ``{time}`` - Time in units of as. * ``{tag}`` - Derivative tag, ``''``, ``'-Iomega'``, or ``'-omega2'``. * ``{pulsefreq}`` - Pulse frequency in units of eV. * ``{pulsefwhm}`` - Pulse FWHM in units of fs. ksd KohnShamDecomposition object or file name. perturbation Perturbation that was present during time propagation. calc_size Size of the calculation communicator. """ def __init__(self, pulserho_fmt: str, ksd: KohnShamDecomposition | str, perturbation: PerturbationLike = None, calc_size: int = 1): super().__init__(ksd=ksd, perturbation=perturbation, calc_size=calc_size) self.pulserho_fmt = pulserho_fmt def __str__(self) -> str: lines = [f'{self.__class__.__name__}'] lines += [f' ksd: {self.ksd.filename if self.ksd.filename is not None else "From calc"}'] lines += [f' pulserho_fmt: {self.pulserho_fmt}'] lines += [' perturbation:'] lines += [' ' + line for line in str(self.perturbation).split('\n')] return '\n'.join(lines) def _get_time_density_matrices(self, times: list[float] | Array1D[np.float64], pulses: Collection[PerturbationLike], derivative_order_s: list[int] = [0], real: bool = True, imag: bool = True, log: Logger | None = None, ) -> ConvolutionDensityMatrices: if (len(pulses) == 1 and list(pulses)[0] == self.perturbation) or isinstance(self.perturbation, NoPerturbation): # Yield the density matrices without performing convolution density_matrices = ConvolutionDensityMatricesFromDisk( ksd=self.ksd, pulserho_fmt=self.pulserho_fmt, times=times, pulses=pulses, derivative_order_s=derivative_order_s, real=real, imag=imag, log=log, calc_size=self.calc_size) else: raise NotImplementedError('Pulse convolution of density matrices on disk is not implemented') return density_matrices def _get_frequency_density_matrices(self, frequencies: list[float] | Array1D[np.float64], frequency_broadening: float = 0, real: bool = True, imag: bool = True, log: Logger | None = None, ) -> FrequencyDensityMatrices: raise NotImplementedError('Fourier transformation of density matrices on disk is not implemented')
[docs] class ResponseFromFourierTransform(BaseResponse): """ Response from Fourier transform of density matrices save on disk. Parameters ---------- frho_fmt Formatting string for the density matrices in frequency space saved to disk. The formatting string should be a plain string containing variable placeholders within curly brackets ``{}``. It should not be confused with a formatted string literal (f-string). Example: * frho_fmt = ``frho/w{freq:05.2f}-{reim}.npy``. Accepts variables: * ``{freq}`` - Frequency in units of eV. * ``{reim}`` - ``'Re'`` or ``'Im'`` for Fourier transform of real/imaginary part of density matrix. ksd KohnShamDecomposition object or file name. perturbation Perturbation that was present during time propagation. calc_size Size of the calculation communicator. """ def __init__(self, frho_fmt: str, ksd: KohnShamDecomposition | str, perturbation: PerturbationLike = None, calc_size: int = 1): super().__init__(ksd=ksd, perturbation=perturbation, calc_size=calc_size) if not isinstance(self.perturbation, (DeltaKick, NoPerturbation)): raise NotImplementedError('Only delta kick implemented') self.frho_fmt = frho_fmt def __str__(self) -> str: lines = [f'{self.__class__.__name__}'] lines += [f' ksd: {self.ksd.filename if self.ksd.filename is not None else "From calc"}'] lines += [f' frho_fmt: {self.frho_fmt}'] lines += [' perturbation:'] lines += [' ' + line for line in str(self.perturbation).split('\n')] return '\n'.join(lines) def _get_time_density_matrices(self, times: list[float] | Array1D[np.float64], pulses: Collection[PerturbationLike], derivative_order_s: list[int] = [0], real: bool = True, imag: bool = True, log: Logger | None = None, ) -> ConvolutionDensityMatrices: if not isinstance(self.perturbation, DeltaKick): raise NotImplementedError('Only delta kick implemented') density_matrices = ConvolutionDensityMatricesFromFrequency( ksd=self.ksd, frho_fmt=self.frho_fmt, perturbation=self.perturbation, pulses=pulses, times=times, derivative_order_s=derivative_order_s, real=real, imag=imag, log=log, calc_size=self.calc_size) return density_matrices def _get_frequency_density_matrices(self, frequencies: list[float] | Array1D[np.float64], frequency_broadening: float = 0, real: bool = True, imag: bool = True, log: Logger | None = None, ) -> FrequencyDensityMatrices: if frequency_broadening > 0: raise NotImplementedError(f'Frequency broadening not implemented for {self.__class__.__name__}') density_matrices = FrequencyDensityMatricesFromDisk( ksd=self.ksd, frho_fmt=self.frho_fmt, perturbation=self.perturbation, frequencies=frequencies, real=real, imag=imag, log=log, calc_size=self.calc_size) return density_matrices