def test_pdos(): filename = tools.unpack_compressed('files/pw.md.out.gz', prefix=__file__) pp = parse.PwMDOutputFile(filename=filename) traj = pp.get_traj() # timestep dt # ----------- # Only needed in pd.*_pdos(), not in pd.velocity(). Here is why: # # vacf_pdos, direct_pdos: # If we compute the *normalized* VCAF, then dt is a factor: # <v_x(0) v_x(t)> = 1/dt^2 <dx(0) dx(t)> # which cancels in the normalization. dt is not needed in the velocity # calculation, hence not # V=velocity(coords, dt=dt) # only # V=velocity(coords). V = traj.velocity # Ang / fs mass = traj.mass # amu dt = traj.timestep # fs timeaxis = traj.timeaxis assert np.allclose(150.0, dt * constants.fs / constants.tryd) # dt=150 Rydberg time units fd, dd = pd.direct_pdos(V, m=mass, dt=dt, npad=1, tonext=False) fv, dv = pd.vacf_pdos(V, m=mass, dt=dt, mirr=True) np.testing.assert_array_almost_equal(fd, fv, err_msg="freq not equal") np.testing.assert_array_almost_equal(dd, dv, err_msg="dos not equal") assert np.allclose(fd, np.loadtxt('files/ref_test_pdos/fd.txt.gz')) assert np.allclose(fv, np.loadtxt('files/ref_test_pdos/fv.txt.gz')) assert np.allclose(dd, np.loadtxt('files/ref_test_pdos/dd.txt.gz')) assert np.allclose(dv, np.loadtxt('files/ref_test_pdos/dv.txt.gz')) df = fd[1] - fd[0] print "Nyquist freq: %e" %(0.5/dt) print "df: %e:" %df print "timestep: %f fs = %f tryd" %(dt, dt * constants.fs / constants.tryd) print "timestep pw.out: %f tryd" %(pp.timestep) # API fd, dd, ffd, fdd, si = pd.direct_pdos(V, m=mass, dt=dt, full_out=True) fv, dv, ffv, fdv, si, vacf, fft_vacf = pd.vacf_pdos(V, m=mass, dt=dt, mirr=True, full_out=True) # Test padding for speed. fd, dd, ffd, fdd, si = pd.direct_pdos(V, m=mass, dt=dt, npad=1, tonext=True, \ full_out=True) assert len(fd) == len(dd) assert len(ffd) == len(fdd) # If `tonext` is used, full fft array lengths must be a power of two. assert len(ffd) >= 2*V.shape[timeaxis] - 1 assert np.log2(len(ffd)) % 1.0 == 0.0
def test_pdos(): filename = tools.unpack_compressed('files/pw.md.out.gz', prefix=__file__) pp = parse.PwMDOutputFile(filename=filename) traj = pp.get_traj() # timestep dt # ----------- # Only needed in pd.*_pdos(), not in pd.velocity(). Here is why: # # vacf_pdos, direct_pdos: # If we compute the *normalized* VCAF, then dt is a factor: # <v_x(0) v_x(t)> = 1/dt^2 <dx(0) dx(t)> # which cancels in the normalization. dt is not needed in the velocity # calculation, hence not # V=velocity(coords, dt=dt) # only # V=velocity(coords). V = traj.velocity # Ang / fs mass = traj.mass # amu dt = traj.timestep # fs timeaxis = traj.timeaxis assert np.allclose(150.0, dt * constants.fs / constants.tryd) # dt=150 Rydberg time units fd, dd = pd.direct_pdos(V, m=mass, dt=dt, npad=1, tonext=False) fv, dv = pd.vacf_pdos(V, m=mass, dt=dt, mirr=True) np.testing.assert_array_almost_equal(fd, fv, err_msg="freq not equal") np.testing.assert_array_almost_equal(dd, dv, err_msg="dos not equal") assert np.allclose(fd, np.loadtxt('files/ref_test_pdos/fd.txt.gz')) assert np.allclose(fv, np.loadtxt('files/ref_test_pdos/fv.txt.gz')) assert np.allclose(dd, np.loadtxt('files/ref_test_pdos/dd.txt.gz')) assert np.allclose(dv, np.loadtxt('files/ref_test_pdos/dv.txt.gz')) df = fd[1] - fd[0] print("Nyquist freq: %e" %(0.5/dt)) print("df: %e:" %df) print("timestep: %f fs = %f tryd" %(dt, dt * constants.fs / constants.tryd)) print("timestep pw.out: %f tryd" %(pp.timestep)) # API fd, dd, ffd, fdd, si = pd.direct_pdos(V, m=mass, dt=dt, full_out=True) fv, dv, ffv, fdv, si, vacf, fft_vacf = pd.vacf_pdos(V, m=mass, dt=dt, mirr=True, full_out=True) # Test padding for speed. fd, dd, ffd, fdd, si = pd.direct_pdos(V, m=mass, dt=dt, npad=1, tonext=True, \ full_out=True) assert len(fd) == len(dd) assert len(ffd) == len(fdd) # If `tonext` is used, full fft array lengths must be a power of two. assert len(ffd) >= 2*V.shape[timeaxis] - 1 assert np.log2(len(ffd)) % 1.0 == 0.0
def pdos(coords_arr_3d, axis=0): f, d = pd.direct_pdos(velocity_traj(coords_arr_3d, axis=axis)) return d
freqs = rand(natoms, 3, nfreq) * fmax for i in range(natoms): for k in range(3): # vector w/ frequencies: freqs[i,k,:] <=> f_j, j=0, ..., nfreq-1 # sum_j sin(2*pi*f_j*t) coords[:, i, k] = np.sin(2 * pi * freqs[i, k, :][:, None] * taxis).sum(axis=0) ##arr = coords arr = crys.velocity_traj(coords) massvec = rand(natoms) # no mass weighting M = None f4, y4n = pydos.vacf_pdos(arr, dt=dt, m=M, mirr=True) f5, y5n = pydos.direct_pdos(arr, dt=dt, m=M) # with mass weighting M = massvec f6, y6nm = pydos.vacf_pdos(arr, dt=dt, m=M, mirr=True) f7, y7nm = pydos.direct_pdos(arr, dt=dt, m=M) if use_fourier: # For each atom, write an array (time.shape[0], 3) with coords at all time # steps, run fourier.x on that, sum up the power spectra. No mass # weighting. fourier_in_data = np.zeros((arr.shape[time_axis], 7)) fourier_in_data[:, 0] = np.arange(arr.shape[time_axis]) fourier_out_fn = pj(fourier_dir, 'fourier_3d.log') common.system("rm -f %s" % fourier_out_fn) for iatom in range(arr.shape[1]):
# `nfreq` frequencies for each x,y,z component of each atom freqs = rand(natoms, 3, nfreq)*fmax for i in range(natoms): for k in range(3): # vector w/ frequencies: freqs[i,k,:] <=> f_j, j=0, ..., nfreq-1 # sum_j sin(2*pi*f_j*t) coords[:,i,k] = np.sin(2*pi*freqs[i,k,:][:,None]*taxis).sum(axis=0) ##arr = coords arr = crys.velocity_traj(coords) massvec = rand(natoms) # no mass weighting M = None f4, y4n = pydos.vacf_pdos(arr, dt=dt, m=M, mirr=True) f5, y5n = pydos.direct_pdos(arr, dt=dt, m=M) # with mass weighting M = massvec f6, y6nm = pydos.vacf_pdos(arr, dt=dt, m=M, mirr=True) f7, y7nm = pydos.direct_pdos(arr, dt=dt, m=M) if use_fourier: # For each atom, write an array (time.shape[0], 3) with coords at all time # steps, run fourier.x on that, sum up the power spectra. No mass # weighting. fourier_in_data = np.zeros((arr.shape[time_axis],7)) fourier_in_data[:,0] = np.arange(arr.shape[time_axis]) fourier_out_fn = pj(fourier_dir, 'fourier_3d.log') common.system("rm -f %s" %fourier_out_fn) for iatom in range(arr.shape[1]):