コード例 #1
0
    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 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))
コード例 #3
0
    def staticStructureFactor(self,
                              q_range=(1., 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: coherent 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 Static Structure Factor 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_coherent')
        mask = subset.booleanMask()
        weights = N.repeat(weights.array, mask.array)
        weights = weights / N.sqrt(N.add.reduce(weights * weights))
        friction = N.repeat(self.friction.array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

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

        kT = Units.k_B * self.temperature
        natoms = subset.numberOfAtoms()
        sq = 0.
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            sab = N.zeros((natoms, natoms), N.Float)
            for i in range(first_mode, self.nmodes):
                irt = self.rawMode(i).inv_relaxation_time
                d = N.repeat((self.rawMode(i)*v).array, mask.array) \
                       / N.sqrt(friction)
                sab = sab + (d[N.NewAxis, :] - d[:, N.NewAxis])**2 / irt
            sab = sab[N.NewAxis, :, :] * q[:, N.NewAxis, N.NewAxis]**2
            phase = N.exp(-1.j*q[:, N.NewAxis]
                          * N.dot(r, v.array)[N.NewAxis, :]) \
                    * weights[N.NewAxis, :]
            temp = N.sum(phase[:, :, N.NewAxis] * N.exp(-0.5 * kT * sab), 1)
            temp = N.sum(N.conjugate(phase) * temp, 1)
            sq = sq + temp.real
        return InterpolatingFunction((q, ), sq / len(random_vectors))
コード例 #4
0
ファイル: BrownianModes.py プロジェクト: acousticpants/mmtk
    def staticStructureFactor(self, q_range = (1., 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: coherent 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 Static Structure Factor 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_coherent')
        mask = subset.booleanMask()
        weights = N.repeat(weights.array, mask.array)
        weights = weights/N.sqrt(N.add.reduce(weights*weights))
        friction = N.repeat(self.friction.array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

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

        kT = Units.k_B*self.temperature
        natoms = subset.numberOfAtoms()
        sq = 0.
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            sab = N.zeros((natoms, natoms), N.Float)
            for i in range(first_mode, self.nmodes):
                irt = self.rawMode(i).inv_relaxation_time
                d = N.repeat((self.rawMode(i)*v).array, mask.array) \
                       / N.sqrt(friction)
                sab = sab + (d[N.NewAxis,:]-d[:,N.NewAxis])**2/irt
            sab = sab[N.NewAxis,:,:]*q[:, N.NewAxis, N.NewAxis]**2
            phase = N.exp(-1.j*q[:, N.NewAxis]
                          * N.dot(r, v.array)[N.NewAxis, :]) \
                    * weights[N.NewAxis, :]
            temp = N.sum(phase[:, :, N.NewAxis]*N.exp(-0.5*kT*sab), 1)
            temp = N.sum(N.conjugate(phase)*temp, 1)
            sq = sq + temp.real
        return InterpolatingFunction((q,), sq/len(random_vectors))
コード例 #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))
コード例 #6
0
ファイル: BrownianModes.py プロジェクト: acousticpants/mmtk
    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))
コード例 #7
0
    def coherentScatteringFunction(self, q, time_range = (0., None, None),
                                   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_coherent')
        mask = subset.booleanMask()
        weights = N.repeat(weights.array, mask.array)
        weights = weights/N.sqrt(N.add.reduce(weights*weights))
        friction = N.repeat(self.friction.array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

        first, last, step = (time_range + (None, None))[:3]
        if last is None:
            last = 3./self.rawMode(first_mode).inv_relaxation_time
        if step is None:
            step = (last-first)/300.
        time = N.arange(first, last, step)

        natoms = subset.numberOfAtoms()
        kT = Units.k_B*self.temperature
        fcoh = N.zeros((len(time),), N.Complex)
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            phase = N.exp(-1.j*q*N.dot(r, v.array))
            for ai in range(natoms):
                fbt = N.zeros((natoms, len(time)), N.Float)
                for i in range(first_mode, self.nmodes):
                    irt = self.rawMode(i).inv_relaxation_time
                    d = q * N.repeat((self.rawMode(i)*v).array, mask.array) \
                        / N.sqrt(friction)
                    ft = N.exp(-irt*time)/irt
                    N.add(fbt,
                          d[ai] * d[:, N.NewAxis] * ft[N.NewAxis, :],
                          fbt)
                    N.add(fbt,
                          (-0.5/irt) * (d[ai]**2 + d[:, N.NewAxis]**2),
                          fbt)
                N.add(fcoh,
                      weights[ai]*phase[ai]
                      * N.dot(weights*N.conjugate(phase),
                              N.exp(kT*fbt)),
                      fcoh)
        return InterpolatingFunction((time,), fcoh.real/len(random_vectors))
コード例 #8
0
    def coherentScatteringFunction(self,
                                   q,
                                   time_range=(0., None, None),
                                   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_coherent')
        mask = subset.booleanMask()
        weights = N.repeat(weights.array, mask.array)
        weights = weights / N.sqrt(N.add.reduce(weights * weights))
        friction = N.repeat(self.friction.array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

        first, last, step = (time_range + (None, None))[:3]
        if last is None:
            last = 3. / self.rawMode(first_mode).inv_relaxation_time
        if step is None:
            step = (last - first) / 300.
        time = N.arange(first, last, step)

        natoms = subset.numberOfAtoms()
        kT = Units.k_B * self.temperature
        fcoh = N.zeros((len(time), ), N.Complex)
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            phase = N.exp(-1.j * q * N.dot(r, v.array))
            for ai in range(natoms):
                fbt = N.zeros((natoms, len(time)), N.Float)
                for i in range(first_mode, self.nmodes):
                    irt = self.rawMode(i).inv_relaxation_time
                    d = q * N.repeat((self.rawMode(i)*v).array, mask.array) \
                        / N.sqrt(friction)
                    ft = N.exp(-irt * time) / irt
                    N.add(fbt, d[ai] * d[:, N.NewAxis] * ft[N.NewAxis, :], fbt)
                    N.add(fbt, (-0.5 / irt) * (d[ai]**2 + d[:, N.NewAxis]**2),
                          fbt)
                N.add(
                    fcoh, weights[ai] * phase[ai] *
                    N.dot(weights * N.conjugate(phase), N.exp(kT * fbt)), fcoh)
        return InterpolatingFunction((time, ), fcoh.real / len(random_vectors))
コード例 #9
0
    def incoherentScatteringFunction(self, q, time_range = (0., None, None),
                                     subset=None, random_vectors=15,
                                     first_mode = 6):
        if subset is None:
            subset = self.universe
        mask = subset.booleanMask()
        weights_inc = self.universe.getParticleScalar('b_incoherent')
        weights_inc = N.repeat(weights_inc.array**2, mask.array)
        weights_inc = weights_inc/N.add.reduce(weights_inc)
        friction = N.repeat(self.friction.array, mask.array)
        mass = N.repeat(self.universe.masses().array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

        first, last, step = (time_range + (None, None))[:3]
        if last is None:
            last = 3./self.weighedMode(first_mode).inv_relaxation_time
        if step is None:
            step = (last-first)/300.
        time = N.arange(first, last, step)

        natoms = subset.numberOfAtoms()
        kT = Units.k_B*self.temperature
        finc = N.zeros((len(time),), N.Float)
        eisf = 0.
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            phase = N.exp(-1.j*q*N.dot(r, v.array))
            faat = N.zeros((natoms, len(time)), N.Float)
            eisf_sum = N.zeros((natoms,), N.Float)
            for i in range(first_mode, self.nmodes):
                irt = self.rawMode(i).inv_relaxation_time
                d = q * N.repeat((self.rawMode(i)*v).array, mask.array) \
                    / N.sqrt(friction)
                ft = (N.exp(-irt*time)-1.)/irt
                N.add(faat,
                      d[:, N.NewAxis]**2 * ft[N.NewAxis, :],
                      faat)
                N.add(eisf_sum, -d**2/irt, eisf_sum)
            N.add(finc,
                  N.sum(weights_inc[:, N.NewAxis]
                        * N.exp(kT*faat), 0),
                  finc)
            eisf = eisf + N.sum(weights_inc*N.exp(kT*eisf_sum))
        return InterpolatingFunction((time,), finc/len(random_vectors))
コード例 #10
0
    def incoherentScatteringFunction(self,
                                     q,
                                     time_range=(0., None, None),
                                     subset=None,
                                     random_vectors=15,
                                     first_mode=6):
        if subset is None:
            subset = self.universe
        mask = subset.booleanMask()
        weights_inc = self.universe.getParticleScalar('b_incoherent')
        weights_inc = N.repeat(weights_inc.array**2, mask.array)
        weights_inc = weights_inc / N.add.reduce(weights_inc)
        friction = N.repeat(self.friction.array, mask.array)
        mass = N.repeat(self.universe.masses().array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

        first, last, step = (time_range + (None, None))[:3]
        if last is None:
            last = 3. / self.weighedMode(first_mode).inv_relaxation_time
        if step is None:
            step = (last - first) / 300.
        time = N.arange(first, last, step)

        natoms = subset.numberOfAtoms()
        kT = Units.k_B * self.temperature
        finc = N.zeros((len(time), ), N.Float)
        eisf = 0.
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            phase = N.exp(-1.j * q * N.dot(r, v.array))
            faat = N.zeros((natoms, len(time)), N.Float)
            eisf_sum = N.zeros((natoms, ), N.Float)
            for i in range(first_mode, self.nmodes):
                irt = self.rawMode(i).inv_relaxation_time
                d = q * N.repeat((self.rawMode(i)*v).array, mask.array) \
                    / N.sqrt(friction)
                ft = (N.exp(-irt * time) - 1.) / irt
                N.add(faat, d[:, N.NewAxis]**2 * ft[N.NewAxis, :], faat)
                N.add(eisf_sum, -d**2 / irt, eisf_sum)
            N.add(finc, N.sum(weights_inc[:, N.NewAxis] * N.exp(kT * faat), 0),
                  finc)
            eisf = eisf + N.sum(weights_inc * N.exp(kT * eisf_sum))
        return InterpolatingFunction((time, ), finc / len(random_vectors))
コード例 #11
0
    def staticStructureFactor(self,
                              q_range=(1., 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_coherent')
        mask = subset.booleanMask()
        weights = N.repeat(weights.array, mask.array)
        weights = weights / N.sqrt(N.add.reduce(weights * weights))
        friction = N.repeat(self.friction.array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

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

        kT = Units.k_B * self.temperature
        natoms = subset.numberOfAtoms()
        sq = 0.
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            sab = N.zeros((natoms, natoms), N.Float)
            for i in range(first_mode, self.nmodes):
                irt = self.rawMode(i).inv_relaxation_time
                d = N.repeat((self.rawMode(i)*v).array, mask.array) \
                       / N.sqrt(friction)
                sab = sab + (d[N.NewAxis, :] - d[:, N.NewAxis])**2 / irt
            sab = sab[N.NewAxis, :, :] * q[:, N.NewAxis, N.NewAxis]**2
            phase = N.exp(-1.j*q[:, N.NewAxis]
                          * N.dot(r, v.array)[N.NewAxis, :]) \
                    * weights[N.NewAxis, :]
            temp = N.sum(phase[:, :, N.NewAxis] * N.exp(-0.5 * kT * sab), 1)
            temp = N.sum(N.conjugate(phase) * temp, 1)
            sq = sq + temp.real
        return InterpolatingFunction((q, ), sq / len(random_vectors))
コード例 #12
0
    def staticStructureFactor(self, q_range = (1., 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_coherent')
        mask = subset.booleanMask()
        weights = N.repeat(weights.array, mask.array)
        weights = weights/N.sqrt(N.add.reduce(weights*weights))
        friction = N.repeat(self.friction.array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

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

        kT = Units.k_B*self.temperature
        natoms = subset.numberOfAtoms()
        sq = 0.
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            sab = N.zeros((natoms, natoms), N.Float)
            for i in range(first_mode, self.nmodes):
                irt = self.rawMode(i).inv_relaxation_time
                d = N.repeat((self.rawMode(i)*v).array, mask.array) \
                       / N.sqrt(friction)
                sab = sab + (d[N.NewAxis,:]-d[:,N.NewAxis])**2/irt
            sab = sab[N.NewAxis,:,:]*q[:, N.NewAxis, N.NewAxis]**2
            phase = N.exp(-1.j*q[:, N.NewAxis]
                          * N.dot(r, v.array)[N.NewAxis, :]) \
                    * weights[N.NewAxis, :]
            temp = N.sum(phase[:, :, N.NewAxis]*N.exp(-0.5*kT*sab), 1)
            temp = N.sum(N.conjugate(phase)*temp, 1)
            sq = sq + temp.real
        return InterpolatingFunction((q,), sq/len(random_vectors))
コード例 #13
0
    def incoherentScatteringFunction(self,
                                     q,
                                     time_range=(0., None, None),
                                     subset=None,
                                     random_vectors=15,
                                     first_mode=6):
        """
        :param q: the angular wavenumber
        :type q: float
        :param time_range: the time values at which the mean-square
                           displacement is evaluated, specified as a
                           range tuple (first, last, step).
                           The defaults are first=0, last=
                           20 times the longest vibration perdiod,
                           and step defined such that 300 points are
                           used in total.
        :type time_range: tuple
        :param subset: the subset of the universe used in the calculation
                       (default: the whole universe)
        :type subset: :class:~MMTK.Collections.GroupOfAtoms
        :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 Incoherent Scattering Function as a function of time
        :rtype: Scientific.Functions.Interpolation.InterpolatingFunction
        """
        if subset is None:
            subset = self.universe
        mask = subset.booleanMask()
        weights_inc = self.universe.getParticleScalar('b_incoherent')
        weights_inc = N.repeat(weights_inc.array**2, mask.array)
        weights_inc = weights_inc / N.add.reduce(weights_inc)
        friction = N.repeat(self.friction.array, mask.array)
        mass = N.repeat(self.universe.masses().array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

        first, last, step = (time_range + (None, None))[:3]
        if last is None:
            last = 3. / self.weighedMode(first_mode).inv_relaxation_time
        if step is None:
            step = (last - first) / 300.
        time = N.arange(first, last, step)

        natoms = subset.numberOfAtoms()
        kT = Units.k_B * self.temperature
        finc = N.zeros((len(time), ), N.Float)
        eisf = 0.
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            phase = N.exp(-1.j * q * N.dot(r, v.array))
            faat = N.zeros((natoms, len(time)), N.Float)
            eisf_sum = N.zeros((natoms, ), N.Float)
            for i in range(first_mode, self.nmodes):
                irt = self.rawMode(i).inv_relaxation_time
                d = q * N.repeat((self.rawMode(i)*v).array, mask.array) \
                    / N.sqrt(friction)
                ft = (N.exp(-irt * time) - 1.) / irt
                N.add(faat, d[:, N.NewAxis]**2 * ft[N.NewAxis, :], faat)
                N.add(eisf_sum, -d**2 / irt, eisf_sum)
            N.add(finc, N.sum(weights_inc[:, N.NewAxis] * N.exp(kT * faat), 0),
                  finc)
            eisf = eisf + N.sum(weights_inc * N.exp(kT * eisf_sum))
        return InterpolatingFunction((time, ), finc / len(random_vectors))
コード例 #14
0
    def coherentScatteringFunction(self,
                                   q,
                                   time_range=(0., None, None),
                                   subset=None,
                                   weights=None,
                                   random_vectors=15,
                                   first_mode=6):
        """
        :param q: the angular wavenumber
        :type q: float
        :param time_range: the time values at which the mean-square
                           displacement is evaluated, specified as a
                           range tuple (first, last, step).
                           The defaults are first=0, last=
                           20 times the longest vibration perdiod,
                           and step defined such that 300 points are
                           used in total.
        :type time_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: coherent 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 Coherent Scattering Function as a function of time
        :rtype: Scientific.Functions.Interpolation.InterpolatingFunction
        """
        if subset is None:
            subset = self.universe
        if weights is None:
            weights = self.universe.getParticleScalar('b_coherent')
        mask = subset.booleanMask()
        weights = N.repeat(weights.array, mask.array)
        weights = weights / N.sqrt(N.add.reduce(weights * weights))
        friction = N.repeat(self.friction.array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

        first, last, step = (time_range + (None, None))[:3]
        if last is None:
            last = 3. / self.rawMode(first_mode).inv_relaxation_time
        if step is None:
            step = (last - first) / 300.
        time = N.arange(first, last, step)

        natoms = subset.numberOfAtoms()
        kT = Units.k_B * self.temperature
        fcoh = N.zeros((len(time), ), N.Complex)
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            phase = N.exp(-1.j * q * N.dot(r, v.array))
            for ai in range(natoms):
                fbt = N.zeros((natoms, len(time)), N.Float)
                for i in range(first_mode, self.nmodes):
                    irt = self.rawMode(i).inv_relaxation_time
                    d = q * N.repeat((self.rawMode(i)*v).array, mask.array) \
                        / N.sqrt(friction)
                    ft = N.exp(-irt * time) / irt
                    N.add(fbt, d[ai] * d[:, N.NewAxis] * ft[N.NewAxis, :], fbt)
                    N.add(fbt, (-0.5 / irt) * (d[ai]**2 + d[:, N.NewAxis]**2),
                          fbt)
                N.add(
                    fcoh, weights[ai] * phase[ai] *
                    N.dot(weights * N.conjugate(phase), N.exp(kT * fbt)), fcoh)
        return InterpolatingFunction((time, ), fcoh.real / len(random_vectors))
コード例 #15
0
ファイル: BrownianModes.py プロジェクト: acousticpants/mmtk
    def incoherentScatteringFunction(self, q, time_range = (0., None, None),
                                     subset=None, random_vectors=15,
                                     first_mode = 6):
        """
        :param q: the angular wavenumber
        :type q: float
        :param time_range: the time values at which the mean-square
                           displacement is evaluated, specified as a
                           range tuple (first, last, step).
                           The defaults are first=0, last=
                           20 times the longest vibration perdiod,
                           and step defined such that 300 points are
                           used in total.
        :type time_range: tuple
        :param subset: the subset of the universe used in the calculation
                       (default: the whole universe)
        :type subset: :class:`~MMTK.Collections.GroupOfAtoms`
        :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 Incoherent Scattering Function as a function of time
        :rtype: Scientific.Functions.Interpolation.InterpolatingFunction
        """
        if subset is None:
            subset = self.universe
        mask = subset.booleanMask()
        weights_inc = self.universe.getParticleScalar('b_incoherent')
        weights_inc = N.repeat(weights_inc.array**2, mask.array)
        weights_inc = weights_inc/N.add.reduce(weights_inc)
        friction = N.repeat(self.friction.array, mask.array)
        mass = N.repeat(self.universe.masses().array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

        first, last, step = (time_range + (None, None))[:3]
        if last is None:
            last = 3./self.weighedMode(first_mode).inv_relaxation_time
        if step is None:
            step = (last-first)/300.
        time = N.arange(first, last, step)

        natoms = subset.numberOfAtoms()
        kT = Units.k_B*self.temperature
        finc = N.zeros((len(time),), N.Float)
        eisf = 0.
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            phase = N.exp(-1.j*q*N.dot(r, v.array))
            faat = N.zeros((natoms, len(time)), N.Float)
            eisf_sum = N.zeros((natoms,), N.Float)
            for i in range(first_mode, self.nmodes):
                irt = self.rawMode(i).inv_relaxation_time
                d = q * N.repeat((self.rawMode(i)*v).array, mask.array) \
                    / N.sqrt(friction)
                ft = (N.exp(-irt*time)-1.)/irt
                N.add(faat,
                      d[:, N.NewAxis]**2 * ft[N.NewAxis, :],
                      faat)
                N.add(eisf_sum, -d**2/irt, eisf_sum)
            N.add(finc,
                  N.sum(weights_inc[:, N.NewAxis]
                        * N.exp(kT*faat), 0),
                  finc)
            eisf = eisf + N.sum(weights_inc*N.exp(kT*eisf_sum))
        return InterpolatingFunction((time,), finc/len(random_vectors))
コード例 #16
0
ファイル: BrownianModes.py プロジェクト: acousticpants/mmtk
    def coherentScatteringFunction(self, q, time_range = (0., None, None),
                                   subset=None, weights=None,
                                   random_vectors=15, first_mode = 6):
        """
        :param q: the angular wavenumber
        :type q: float
        :param time_range: the time values at which the mean-square
                           displacement is evaluated, specified as a
                           range tuple (first, last, step).
                           The defaults are first=0, last=
                           20 times the longest vibration perdiod,
                           and step defined such that 300 points are
                           used in total.
        :type time_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: coherent 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 Coherent Scattering Function as a function of time
        :rtype: Scientific.Functions.Interpolation.InterpolatingFunction
        """
        if subset is None:
            subset = self.universe
        if weights is None:
            weights = self.universe.getParticleScalar('b_coherent')
        mask = subset.booleanMask()
        weights = N.repeat(weights.array, mask.array)
        weights = weights/N.sqrt(N.add.reduce(weights*weights))
        friction = N.repeat(self.friction.array, mask.array)
        r = N.repeat(self.universe.configuration().array, mask.array)

        first, last, step = (time_range + (None, None))[:3]
        if last is None:
            last = 3./self.rawMode(first_mode).inv_relaxation_time
        if step is None:
            step = (last-first)/300.
        time = N.arange(first, last, step)

        natoms = subset.numberOfAtoms()
        kT = Units.k_B*self.temperature
        fcoh = N.zeros((len(time),), N.Complex)
        random_vectors = Random.randomDirections(random_vectors)
        for v in random_vectors:
            phase = N.exp(-1.j*q*N.dot(r, v.array))
            for ai in range(natoms):
                fbt = N.zeros((natoms, len(time)), N.Float)
                for i in range(first_mode, self.nmodes):
                    irt = self.rawMode(i).inv_relaxation_time
                    d = q * N.repeat((self.rawMode(i)*v).array, mask.array) \
                        / N.sqrt(friction)
                    ft = N.exp(-irt*time)/irt
                    N.add(fbt,
                          d[ai] * d[:, N.NewAxis] * ft[N.NewAxis, :],
                          fbt)
                    N.add(fbt,
                          (-0.5/irt) * (d[ai]**2 + d[:, N.NewAxis]**2),
                          fbt)
                N.add(fcoh,
                      weights[ai]*phase[ai]
                      * N.dot(weights*N.conjugate(phase),
                              N.exp(kT*fbt)),
                      fcoh)
        return InterpolatingFunction((time,), fcoh.real/len(random_vectors))