Source code for MDMC.trajectory_analysis.observables.fqt_incoh

"""
Module for incoherent FQt class.
"""

import numpy as np

from MDMC.common.mathematics import faster_autocorrelation
from MDMC.common.periodictable_objects import create_list_of_element_objects
from MDMC.trajectory_analysis.observables.concurrency_tools import core_batch, create_executor
from MDMC.trajectory_analysis.observables.fqt import (
    AbstractFQt,
    calc_incoherent_scatt_length,
    calculate_rho,
)
from MDMC.trajectory_analysis.observables.obs_factory import ObservableFactory


[docs] @ObservableFactory.register(('IncoherentIntermediateScatteringFunction', 'FQtIncoherent' 'FQtIncoh', 'FQt_incoh')) class FQtIncoherent(AbstractFQt): """ Class for processing intermediate scattering function for incoherent dynamic structure factor. """ def _set_weights(self) -> None: """Calculate the neutron weighting for incoherent scattering.""" elements_list = create_list_of_element_objects(self._trajectory.element_set) element_weights = {str(element): element.neutron.b_c_i**2\ if element.neutron.b_c_i is not None \ else calc_incoherent_scatt_length(str(element))**2 for element in elements_list} self.weights = [element_weights[str(atom.element)] for atom in [self._trajectory.exportAtom(atom_number=x) for x in range(self._trajectory.n_atoms)]] def _calculate_FQt_single_Q(self, single_Q_vectors: list) -> np.ndarray: # Inherit docstring of abstract method n_t = len(self.t) n_atoms = self._trajectory.n_atoms FQt_single_Q = np.zeros(n_t) weight = self.weights executor = create_executor() configs = np.swapaxes(self._trajectory.position, 1, 2) configs = np.swapaxes(configs, 0, 2) rho_all = calculate_rho(configs, np.array(single_Q_vectors)) futures = core_batch((executor.submit(faster_autocorrelation, rho.T, weights=np.array(weight)) for rho in rho_all)) for future_batch in futures: results = [future.result() for future in future_batch] for result in results: FQt_single_Q += result # Normalise to the number of orthogonal vectors try: norm = np.shape(single_Q_vectors)[0] except IndexError: norm = 1 return FQt_single_Q / (n_atoms * norm)