def Energy(self, coordinates3, gradients3=None): """Calculate the energy.""" # . Displacements. v12 = coordinates3.Displacement(self.point1, self.point2) v32 = coordinates3.Displacement(self.point3, self.point2) v34 = coordinates3.Displacement(self.point3, self.point4) # . Get m and n. m = Clone(v12) m.Cross(v32) n = Clone(v32) n.Cross(v34) # . Get the sizes of m and n. msize = m.Norm2() nsize = n.Norm2() # . Normalize m and n. m.Scale(1.0 / msize) n.Scale(1.0 / nsize) # . Get the dot-product. dotfac = m.Dot(n) if dotfac > 1.0: dotfac = 1.0 elif dotfac < -1.0: dotfac = -1.0 # . Get the sign of the angle. sgnfac = 1.0 if v12.Dot(n) < 0.0: sgnfac = -1.0 # . Determine the dihedral. value = sgnfac * math.acos(dotfac) * UNITS_ANGLE_RADIANS_TO_DEGREES # . Get the energy. (f, df) = self.energyModel.Energy(value) # . Derivatives. if gradients3 is not None: df *= UNITS_ANGLE_RADIANS_TO_DEGREES # . Calculate r32. r32 = v32.Norm2() # . Calculate dedi and dedl in m and n respectively. m.Scale(df * r32 / msize) n.Scale(-df * r32 / nsize) # . Calculate some additional factors. fact12 = v12.Dot(v32) / (r32 * r32) fact34 = v34.Dot(v32) / (r32 * r32) # . Gradients for i and l. gradients3.Increment(self.point1, m) gradients3.Increment(self.point4, n) # . Calculate dedj and dedk in v12 and v32 respectively. m.CopyTo(v12) v12.Scale(fact12 - 1.0) v12.AddScaledVector3(-fact34, n) n.CopyTo(v32) v32.Scale(fact34 - 1.0) v32.AddScaledVector3(-fact12, m) # . calculate the gradients. gradients3.Increment(self.point2, v12) gradients3.Increment(self.point3, v32) return (f, value)
def NormalModesTrajectory_SystemGeometry(system, trajectory, cycles=10, frames=21, mode=0, state=None, temperature=300.0): """Generate a normal mode trajectory.""" # . Get the state. if state is None: state = system.configuration.nmState # . Get state-related information. if state.freeAtoms == None: freeAtoms = range(len(system.atoms)) else: freeAtoms = state.freeAtoms frequencies = state.frequencies modes = state.modes # . Get the mode frequency. omega = math.fabs(frequencies[mode]) # . Calculate the number of frames. total = cycles * frames # . Check for a calculation. if (mode >= 0) and (mode < state.dimension) and ( omega > _LOWFREQUENCY) and (total > 0): # . Calculate the amplitude (in Angstroms). amplitude = math.sqrt( 2.0 * 1.0e-3 * CONSTANT_AVOGADRO_NUMBER * CONSTANT_BOLTZMANN * temperature) * (_TO_WAVENUMBERS / omega) # . Allocate space for the coordinates and mode. coordinates3 = Clone(system.coordinates3) displacement = Coordinates3.WithExtent(len(system.atoms)) displacement.Set(0.0) # . Get the displacement. for f in freeAtoms: displacement[f, 0] = modes[mode, 3 * f] displacement[f, 1] = modes[mode, 3 * f + 1] displacement[f, 2] = modes[mode, 3 * f + 2] # . Loop over the cycles and frames. # . Calculate the displacement prefactor using sine instead of cosine. trajectory.WriteHeader(temperature=temperature) for c in range(cycles): for f in range(frames): factor = amplitude * math.sin( 2.0 * math.pi * float(f) / float(frames)) coordinates3.CopyTo(system.coordinates3) system.coordinates3.AddScaledMatrix(factor, displacement) trajectory.WriteOwnerData() # . Finish up. trajectory.WriteFooter() trajectory.Close()
def Superimpose(self, reference3=None, weights=None): """Superimpose the trajectory on a reference structure using the first trajectory frame by default.""" # . Initialization. coordinates3 = self.owner.coordinates3 # . Save the owner coordinates to restore later. saved3 = Clone(coordinates3) # . Get the reference coordinates. if reference3 is coordinates3: reference3 = saved3 elif reference3 is None: self.RestoreOwnerData(index=0) reference3 = Clone(coordinates3) # . Loop over trajectory frames. results = [] for index in range(self.frames): self.RestoreOwnerData(index=index) rms0 = coordinates3.RMSDeviation(reference3, weights=weights) coordinates3.Superimpose(reference3, weights=weights) rms1 = coordinates3.RMSDeviation(reference3, weights=weights) self.WriteOwnerData(index=index) results.append((rms0, rms1)) # . Finish up. saved3.CopyTo(coordinates3) return results