Initial version
This commit is contained in:
2
examples/README.txt
Normal file
2
examples/README.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Example Gallery
|
||||
===============
|
47
examples/plot_chi4.py
Normal file
47
examples/plot_chi4.py
Normal file
@ -0,0 +1,47 @@
|
||||
r"""
|
||||
Four-Point susceptibility
|
||||
=========================
|
||||
|
||||
The dynamic four-point susceptibility :math:`\chi_4(t)` is a measure for heterogenous dynamics. [Berthier]_
|
||||
It can be calculated from the variance of the incoherent intermediate scattering function
|
||||
:math:`F_q(t)`.
|
||||
|
||||
.. math::
|
||||
\chi_4 (t) = N\cdot\left( \left\langle F_q^2(t) \right\rangle - \left\langle F_q(t) \right\rangle^2 \right)
|
||||
|
||||
This is astraight forward calculation in mdevaluate.
|
||||
First calculate the ISF without time average and then take the variance along the first axis of this data.
|
||||
Note that this quantity requires good statistics, hence it is adviced to use a small time window
|
||||
and a sufficient number of segments for the analysis.
|
||||
Another way to reduce scatter is to smooth the data with a running mean,
|
||||
calling :func:`~mdevaluate.utils.runningmean` as shown below.
|
||||
|
||||
.. [Berthier] http://link.aps.org/doi/10.1103/Physics.4.42
|
||||
"""
|
||||
|
||||
from functools import partial
|
||||
import matplotlib.pyplot as plt
|
||||
import mdevaluate as md
|
||||
import tudplot
|
||||
|
||||
OW = md.open('/data/niels/sim/water/bulk/260K', trajectory='out/*.xtc').subset(atom_name='OW')
|
||||
|
||||
t, Fqt = md.correlation.shifted_correlation(
|
||||
partial(md.correlation.isf, q=22.7),
|
||||
OW,
|
||||
average=False,
|
||||
window=0.2,
|
||||
skip=0.1,
|
||||
segments=20
|
||||
)
|
||||
chi4 = len(OW[0]) * Fqt.var(axis=0)
|
||||
|
||||
tudplot.activate()
|
||||
|
||||
plt.plot(t, chi4, 'h', label=r'$\chi_4$')
|
||||
plt.plot(t[2:-2], md.utils.runningmean(chi4, 5), '-', label='smoothed')
|
||||
|
||||
plt.semilogx()
|
||||
plt.xlabel('time / ps')
|
||||
plt.ylabel('$\\chi_4$')
|
||||
plt.legend(loc='best')
|
30
examples/plot_isf.py
Normal file
30
examples/plot_isf.py
Normal file
@ -0,0 +1,30 @@
|
||||
"""
|
||||
Calculating the ISF of Water
|
||||
=======================================================
|
||||
|
||||
In this example the ISF of water oxygens is calculated for a bulk simulation.
|
||||
Additionally a KWW function is fitted to the results.
|
||||
"""
|
||||
from functools import partial
|
||||
import matplotlib.pyplot as plt
|
||||
from scipy.optimize import curve_fit
|
||||
import mdevaluate as md
|
||||
import tudplot
|
||||
|
||||
OW = md.open('/data/niels/sim/water/bulk/260K', trajectory='out/*.xtc').subset(atom_name='OW')
|
||||
t, S = md.correlation.shifted_correlation(
|
||||
partial(md.correlation.isf, q=22.7),
|
||||
OW,
|
||||
average=True
|
||||
)
|
||||
# Only include data-points of the alpha-relaxation for the fit
|
||||
mask = t > 3e-1
|
||||
fit, cov = curve_fit(md.functions.kww, t[mask], S[mask])
|
||||
tau = md.functions.kww_1e(*fit)
|
||||
|
||||
tudplot.activate()
|
||||
plt.figure()
|
||||
plt.plot(t, S, '.', label='ISF of Bulk Water')
|
||||
plt.plot(t, md.functions.kww(t, *fit), '-', label=r'KWW, $\tau$={:.2f}ps'.format(tau))
|
||||
plt.xscale('log')
|
||||
plt.legend()
|
121
examples/plot_spatialisf.py
Normal file
121
examples/plot_spatialisf.py
Normal file
@ -0,0 +1,121 @@
|
||||
"""
|
||||
Spatially resolved analysis in a cylindrical pore
|
||||
=======================================================
|
||||
|
||||
Calculate the spatially resolved ISF inside a cylindrical neutral water pore
|
||||
In this case the bins describe the shortest distance of an oxygen atom to any wall atom
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import mdevaluate as md
|
||||
import tudplot
|
||||
from scipy import spatial
|
||||
from scipy.optimize import curve_fit
|
||||
|
||||
#trajectory with index file
|
||||
#TODO eine allgemeinere stelle?
|
||||
traj = md.open('/data/robin/sim/nvt/12kwater/240_r25_0_NVT',
|
||||
trajectory='nojump.xtc', index_file='indexSL.ndx',topology='*.gro')
|
||||
#Liquid oxygens
|
||||
LO = traj.subset(indices= traj.atoms.indices['LH2O'])
|
||||
#Solid oxygens
|
||||
SO = traj.subset(indices= traj.atoms.indices['SH2O'])
|
||||
#Solid oxygens and bonded hydrogens
|
||||
SW = traj.subset(residue_id = SO.atom_subset.residue_ids)
|
||||
|
||||
#TODO die folgenden beiden zusammen sind nochmal deutlich schneller als
|
||||
#md.atom.distance_to_atoms, kannst du entweder in irgendeiner weise einbauen
|
||||
#oder hier lassen, man muss aber auf thickness achten, dass das sinn macht
|
||||
#adds periodic layers of the atoms
|
||||
def pbc_points(points, box_vector, thickness=0, index=False, inclusive=True):
|
||||
coordinates = np.copy(points)%box_vector
|
||||
allcoordinates = np.copy(coordinates)
|
||||
indices = np.tile(np.arange(len(points)),(27))
|
||||
for x in range(-1, 2, 1):
|
||||
for y in range(-1, 2, 1):
|
||||
for z in range(-1, 2, 1):
|
||||
vv = np.array([x, y, z], dtype=float)
|
||||
if not (vv == 0).all() :
|
||||
allcoordinates = np.concatenate((allcoordinates, coordinates + vv*box_vector), axis=0)
|
||||
|
||||
if thickness != 0:
|
||||
mask = np.all(allcoordinates < box_vector+thickness, axis=1)
|
||||
allcoordinates = allcoordinates[mask]
|
||||
indices = indices[mask]
|
||||
mask = np.all(allcoordinates > -thickness, axis=1)
|
||||
allcoordinates = allcoordinates[mask]
|
||||
indices = indices[mask]
|
||||
if not inclusive:
|
||||
allcoordinates = allcoordinates[len(points):]
|
||||
indices = indices[len(points):]
|
||||
if index:
|
||||
return (allcoordinates, indices)
|
||||
return allcoordinates
|
||||
|
||||
#fast calculation of shortest distance from one subset to another, uses pbc_points
|
||||
def distance_to_atoms(ref, observed_atoms, box=None, thickness=0.5):
|
||||
if box is not None:
|
||||
start_coords = np.copy(observed_atoms)%box
|
||||
all_frame_coords = pbc_points(ref, box, thickness = thickness)
|
||||
else:
|
||||
start_coords = np.copy(observed_atoms)
|
||||
all_frame_coords = np.copy(ref)
|
||||
|
||||
tree = spatial.cKDTree(all_frame_coords)
|
||||
first_neighbors = tree.query(start_coords)[0]
|
||||
return first_neighbors
|
||||
|
||||
#this is used to reduce the number of wall atoms to those relevant, speeds up the rest
|
||||
dist = distance_to_atoms(LO[0], SW[0], np.diag(LO[0].box))
|
||||
wall_atoms = SW.atom_subset.indices[0]
|
||||
wall_atoms = wall_atoms[dist < 0.35]
|
||||
SW = traj.subset(indices = wall_atoms)
|
||||
|
||||
from functools import partial
|
||||
func = partial(md.correlation.isf, q=22.7)
|
||||
|
||||
#selector function to choose liquid oxygens with a certain distance to wall atoms
|
||||
def selector_func(coords, lindices, windices, dmin, dmax):
|
||||
lcoords = coords[lindices]
|
||||
wcoords = coords[windices]
|
||||
dist = distance_to_atoms(wcoords, lcoords,box=np.diag(coords.box))
|
||||
#radial distance to pore center to ignore molecules that entered the wall
|
||||
rad = np.sum((lcoords[:,:2]-np.diag(coords.box)[:2]/2)**2,axis=1)**.5
|
||||
return lindices[(dist >= dmin) & (dist < dmax) & (rad < 2.7)]
|
||||
|
||||
#calculate the shifted correlation for several bins
|
||||
#bin positions are roughly the average of the limits
|
||||
bins = np.array([0.15,0.2,0.3,0.4,0.5,0.8,1.0,1.4,1.8,2.3])
|
||||
binpos = (bins[1:]+bins[:-1])/2
|
||||
S = np.empty(len(bins)-1, dtype='object')
|
||||
for i in range(len(bins)-1):
|
||||
selector = partial(selector_func,lindices=LO.atom_subset.indices[0],
|
||||
windices=SW.atom_subset.indices[0],dmin=bins[i],
|
||||
dmax = bins[i+1])
|
||||
t, S[i] = md.correlation.shifted_correlation(
|
||||
func, traj,segments=50, skip=0.1,average=True,
|
||||
correlation=md.correlation.subensemble_correlation(selector),
|
||||
description=str(bins[i])+','+str(bins[i+1]))
|
||||
|
||||
taus = np.zeros(len(S))
|
||||
tudplot.activate()
|
||||
plt.figure()
|
||||
for i,s in enumerate(S):
|
||||
pl = plt.plot(t, s, '.', label='d = ' + str(binpos[i]) + ' nm')
|
||||
#only includes the relevant data for 1/e fitting
|
||||
mask = s < 0.6
|
||||
fit, cov = curve_fit(md.functions.kww, t[mask], s[mask],
|
||||
p0=[1.0,t[t>1/np.e][-1],0.5])
|
||||
taus[i] = md.functions.kww_1e(*fit)
|
||||
plt.plot(t, md.functions.kww(t, *fit), c=pl[0].get_color())
|
||||
plt.xscale('log')
|
||||
plt.legend()
|
||||
#plt.show()
|
||||
|
||||
tudplot.activate()
|
||||
plt.figure()
|
||||
plt.plot(binpos, taus,'.',label=r'$\tau$(d)')
|
||||
plt.yscale('log')
|
||||
plt.legend()
|
||||
#plt.show()
|
17
examples/plot_temperature.py
Normal file
17
examples/plot_temperature.py
Normal file
@ -0,0 +1,17 @@
|
||||
"""
|
||||
Plotting the Temperature from an Energy File
|
||||
============================================
|
||||
|
||||
This example reads an Gromacs energy file and plots the evolultion and mean of the temperature.
|
||||
"""
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
import mdevaluate as md
|
||||
import tudplot
|
||||
|
||||
tudplot.activate()
|
||||
|
||||
edr = md.open_energy('/data/niels/sim/water/bulk/300K/out/energy_water1000bulk300.edr')
|
||||
T = edr['Temperature']
|
||||
plt.plot(edr.time, T)
|
||||
plt.plot(edr.time[[0, -1]], [T.mean(), T.mean()])
|
Reference in New Issue
Block a user