def EISF(self,
             q_range=(0., 15.),
             subset=None,
             weights=None,
             random_vectors=15,
             first_mode=6):
        if subset is None:
            subset = self.universe
        if weights is None:
            weights = self.universe.getParticleScalar('b_incoherent')
            weights = weights * weights
        weights = weights * subset.booleanMask()
        total = weights.sumOverParticles()
        weights = weights / total

        first, last, step = (q_range + (None, ))[:3]
        if step is None:
            step = (last - first) / 50.
        q = N.arange(first, last, step)

        f = ParticleProperties.ParticleTensor(self.universe)
        for i in range(first_mode, self.nmodes):
            mode = self.rawMode(i)
            f = f + (1. / mode.inv_relaxation_time) * mode.dyadicProduct(mode)
        f = Units.k_B * self.temperature * f / self.friction

        eisf = N.zeros(q.shape, N.Float)
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            for a in subset.atomList():
                exp = N.exp(-v * (f[a] * v))
                N.add(eisf, weights[a] * exp**(q * q), eisf)
        return InterpolatingFunction((q, ), eisf / len(random_vectors))
예제 #2
0
 def anisotropicFluctuations(self, first_mode=6):
     f = ParticleProperties.ParticleTensor(self.universe)
     for i in range(first_mode, self.nmodes):
         mode = self.rawMode(i)
         array = mode.array
         f.array += (array[:, :, N.NewAxis]*array[:, N.NewAxis, :]) \
                    / mode.force_constant
     if self.temperature is not None:
         f.array *= Units.k_B * self.temperature
     return f
예제 #3
0
 def anisotropicFluctuations(self, first_mode=6):
     """Returns a Class:MMTK.ParticleTensor containing the thermal
     fluctuations for each atom in the universe."""
     f = ParticleProperties.ParticleTensor(self.universe)
     for i in range(first_mode, self.nmodes):
         mode = self.rawMode(i)
         array = mode.array
         f.array += (array[:, :, N.NewAxis]*array[:, N.NewAxis, :]) \
                    / mode.force_constant
     f.array *= Units.k_B * self.temperature
     return f
예제 #4
0
 def anisotropicFluctuations(self, first_mode=6):
     f = ParticleProperties.ParticleTensor(self.universe)
     for i in range(first_mode, self.nmodes):
         mode = self.rawMode(i)
         array = mode.array
         f.array += (array[:, :, N.NewAxis]*array[:, N.NewAxis, :]) \
                    / mode.frequency**2
     s = (2. * N.pi)**2
     if self.temperature is not None:
         s /= Units.k_B * self.temperature
     f.array /= s * self.universe.masses().array[:, N.NewAxis, N.NewAxis]
     return f
예제 #5
0
    def EISF(self,
             q_range=(0., 15.),
             subset=None,
             weights=None,
             random_vectors=15,
             first_mode=6):
        """
        :param q_range: the range of angular wavenumber values
        :type q_range: tuple
        :param subset: the subset of the universe used in the calculation
                       (default: the whole universe)
        :type subset: :class:~MMTK.Collections.GroupOfAtoms
        :param weights: the weight to be given to each atom in the average
                        (default: incoherent scattering lengths)
        :type weights: :class:~MMTK.ParticleProperties.ParticleScalar
        :param random_vectors: the number of random direction vectors
                               used in the orientational average
        :type random_vectors: int
        :param first_mode: the first mode to be taken into account for
                           the fluctuation calculation. The default value
                           of 6 is right for molecules in vacuum.
        :type first_mode: int
        :returns: the Elastic Incoherent Structure Factor (EISF) as a
                  function of angular wavenumber
        :rtype: Scientific.Functions.Interpolation.InterpolatingFunction
        """
        if subset is None:
            subset = self.universe
        if weights is None:
            weights = self.universe.getParticleScalar('b_incoherent')
            weights = weights * weights
        weights = weights * subset.booleanMask()
        total = weights.sumOverParticles()
        weights = weights / total

        first, last, step = (q_range + (None, ))[:3]
        if step is None:
            step = (last - first) / 50.
        q = N.arange(first, last, step)

        f = ParticleProperties.ParticleTensor(self.universe)
        for i in range(first_mode, self.nmodes):
            mode = self.rawMode(i)
            f = f + (1. / mode.inv_relaxation_time) * mode.dyadicProduct(mode)
        f = Units.k_B * self.temperature * f / self.friction

        eisf = N.zeros(q.shape, N.Float)
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            for a in subset.atomList():
                exp = N.exp(-v * (f[a] * v))
                N.add(eisf, weights[a] * exp**(q * q), eisf)
        return InterpolatingFunction((q, ), eisf / len(random_vectors))