Source code for MDMC.trajectory_analysis.observables.fqt_coh

"""Module for coherent FQt class"""

import numpy as np
import periodictable

from MDMC.common.mathematics import faster_correlation
from MDMC.trajectory_analysis.observables.fqt import AbstractFQt
from MDMC.trajectory_analysis.observables.obs_factory import ObservableFactory


[docs] @ObservableFactory.register(('CoherentIntermediateScatteringFunction', 'FQtCoherent', 'FQtCoh', 'FQt_coh')) class FQtCoherent(AbstractFQt): """ A class for containing, calculating and reading the intermediate scattering function for the coherent dynamic structure factor """ def _set_weights(self) -> None: """Calculate the neutron weighting for coherent scattering""" self.weights = {element: periodictable.elements.symbol(element).neutron.b_c \ if periodictable.elements.symbol(element).neutron.b_c is not None \ else 0 for element in self._trajectory.element_set} def _calculate_FQt_single_Q(self, single_Q_vectors: list) -> 'np.ndarray': # Inherit docstring of abstract method n_t = len(self.t) elements = self._trajectory.element_set FQt_single_Q = np.zeros(n_t) rho_element = {} n_atoms = 0 for element in elements: # Get the positions of all atoms (the configuration) of each # element over time such that ``element_configs`` has time as its # first dimension and each atom of ``element`` as its second indexes = np.where(np.array(self._trajectory.element_list) == element) element_configs = self._trajectory.position[:, indexes[0], :] rho_element[element] = self.calculate_rho_config(element_configs, single_Q_vectors) n_atoms += np.shape(indexes)[1] for element1 in elements: for element2 in elements: # A sum over the Q vectors is performed within ``correlation``. FQt_single_Q += self.weights[element1] \ * self.weights[element2] \ * faster_correlation(rho_element[element1], rho_element[element2])[:n_t] # 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)