2
c md example program due to dieter heermann
3
c restructured and pdf added by rjh december 1990
5
c the message passing version distributes the computation
6
c of the forces (order npart**2) over the processes, assuming
7
c that each process has all of the co-ordinates.
8
c A global add then gives each process all the information
9
c needed to compute the next update.
10
c None of the order npart work has been parallelized so that
11
c will begin to dominate on many processors.
13
implicit double precision (a-h, o-z)
14
c parameter (mm = 13, lenpdf = 256)
15
c parameter (mm = 8, lenpdf = 256)
16
c parameter (mm = 6, lenpdf = 256)
17
C$Id: md.f,v 1.2 1995-02-02 23:24:18 d3g681 Exp $
18
parameter (mm = 4, lenpdf = 256)
19
c parameter (mm = 3, lenpdf = 256)
20
parameter (npart = 4*mm*mm*mm)
21
parameter (maxint = npart*150)
24
dimension x(1:npart,1:3), vh(1:npart,1:3),f(1:npart,1:3),
25
& pdf(1:lenpdf+1), times(8), inter(2,maxint)
28
c initalize message passing environment
33
c parameter definition (density, volume, temperature ...)
36
side = (dble(npart) / den)**0.3333333d0
38
rcoff = min(3.5d0, side/2.0d0)
39
c islow = 1 to match the rather large original timestep
45
ineigh = 10 * (1 + islow/4)
47
delpdf = 0.5d0*side/lenpdf
48
rdelp = 1.0d0 / delpdf
50
if (me.eq.0)write(6,1) npart,side,rcoff,tref,h,delpdf,irep,istop,
51
& iprint,ineigh,movemx
52
1 format(' molecular dynamics simulation example program'/
53
& ' ---------------------------------------------'//
54
& ' number of particles is ............ ',i6/
55
& ' side length of the box is ......... ',f13.6/
56
& ' cut off is ........................ ',f13.6/
57
& ' reduced temperature is ............ ',f13.6/
58
& ' basic time step is ................ ',f13.6/
59
& ' pdf sampling interval ............. ',f13.6/
60
& ' temperature scale interval ........ ',i6/
61
& ' stop scaling at move .............. ',i6/
62
& ' print interval .................... ',i6/
63
& ' update neighbor list every ........ ',i6, ' steps'/
64
& ' total no. of steps ................ ',i6)
72
rcoffs = rcoff * rcoff
73
tscale = 16.0d0 / (1.0d0 * npart - 1.0d0)
74
vaver = 1.13d0 * sqrt(tref / 24.0d0)
77
c generate fcc lattice for atoms inside box
80
call fcc(x, npart, mm, a)
81
times(1) = times(1) + timer()
83
c initialise velocites and forces (which are zero in fcc positions)
85
call mxwell(vh,3*npart,h,tref)
86
call dfill(3*npart, 0.0d0, f, 1)
87
times(2) = times(2) + timer()
91
if (me.eq.0) write(6,3)
92
3 format(//1x,' i ',' ke ',' pe ',' e ',
93
& ' temp ',' pres ',' vel ',' rp'/
94
& 1x,' -----',' ----------',' ----------',' ----------',
95
& ' --------',' --------',' --------',' ----')
98
do 200 move = 1,movemx
99
if (move.eq.1 .or. move.eq.(istop+1))
100
$ call dfill(lenpdf, 0.0d0, pdf, 1)
102
c move the particles and partially update velocities
104
call domove(3*npart,x,vh,f,side)
105
times(3) = times(3) + timer()
107
c compute forces in the new positions and accumulate the pdf
108
c virial and potential energy. Have to get the full forces
109
c on each node, hence the dgop (global add).
111
if (mod(move-1,ineigh).eq.0) then
112
call neigh(npart, x, side, rcoff, ninter, inter, maxint,
113
$ pdf, rdelp, lenpdf)
114
times(8) = times(8) + timer()
116
call forces(npart, x, f, vir, epot, side, rcoff, ninter, inter)
117
call dgop(1+MSGDBL, f, 3*npart, '+')
118
times(4) = times(4) + timer()
120
c scale forces, complete update of velocites and compute k.e.
122
call mkekin(npart,f,vh,hsq2,hsq,ekin)
123
ekinavg = ekinavg + ekin
124
times(5) = times(5) + timer()
126
c average the velocity and temperature scale if desired
128
if ((move.le.istop) .and. (mod(move, irep).eq.0)) then
129
call velavg(npart, vh, vaver, count, vel, h)
130
sc = sqrt( tref / (tscale * ekinavg / irep) )
131
call dscal(3*npart, sc, vh, 1)
134
times(6) = times(6) + timer()
136
c printout information if desired ... have to do global
137
c sum to get full potential energy and virial
139
if (mod(move, iprint) .eq. 0) then
140
call velavg(npart, vh, vaver, count, vel, h)
141
call dgop(2+MSGDBL, epot, 1, '+')
142
call dgop(2+MSGDBL, vir, 1, '+')
144
$ call prnout(move, ekin, epot, tscale, vir, vel, count,
146
times(7) = times(7) + timer()
151
c print out the pdf at the end of the calculation
152
c have first to get contribution from everyone with global add
154
call dgop(2+MSGDBL, pdf, lenpdf, '+')
156
$ call prnpdf(lenpdf, pdf, side, delpdf, npart, movemx-istop,
158
times(7) = times(7) + timer()
159
if (me.eq.0) write(6,431) nnodes(),(times(i),i=1,8)
160
431 format(' nproc geom mxwell domove forces ekin velscl',
164
if (me.eq.0) call stats
168
subroutine mxwell(vh,n3,h,tref)
169
implicit double precision (a-h, o-z)
172
c sample maxwell distribution at temperature tref
176
ujunk = drand48(iseed)
181
tscale = 16.0d0 / (1.0d0 * npart - 1.0d0)
188
1 u1 = drand48(iseed)
190
v1 = 2.0d0 * u1 - 1.0d0
191
v2 = 2.0d0 * u2 - 1.0d0
195
r = sqrt(-2.0d0*dlog(s)/s)
208
ekin = ekin + vh(i)*vh(i)
211
do 22 i = iof1 + 1,iof2
215
do 23 i = iof1 + 1,iof2
217
ekin = ekin + vh(i)*vh(i)
220
do 24 i = iof2 + 1,n3
224
do 25 i = iof2 + 1,n3
226
ekin = ekin + vh(i)*vh(i)
229
sc = h * sqrt(tref/ts)
235
subroutine domove(n3,x,vh,f,side)
236
implicit double precision (a-h, o-z)
237
dimension x(n3),vh(n3),f(n3)
242
x(i) = x(i) + vh(i) + f(i)
243
c periodic boundary conditions
244
if (x(i).lt.0.0d0) x(i) = x(i) + side
245
if (x(i).gt.side) x(i) = x(i) - side
246
c partial velocity updates
248
c initialise forces for next iteration
253
subroutine mkekin(npart,f,vh,hsq2,hsq,ekin)
254
implicit double precision (a-h, o-z)
255
dimension f(1:npart,3),vh(1:npart,3)
257
c scale forces, update velocites and compute k.e.
262
f(i,ix) = f(i,ix) * hsq2
264
vh(i,ix) = vh(i,ix) + f(i,ix)
265
sum = sum + vh(i,ix) * vh(i,ix)
271
subroutine fcc(x, npart, mm, a)
272
implicit double precision (a-h, o-z)
273
dimension x(1:npart, 3)
275
c generate fcc lattice for atoms inside box
283
x(ijk,1) = i * a + lg * a * 0.5d0
284
x(ijk,2) = j * a + lg * a * 0.5d0
295
x(ijk,1) = i * a + (2-lg) * a * 0.5d0
296
x(ijk,2) = j * a + (lg-1) * a * 0.5d0
297
x(ijk,3) = k * a + a * 0.5d0
304
subroutine dfill(n,val,a,ia)
305
implicit double precision (a-h, o-z)
308
c initialise double precision array to scalar value
310
do 10 i = 1,(n-1)*ia+1,ia
315
subroutine prnout(move, ekin, epot, tscale, vir, vel, count,
317
implicit double precision (a-h, o-z)
319
c printout interesting (?) information at current timestep
325
pres = den * 16.0d0 * (ekin - vir) / npart
327
rp = (count / dble(npart)) * 100.0d0
328
write(6,2) move,ek,epot,etot,temp,pres,vel,rp
329
2 format(1x,i6,3f12.4,f10.4,f10.4,f10.4,f6.1)
333
subroutine velavg(npart, vh, vaver, count, vel, h)
334
implicit double precision (a-h, o-z)
335
dimension vh(npart, 3)
337
c compute average velocity
343
sq = sqrt(vh(i,1)**2 + vh(i,2)**2 + vh(i,3)**2)
344
if (sq.gt.vaverh) count = count + 1.0d0
350
subroutine prnpdf(lenpdf, pdf, side, delpdf, npart, nmove, ineigh)
351
implicit double precision (a-h, o-z)
352
dimension pdf(lenpdf)
354
c final scaling and printout of the pdf
357
1 format(/' pair distribution function written to file pdf.dat'/)
358
open(1, file='pdf.dat', form='formatted', status='unknown',
362
volfac = side*side*side / (4.0d0*delpdf*delpdf*delpdf*3.141593d0)
363
facnn = 2.0d0 / dble(npart*nmove/ineigh)
364
facn = 1.0d0 / dble(npart)
367
grfac = volfac / (ri*ri)
368
func = pdf(i) * facnn
370
pdf(i) = func * grfac * facn
371
write(1,2) dble(i)*delpdf,pdf(i),coord
373
2 format(1x,f7.3,f13.6,4x,f9.2)
377
999 write(6,*) ' error opening pdf.dat'
381
subroutine neigh(npart, x, side, rcoff, ninter, inter, maxint,
382
$ pdf, rdelp, lenpdf)
383
implicit double precision (a-h, o-z)
384
dimension x(npart, 3), inter(2,maxint), pdf(lenpdf)
386
c Form my part of the neighbour list and also compute the pair
387
c distribution function.
389
c npart = no. of particles
392
c rcoff = cutoff for force
393
c ninter= returns no. of interactions
394
c inter(,) = returns interactions
395
c maxint = size of inter
401
rcoffs = (rcoff*1.2d0)**2
404
c Get better work distribution by having the same
405
c processor handle particles (i) and (npart-i)
406
c Note that assume that npart is even.
408
do 270 ii = me+1, npart/2, nproc
410
if (icase .eq. 1) then
423
if (xx .lt. -sideh) xx = xx + side
424
if (xx .gt. sideh) xx = xx - side
425
if (yy .lt. -sideh) yy = yy + side
426
if (yy .gt. sideh) yy = yy - side
427
if (zz .lt. -sideh) zz = zz + side
428
if (zz .gt. sideh) zz = zz - side
429
rd = xx*xx + yy*yy + zz*zz
430
ipdf = min(sqrt(rd),sideh) * rdelp + 1
431
pdf(ipdf) = pdf(ipdf) + 1.0d0
432
if (rd .le. rcoffs) then
434
if (ninter.gt.maxint) then
435
write(6,*) ' too many interactions ', ninter
446
c$$$ call igop(99, ij, 1, '+')
447
c$$$ if (me .eq. 0) then
448
c$$$ write(6,*) ' No. of interactions per particle = ',
453
subroutine forces(npart, x, f, vir, epot, side, rcoff,
455
implicit double precision (a-h, o-z)
457
parameter (oshift = .true.)
458
dimension x(npart, 3), f(npart, 3), inter(2, ninter)
460
c compute forces driven by the neighbour list
467
c for shifted potential ... set oshift true to enable
470
rc6 = 1.0d0 / rcoff**6
471
rc12 = 1.0d0 / rcoff**12
473
fcut = (rc12 - 0.5d0*rc6)/rcoff
474
efcut = 12.0d0 * fcut
483
if (xx .lt. -sideh) xx = xx + side
484
if (xx .gt. sideh) xx = xx - side
485
if (yy .lt. -sideh) yy = yy + side
486
if (yy .gt. sideh) yy = yy - side
487
if (zz .lt. -sideh) zz = zz + side
488
if (zz .gt. sideh) zz = zz - side
489
rd = xx*xx + yy*yy + zz*zz
490
if (rd .le. rcoffs) then
497
epot = epot + (rrd6 - rrd3)
498
r148 = rrd7 - 0.5d0*rrd4
501
epot = epot - ecut + efcut*(r-rcoff)
502
r148 = r148 - fcut / r
506
f(i,1) = f(i,1) + forcex
507
f(j,1) = f(j,1) - forcex
509
f(i,2) = f(i,2) + forcey
510
f(j,2) = f(j,2) - forcey
512
f(i,3) = f(i,3) + forcez
513
f(j,3) = f(j,3) - forcez