Elementy dynamiki molekularnej - Lublinkft.umcs.lublin.pl/baran/epk/modelowanie/md/md.pdf · Co to...
Transcript of Elementy dynamiki molekularnej - Lublinkft.umcs.lublin.pl/baran/epk/modelowanie/md/md.pdf · Co to...
Elementy dynamiki molekularnej
AB
13 grudnia 2016
Czym zajmuje się DM?
Co to jest DM?
Dynamika molekularna (MD lub DM) zajmuje się czastkami masywnymi,poruszającymi się pod działaniem sił newtonowskich. Pozwala symulowaćukłady cząstek w ciałach stałych, cieczach i gazach, opisywać ruch gwiazd igalaktyk.1
Prostym przykładem, który omawialiśmy, jest wahadło.
1Patrz: np. F. Ercolessi, A Molecular Dynamics Primer, and Examples in Fortran 90.http://www.fisica.uniud.it/~ercolessi/md/
1
Co to jest DM?
W przypadku układów chaotycznych, jak np. oscylator Duffinga
mx(t) = −γx(t) + 2ax − 4bx3 + F0cos(ωt) .
rozwiązania numeryczne są praktycznie niewykonalne. Małe błedy numerycznew danych oraz błędy numerycznych zaokrągleń prowadzą do rozbieżności(badanie wykładników Liapunowa).
2
Przestrzeń fazowa. Mapy Poincare’go.
Analizę wyników prowadzi się najczęściej w przestrzeni fazowej położeń (x(t)) iprędkości (v(t)).
W przypadku zachowań chaotycznych przestrzeń fazową zastępuje się mapąPoincare’go, która jest zbiorem punktów przestrzeni fazowej, odpowiadającychchwilom czasu t = 0,T , 2T , ..., gdzie T jest okresem związanym zcharakterystyczną częstością w układzie cząstek, np. częstością w członiewymuszającym w przypadku oscylatora Duffinga, a więc ω. W przypadkuukładów okresowych otrzymamy jeden punkt w przestrzeni fazowej. Dlaukładów chaotycznych mogą to być dowolne zbiory punktów. Mogą pojawiaćsię tzw. bifurkacje (rozgałęzienia). Układy z tzw. chaosem deterministycznymmogą prowadzić do struktur fraktalnych, dziwnych atraktorów, których wymiarprzestrzenny jest ułamkowy.
3
Metoda Runge-Kutta I
dx
dt= v (1)
dv
dx= −γv + 2ax − 4bx3 + F0 cos(ωt) (2)
Program całkuje układ równań ruchu metodą Runge’go-Kutty 4go rzędu:
~k1 = h~f (t, ~x(t))
~k2 = h~f (t +h
2, ~x(t) +
12~k1)
~k3 = h~f (t +h
2, ~x(t) +
12~k2)
~k2 = h~f (t + h, ~x(t) + ~k3)
~x(t + h) = ~x(t) +16
(~k1 + 2~k2 + 2~k3 + ~k4) . (3)
4
Program I
! Duffing Oscillatorprogram duffing
implicit none
! real kind with decimal precision() >= 14 and exponent range() >= 300integer, parameter :: dp = selected_real_kind(14, 300)
! constantsreal(dp), parameter :: zero = 0._dp, one = 1._dp, two = 2._dpreal(dp), parameter :: half = one / two, six = (one + two) * two
! physics parametersreal(dp) :: omega = 2.4_dp, gamma = 0.1_dpreal(dp) :: a = 0.5_dp, b = 0.25_dpreal(dp) :: F0 = 2.0_dp
! variablesreal(dp), dimension(2) :: xv, dxvdtreal(dp) :: t, t_max, dtreal(dp), dimension(2) :: k1, k2, k3, k4, xv_stepcharacter(len=50) :: file_name
! get input from user and initializeprint *, ’Duffing Oscillator Simulation’print *, ’=============================’
5
Program II
print *, ’Enter initial x and v: ’read *, xv(1), xv(2)print *, ’Enter time step dt’read *, dtprint *, ’Enter integration time: ’read *, t_maxprint *, ’Enter output file name: ’read *, file_nameopen(unit=2, file=file_name)t = zerowrite(2, *) t, xv(1), xv(2)
! main integration loopdo
if (t >= t_max) exit! 4th order Runge-Kutta stepcall find_dxvdt(t, xv, dxvdt)k1 = dt * dxvdtxv_step = xv + k1 / twocall find_dxvdt(t + half * dt, xv_step, dxvdt)k2 = dt * dxvdtxv_step = xv + k2 / twocall find_dxvdt(t + half * dt, xv_step, dxvdt)k3 = dt * dxvdtxv_step = xv + k3call find_dxvdt(t + dt, xv_step, dxvdt)
6
Program III
k4 = dt * dxvdtxv = xv + (k1 + two * k2 + two * k3 + k4) / sixt = t + dtwrite(2, *) t, xv(1), xv(2)
end doprint *, ’Output in file: ’, file_nameclose(2)
contains! Duffing equationsubroutine find_dxvdt(t, xv, dxvdt)
implicit nonereal(dp), intent(in) :: treal(dp), dimension(2), intent(in) :: xvreal(dp), dimension(2), intent(out) :: dxvdtdxvdt(1) = xv(2)dxvdt(2) = - gamma * xv(2) + 2 * a * xv(1) - 4 * b * xv(1)**3dxvdt(2) = dxvdt(2) + F0 * cos(omega * t)
end subroutine find_dxvdt
end program duffing
7
Przykładowe wyniki
8
Przykładowe wyniki
9
Przykładowe wyniki
10
Przykładowa mapa Poincare’go
11
Podobna mapa dla wahadła tłumionego
3 2 1 0 1 2 3Angle
1.0
0.5
0.0
0.5
1.0
1.5
2.0
Angula
rVelo
city
d2θ/dt2 + sin(θ(t)) + βθ(t) + A ∗ sin(Ωt) = 0
12
Zadanie
Proszę dopisać w programie fragment obliczeń mapy Poincarego dl oscylatoraDuffinga. Narysować mapę dla kilku wybranych przypadków danychpoczątkowych. a) tylko punkty. b) punkty i linie. Porównać i wyciągnąćwnioski. Wykonać to samo dla prostego oscylatora harmonicznego.
13
Algorytm Verleta I
Algorytm Verleta jest tzw. algorytmem symplektycznym i zachowuje energięcałkowitą cząstek spełniających równania ruchu Hamiltona dokładniej niżalgorytm Runge’go-Kutty.
Załóżmy, że jednowymiarowy ruch cząstki dany jest równaniwm F = ma.Rozwińmy położenie x cząstki w szereg Taylora
x(t + h) = x(t) + v(t) +12a(t)h2 +
16a(t)h3 + O(h4)
x(t − h) = x(t)− v(t) +12a(t)h2 − 1
6a(t)h3 + O(h4)
Dodając te równania otrzymamy prosty algorytm Verleta:
x(t + h) = 2x(t)− x(t − h) + a(t)h2 + O(h4)
v(t) =x(t + h)− x(t − h)
2h+ O(h2) (4)
14
Algorytm Verleta II
Nie jest to algorytm samostartujący (jak np. algorytm RK). Samostartującyalgorytm Verleta o podobnej dokładności jest
x(t + h) = x(t) + v(t)h +12a(t)h2 + O(h4)
v(t + h) = v(t) +12
[a(t) + a(t + h)] h + O(h2) (5)
Jest to algorytm dwukrokowy. Położenie x(t + h) wylicza się na podstawiex(t), v(t) i a(t). Stąd a(t + h) i v(t + h).
15
Schemat algorytmu Verleta I
! samostartujący algorytm Verleta!subroutine sVerlet(dt, x, dxdt, d2xdt2, n, alpha)
dimension x(n), dxdt(n), d2dxt(n)do i=1,n
x(i) = x(i) + dxdt(i) * dt + 0.5 * d2xdt2(i) * dt**2dxdt(i) = dxdt(i) + 0.5 * d2xdt2(i) * dt
end docompute_accelerations(x, d2xdt2, alpha, n)do i=1,n
dxdt(i) += 0.5 * d2xdt2(i) * dtend do
end subroutine sVerlet
16
Schemat algorytmu Verleta II
subroutine compute_accelerations(x, d2xdt2, alpha, n)dimension x(n), d2xdt2,real alphado i = 2, n-1
dx_plus = x[i+1] - x[i]dx_minus = x[i] - x[i-1]d2xdt2[i] = dx_plus - dx_minus + &
alpha * (dx_plus**2 - dx_minus**2.0);end do
end subroutine compute_accelerations
17
Modelowanie argonu (Ar)
Modelowanie argonu
Rozpatrujemy N atomów szlachetnego argonu (m ∼ 6, 7× 10−26kg). Atomy wprzybliżeniu zachowują się jak sztywne kule przyciągające się siłami van derWaalsa, które będziemy modelować potencjałem Lennarda-Jonesa’:
V (r) = 4ε[(σ
r
)12−(σr
)6].
Tutaj r jest odległością centrów atomów, ε = 1, 65× 10−21J,a σ = 3, 4× 10−10m odpowiada r dla którego energia jest zerem. Człon r−12
opisuje odpychający twardy rdzeń, a r−6 reprezentuje przyciąganie typudipol-dipol.
18
Potencjał L-J
-6
-4
-2
0
2
4
6
3 4 5 6 7 8 9 10
V(r
) [m
eV
]
r [σ]
19
Potencjał L-J
Zadania
1. Obliczyć V w jego minimum rmin.
2. Obliczyć siłę F działającą na cząstki umieszczone w potencjale L-J.
3. Narysować F (r) dla 0 < r ≤ 10.
20
Przygotowanie programu MD (java) I
• Ustalenie jednostek. m = σ = ε = 1. Jednostką czasu jest w tym układzie
τ =√
mσ2
ε= 2, 17× 10−12s. Czas charakterystyczny jest więc rzędu
picosekund.
• Ustalenie liczby cząstek N i rozmiarów sieci (pojemnika) L
• Zadanie położeń początkowych cząstek
• Zadanie prędkości początkowych (metoda initialize())
• Obliczenie sił i przyspieszeń. Siła działająca na atom i-ty jest~Fi =
∑j=1,j 6=i Fij , gdzie Fij dostajemy z potencjału L-J. Stąd,
przyspieszenie ~ai (t) = d~vi (t)/dt = d2ri (t)/dt2 = ~Fi/m (metodacomputeAccelerations()).
• Całkowanie 3N równań różniczkowych drugiego rzędu z użyciem algorytmuVerleta, z zadanym krokiem czasowym (metoda velocityVerlet()).
21
Przygotowanie programu MD (java) II
• Ponieważ liczba cząstek N w układzie jest stała i stała jest objętość L3, asiły L-J są konserwatywne, więc całkowita energia jest również zachowana.Dla układu w równowadze termicznej spełniona jest zasada ekwipartycjienergii:
3(N − 1)× 12kBT =
⟨m
2
N∑i
v2i
⟩.
Nawias 〈· · · 〉 oznacza średnią termiczną po zespole. Wielkość 3(N − 1)
jest liczbą temperaturowych stopni swobody (wszystkie stopnie swobodyminus trzy translacyjne). Stąd obliczamy temperaturę T .
• Program główny main() wywołuje metodę inicjalizacji (initialize()),następnie oblicza krok za krokiem kolejne stany układu (velocityVerlet())i na koniec oblicza temperaturę T (metoda instantenousTemperature).
22
Schemat algorytmu MD I
// Basis:// http://www.physics.buffalo.edu/gonsalves/
public class MD static int N = 64; // number of particles
double[][] r = new double[N][3]; // positionsdouble[][] v = new double[N][3]; // velocitiesdouble[][] a = new double[N][3]; // accelerations
double L = 10; // linear size of cubical volumedouble vMax = 0.1; // maximum initial velocity component
void initialize() // initialize positionsint n = (int)(Math.ceil(Math.pow(N, 1.0/3)));// ^ number of atoms in each directiondouble a = L / n; // lattice spacingint p = 0; // particles placed so farfor (int x = 0; x < n; x++)
for (int y = 0; y < n; y++)for (int z = 0; z < n; z++)
if (p < N) r[p][0] = (x + 0.5) * a;r[p][1] = (y + 0.5) * a;
23
Schemat algorytmu MD II
r[p][2] = (z + 0.5) * a;++p;
// initialize velocitiesfor (int part = 0; part < N; part++)
for (int i = 0; i < 3; i++)v[part][i] = vMax * (2 * Math.random());
void computeAccelerations() for (int i = 0; i < N; i++) // set all accelerations to zero
for (int k = 0; k < 3; k++)a[i][k] = 0;
for (int i = 0; i < N-1; i++) // loop over all distinct pairs i,jfor (int j = i+1; j < N; j++)
double[] rij = new double[3]; // position of i relative to jdouble rSqd = 0;for (int k = 0; k < 3; k++)
rij[k] = r[i][k] - r[j][k];rSqd += rij[k] * rij[k];
double f = 24 * (2 * Math.pow(rSqd, -7) - Math.pow(rSqd, -4));for (int k = 0; k < 3; k++)
a[i][k] += rij[k] * f;
24
Schemat algorytmu MD III
a[j][k] -= rij[k] * f;
void velocityVerlet(double dt) computeAccelerations();for (int i = 0; i < N; i++)
for (int k = 0; k < 3; k++) r[i][k] += v[i][k] * dt + 0.5 * a[i][k] * dt * dt;v[i][k] += 0.5 * a[i][k] * dt;
computeAccelerations();
for (int i = 0; i < N; i++)for (int k = 0; k < 3; k++)
v[i][k] += 0.5 * a[i][k] * dt;
double instantaneousTemperature() double sum = 0;for (int i = 0; i < N; i++)
for (int k = 0; k < 3; k++)sum += v[i][k] * v[i][k];
25
Schemat algorytmu MD IV
return sum / (3 * (N - 1));
public static void main(String[] argv) MD md = new MD();md.initialize();double dt = 0.01;for (int i = 0; i < 2000; i++)
md.velocityVerlet(dt);System.out.println("" + md.instantaneousTemperature());
26
Potencjał L-J
27
Dalsze ulepszenia algorytmu MD
• Periodyczne warunki brzegowe -możliwość ucieczki cząstek z układu.
• Warunki początkowe dla położeń iprędkości powinny być bardziejfizyczne (np. sieć fcc - face centeredcubic lattice; prędkości zgodne zrozkładem Maxwella-Boltzmanna).
• Układ powinien dążyć do stanurównowagi przy zadanejtemperaturze.
• Pomiar (obliczenia) różnychwielkości charakteryzujących układ.
Niebieskie atomy (4) tworzą bazękomórki elementarnej. Ich położeniaw jednostkach a są: (0, 0, 0), (0.5,0.5, 0), (0.5, 0, 0.5), (0, 0.5, 0.5).W programie przesuwamy bazę o (0.5,0.5, 0.5) tak, że atomy znajdują sięwewnątrz objętości; żaden nie jest nabrzegu.
28
Vdistribution.java I
/**The method gasdev() from Numerical Recipes returns random numberswith a Gaussian probability distribution
P(x) = (1/(2\pi\sigma^2)) * e^-(x-x0)^2/(2*sig^2),
with center x0 = 0 and unit variance \sigma^2 = 1. This functionuses the Box-M\"uller algorithm.
*/import java.util.Random;
class Vdistribution
static boolean available = false;static double gset;
Random ran = new Random();
double gasdev () double fac, rsq, v1, v2;if (!available)
do v1 = 2.0 * ran.nextDouble();v2 = 2.0 * ran.nextDouble();rsq = v1 * v1 + v2 * v2;
29
Vdistribution.java II
while (rsq >= 1.0 || rsq == 0.0);fac = Math.sqrt(-2.0 * Math.log(rsq) / rsq);gset = v1 * fac;available = true;return v2*fac;
else available = false;return gset;
void initVelocities(double[][] v, int N) // Gaussian with unit variancefor (int n = 0; n < N; n++) // number of particles
for (int i = 0; i < 3; i++)v[n][i] = gasdev(); // x, y, z components of velocity
// Test method; plot histogrampublic static void main(String[] argv)
int N = 100000; // number of random g-numbersint nbins = 30; // number of binsdouble hbin = 0.1;int[] bins = new int[nbins];Vdistribution vd = new Vdistribution();
30
Vdistribution.java III
for(int i=0;i<N;i++) double g = vd.gasdev();int j = (int)(g / hbin);if (j < nbins) ++bins[j];//System.out.println(" "+available);
int mmax = bins[0];for(int i=1;i<nbins;i++)
mmax = bins[i]>mmax ? bins[i] : mmax;// plot histfor(int i=0;i<nbins;i++)
double hist = (50*bins[i])/mmax;if(hist>0)
System.out.print("|");for(int j=1;j<hist;j++)
System.out.print("-");if(50*bins[i]/mmax>0) System.out.println("*");
31
Liczby gaussowskie
!""""""""""""""""""""""""""""""""""""""""""""""""#
!"""""""""""""""""""""""""""""""""""""""""""""""""#
!"""""""""""""""""""""""""""""""""""""""""""""""#
!"""""""""""""""""""""""""""""""""""""""""""""#
!""""""""""""""""""""""""""""""""""""""""""""#
!""""""""""""""""""""""""""""""""""""""""#
!"""""""""""""""""""""""""""""""""""""""#
!""""""""""""""""""""""""""""""""""""#
!""""""""""""""""""""""""""""""""""#
!""""""""""""""""""""""""""""""#
!"""""""""""""""""""""""""""#
!""""""""""""""""""""""""#
!"""""""""""""""""""""#
!"""""""""""""""""""#
!""""""""""""""""#
!"""""""""""""#
!"""""""""""#
!""""""""""#
!"""""""#
!""""""#
!""""#
!"""#
!"""#
!""#
!"#
!# !# !#
Liczby losowe gaussowskie otrzymane metodą gasdev() (wynik z terminala).
32
Schemat algorytmu MD I
import java.util.Random;
class MD2
// simulation parametersint N = 64; // number of particlesdouble rho = 1.0; // density (number per unit volume)double T = 1.0; // temperaturedouble L; // linear size of cubical volume
/* Functions
void initialize(); // allocates memory, calls following 2 functionsvoid initPositions(); // places particles on an fcc latticevoid initVelocities(); // initial Maxwell-Boltzmann velocity distributionvoid rescaleVelocities(); // adjust the instanteous temperature to Tdouble gasdev(); // Gaussian distributed random numbers
*/
Random gen = new Random(); // random number generator
double[][] r = new double[N][3]; // positionsdouble[][] v = new double[N][3]; // velocitiesdouble[][] a = new double[N][3]; // accelerations
33
Schemat algorytmu MD II
void initialize() initPositions();initVelocities();
/**Calculations of lattice constant from number of particles andnumber density, and positions; fcc latice
*/void initPositions()
// compute side of cube from number of particles and number densityL = Math.pow(N / rho, 1.0/3);
// find M large enough to fit N atoms on an fcc latticeint M = 1;while (4 * M * M * M < N)
++M;double a = L / M; // lattice constant of conventional cell
// 4 atomic positions in fcc unit celldouble xCell[] = 0.25, 0.75, 0.75, 0.25;double yCell[] = 0.25, 0.75, 0.25, 0.75;double zCell[] = 0.25, 0.25, 0.75, 0.75;
34
Schemat algorytmu MD III
int n = 0; // atoms placed so farfor (int x = 0; x < M; x++)
for (int y = 0; y < M; y++)for (int z = 0; z < M; z++)
for (int k = 0; k < 4; k++)if (n < N)
r[n][0] = (x + xCell[k]) * a;r[n][1] = (y + yCell[k]) * a;r[n][2] = (z + zCell[k]) * a;++n;
static boolean available = false;static double gset;/**
The method gasdev() from Numerical Recipes returns random numberwith a Gaussian probability distribution
P(x) = (1/(2\pi\sigma^2)) * e^-(x-x0)^2/(2*sig^2),
with center x0 = 0 and unit variance \sigma^2 = 1. This functionuses the Box-M\"uller algorithm.
*/
35
Schemat algorytmu MD IV
double gasdev () double fac, rsq, v1, v2;if (!available)
do v1 = 2.0 * gen.nextDouble();v2 = 2.0 * gen.nextDouble();rsq = v1 * v1 + v2 * v2;
while (rsq >= 1.0 || rsq == 0.0);fac = Math.sqrt(-2.0 * Math.log(rsq) / rsq);gset = v1 * fac;available = true;return v2*fac;
else available = false;return gset;
/**Initial velocities of all particles (Maxwell-Boltzmann dist)
*/void initVelocities()
// Gaussian with unit variancefor (int n = 0; n < N; n++)
for (int i = 0; i < 3; i++)
36
Schemat algorytmu MD V
v[n][i] = gasdev();// Adjust velocities so center-of-mass velocity is zerodouble vCM[] = 0, 0, 0;for (int n = 0; n < N; n++)
for (int i = 0; i < 3; i++)vCM[i] += v[n][i];
for (int i = 0; i < 3; i++)vCM[i] /= N;
for (int n = 0; n < N; n++)for (int i = 0; i < 3; i++)
v[n][i] -= vCM[i];
// Rescale velocities to get the desired instantaneous temperaturerescaleVelocities();
/**Rescales velocities of particles
*/void rescaleVelocities()
double vSqdSum = 0;for (int n = 0; n < N; n++)
for (int i = 0; i < 3; i++)vSqdSum += v[n][i] * v[n][i];
double lambda = Math.sqrt( 3 * (N-1) * T / vSqdSum );for (int n = 0; n < N; n++)
37
Schemat algorytmu MD VI
for (int i = 0; i < 3; i++)v[n][i] *= lambda;
/**Calculates accelerations of particles
*/void computeAccelerations()
for (int i = 0; i < N; i++) // set all accelerations to zerofor (int k = 0; k < 3; k++)
a[i][k] = 0;
for (int i = 0; i < N-1; i++) // loop over all distinct pairs i,jfor (int j = i+1; j < N; j++)
double[] rij = new double[3]; // position of i relative to jdouble rSqd = 0;for (int k = 0; k < 3; k++)
rij[k] = r[i][k] - r[j][k];
// closest image conventionif (Math.abs(rij[k]) > 0.5 * L)
if (rij[k] > 0)rij[k] -= L;
else
38
Schemat algorytmu MD VII
rij[k] += L;rSqd += rij[k] * rij[k];
double f = 24 * (2 * Math.pow(rSqd, -7) - Math.pow(rSqd, -4));for (int k = 0; k < 3; k++)
a[i][k] += rij[k] * f;a[j][k] -= rij[k] * f;
/**Calculates positions/velocities from the Verlet algorithm
*/void velocityVerlet(double dt)
computeAccelerations();for (int i = 0; i < N; i++)
for (int k = 0; k < 3; k++) r[i][k] += v[i][k] * dt + 0.5 * a[i][k] * dt * dt;
// use periodic boundary conditionsif (r[i][k] < 0)
r[i][k] += L;if (r[i][k] >= L)
39
Schemat algorytmu MD VIII
r[i][k] -= L;v[i][k] += 0.5 * a[i][k] * dt;
computeAccelerations();for (int i = 0; i < N; i++)
for (int k = 0; k < 3; k++)v[i][k] += 0.5 * a[i][k] * dt;
/**Calculate temperature
*/double instantaneousTemperature()
double sum = 0;for (int i = 0; i < N; i++)
for (int k = 0; k < 3; k++)sum += v[i][k] * v[i][k];
return sum / (3 * (N - 1));
/**Main methodWrites data to the file
*/
40
Schemat algorytmu MD IX
public static void main(String[] argv) MD2 md = new MD2();md.initialize();double dt = 0.01;for (int i = 0; i < 2000; i++)
md.velocityVerlet(dt);System.out.println("" + md.instantaneousTemperature());if (i % 100 == 0)
md.rescaleVelocities();
41
Wyniki MD2
Temperatura (T=1) w funkcji czasu.
42
MD bardziej wydajnie
MD wydajniej
• Obcięcie potencjału – dla potencjałów krótkozasięgowych i szybkomalejących z odległością (np. r/σ > 1) można dokonać obcięcia
• .
• .
43
Schemat algorytmu MD I
import java.util.Random;
public class MD3
// simulation parameters
int N = 864; // number of particlesdouble rho = 1.0; // density (number per unit volume)double T = 1.0; // temperaturedouble L; // will be computed from N and rho
double[][] r, v, a; // positions, velocities, accelerations
// variables to implement Verlet’s neighbor list
double rCutOff = 2.5; // cut-off on Lennard-Jones potential and forcedouble rMax = 3.3; // maximum separation to include in pair listint nPairs; // number of pairs currently in pair listint[][] pairList; // the list of pair indices (i,j)double[][] drPair; // vector separations of each pair (i,j)double[] rSqdPair; // squared separation of each pair (i,j)int updateInterval = 10; // number of time steps between
// updates of pair list
44
Schemat algorytmu MD II
Random gen = new Random();
void initialize() r = new double[N][3];v = new double[N][3];a = new double[N][3];initPositions();initVelocities();
// allocate memory for neighbor list variablesnPairs = N * (N - 1) / 2;pairList = new int[nPairs][2]; // to store indices i and jdrPair = new double[nPairs][3]; // to store components x,y,zrSqdPair = new double [nPairs];
double computeSeparation (int i, int j, double dr[])
// find separation using closest image conventiondouble rSqd = 0;for (int d = 0; d < 3; d++)
dr[d] = r[i][d] - r[j][d];if (dr[d] >= 0.5*L)
dr[d] -= L;if (dr[d] < -0.5*L)
45
Schemat algorytmu MD III
dr[d] += L;rSqd += dr[d]*dr[d];
return rSqd;
void updatePairList() nPairs = 0;double[] dr = new double[3];for (int i = 0; i < N-1; i++) // all distinct pairs
for (int j = i+1; j < N; j++) // of particles i,jdouble rSqd=computeSeparation(i, j, dr);if (rSqd < rMax*rMax)
pairList[nPairs][0] = i;pairList[nPairs][1] = j;++nPairs;
void updatePairSeparations() double[] dr = new double[3];for (int p = 0; p < nPairs; p++)
int i = pairList[p][0];
46
Schemat algorytmu MD IV
int j = pairList[p][1];double rSqd = 0;rSqd = computeSeparation(i, j, dr);for (int d = 0; d < 3; d++)
drPair[p][d] = dr[d];rSqdPair[p] = rSqd;
void computeAccelerations()
for (int i = 0; i < N; i++) // set all accelerations to zerofor (int k = 0; k < 3; k++) a[i][k] = 0;
for (int p = 0; p < nPairs; p++) int i = pairList[p][0];int j = pairList[p][1];if (rSqdPair[p] < rCutOff*rCutOff)
double r2Inv = 1 / rSqdPair[p];double r6Inv = r2Inv*r2Inv*r2Inv;double f = 24*r2Inv*r6Inv*(2*r6Inv - 1);for (int d = 0; d < 3; d++)
a[i][d] += f * drPair[p][d];a[j][d] -= f * drPair[p][d];
47
Schemat algorytmu MD V
void velocityVerlet(double dt) // assume accelerations have been computedfor (int i = 0; i < N; i++)
for (int k = 0; k < 3; k++) r[i][k] += v[i][k] * dt + 0.5 * a[i][k] * dt * dt;
// use periodic boundary conditionsif (r[i][k] < 0)
r[i][k] += L;if (r[i][k] >= L)
r[i][k] -= L;v[i][k] += 0.5 * a[i][k] * dt;
updatePairSeparations();computeAccelerations();for (int i = 0; i < N; i++)
for (int k = 0; k < 3; k++)v[i][k] += 0.5 * a[i][k] * dt;
48
Schemat algorytmu MD VI
void initPositions()
// compute side of cube from number of particles and number densityL = Math.pow(N / rho, 1.0/3);
// find M large enough to fit N atoms on an fcc latticeint M = 1;while (4 * M * M * M < N)
++M;double a = L / M; // lattice constant of conventional cell
// 4 atomic positions in fcc unit celldouble[] xCell = 0.25, 0.75, 0.75, 0.25;double[] yCell = 0.25, 0.75, 0.25, 0.75;double[] zCell = 0.25, 0.25, 0.75, 0.75;
int n = 0; // atoms placed so farfor (int x = 0; x < M; x++)
for (int y = 0; y < M; y++)for (int z = 0; z < M; z++)
for (int k = 0; k < 4; k++)if (n < N)
r[n][0] = (x + xCell[k]) * a;r[n][1] = (y + yCell[k]) * a;r[n][2] = (z + zCell[k]) * a;++n;
49
Schemat algorytmu MD VII
static boolean available = false;static double gset;
double gasdev () double fac, rsq, v1, v2;if (!available)
do v1 = 2.0 * gen.nextDouble();v2 = 2.0 * gen.nextDouble();rsq = v1 * v1 + v2 * v2;
while (rsq >= 1.0 || rsq == 0.0);fac = Math.sqrt(-2.0 * Math.log(rsq) / rsq);gset = v1 * fac;available = true;return v2*fac;
else available = false;return gset;
50
Schemat algorytmu MD VIII
void initVelocities()
// Gaussian with unit variancefor (int n = 0; n < N; n++)
for (int i = 0; i < 3; i++)v[n][i] = gasdev();
// Adjust velocities so center-of-mass velocity is zerodouble[] vCM = 0, 0, 0;for (int n = 0; n < N; n++)
for (int i = 0; i < 3; i++)vCM[i] += v[n][i];
for (int i = 0; i < 3; i++)vCM[i] /= N;
for (int n = 0; n < N; n++)for (int i = 0; i < 3; i++)
v[n][i] -= vCM[i];
// Rescale velocities to get the desired instantaneous temperaturerescaleVelocities();
void rescaleVelocities() double vSqdSum = 0;for (int n = 0; n < N; n++)
for (int i = 0; i < 3; i++)
51
Schemat algorytmu MD IX
vSqdSum += v[n][i] * v[n][i];double lambda = Math.sqrt( 3 * (N-1) * T / vSqdSum );for (int n = 0; n < N; n++)
for (int i = 0; i < 3; i++)v[n][i] *= lambda;
double instantaneousTemperature() double sum = 0;for (int i = 0; i < N; i++)
for (int k = 0; k < 3; k++)sum += v[i][k] * v[i][k];
return sum / (3 * (N - 1));
public static void main(String[] argv) MD3 md = new MD3();md.initialize();md.updatePairList();md.updatePairSeparations();md.computeAccelerations();double dt = 0.01;for (int i = 0; i < 1000; i++)
md.velocityVerlet(dt);
52
Schemat algorytmu MD X
System.out.println("" + md.instantaneousTemperature());if (i % 200 == 0)
md.rescaleVelocities();if (i % md.updateInterval == 0)
md.updatePairList();md.updatePairSeparations();
53
Wyniki MD2
Temperatura (T=1) w funkcji czasu.
54
Thank you!
54