Vector Analysis
1. participation ratio
This module calculates the participation ratio of one vibration mode. It is measured as
where \(e_{i,n}\) is the eigenvector of particle \(i\) in mode \(n\). \(N\) is the particle number.
Input Argument
vector(npt.NDArray): input vector field, shape as [num_of_particles, ndim]
Return
participation ratio of the vector field (float)
Example
import numpy as np
from PyMatterSim.reader.dump_reader import DumpReader
from PyMatterSim.reader.reader_utils import DumpFileType
from PyMatterSim.static.vector import participation_ratio
test_file = "test.atom"
Readdump =DumpReader(test_file, ndim=2,filetype=DumpFileType.LAMMPSVECTOR,columnsids=[5,6])
Readdump.read_onefile()
v = test_file.snapshots.snapshots[0].positions
pr = participation_ratio(v)
2. local vector alignment
This module calculates the orientational ordering of each particle based on the vector alignments. It is measured as
where \({\vec e_i}\) is the eigenvector of particle \(i\) and \({CN_i}\) is the number of neighbors of particle \(i\).
Input Argument
vector(npt.NDArray): input vector field, shape as [num_of_particles, ndim]neighborfile(str): file name of particle neighbors (see moduleneighbors)
Return
phase quotient measured as a
float
Example
import numpy as np
from PyMatterSim.reader.dump_reader import DumpReader
from PyMatterSim.reader.reader_utils import DumpFileType
from PyMatterSim.static.vector import local_vector_alignment
from PyMatterSim.neighbors.calculate_neighbors import Nnearests
test_file = "test.atom"
input_vp =DumpReader(test_file, ndim=2)
input_vp.read_onefile()
input_v =DumpReader(test_file, ndim=2,filetype=DumpFileType.LAMMPSVECTOR,columnsids=[5,6])
input_v.read_onefile()
v = input_v.snapshots.snapshots[0].positions
Nnearests(input_vp.snapshots, N = 6, ppp = np.array([1,1]), fnfile = 'neighborlist.dat')
neighborfile='neighborlist.dat'
pr = local_vector_alignment(v,neighborfile)
3. phase quotient
This module calculates the phase quotient of a vector field. Maximum 200 neighbors are considered. It is defined as
where \(i\) and \(j\) are atom indices, \(N\) is the total atom number, \({CN_i}\) is the coordination number of atom \(i\), n is the mode number, \(\vec e_{i, n}\) is the eigenvector of atom \(i\) in mode \(n\). The upper bound \(PQ_n=1\) means acoustic nature of the mode (an atom has the same direction as the neighbors), while the lower bound of -1 means optical nature of the mode (an atom has the opposite direction as the neighbors). If \(PQ_n \gt 0\), the mode is acoustic-like otherwise is optical-like mode.
Input Argument
vector(npt.NDArray): input vector field, shape as [num_of_particles, ndim]neighborfile(str): file name of particle neighbors (see module neighbors)
Return
phase quotient measured as a float
Example
import numpy as np
from PyMatterSim.reader.dump_reader import DumpReader
from PyMatterSim.static.vector import phase_quotient
from PyMatterSim.neighbors.calculate_neighbors import Nnearests
test_file = "test.atom"
input_vp =DumpReader(test_file, ndim=2)
input_vp.read_onefile()
input_v =DumpReader(test_file, ndim=2,filetype=DumpFileType.LAMMPSVECTOR,columnsids=[5,6])
input_v.read_onefile()
v = input_v.snapshots.snapshots[0].positions
Nnearests(input_vp.snapshots, N = 6, ppp = np.array([1,1]), fnfile = 'neighborlist.dat')
neighborfile='neighborlist.dat'
pq = phase_quotient(v,neighborfile)
4. divergence and curl
This module calculates the divergence and curl of a vector field at 2D and 3D. Divergence is scalar over all dimensions. Curl only exists in 3D as a vector. Maximum 200 neighbors are considered. Differently, curl can only be defined 3D as a vector, its direction shows the local rotational direction while its magnitude means the amplitude of such motion.
Both divergence and curl can be defined anywhere in space within the vector field, so i and j in above equations can be any lattice position in space.
\({\rm divergence\ (scalar):\quad} div\ {\vec u_i} = \nabla \cdot {\vec u} = \frac{1}{N_i} \sum_j^{N_i} (\vec R_j - \vec R_i) \cdot (\vec u_j - \vec u_i)\)
\({\rm curl\ (vector):\quad} curl\ {\vec u_i} = \nabla \times {\vec u} = \frac{1}{N_i} \sum_j^{N_i} (\vec R_j - \vec R_i) \times (\vec u_j - \vec u_i)\)
in which \(\vec R_i\) is the position vector of atom \(i\), \(\vec u_i\) is the vector field (e.g. eigenvector) at atom \(i\), \(N_i\) is the number of nearest neighbors of atom \(i\).
Input Arguments
snapshots(reader.reader_utils.SingleSnapshot): snapshot object of input trajectory (returned byreader.dump_reader.DumpReader)vector(npt.NDArray): vector field shape as [num_of_partices, ndim], it determines the dimensionality of the calculation.ppp(npt.NDArray): the periodic boundary conditions, setting 1 for yes and 0 for no, defaultnp.array([1,1,1]), setnp.array([1,1])for two-dimensional systemsneighborfile(str): file name of particle neighbors (see moduleneighbors)
Return
divergence and curl (only 3D) in numpy array of the input vector
Example
import numpy as np
from PyMatterSim.reader.dump_reader import DumpReader
from PyMatterSim.static.vector import divergence_curl
from PyMatterSim.neighbors.calculate_neighbors import Nnearests
test_file = "test.atom"
input_vp =DumpReader(test_file, ndim=2)
input_vp.read_onefile()
input_v =DumpReader(test_file, ndim=2,filetype=DumpFileType.LAMMPSVECTOR,columnsids=[5,6])
input_v.read_onefile()
ppp = np.array([1,1])
Nnearests(input_vp.snapshots, N = 6, ppp = ppp, fnfile = 'neighborlist.dat')
neighborfile='neighborlist.dat'
v = input_v.snapshots.snapshots[0].positions
pq = divergence_curl(input_vp.snapshots.snapshots[0],v,ppp,neighborfile)[:10]
5. vibrability
This calculates the susceptibility of particle motion to infinitesimal thermal excitation in the zero temperature limit, defined as:
where \(\omega_l^2\) is the eigenvalue of the lth mode, while \({\vec e}_{l, i}\) is the corresponding eigenvector for particle \(i\). Larger \(\Psi\) indicates more susceptible to excitation and hence more disorder.
Input Arguments
eigenfrequencies(npt.NDArray): eigen frequencies generally from Hessian diagonalization, shape as [num_of_modes,]eigenvectors(npt.NDArray): eigen vectors associated with eigenfrequencies, each column represents an eigen mode as fromnp.linalg.eigmethod
Return
particle-level vibrability in a numpy array
Example
import numpy as np
from PyMatterSim.reader.dump_reader import DumpReader
from PyMatterSim.static.vector import vibrability
###example for 10x10 matrix
a = np.array([[2, 3, 4, 1, 3, 3, 2, 2, 2, 2],
[3, 2, 2, 2, 3, 3, 3, 2, 3, 3],
[2, 2, 3, 3, 1, 2, 4, 1, 4, 3],
[2, 1, 2, 2, 3, 1, 1, 2, 3, 4],
[3, 2, 3, 4, 3, 2, 2, 2, 1, 4],
[4, 3, 4, 1, 2, 2, 4, 2, 2, 3],
[3, 4, 3, 1, 1, 1, 2, 2, 3, 1],
[3, 1, 2, 3, 2, 4, 2, 4, 4, 1],
[2, 2, 2, 4, 3, 4, 3, 3, 3, 2],
[1, 1, 1, 1, 1, 1, 2, 1, 2, 3]])
eigenfrequencies, eigenvectors = np.linalg.eig(a)
eigenfrequencies = np.abs(eigenfrequencies.real)
eigenfrequencies = np.sqrt(eigenfrequencies)
eigenvectors = eigenvectors.real
vb = vibrability(eigenfrequencies,eigenvectors,10)
6. vector decompostion structure factor
Decomposing the vector into transverse and longitudinal components and calculate their corresponding stucture factor.
where
in which \(\bf \hat q = \bf q/|\bf q|\), \(m_i\) and \(\bf{r}_i\) are the mass and positional vector in the inherent structure of particle \(i\). The average mass is approximated as \(M^{-1} = \sum_l m_l^{-1} /N_l \) in which \(l\) runs over all species. The code calculates \(E(q)\).
Another faster method is first taking the FFT of the eigenvector and then take dot product for the longitudinal component and cross product for the transverse component, as
This new method is utilized in the calculation. Basically, the vector field is first Fourier transformed and then decomposed into transverse and longitudinal components. The corresponding structure factor is then calculated.
Input Arguments
snapshot(reader.reader_utils.SingleSnapshot): single snapshot object of input trajectoryqvector(npt.NDArrayofint): designed wavevectors in two-dimensionalnp.array(seeutils.wavevector)vector(npt.NDArray): particle-level vector, shape as [num_of_particles, ndim], for example, eigenvector field and velocity fieldoutputfile(str): filename.csv to save the calculatedS(q), defaultNone
Return
vector_fft: calculated transverse and longitudinalS(q)for each input wavevector (pd.DataFrame), FFT in complex number is also returned for referenceave_sqresults: the ensemble averagedS(q)over the same wavenumber (pd.DataFrame)
Example
import numpy as np
from PyMatterSim.reader.dump_reader import DumpReader
from PyMatterSim.static.vector import vector_decomposition_sq
from PyMatterSim.utils.wavevector import choosewavevector
test_file = "test.atom"
input_vp =DumpReader(test_file, ndim=2)
input_vp.read_onefile()
input_v =DumpReader(test_file, ndim=2,filetype=DumpFileType.LAMMPSVECTOR,columnsids=[5,6])
input_v.read_onefile()
v = input_v.snapshots.snapshots[0].positions
qvector = choosewavevector(2,10)
vector_fft, ave_sqresults=vector_decomposition_sq(input_vp.snapshots.snapshots[0],qvector,v)
7. vectors Fourier transformaiton and their time correlations
This module calculates spectra and time correlation of the longitudinal and tranverse components of a vector field by fast fourier transformation (FFT). This is usually used to calculate the current-current correlation function and its power spectra. This is also useful to calculate the dynamic structure factor based on the velocity field.
where \(\vec v_m(t)\) is the vector of particle \(m\) at time \(t\), and \(\vec r_m(t)\) is the particle position.. It is decomposed into transverse and longitudinal components as
where \(\mathbf{\hat q}\) is the unit vector \({\bf \hat q}={\vec q}/|{\bf q}|\).
The ensemble averaged power spectra is calculated as
and the time correlation functions are calculated as
where \(\alpha\) represents longitudinal (\(L\)) or transverse (\(T\)) current.
Input Arguments
snapshots(read.reader_utils.snapshots): multiple trajectories dumped linearly or in logscaleqvector(npt.NDArrayofint): designed wavevectors in two-dimensionalnp.array(seeutils.wavevector)vectors(npt.NDArray): particle-level vector, shape as [num_of_snapshots, num_of_particles, ndim], for example, eigenvector field and velocity fielddt(float): time step of input snapshots, default 0.002outputfile(str): filename.csv to save the calculatedS(q), defaultNone
Return
the averaged spectra of full, transverse, and longitudinal mode, saved into a csv dataset
time correlation of FFT of vectors in full, transverse, and longitudinal mode. Dict as
{"FFT": pd.DataFrame, "T_FFT": pd.DataFrame, "L_FFT": pd.DataFrame}
Example
import numpy as np
from PyMatterSim.reader.dump_reader import DumpReader
from PyMatterSim.static.vector import vector_fft_corr
from PyMatterSim.utils.wavevector import choosewavevector
test_file = "test.atom"
input_vp =DumpReader(test_file, ndim=2)
input_vp.read_onefile()
input_v =DumpReader(test_file, ndim=2,filetype=DumpFileType.LAMMPSVECTOR,columnsids=[5,6])
input_v.read_onefile()
qvector = choosewavevector(2, 27, False)
v =[]
for i in range(input_v.snapshots.nsnapshots):
temp = input_v.snapshots.snapshots[i].positions
v.append(temp)
v=np.array(v)
alldata = vector_fft_corr(input_vp.snapshots,qvector,v,outputfile="test")