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 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 = wavevector2d(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 = wavevector2d(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