def choosewavevector(Numofq, ndim): """ Choose Wavevector in dynamic structure factor """ if ndim == 3: return wavevector3d(Numofq) elif ndim == 2: return wavevector2d(Numofq)
def slowS4(self, outputfile, X4time, dt = 0.002, a = 1.0, results_path = '../../analysis/dynamics'): """ Compute four-point dynamic structure factor at peak timescale of dynamic susceptibility Based on overlap function Qt and its corresponding dynamic susceptibility QtX4 a is the cutoff for the overlap function, default is 1.0 (EAM) and 0.3(LJ) (0.3<d>) X4time is the peaktime scale of X4 dt is the timestep in MD simulations Dynamics should be calculated before computing S4 Only considered the particles which are slow """ print ('-----------------Compute dynamic S4(q) of slow particles --------------') if not os.path.exists(results_path): os.makedirs(results_path) X4time = int(X4time / dt / self.TimeStep) twopidl = 2 * pi / self.Boxlength[0] if self.Boxlength[0] <= 40.0: Numofq = int(self.Boxlength[0] / twopidl) else: Numofq = int(self.Boxlength[0] / 2 / twopidl) wavevector = wavevector3d(Numofq) #Only S4(q) at low wavenumber range is interested qvalue, qcount = np.unique(wavevector[:, 0], return_counts = True) sqresults = np.zeros((len(wavevector[:, 0]), 3)) #the first row accouants for wavenumber for n in range(self.SnapshotNumber - X4time): RII = np.square(self.Positions[n + X4time] - self.Positions[n]).sum(axis = 1) RII = np.where(np.sqrt(RII) <= a, 1, 0) sqtotal = np.zeros((len(wavevector[:, 0]), 2)) for i in range(self.ParticleNumber): medium = twopidl * (self.Positions[n][i] * wavevector[:, 1:]).sum(axis = 1) sqtotal[:, 0] += np.sin(medium) * RII[i] sqtotal[:, 1] += np.cos(medium) * RII[i] sqresults[:, 1] += np.square(sqtotal).sum(axis = 1) / self.ParticleNumber sqresults[:, 2] += sqtotal[:, 1] sqresults[:, 0] = wavevector[:, 0] sqresults[:, 1] = sqresults[:, 1] / (self.SnapshotNumber - X4time) sqresults[:, 2] = np.square(sqresults[:, 2] / (self.SnapshotNumber - X4time)) / self.ParticleNumber sqresults = pd.DataFrame(sqresults) results = np.array(sqresults.groupby(sqresults[0]).mean()) results[:, 1] = results[:, 0] - results[:, 1] / qcount qvalue = twopidl * np.sqrt(qvalue) results = np.column_stack((qvalue, results)) names = 'q S4a(q) S4b(q)' np.savetxt(results_path + outputfile, results, fmt='%.6f', header = names, comments = '') print ('--------- Compute S4(q) of slow particles over ------') return results
def fastS4(self, outputfile, a = 1.0, dt = 0.002, X4timeset = 0, results_path = '../../analysis/dynamics'): """ Compute four-point dynamic structure factor at peak timescale of dynamic susceptibility Based on overlap function Qt and its corresponding dynamic susceptibility QtX4 a is the cutoff for the overlap function, default is 1.0 (EAM) and 0.3(LJ) (0.3<d>) dt is the timestep of MD simulations X4timeset is the peaktime scale of X4, if 0 will use the calculated one Dynamics should be calculated before computing S4 Only considered the particles which are fast The Qt and X4 should be calculated first """ print ('-----------------Compute dynamic S4(q) of fast particles --------------') if not os.path.exists(results_path): os.makedirs(results_path) #-----------calculte overall dynamics first---------------- results = np.zeros(((self.SnapshotNumber - 1), 3)) names = 't Qt QtX4' cal_Qt = pd.DataFrame(np.zeros((self.SnapshotNumber-1))[np.newaxis, :]) deltat = np.zeros(((self.SnapshotNumber - 1), 2), dtype = np.int) #deltat, deltatcounts for n in range(self.SnapshotNumber - 1): #time interval RII = self.Positions[n + 1:] - self.Positions[n] distance = np.square(RII).sum(axis = 2) RII_Qt = (np.sqrt(distance) >= a).sum(axis = 1) cal_Qt = pd.concat([cal_Qt, pd.DataFrame(RII_Qt[np.newaxis, :])]) cal_Qt = cal_Qt.iloc[1:] deltat[:, 0] = np.array(cal_Qt.columns) + 1 #Timeinterval deltat[:, 1] = np.array(cal_Qt.count()) #Timeinterval frequency results[:, 0] = deltat[:, 0] * self.TimeStep * dt results[:, 1] = cal_Qt.mean() / self.ParticleNumber results[:, 2] = ((cal_Qt**2).mean() - (cal_Qt.mean())**2) / self.ParticleNumber np.savetxt(results_path + 'Dynamics.' + outputfile, results, fmt='%.6f', header = names, comments = '') #-----------calculte S4(q) of fast particles---------------- twopidl = 2 * pi / self.Boxlength[0] if self.Boxlength[0] <= 40.0: Numofq = int(self.Boxlength[0] / twopidl) else: Numofq = int(self.Boxlength[0] / 2 / twopidl) wavevector = wavevector3d(Numofq) #Only S4(q) at low wavenumber range is interested qvalue, qcount = np.unique(wavevector[:, 0], return_counts = True) sqresults = np.zeros((len(wavevector[:, 0]), 3)) #the first row accouants for wavenumber if X4timeset: X4time = int(X4timeset / dt / self.TimeStep) else: X4time = deltat[results[:, 2].argmax(), 0] for n in range(self.SnapshotNumber - X4time): RII = np.square(self.Positions[n + X4time] - self.Positions[n]).sum(axis = 1) RII = np.where(np.sqrt(RII) >= a, 1, 0) sqtotal = np.zeros((len(wavevector[:, 0]), 2)) for i in range(self.ParticleNumber): medium = twopidl * (self.Positions[n][i] * wavevector[:, 1:]).sum(axis = 1) sqtotal[:, 0] += np.sin(medium) * RII[i] sqtotal[:, 1] += np.cos(medium) * RII[i] sqresults[:, 1] += np.square(sqtotal).sum(axis = 1) / self.ParticleNumber sqresults[:, 2] += sqtotal[:, 1] sqresults[:, 0] = wavevector[:, 0] sqresults[:, 1] = sqresults[:, 1] / (self.SnapshotNumber - X4time) sqresults[:, 2] = np.square(sqresults[:, 2] / (self.SnapshotNumber - X4time)) / self.ParticleNumber sqresults = pd.DataFrame(sqresults) results = np.array(sqresults.groupby(sqresults[0]).mean()) results[:, 1] = results[:, 0] - results[:, 1] / qcount qvalue = twopidl * np.sqrt(qvalue) results = np.column_stack((qvalue, results)) names = 'q S4a(q) S4b(q)' np.savetxt(results_path + outputfile, results, fmt='%.6f', header = names, comments = '') print ('--------- Compute S4(q) of fast particles over ------') return results