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))
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))
def evaluationPoints(object, n, smallest = 0.3, largest = 0.5): """Returns a list of |n| points suitable for the evaluation of the electrostatic potential around |object|. The points are chosen at random and uniformly in a shell around the object such that no point has a distance larger than |largest| from any atom or smaller than |smallest| from any non-hydrogen atom. """ atoms = object.atomList() p1, p2 = object.boundingBox() margin = Vector(largest, largest, largest) p1 = p1 - margin p2 = p2 + margin a, b, c = tuple(p2-p1) offset = 0.5*Vector(a, b, c) points = [] while len(points) < n: p = p1 + Random.randomPointInBox(a, b, c) + offset m = 2*largest ok = 1 for atom in atoms: d = (p-atom.position()).length() m = min(m, d) if d < smallest and atom.symbol != 'H': ok = 0 if not ok: break if ok and m <= largest: points.append(p) return points
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))
def evaluationPoints(object, n, smallest=0.3, largest=0.5): """Returns a list of |n| points suitable for the evaluation of the electrostatic potential around |object|. The points are chosen at random and uniformly in a shell around the object such that no point has a distance larger than |largest| from any atom or smaller than |smallest| from any non-hydrogen atom. """ atoms = object.atomList() p1, p2 = object.boundingBox() margin = Vector(largest, largest, largest) p1 = p1 - margin p2 = p2 + margin a, b, c = tuple(p2 - p1) offset = 0.5 * Vector(a, b, c) points = [] while len(points) < n: p = p1 + Random.randomPointInBox(a, b, c) + offset m = 2 * largest ok = 1 for atom in atoms: d = (p - atom.position()).length() m = min(m, d) if d < smallest and atom.symbol != 'H': ok = 0 if not ok: break if ok and m <= largest: points.append(p) return points
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))
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))
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))
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))
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))
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))
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))
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))
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))
def evaluationPoints(system, n, smallest = 0.3, largest = 0.5): """ Generate points in space around a molecule that are suitable for potential evaluation in view of a subsequent charge fit. The points are chosen at random and uniformly in a shell around the system. :param system: the chemical object for which the charges will be fitted :param n: the number of evaluation points to be generated :param smallest: the smallest allowed distance of any evaluation point from any non-hydrogen atom :param largest: the largest allowed value for the distance from an evaluation point to the nearest atom :returns: a list of evaluation points :rtype: list of Scientific.Geometry.Vector """ atoms = system.atomList() p1, p2 = system.boundingBox() margin = Vector(largest, largest, largest) p1 -= margin p2 += margin a, b, c = tuple(p2-p1) offset = 0.5*Vector(a, b, c) points = [] while len(points) < n: p = p1 + Random.randomPointInBox(a, b, c) + offset m = 2*largest ok = 1 for atom in atoms: d = (p-atom.position()).length() m = min(m, d) if d < smallest and atom.symbol != 'H': ok = 0 if not ok: break if ok and m <= largest: points.append(p) return points
def evaluationPoints(system, n, smallest=0.3, largest=0.5): """ Generate points in space around a molecule that are suitable for potential evaluation in view of a subsequent charge fit. The points are chosen at random and uniformly in a shell around the system. :param system: the chemical object for which the charges will be fitted :param n: the number of evaluation points to be generated :param smallest: the smallest allowed distance of any evaluation point from any non-hydrogen atom :param largest: the largest allowed value for the distance from an evaluation point to the nearest atom :returns: a list of evaluation points :rtype: list of Scientific.Geometry.Vector """ atoms = system.atomList() p1, p2 = system.boundingBox() margin = Vector(largest, largest, largest) p1 -= margin p2 += margin a, b, c = tuple(p2 - p1) offset = 0.5 * Vector(a, b, c) points = [] while len(points) < n: p = p1 + Random.randomPointInBox(a, b, c) + offset m = 2 * largest ok = 1 for atom in atoms: d = (p - atom.position()).length() m = min(m, d) if d < smallest and atom.symbol != 'H': ok = 0 if not ok: break if ok and m <= largest: points.append(p) return points
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))
def __call__(self, **options): # Process the keyword arguments self.setCallOptions(options) random.seed(self.getOption('seed')) np.random.seed(self.getOption('seed')) memid = np.random.randint(2000, 9999) np.random.seed(int(time.time() + os.getpid())) Random.initializeRandomNumbersFromTime() # Check if the universe has features not supported by the integrator Features.checkFeatures(self, self.universe) RT = R * self.getOption('T') delta_t = self.getOption('delta_t') server = self.getOption('server') ligand_dir = self.getOption('ligand_dir') dyn_type = self.getOption('dyn_type') server_cmd = '' server_cmd = server + ' -mol2 ' + ligand_dir + 'ligand.mol2' + ' -rb ' + ligand_dir + 'ligand.rb' + ' -gaff gaff.dat -frcmod ' + ligand_dir + 'ligand.frcmod -ictd ' + dyn_type + ' -memid ' + str( memid) + ' > tdout' #print server_cmd tdserver = subprocess.Popen(server_cmd, shell=True, preexec_fn=os.setsid) sleep(0.1) if 'steps_per_trial' in self.call_options.keys(): steps_per_trial = self.getOption('steps_per_trial') ntrials = self.getOption('steps') / steps_per_trial else: steps_per_trial = self.getOption('steps') ntrials = 1 if 'normalize' in self.call_options.keys(): normalize = self.getOption('normalize') else: normalize = False # Get the universe variables needed by the integrator masses = self.universe.masses() fixed = self.universe.getAtomBooleanArray('fixed') nt = self.getOption('threads') comm = self.getOption('mpi_communicator') evaluator = self.universe.energyEvaluator(threads=nt, mpi_communicator=comm) evaluator = evaluator.CEvaluator() # Deal with reordering #print "objectList = ", self.universe.objectList() #print "objectList prmtop_order = ", self.universe.objectList()[0].prmtop_order #print "atomList = ", self.universe.objectList()[0].atomList() names = [] order = [] for a in self.universe.objectList()[0].atomList(): names.append(a.name) for i in self.universe.objectList()[0].prmtop_order: order.append(i.number) #print "names = ", names #print "order = ", order descorder = list('') for o in order: descorder = descorder + list(str(o)) descorder = descorder + list('|') descorder = descorder + list('1') descorder = descorder + list('|') descorder = descorder + list(str(memid)) descorder = descorder + list('|') #print descorder #print 'Py T ', self.getOption('T'), ' dt ', delta_t, ' trls ', ntrials, 'stps/trl ', steps_per_trial xs = [] energies = [] k = 0 acc = 0 for t in range(ntrials): # Initialize the velocity self.universe.initializeVelocitiesToTemperature( self.getOption('T')) #print "Python vels= ", #for t in self.universe.velocities(): print t, #print # Store previous configuration and initial energy xo = self.universe.copyConfiguration() pe_o = self.universe.energy() eo = pe_o + self.universe.kineticEnergy() ke_o = self.universe.kineticEnergy() # Run the velocity verlet integrator late_args = (masses.array, fixed.array, evaluator, N.zeros((0, 2), N.Int), N.zeros( (0, ), N.Float), N.zeros( (1, ), N.Int), N.zeros((0, ), N.Float), N.zeros((2, ), N.Float), N.zeros( (0, ), N.Float), N.zeros((1, ), N.Float), delta_t, self.getOption('first_step'), steps_per_trial, self.getActions(), ''.join(descorder)) #self.run(bTD_dynamics.integrateRKM_SPLIT, #tdserver = subprocess.Popen(server_cmd, shell=True, preexec_fn=os.setsid) #sleep(0.1) self.run(bTD_dynamics.integrateRKM_INTER3, (self.universe, self.universe.configuration().array, self.universe.velocities().array) + late_args) # Decide whether to accept the move pe_n = self.universe.energy() ke_n = self.universe.kineticEnergy() en = pe_n + ke_n random_number = np.random.random() expression = np.exp(-(en - eo) / RT) #expression = np.exp(-(pe_n-pe_o)/RT) #print ' stps Py PEo ', pe_o, ' KEo ', ke_o, ' Eo ', eo, ' PEn ', pe_n, ' KEn ', ke_n, ' En ', en, ' rand ', random_number, ' exp ', expression if (((en < eo) or (random_number < expression)) and (not np.isnan(en))): #if ((pe_n<pe_o) or (random_number<expression)): #or (t==0): # Always acc 1st step for now acc += 1 #print 'Py MC acc' if normalize: self.universe.normalizeConfiguration() descorder[-7] = '1' else: #print 'Py MC nacc' self.universe.setConfiguration(xo) pe_n = pe_o descorder[-7] = '0' xs.append(self.universe.copyConfiguration().array) energies.append(pe_n) # Kill the server tdserver.terminate() os.killpg(tdserver.pid, signal.SIGTERM) # Send the signal to all the process groups os.system('ipcrm -M ' + str(memid)) # Free shared memory #Return return (xs, energies, float(acc) / float(ntrials), delta_t)
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))
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))
def __call__(self, **options): # Process the keyword arguments self.setCallOptions(options) random.seed(self.getOption('seed')) np.random.seed(self.getOption('seed')) memid = np.random.randint(2000,9999) np.random.seed(int(time.time() + os.getpid())) Random.initializeRandomNumbersFromTime() # Check if the universe has features not supported by the integrator Features.checkFeatures(self, self.universe) RT = R*self.getOption('T') delta_t = self.getOption('delta_t') server = self.getOption('server') ligand_dir = self.getOption('ligand_dir') dyn_type = self.getOption('dyn_type') server_cmd = '' server_cmd = server + ' -mol2 ' + ligand_dir + 'ligand.mol2' + ' -rb ' + ligand_dir + 'ligand.rb' + ' -gaff gaff.dat -frcmod ' + ligand_dir + 'ligand.frcmod -ictd ' + dyn_type + ' -memid ' + str(memid) + ' > tdout' #print server_cmd tdserver = subprocess.Popen(server_cmd, shell=True, preexec_fn=os.setsid) sleep(0.1) if 'steps_per_trial' in self.call_options.keys(): steps_per_trial = self.getOption('steps_per_trial') ntrials = self.getOption('steps')/steps_per_trial else: steps_per_trial = self.getOption('steps') ntrials = 1 if 'normalize' in self.call_options.keys(): normalize = self.getOption('normalize') else: normalize = False # Get the universe variables needed by the integrator masses = self.universe.masses() fixed = self.universe.getAtomBooleanArray('fixed') nt = self.getOption('threads') comm = self.getOption('mpi_communicator') evaluator = self.universe.energyEvaluator(threads=nt, mpi_communicator=comm) evaluator = evaluator.CEvaluator() # Deal with reordering #print "objectList = ", self.universe.objectList() #print "objectList prmtop_order = ", self.universe.objectList()[0].prmtop_order #print "atomList = ", self.universe.objectList()[0].atomList() names = [] order = [] for a in self.universe.objectList()[0].atomList(): names.append(a.name) for i in self.universe.objectList()[0].prmtop_order: order.append(i.number) #print "names = ", names #print "order = ", order descorder = list('') for o in order: descorder = descorder + list(str(o)) descorder = descorder + list('|') descorder = descorder + list('1') descorder = descorder + list('|') descorder = descorder + list(str(memid)) descorder = descorder + list('|') #print descorder #print 'Py T ', self.getOption('T'), ' dt ', delta_t, ' trls ', ntrials, 'stps/trl ', steps_per_trial xs = [] energies = [] k = 0 acc = 0 for t in range(ntrials): # Initialize the velocity self.universe.initializeVelocitiesToTemperature(self.getOption('T')) #print "Python vels= ", #for t in self.universe.velocities(): print t, #print # Store previous configuration and initial energy xo = self.universe.copyConfiguration() pe_o = self.universe.energy() eo = pe_o + self.universe.kineticEnergy() ke_o = self.universe.kineticEnergy() # Run the velocity verlet integrator late_args = ( masses.array, fixed.array, evaluator, N.zeros((0, 2), N.Int), N.zeros((0, ), N.Float), N.zeros((1,), N.Int), N.zeros((0,), N.Float), N.zeros((2,), N.Float), N.zeros((0,), N.Float), N.zeros((1,), N.Float), delta_t, self.getOption('first_step'), steps_per_trial, self.getActions(), ''.join(descorder)) #self.run(bTD_dynamics.integrateRKM_SPLIT, #tdserver = subprocess.Popen(server_cmd, shell=True, preexec_fn=os.setsid) #sleep(0.1) self.run(bTD_dynamics.integrateRKM_INTER3, (self.universe, self.universe.configuration().array, self.universe.velocities().array) + late_args) # Decide whether to accept the move pe_n = self.universe.energy() ke_n = self.universe.kineticEnergy() en = pe_n + ke_n random_number = np.random.random() expression = np.exp(-(en-eo)/RT) #expression = np.exp(-(pe_n-pe_o)/RT) #print ' stps Py PEo ', pe_o, ' KEo ', ke_o, ' Eo ', eo, ' PEn ', pe_n, ' KEn ', ke_n, ' En ', en, ' rand ', random_number, ' exp ', expression if (((en<eo) or (random_number<expression)) and (not np.isnan(en))): #if ((pe_n<pe_o) or (random_number<expression)): #or (t==0): # Always acc 1st step for now acc += 1 #print 'Py MC acc' if normalize: self.universe.normalizeConfiguration() descorder[-7] = '1' else: #print 'Py MC nacc' self.universe.setConfiguration(xo) pe_n = pe_o descorder[-7] = '0' xs.append(self.universe.copyConfiguration().array) energies.append(pe_n) # Kill the server tdserver.terminate() os.killpg(tdserver.pid, signal.SIGTERM) # Send the signal to all the process groups os.system('ipcrm -M ' + str(memid)) # Free shared memory #Return return (xs, energies, float(acc)/float(ntrials), delta_t)
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))