7
c This software is being made available for internal testing and
8
c evaluation purposes only. This software is a pre-release test version
9
c which has not yet been authenticated and cleared for publication. Adherence
10
c to this notice may be necessary for the author, Battelle Memorial
11
c Institute, to successfully assert copyright in and commercialize this
12
c software. This software is not intended for duplication or distribution
13
c to third parties without the permission of the Manager of Software
14
c Products at Pacific Northwest Laboratory, Richland, Washington, 99352.
16
subroutine cluster_com
20
double precision masstot, dx, dy, dz
21
double precision r,rdot,com(10)
23
c This subroutine calculates the center of mass (COM) of the cluster of
24
c particles of type 2, excluding the lone particle.
39
c if (at(i).eq.2.and.aidx(i).ne.cl_lone_particle) then
41
cl_cmx = cl_cmx + mass(i)*ra(i,1,6)
42
cl_cmy = cl_cmy + mass(i)*ra(i,2,6)
43
cl_cmz = cl_cmz + mass(i)*ra(i,3,6)
44
cl_acmx = cl_acmx + ra(i,1,4)
45
cl_acmy = cl_acmy + ra(i,2,4)
46
cl_acmz = cl_acmz + ra(i,3,4)
47
cl_vcmx = cl_vcmx + mass(i)*ra(i,1,2)
48
cl_vcmy = cl_vcmy + mass(i)*ra(i,2,2)
49
cl_vcmz = cl_vcmz + mass(i)*ra(i,3,2)
50
masstot = masstot + mass(i)
63
call ga_dgop(3,com,10,'+')
74
if (masstot.gt.0.0d00) then
75
cl_cmx = cl_cmx / masstot
76
cl_cmy = cl_cmy / masstot
77
cl_cmz = cl_cmz / masstot
78
cl_acmx = cl_acmx / masstot
79
cl_acmy = cl_acmy / masstot
80
cl_acmz = cl_acmz / masstot
81
cl_vcmx = cl_vcmx / masstot
82
cl_vcmy = cl_vcmy / masstot
83
cl_vcmz = cl_vcmz / masstot
90
subroutine cluster_therm
94
double precision dx, dy, dz
95
double precision r,rdot
97
c remove component of velocity that lies along the vector from COM
98
c to the particle, if particle is outside cluster radius. This gradually
99
c forces particles to form a drop.
101
if (nocluster) return
102
if (istep.ge.equil_1) return
105
c if (at(i).eq.2.and.aidx(i).ne.cl_lone_particle) then
107
dx = ra(i,1,1) - cl_cmx
108
dy = ra(i,2,1) - cl_cmy
109
dz = ra(i,3,1) - cl_cmz
110
r = sqrt(dx**2 + dy**2 + dz**2)
114
if (r.gt.r_cluster) then
115
rdot = ra(i,1,2)*dx+ra(i,2,2)*dy+ra(i,3,2)*dz
116
if (rdot.gt.0.0d00) then
117
ra(i,1,2) = ra(i,1,2) - 2.0d00*rdot*dx
118
ra(i,2,2) = ra(i,2,2) - 2.0d00*rdot*dy
119
ra(i,3,2) = ra(i,3,2) - 2.0d00*rdot*dz
128
subroutine cluster_center
131
c move center of mass to origin (only perform this if it is immediately
132
c followed by a call to update subroutine)
136
if (nocluster) return
137
if (istep.eq.0.or.(mod(istep,ilist).eq.0.and.
138
+ t_rmndr.eq.0.0d00)) then
140
if (istep.ge.6932366) then
146
write(6,*) me,' mod(istep,ilist) = ',mod(istep,ilist)
147
write(6,*) me,' ilist = ',ilist
150
if (debug) write(6,*) me,'cl_cmx (a) = ',cl_cmx,istep
151
if (debug) write(6,*) me,'cl_cmy (a) = ',cl_cmy,istep
152
if (debug) write(6,*) me,'cl_cmz (a) = ',cl_cmz,istep
154
ra(i,1,6) = ra(i,1,6) - cl_cmx
155
ra(i,2,6) = ra(i,2,6) - cl_cmy
156
ra(i,3,6) = ra(i,3,6) - cl_cmz
160
if (debug) write(6,*) me,'cl_cmx (b) = ',cl_cmx,istep
161
if (debug) write(6,*) me,'cl_cmy (b) = ',cl_cmy,istep
162
if (debug) write(6,*) me,'cl_cmz (b) = ',cl_cmz,istep
167
subroutine cluster_old_at
170
c store original coordinates of cluster atoms
172
integer i, icnt, jcnt
173
if (nocluster) return
180
cl_old(icnt,1,1) = ra(i,1,1)
181
cl_old(icnt,2,1) = ra(i,2,1)
182
cl_old(icnt,3,1) = ra(i,3,1)
183
cl_old(icnt,1,2) = ra(i,1,6)
184
cl_old(icnt,2,2) = ra(i,2,6)
185
cl_old(icnt,3,2) = ra(i,3,6)
186
cl_old(icnt,1,3) = ra(i,1,2)
187
cl_old(icnt,2,3) = ra(i,2,2)
188
cl_old(icnt,3,3) = ra(i,3,2)
193
sl_old(jcnt,1,1) = ra(i,1,1)
194
sl_old(jcnt,2,1) = ra(i,2,1)
195
sl_old(jcnt,3,1) = ra(i,3,1)
196
sl_old(jcnt,1,2) = ra(i,1,6)
197
sl_old(jcnt,2,2) = ra(i,2,6)
198
sl_old(jcnt,3,2) = ra(i,3,6)
199
sl_old(jcnt,1,3) = ra(i,1,2)
200
sl_old(jcnt,2,3) = ra(i,2,2)
201
sl_old(jcnt,3,3) = ra(i,3,2)
205
cl_cm_old(1) = cl_cmx
206
cl_cm_old(2) = cl_cmy
207
cl_cm_old(3) = cl_cmz
208
cl_vcm_old(1) = cl_vcmx
209
cl_vcm_old(2) = cl_vcmy
210
cl_vcm_old(3) = cl_vcmz
213
cl_alen1_old(i) = alen1(i)
214
cl_alen2_old(i) = alen2(i)
229
subroutine cluster_check_cllsn
232
c This subroutine checks to see if any of the cluster particles have moved
233
c beyond the cutoff radius from the center of mass of the cluster. If they
234
c have, then the initial guess for the particle coordinates and velocities
235
c is modified to reflect the collision with the restraining sphere.
237
integer icnt, iat, i, j, ii, jj, iloc, imin, scndat, reset
238
double precision r, r2, rx, ry, rz, dtmax, tsav
239
double precision rrx, rry, rrz, vvx, vvy, vvz
240
double precision vn, vx, vy, vz, fx, fy, fz, mu, v2, f2
241
double precision vrdot, frdot, vfdot, a, b, c
242
double precision t1, t2, tcut, comm(4), tmax, htausq
243
double precision rnx, rny, rnz, vpx, vpy, vpz, vllx, vlly, vllz
244
double precision t3, t4, ax, ay, az, tchk, tmin, t_est
245
double precision r1x, r1y, r1z, r2x, r2y, r2z, rmax, rskin, rn
246
double precision cluster_find_tau
247
integer failsafe, ibuf(MD_MAXPROC), me, nproc, twohit
260
if (istep.ge.68365721.and.istep.le.68365723) then
267
if (t_rmndr.eq.tau) cllsn_isav = 0
268
100 dtmax = 2.0d00*t_rmndr
275
if (debug) write(6,*) me,' atot = ',atot,istep
276
if (debug) write(6,*) me,' antot = ',antot,istep
277
if (debug) write(6,*) me, ' r_cluster = ',r_cluster,istep
278
if (debug) write(6,*) me,' t_rmndr = ',tmax,istep
279
if (debug) write(6,*) me,' cl_cmx(1) = ',cl_cmx,istep
280
if (debug) write(6,*) me,' cl_cmy(1) = ',cl_cmy,istep
281
if (debug) write(6,*) me,' cl_cmz(1) = ',cl_cmz,istep
284
rx = ra(ii,1,6) - cl_cmx
285
ry = ra(ii,2,6) - cl_cmy
286
rz = ra(ii,3,6) - cl_cmz
287
r2 = rx**2 + ry**2 + rz**2
289
c if (debug) write(6,*) me, 'ra(ii,1,6) ',ra(ii,1,6),istep
290
c if (debug) write(6,*) me, 'ra(ii,2,6) ',ra(ii,2,6),istep
291
c if (debug) write(6,*) me, 'ra(ii,3,6) ',ra(ii,3,6),istep
292
if (r.gt.r_cluster) then
293
if (r.gt.rmax) rmax = r
294
if (debug) write(6,*) me,' tmax = ',tmax,istep
295
if (debug) write(6,*) me,' dtmax = ',dtmax,istep
296
if (debug) write(6,*) me,' ii = ',ii,istep
297
if (debug) write(6,*) me,' antot = ',antot,istep
298
if (debug) write(6,*) me,' r-r_cluster ',r-r_cluster,istep
299
if (debug) write(6,*) me,' r_cluster = ',r_cluster,istep
300
if (debug) write(6,*) me,' sqrt(r2) = ',sqrt(r2),istep
301
if (debug) write(6,*) me,' ra(1) = ',ra(ii,1,6),istep
302
if (debug) write(6,*) me,' ra(2) = ',ra(ii,2,6),istep
303
if (debug) write(6,*) me,' ra(3) = ',ra(ii,3,6),istep
304
if (debug) write(6,*) me,' cl_cmx = ',cl_cmx,istep
305
if (debug) write(6,*) me,' cl_cmy = ',cl_cmy,istep
306
if (debug) write(6,*) me,' cl_cmz = ',cl_cmz,istep
307
if (debug) write(6,*) me,' r_cluster_old = ',r_cluster_old,
309
if (debug) write(6,*) me,' cl_old(1) = ',cl_old(i,1,2),istep
310
if (debug) write(6,*) me,' cl_old(2) = ',cl_old(i,2,2),istep
311
if (debug) write(6,*) me,' cl_old(3) = ',cl_old(i,3,2),istep
312
if (debug) write(6,*) me,' cl_cm_old(1) = ',cl_cm_old(1),istep
313
if (debug) write(6,*) me,' cl_cm_old(2) = ',cl_cm_old(2),istep
314
if (debug) write(6,*) me,' cl_cm_old(3) = ',cl_cm_old(3),istep
315
if (debug) write(6,*) me,' r_old = ', sqrt(
316
+ + (cl_old(i,1,2)-cl_cm_old(1))**2
317
+ + (cl_old(i,2,2)-cl_cm_old(2))**2
318
+ + (cl_old(i,3,2)-cl_cm_old(3))**2)
319
rn = sqrt(rx**2+ry**2+rz**2)
320
vn = ra(ii,1,2)*rx+ra(ii,2,2)*ry+ra(ii,3,2)*rz
322
t_est = vn*(rn-r_cluster)
323
tcut = cluster_find_tau(ii,i,cllsn_isav,tmax,.false.)
324
if (debug) write(6,*) me,' tcut = ',tcut,istep
325
if (debug) write(6,*) me,' t_est = ',t_est,istep
326
if (debug) write(6,155) me,1,tcut,istep
327
155 format(i3,' tcut at ',i1,': ',f12.4,' step: ',i8)
329
c Check to see if collision is earlier than previously found collisions
330
c and that it is also greater than zero.
332
if (tcut.lt.dtmax.and.tcut.gt.0.0d00) then
334
c Try to protect against numerical roundoff by checking that different
335
c particle collides with sphere or that collision time is significantly
336
c greater than zero if it is the same particle
338
if (.not.(ii.eq.cllsn_isav.and.tcut.lt.1.0d-03)) then
344
write(6,101) ii, tcut, istep
345
101 format('Rejected collision of atom ',i8,' at time ',
346
+ f16.8,' at step ',i8)
349
else if (tcut.lt.0.0d00) then
350
write(6,*) ga_nodeid(),' vn ',vn,istep
351
write(6,*) ga_nodeid(),' t_est ',t_est,istep
352
write(6,*) ga_nodeid(),' r-r_cluster ',r-r_cluster,istep
353
write(6,*) ga_nodeid(),' Returned negative value at 1',istep
358
c Check for trajectories that may have gone out and then back into
361
else if (r_cluster-r.lt.rskin.and.r_cluster-r.gt.0.0d00) then
362
vn = rx*ra(ii,1,2)+ry*ra(ii,2,2)+rz*ra(ii,3,2)
363
if (vn.le.0.0d00) then
364
tcut = cluster_find_tau(ii,i,cllsn_isav,tmax,.true.)
365
if (tcut.lt.dtmax.and.tcut.gt.0.0d00) then
366
write(6,*) 'Found looping trajectory',istep
367
write(6,*) 'dtmax = ',dtmax,istep
368
write(6,*) 'tcut = ',tcut,istep
369
write(6,*) 'ii = ',ii,istep
370
write(6,*) 'cllsn_isav = ',cllsn_isav,istep
371
write(6,*) 'r = ',r,istep
372
write(6,*) 'r_cluster = ',r_cluster,istep
373
if (.not.(ii.eq.cllsn_isav.and.tcut.lt.1.0d-10)) then
374
write(6,*) 'Resetting trajectory',istep
380
write(6,*)'Not resetting trajectory (loop is too short)'
388
c Check to see if a collision occured on another processor
392
if (debug) write(6,*) me,' iat = ',iat,istep
393
if (debug) write(6,*) me,' failsafe = ',failsafe,istep
394
if (debug) write(6,*) me,' ibuf(1) = ',ibuf(1),istep
395
if (debug) write(6,*) me,' ibuf(2) = ',ibuf(2),istep
396
call ga_igop(5,ibuf,2,'+')
397
if (debug) write(6,*) me,' ibuf(1) = ',ibuf(1),istep
398
if (debug) write(6,*) me,' ibuf(2) = ',ibuf(2),istep
400
c No collisions detected. Step is complete so just return.
402
if (ibuf(1).eq.0.and.ibuf(2).eq.0) then
405
if (debug) write(6,*) me,' Returning with no hits ',istep
409
c If no solution found for atom outside confining sphere, then bail
410
c completely and increase diameter of confining sphere so that all
411
c atoms are enclosed.
413
if (ibuf(2).gt.0) then
414
call ga_dgop(4,rmax,1,'max')
415
if (debug) write(6,*) me,' r_cluster (a) = ',r_cluster
416
r_cluster = r_cluster + (rmax - r_cluster)*1.1d00
417
if (debug) write(6,*) me,' r_cluster (b) = ',r_cluster
418
if (ga_nodeid().eq.0) then
419
write(6,*) ga_nodeid(),' Returned negative value at 2',istep
421
failcount = failcount + 1
427
c At this point, a collision has been detected on at least on
428
c processor. Check to find minimum time if collisions occur on more
429
c than one processor.
435
call ga_dgop(6,a,1,'min')
437
c Find mass of particle that has first collision with confining sphere
444
call ga_dgop(7,b,1,'max')
445
1000 mmass = cl_mass - b
447
if (debug) write(6,155) me,2,tcut,istep
452
if (debug) write(6,*) me,' cllsn_isav(1): ',cllsn_isav
455
if (debug) write(6,*) me,' cllsn_isav(2): ',cllsn_isav
458
c Handle degenerate case of only two atoms in cluster, which will
459
c generally have two simultaneous collisions
469
call ga_igop(3,ibuf,nproc,'+')
474
if (ibuf(i).gt.0.and.i-1.eq.me.and.j.eq.0) then
478
else if (ibuf(i).gt.0) then
483
c Make sure that correct mass is being used for collision
490
call ga_dgop(6,b,1,'max')
494
c Now recalculate coordinates of all particles in the cluster
496
call cluster_reset(tcut)
497
call cluster_com !CHECK
499
c Check to see if there were any trajectories that pass through confining
500
c sphere twice (i.e. goes out and then comes back in). Don't bother with
501
c check if there are only 2 particles in system.
514
rx = ra(ii,1,6) - cl_cmx
515
ry = ra(ii,2,6) - cl_cmy
516
rz = ra(ii,3,6) - cl_cmz
517
r = sqrt(rx**2+ry**2+rz**2)
518
if (r.ge.r_cluster.and.ii.ne.cllsn_isav) then
519
tchk = cluster_find_tau(ii,i,cllsn_isav,tcut,.false.)
520
if (debug) write(6,155) me,7,tchk,istep
521
if (debug) write(6,*) me, 'ii: ',ii
522
if (debug) write(6,*) me, 'cllsn_isav: ',cllsn_isav
524
if (tchk.lt.tmin.and.tchk.gt.0.0d00) then
525
if (debug) write(6,*) me,' Shorter collision found'
528
if (debug) write(6,155) me,4,tchk,istep
529
if (debug) write(6,155) me,5,tmin,istep
530
else if (tchk.lt.0.0d00) then
531
write(6,*) ga_nodeid(),' Returned negative value at 3',istep
535
c This case should theoretically be impossible, but it may occur because of
538
write(6,*) me,' tchk greater than or equal to tmin',istep
539
write(6,*) me,' tchk = ',tchk,istep
540
write(6,*) me,' tmin = ',tmin,istep
547
call ga_igop(2,ibuf,2,'+')
549
c No solution for tau found, so increase confining sphere and then bail
551
if (ibuf(2).gt.0) then
552
if (debug) write(6,*) me,' rmax (c) = ',rmax
553
call ga_dgop(4,rmax,1,'max')
554
if (debug) write(6,*) me,' rmax (d) = ',rmax
555
if (debug) write(6,*) me,' r_cluster (c) = ',r_cluster
556
r_cluster = r_cluster + (rmax - r_cluster)*1.1d00
557
if (debug) write(6,*) me,' r_cluster (d) = ',r_cluster
558
if (ga_nodeid().eq.0) then
559
write(6,*) 'Bogus value of collision time at 2'
561
call cluster_reset(t_rmndr)
568
c Shorter collision found so recalculate positions
571
if (tmin.le.tsav) then
572
if (debug) write(6,*) 'tmin = ',tmin,istep
573
if (debug) write(6,*) 'tsav = ',tsav,istep
578
call ga_dgop(2,a,1,'min')
585
if (debug) write(6,*) me,'cllsn_isav(3): ',cllsn_isav
588
if (debug) write(6,*) me,'cllsn_isav(4): ',cllsn_isav
591
tsav = a !BJP is this correct?
592
if (debug) write(6,155) me,3,tcut,istep
598
call ga_dgop(7,b,1,'+')
599
call cluster_reset(0.0d00)
601
if (iter.gt.100) debug = .true.
602
if (iter.gt.1000) call ga_error('Too many iterations',0)
607
2000 l_cllsn = .true.
608
cllsn_idx = cllsn_isav
610
t_rmndr = tmax - tcut
611
t_done = tau - t_rmndr
612
if (debug) write(6,*) me, 't_rmndr = ',t_rmndr
613
if (debug) write(6,*) me, 't_done = ',t_done
618
double precision function cluster_find_tau(iat,iloc,isav,tmax,
622
c This function calculates the time at which a particle outside the confining
623
c sphere would have collided with the sphere.
625
integer iat, iloc, isav
626
double precision r, r2, rx, ry, rz, dr
627
double precision rrx, rry, rrz, vvx, vvy, vvz
628
double precision vx, vy, vz, fx, fy, fz, v2, f2
629
double precision clcut, frdot, vrdot, vfdot, a, b, c
630
double precision t, t1, t2, tcut, tmax, thi, tlo, tmid
631
double precision ttmin,ttmax
633
logical forward, debug
635
c A particle lies outside the cutoff. Find particle that crosses
638
if (istep.ge.68365721.and.istep.le.68365723) then
644
mmass = cl_mass - mass(iat)
646
c Calculate center of mass and velocity of center of mass of remaining
647
c particles in cluster (these are the rr and vv vectors)
649
rrx = (cl_mass*cl_cm_old(1) - mass(iat)*cl_old(iloc,1,2))/mmass
650
rry = (cl_mass*cl_cm_old(2) - mass(iat)*cl_old(iloc,2,2))/mmass
651
rrz = (cl_mass*cl_cm_old(3) - mass(iat)*cl_old(iloc,3,2))/mmass
652
vvx = (cl_mass*cl_vcm_old(1) - mass(iat)*cl_old(iloc,1,3))/mmass
653
vvy = (cl_mass*cl_vcm_old(2) - mass(iat)*cl_old(iloc,2,3))/mmass
654
vvz = (cl_mass*cl_vcm_old(3) - mass(iat)*cl_old(iloc,3,3))/mmass
656
c The r and v vectors are the relative coordinates and velocities of
657
c particle iat and the center of mass vectors. The vector f is the
658
c force along this relative coordinate.
660
rx = cl_old(iloc,1,2) - cl_cm_old(1)
661
ry = cl_old(iloc,2,2) - cl_cm_old(2)
662
rz = cl_old(iloc,3,2) - cl_cm_old(3)
663
vx = cl_old(iloc,1,3) - cl_vcm_old(1)
664
vy = cl_old(iloc,2,3) - cl_vcm_old(2)
665
vz = cl_old(iloc,3,3) - cl_vcm_old(3)
666
fx = ra(iat,1,3) - cl_acmx
667
fy = ra(iat,2,3) - cl_acmy
668
fz = ra(iat,3,3) - cl_acmz
670
r = sqrt(rx**2 + ry**2 + rz**2)
672
c Note that we are using acceleration instead of force,
673
c so factors of reduced mass disappear
675
vrdot = vx*rx + vy*ry + vz*rz
676
frdot = fx*rx + fy*ry + fz*rz
677
vfdot = vx*fx + vy*fy + vz*fz
679
v2 = vx**2 + vy**2 + vz**2
683
c c = rx**2 + ry**2 + rz**2 - clcut**2
685
c Calculate c to minimize roundoff error from subtracting large numbers
688
c = 2.0d00*r*dr+dr**2
689
f2 = fx**2 + fy**2 + fz**2
691
c Scan forwards from 0 to find a final value of t2. If no final
692
c value found, then return with value of -1.
694
if (debug) write(6,*) me, 'iat: ',iat
695
if (debug) write(6,*) me, 'a: ',a
696
if (debug) write(6,*) me, 'b: ',b
697
if (debug) write(6,*) me, 'c: ',c
698
if (debug) write(6,*) me, 'f2: ',f2
699
if (debug) write(6,*) me, 'vfdot: ',vfdot
705
c tlo = c + t1*(b + t1*(a+t1*(vfdot+t1*0.25d00*f2)))
706
tlo = (-c-t1**2*(a+t1*(vfdot+t1*0.25d00*f2)))/b - t1
709
t2= tmax*dble(i)/1000.0d00
710
c thi = c + t2*(b + t2*(a+t2*(vfdot+t2*0.25d00*f2)))
711
thi = (-c-t2**2*(a+t2*(vfdot+t2*0.25d00*f2)))/b - t2
712
if ((thi.ge.0.0d00.and.tlo.le.0.0d00).or.
713
+ (thi.le.0.0d00.and.tlo.ge.0.0d00)) then
715
write(6,*) ga_nodeid(),' tmin = ',ttmin,istep
716
write(6,*) ga_nodeid(),' tmax = ',ttmax,istep
717
write(6,*) ga_nodeid(),' tlo = ',tlo,istep
718
write(6,*) ga_nodeid(),' thi = ',thi,istep
719
write(6,*) ga_nodeid(),' t = ',t,istep
724
cluster_find_tau = -1.0d00
727
c scan backwards from tmax to find an initial value of t1
732
c thi = c + t2*(b + t2*(a+t2*(vfdot+t2*0.25d00*f2)))
733
thi = (-c-t2**2*(a+t2*(vfdot+t2*0.25d00*f2)))/b - t2
735
if (t.eq.0.0d00) then
736
t1= tmax - tmax*dble(i)/1000.0d00
737
c tlo = c + t1*(b + t1*(a+t1*(vfdot+t1*0.25d00*f2)))
738
tlo = (-c-t1**2*(a+t1*(vfdot+t1*0.25d00*f2)))/b - t1
739
if ((thi.ge.0.0d00.and.tlo.le.0.0d00).or.
740
+ (thi.le.0.0d00.and.tlo.ge.0.0d00)) then
742
if (debug) write(6,*) me, 'tlo: ',tlo
743
if (debug) write(6,*) me, 'thi: ',thi
744
if (debug) write(6,*) me, 't: ',t
751
c Use bisections to find accurate solution
753
500 if (forward) then
759
if (debug) write(6,*) me, 't1: ',t1
760
if (debug) write(6,*) me, 't2: ',t2
763
c 600 tlo = c + t1*(b + t1*(a+t1*(vfdot+t1*0.25d00*f2)))
764
c thi = c + t2*(b + t2*(a+t2*(vfdot+t2*0.25d00*f2)))
765
600 tlo = (-c-t1**2*(a+t1*(vfdot+t1*0.25d00*f2)))/b - t1
766
thi = (-c-t2**2*(a+t2*(vfdot+t2*0.25d00*f2)))/b - t2
767
if ((thi.ge.0.0d00.and.tlo.le.0.0d00).or.
768
+ (thi.le.0.0d00.and.tlo.ge.0.0d00)) then
770
c tmid = c + t*(b + t*(a+t*(vfdot+t*0.25d00*f2)))
771
tmid = (-c-t**2*(a+t*(vfdot+t*0.25d00*f2)))/b - t
772
if ((tmid.ge.0.0d00.and.thi.le.0.0d00).or.
773
+ (tmid.le.0.0d00.and.thi.ge.0.0d00)) then
775
else if ((tmid.ge.0.0d00.and.tlo.le.0.0d00).or.
776
+ (tmid.le.0.0d00.and.tlo.ge.0.0d00)) then
779
tcut = 0.5d00*(t1+t2)
781
if (abs(t1-t2)/tau.gt.1.0d-14.and.iter.lt.1000) go to 600
783
c Protect against numerical roundoff errors
785
if (iter.ge.1000) then
786
write(6,*) ga_nodeid(),' Maxed out on iterations'
788
if (forward.and.(tcut.lt.1.0d-10.or.
789
+ abs(tcut-tmax).lt.1.0d-10)) then
790
cluster_find_tau = -1.0d00
794
open(unit=2,file='tau.dat',status='unknown')
796
t = tmax*dble(j)/1000.0d00
797
t1 = (-c-t**2*(a+t*(vfdot+t*0.25d00*f2)))/b - t
798
tmid = c + t*(b + t*(a+t*(vfdot+t*0.25d00*f2)))
799
write(2,300) t,t1, tmid
800
300 format(3(' ',f16.8))
803
if (iat.ne.isav) then
804
if (abs(thi).lt.0.000001d00) then
806
else if (abs(tlo).lt.0.000001d00) then
807
if (vrdot.gt.0.0d00) then
813
if (forward) write(6,*) 'Searching forward'
814
write(6,*) 'Collision time does not converge at step ',istep
822
if (forward) write(6,*) ga_nodeid(),' tcut = ',tcut
823
cluster_find_tau = tcut
827
double precision function cluster_check_radius()
829
double precision rx, ry, rz, r2, cl2
832
c check to make sure that all cluster particles are within cluster
838
rx = ra(i,1,6) - cl_cmx
839
ry = ra(i,2,6) - cl_cmy
840
rz = ra(i,3,6) - cl_cmz
841
r2 = rx**2 + ry**2 + rz**2
842
if (r2.gt.cl2) cl2 = r2
845
call ga_dgop(4,cl2,1,'max')
847
cluster_check_radius = sqrt(cl2)
851
subroutine cluster_mc
854
c Perform Monte Carlo adjustment of volume on confining volume
856
double precision r_old, delta_r, r2, cl2, rx, ry, rz, pi
857
double precision vol_new, vol_old, x, ran1, ratio
858
integer i, icnt, iat, me
859
logical force_move,debug
861
if (nocluster) return
862
if (istep.ge.6932366) then
869
r_cluster_old = r_cluster
873
if (debug) write(6,*)me,' (1) r_cluster ',r_cluster,istep
875
r_cluster = r_cluster + delta_r*(ran1(0)-0.5d00)
879
if (debug) write(6,*)me,' (2) r_cluster ',r_cluster,istep
880
call ga_dgop(1,r_cluster,1,'+')
881
if (debug) write(6,*)me,' (3) r_cluster ',r_cluster,istep
883
c If new value of r_cluster falls outside of allowed interval then
884
c it is rejected, unless old value was aready outside interval.
886
if (r_cluster.ge.cl_upper.or.r_cluster.le.cl_lower) then
888
c If new values move cluster radius closer to cutoffs from the outside,
889
c then accept them, reject them otherwise. Before accepting move, make
890
c sure that there are no illegal overlaps.
893
if (r_cluster.gt.r_old.and.r_cluster.gt.cl_upper) then
895
else if (r_cluster.lt.r_old.and.r_cluster.lt.cl_lower) then
898
if (r_cluster.eq.r_old) return
900
if (debug) write(6,*)me,' (4) r_cluster ',r_cluster,istep
902
c Check to see if any particles are outside new value of r_cluster.
903
c If so, then new value is rejected.
905
if (r_cluster.lt.r_old) then
910
rx = ra(i,1,6) - cl_cmx
911
ry = ra(i,2,6) - cl_cmy
912
rz = ra(i,3,6) - cl_cmz
913
r2 = rx**2 + ry**2 + rz**2
919
call ga_igop(9,icnt,1,'+')
925
if (debug) write(6,*)me,' (5) r_cluster ',r_cluster,istep
926
if (force_move) return
928
c Accept with Monte Carlo probability.
930
pi = 4.0d00*atan(1.0d00)
931
vol_new = 4.0d00*pi*r_cluster**3/3.0d00
932
vol_old = 4.0d00*pi*r_old**3/3.0d00
933
ratio = (r_cluster/r_old)**2
935
x = ratio*exp(-cl_prssr*(vol_new-vol_old)/mc_tmprtr)
937
if (x.ge.1.0d00) then
940
if (ran1(0).lt.x) then
949
call ga_igop(1,icnt,1,'+')
953
if (debug) write(6,*)me,' (6) r_cluster ',r_cluster,istep
957
subroutine cluster_binr
960
c Bin the current value of r_cluster
964
if (nocluster) return
968
dr = r_cluster - cl_lower
969
ir = int(dr/mc_step) + 1
971
if (ir.gt.mcbins) ir = mcbins
974
c Find slice for statistics
976
if (istep.gt.mc_start) then
977
isample = int(10.0d00*(dble(istep-mc_start)-0.5d00)
978
+ / dble(nstep-mc_start)) + 1
979
if (isample.gt.10) isample = 10
983
r_cnt(isample) = r_cnt(isample) + 1
984
r_distr(ir,isample) = r_distr(ir,isample) + 1
988
subroutine cluster_print_binr
991
c Print out the distribution of r_cluster
993
double precision rdist(MAXBINS), norm, r, normi
994
double precision rdist2(MAXBINS), sum
995
double precision sigr(MAXBINS),sigr2(MAXBINS)
996
double precision sig2(MAXBINS),sig2_2(MAXBINS)
997
double precision rdisti(MAXBINS,10),rdisti2(MAXBINS,10)
998
integer itot, i, j, isample
999
character*32 filename
1001
if (nocluster) return
1002
if (task_id.lt.10) then
1003
write(filename,100) task_id
1004
else if (task_id.ge.10.and.task_id.lt.100) then
1005
write(filename,101) task_id
1006
else if (task_id.ge.100.and.task_id.lt.1000) then
1007
write(filename,102) task_id
1008
else if (task_id.ge.1000.and.task_id.lt.10000) then
1009
write(filename,103) task_id
1011
100 format('cl.distr.',i1)
1012
101 format('cl.distr.',i2)
1013
102 format('cl.distr.',i3)
1014
103 format('cl.distr.',i4)
1016
c Evaluate normalized distribution and uncertainty for P(r)
1018
if (mc_cnt.lt.0) return
1028
rdisti(i,j) = 0.0d00
1029
rdisti2(i,j) = 0.0d00
1033
normi = dble(r_cnt(j))
1035
rdist(i) = rdist(i) + dble(r_distr(i,j))/norm
1036
rdisti(i,j) = dble(r_distr(i,j))/normi
1041
sig2(i) = sig2(i) + rdisti(i,j)**2
1045
sigr(i) = (sig2(i)-10.0d00*rdist(i)**2)/9.0d00
1048
c Uncertainty at the 95% confidence level
1051
sigr(i) = 2.23d00*sqrt(sigr(i)/10.d00)
1055
sum = sum + rdist(i)
1058
rdist(i) = rdist(i)/(sum*mc_step)
1059
sigr(i) = sigr(i)/(sum*mc_step)
1062
c Evaluate normalized distribution and uncertainty for P(V)
1065
normi = dble(r_cnt(j))
1067
r = cl_lower + (dble(i)-0.5d00)*mc_step
1068
rdist2(i) = rdist2(i) + dble(r_distr(i,j))/(r**2*norm)
1069
rdisti2(i,j) = dble(r_distr(i,j))/(r**2*normi)
1074
sig2_2(i) = sig2_2(i) + rdisti2(i,j)**2
1078
sigr2(i) = (sig2_2(i)-10.0d00*rdist2(i)**2)/9.0d00
1081
c Uncertainty at the 95% confidence level
1084
sigr2(i) = 2.23d00*sqrt(sigr2(i)/10.d00)
1088
sum = sum + rdist2(i)
1091
rdist2(i) = rdist2(i)/(sum*mc_step)
1092
sigr2(i) = sigr2(i)/(sum*mc_step)
1095
if (ga_nodeid().eq.0) then
1096
open(unit=2,file=filename,status='unknown')
1098
r = cl_lower + (dble(i)-0.5d00)*mc_step
1099
write(2,200) r, rdist(i), rdist2(i),sigr(i),sigr2(i)
1100
200 format(f12.4,' ',f16.8,' ',f16.8,' ',
1109
subroutine cluster_clear_binr
1110
#include "common.fh"
1112
c clear the distribution of r_cluster
1116
if (nocluster) return
1129
subroutine cluster_reset_binr(iflg)
1130
#include "common.fh"
1132
c recalculate bounds for confining sphere
1134
integer iflg,ilow,ihi,imax,i
1135
if (nocluster) return
1138
c find minimum and maximum values of distribution and reset
1139
c windows to just bound these values
1141
if (ga_nodeid().eq.0.and.l_rad) then
1142
open(unit=3,file="win1.dat",status='unknown')
1144
write(3,*) i, r_distr(i,1)
1150
if (r_distr(i,1).gt.0.and.ilow.eq.0) then
1152
if (ilow.lt.1) ilow = 1
1154
if (ilow.gt.0.and.ihi.eq.0.and.r_distr(i,1).eq.0) then
1158
if (ihi.eq.0) ihi = mcbins
1159
if (ihi.lt.mcbins) then
1160
cl_upper = cl_lower + mc_step*dble(ihi)
1163
cl_lower = cl_lower + mc_step*dble(ilow-1)
1165
else if (iflg.eq.2) then
1167
c reset bounds so that maximum is set at radius value that
1168
c is the maximum value of distribution
1174
c if (r_distr(i,1).gt.0.and.ilow.eq.0) then
1176
c if (ilow.lt.1) ilow = 1
1178
if (r_distr(i,1).gt.imax) then
1183
if (ihi.eq.0) ihi = mcbins
1184
if (ihi.lt.mcbins) then
1185
cl_upper = cl_lower + mc_step*dble(ihi)
1188
cl_lower = cl_lower + mc_step*dble(ilow-1)
1195
mc_step = (cl_upper-cl_lower)/dble(mcbins)
1196
call cluster_clear_binr
1200
subroutine cluster_do_cllsn
1201
#include "common.fh"
1202
integer iat, i, j, ii, jj, iloc, isav, scndat
1203
double precision r, r2, rc2, rx, ry, rz
1204
double precision rrx, rry, rrz, vvx, vvy, vvz
1205
double precision vx, vy, vz, fx, fy, fz, mu, v2, f2
1206
double precision comm(4), tmax, tcut, vrdot
1207
double precision rnx, rny, rnz, vpx, vpy, vpz, vllx, vlly, vllz
1209
c Re-evaluate all particle velocities. First, recalculate center of
1210
c mass and center of mass velocity of cluster at new coordinates
1213
if (nocluster) return
1214
cllsn_cnt = cllsn_cnt + 1
1218
rrx = (cl_mass*cl_cmx - mass(iat)*ra(iat,1,6))/mmass
1219
rry = (cl_mass*cl_cmy - mass(iat)*ra(iat,2,6))/mmass
1220
rrz = (cl_mass*cl_cmz - mass(iat)*ra(iat,3,6))/mmass
1221
vvx = (cl_mass*cl_vcmx - mass(iat)*ra(iat,1,2))/mmass
1222
vvy = (cl_mass*cl_vcmy - mass(iat)*ra(iat,2,2))/mmass
1223
vvz = (cl_mass*cl_vcmz - mass(iat)*ra(iat,3,2))/mmass
1225
c The r and v vectors are the relative coordinates and velocities of
1226
c particle iat and the center of mass vectors. The vector f is the
1227
c force along this relative coordinate.
1229
rx = ra(iat,1,6) - rrx
1230
ry = ra(iat,2,6) - rry
1231
rz = ra(iat,3,6) - rrz
1232
vx = ra(iat,1,2) - vvx
1233
vy = ra(iat,2,2) - vvy
1234
vz = ra(iat,3,2) - vvz
1236
c Decompose velocity v into components that are parallel and perpendicular
1237
c to r. Save this information for computing post-collision velocities.
1239
r = sqrt(rx**2 + ry**2 + rz**2)
1243
vrdot = vx*rnx + vy*rny + vz*rnz
1250
comm(1) = (vpx-vllx-vx)/cl_mass
1251
comm(2) = (vpy-vlly-vy)/cl_mass
1252
comm(3) = (vpz-vllz-vz)/cl_mass
1260
call ga_dgop(8,comm,4,'+')
1269
ra(ii,1,2) = ra(ii,1,2) + mmass*vvx
1270
ra(ii,2,2) = ra(ii,2,2) + mmass*vvy
1271
ra(ii,3,2) = ra(ii,3,2) + mmass*vvz
1273
ra(ii,1,2) = ra(ii,1,2) - mass(ii)*vvx
1274
ra(ii,2,2) = ra(ii,2,2) - mass(ii)*vvy
1275
ra(ii,3,2) = ra(ii,3,2) - mass(ii)*vvz
1283
subroutine cluster_reset(dt)
1284
#include "common.fh"
1285
double precision dt, htausq, scale
1288
c Reset coordinates and velocities using old values from beginning of
1291
htausq = 0.5d00*dt**2
1294
ra(ii,1,1) = cl_old(i,1,1)+dt*cl_old(i,1,3)+htausq*ra(ii,1,3)
1295
ra(ii,2,1) = cl_old(i,2,1)+dt*cl_old(i,2,3)+htausq*ra(ii,2,3)
1296
ra(ii,3,1) = cl_old(i,3,1)+dt*cl_old(i,3,3)+htausq*ra(ii,3,3)
1297
ra(ii,1,6) = cl_old(i,1,2)+dt*cl_old(i,1,3)+htausq*ra(ii,1,3)
1298
ra(ii,2,6) = cl_old(i,2,2)+dt*cl_old(i,2,3)+htausq*ra(ii,2,3)
1299
ra(ii,3,6) = cl_old(i,3,2)+dt*cl_old(i,3,3)+htausq*ra(ii,3,3)
1300
ra(ii,1,2) = cl_old(i,1,3)+dt*ra(ii,1,3)
1301
ra(ii,2,2) = cl_old(i,2,3)+dt*ra(ii,2,3)
1302
ra(ii,3,2) = cl_old(i,3,3)+dt*ra(ii,3,3)
1307
ra(ii,1,1) = sl_old(i,1,1)+dt*sl_old(i,1,3)+htausq*ra(ii,1,3)
1308
ra(ii,2,1) = sl_old(i,2,1)+dt*sl_old(i,2,3)+htausq*ra(ii,2,3)
1309
ra(ii,3,1) = sl_old(i,3,1)+dt*sl_old(i,3,3)+htausq*ra(ii,3,3)
1310
ra(ii,1,6) = sl_old(i,1,2)+dt*sl_old(i,1,3)+htausq*ra(ii,1,3)
1311
ra(ii,2,6) = sl_old(i,2,2)+dt*sl_old(i,2,3)+htausq*ra(ii,2,3)
1312
ra(ii,3,6) = sl_old(i,3,2)+dt*sl_old(i,3,3)+htausq*ra(ii,3,3)
1313
ra(ii,1,2) = sl_old(i,1,3)+dt*ra(ii,1,3)
1314
ra(ii,2,2) = sl_old(i,2,3)+dt*ra(ii,2,3)
1315
ra(ii,3,2) = sl_old(i,3,3)+dt*ra(ii,3,3)
1320
c resete extended Hamiltonian parameters
1322
if ((prsflg.or.ptflg).and.ipmode.eq.0) then
1323
vol1 = cl_vol1_old + dt * cl_vol2_old + htausq * vol3
1324
vol2 = cl_vol2_old + dt * vol3
1325
scale = vol1 / (cl_box_old(1) * cl_box_old(2) * cl_box_old(3))
1326
scale = exp(log(scale)/3.0d00)
1327
xbox = scale * cl_box_old(1)
1328
ybox = scale * cl_box_old(2)
1329
zbox = scale * cl_box_old(3)
1330
xbox2 = 0.5d00 * xbox
1331
ybox2 = 0.5d00 * ybox
1332
zbox2 = 0.5d00 * zbox
1335
if ((prsflg.or.ptflg).and.ipmode.eq.1) then
1337
alen1(i) = cl_alen1_old(i) + dt * cl_alen2_old(i)
1338
+ + htausq * alen3(i)
1339
alen2(i) = cl_alen2_old(i) + dt * alen3(i)
1344
xbox2 = 0.5d00 * xbox
1345
ybox2 = 0.5d00 * ybox
1346
zbox2 = 0.5d00 * zbox
1349
if ((prsflg.or.ptflg).and.ipmode.eq.2) then
1351
alen1(i) = cl_alen1_old(i) + dt * cl_alen2_old(i)
1352
+ + htausq * alen3(i)
1353
alen2(i) = cl_alen2_old(i) + dt * alen3(i)
1357
xbox2 = 0.5d00 * xbox
1358
ybox2 = 0.5d00 * ybox
1361
c predictor step for time scale
1363
if (tmpflg.or.ptflg) then
1364
scal1 = cl_scal1_old + dt * cl_scal2_old + htausq * scal3
1365
scal2 = cl_scal2_old + dt * scal3
1368
c center of mass parameters
1370
cl_cmx = cl_cm_old(1)
1371
cl_cmy = cl_cm_old(2)
1372
cl_cmz = cl_cm_old(3)
1373
cl_vcmx = cl_vcm_old(1)
1374
cl_vcmy = cl_vcm_old(2)
1375
cl_vcmz = cl_vcm_old(3)