ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/nano_mpi/src/dynamics_nose_hoover.F90
Revision: 9
Committed: Mon Jul 1 15:27:33 2002 UTC (22 years ago) by chuckv
File size: 9831 byte(s)
Log Message:
nose hoover chains added

File Contents

# User Rev Content
1 pconfort 8 ! MTK (Martina Tuckerman and Klein) Nosie' Hoover chains
2     ! See Molecular Physics, 1996, Vol. 87, No. 5, 1117-1157 for details of
3     ! the algorithm.
4     !
5     ! author: Charles F. Vardeman II
6     ! date: 6-12-02
7     !
8     ! Interfaces:
9     ! Called from dynamics module:
10     ! public: nose_hoover_dynamics(): controls nose-hoover chains dynamics
11     ! for the length of the simulation time:
12     ! No Arguments:
13    
14     ! private:
15     ! nose_hoovera: updates nose_hoover chains and then advances particle positions and velocities
16     ! by velocity verlet.
17     ! nose_hooverb: updates velocities, second half of velocity verlet. and thermostat velocities and
18     ! positions.
19     ! init_hoover: initalize hoover structures
20     ! apply_NHC_par: performs details of nose-hoover chains.
21    
22    
23 chuckv 4 module dynamics_nose_hoover
24     use definitions, ONLY : DP,NDIM
25     use constants
26     use simulation
27     use parameter
28     use force_module, ONLY : calc_forces
29     use force_utilities, ONLY : check
30     use velocity, ONLY : scale_velocities
31     use dynamics_utilities, ONLY : evolve_time, sim_status, init_dynamics_loop, &
32 chuckv 9 DT2,DTSQRT,DTSQ2,init_status
33 chuckv 4 #ifdef MPI
34     use mpi_module, ONLY : mpi_allreduce,mpi_comm_world,mpi_err,&
35     mpi_double_precision, mpi_sum
36     #endif
37    
38     implicit none
39     PRIVATE
40 chuckv 9 SAVE
41 chuckv 4
42    
43     public :: nose_hoover_dynamics
44 pconfort 8
45 chuckv 4 type (sim_status) :: nose_status
46    
47 chuckv 9
48 chuckv 4 contains
49    
50    
51 pconfort 8 subroutine nose_hoover_dynamics()
52     use velocity, ONLY : calc_temp
53 chuckv 4
54    
55    
56 pconfort 8 logical :: update_nlist
57     logical :: do_pot
58     logical :: not_done
59     logical :: nmflag
60 chuckv 4
61 chuckv 9
62    
63 pconfort 8 integer :: step, i
64 chuckv 4
65 pconfort 8 ! initialize status (ke,pe,time, etc.)
66     call init_status(nose_status)
67     call init_dynamics_loop( nose_status )
68 chuckv 4
69 pconfort 8 ! Start the main simulation loop.
70 chuckv 4
71 pconfort 8 do_pot = .true.
72     not_done = .true.
73     nmflag = .false.
74     step = 0
75 chuckv 4
76 pconfort 8 dynamics: do
77     if (.not.not_done) exit dynamics
78 chuckv 4
79 pconfort 8 step = step + 1
80 chuckv 4
81 pconfort 8
82     if (checktemp.and.(mod(step,check_temp_steps).eq.0)) then
83 chuckv 4 call calc_temp(nose_status%temp)
84 pconfort 8 if (dabs(nose_status%temp-target_temp).gt.therm_variance) then
85     call scale_velocities(target_temp)
86     end if
87     end if
88 chuckv 4
89 pconfort 8 call nose_hoovera()
90 chuckv 4
91 pconfort 8 call check(update_nlist)
92 chuckv 4
93    
94 pconfort 8 if (do_pot) then
95     call calc_forces(update_nlist,nmflag,pe = nose_status%pot_e)
96     else
97     call calc_forces(update_nlist,nmflag)
98     endif
99 chuckv 4
100 pconfort 8
101     call nose_hooverb()
102    
103     call evolve_time(step,nose_status,do_pot,not_done)
104    
105    
106 chuckv 4 #ifdef MPI
107 pconfort 8 call mpi_barrier(mpi_comm_world,mpi_err)
108 chuckv 4 #endif
109 pconfort 8 end do dynamics
110 chuckv 4
111 pconfort 8 end subroutine nose_hoover_dynamics
112 chuckv 4
113    
114 pconfort 8 ! nose_hoovera(): advances velocities from T to T + DT/2 and positions from T to T + DT
115     subroutine nose_hoovera()
116     use velocity, ONLY : remove_cm_momentum,remove_angular_momentum
117 chuckv 4
118    
119    
120    
121 pconfort 8 integer :: i, dim
122     real( kind = DP) :: ke, v2, instatemp, chi
123     real( kind = DP) :: kebar
124 chuckv 4
125 pconfort 8 real( kind = DP ), dimension(ndim) :: v_dim_i
126 chuckv 4
127 pconfort 8 real(kind=DP) :: ke_local
128 chuckv 4
129 pconfort 8 ! units for time are femtosec (10^-15 sec)
130     ! units for distance are angstroms (10^-10 m)
131     ! units for velocity are angstroms femtosec^-1
132     ! units for mass are a.m.u. (1.661 * 10^-27 kg)
133     ! units for force are kcal mol^-1 angstrom^-1
134     !
135     ! converter will put the final terms into angstroms.
136     ! or angstrom/femtosecond.
137 chuckv 4
138 pconfort 8 ! converter = 1.0d0/2.390664d3
139 chuckv 4
140    
141 pconfort 8 ! call nose_hoover chains
142 chuckv 9 call apply_NHC_par(dt2)
143    
144 chuckv 4
145 pconfort 8 ! advance velocities from t to t + dt/2
146     do i = 1, nlocal
147     v(1:ndim,i) = v(1:ndim,i) + &
148     (dt2*f(1:ndim,i)/mass(i))*KCALMOL_TO_AMUA2FS2
149     end do
150 chuckv 4
151 pconfort 8 ! advance positions from t to t+dt
152     do i = 1, nlocal
153     q(1:ndim,i) = q(1:ndim,i) + dt*v(1:ndim,i)
154     end do
155 chuckv 4
156    
157 pconfort 8 end subroutine nose_hoovera
158 chuckv 4
159    
160 pconfort 8 ! advances velocities another half step from t+dt/2 to t + dt
161 chuckv 9 subroutine nose_hooverb()
162 pconfort 8 use velocity, ONLY : remove_cm_momentum,remove_angular_momentum
163     integer i
164 chuckv 4
165 pconfort 8 ! units for time are femtosec (10^-15 sec)
166     ! units for distance are angstroms (10^-10 m)
167     ! units for velocity are angstroms femtosec^-1
168     ! units for mass are a.m.u. (1.661 * 10^-27 kg)
169     ! units for force are kcal mol^-1 angstrom^-1
170 chuckv 4
171 pconfort 8 do i = 1, nlocal
172     v(1:ndim,i) = v(1:ndim,i) + &
173     (dt2*f(1:ndim,i)/mass(i))*KCALMOL_TO_AMUA2FS2
174     end do
175 chuckv 4
176 pconfort 8 ! apply nose-hoover thermostat
177 chuckv 9 call apply_NHC_par(dt2)
178 chuckv 4
179 chuckv 9 ! if (sim_type == "cluster") then
180     ! call remove_cm_momentum()
181     ! call remove_angular_momentum()
182     ! endif
183 pconfort 8 end subroutine nose_hooverb
184 chuckv 4
185    
186 pconfort 8 ! does the Nose-Hoover part of the integration from t = 0 to t=DT/2
187     ! borrowed from Chris Fennel's code of thermostating
188     ! by way of Hoover, Phys.Rev.A 1985, Vol.31 (3) 1695-1697
189 chuckv 4
190 chuckv 9 subroutine apply_NHC_par(this_time)
191 pconfort 8 use velocity, ONLY : calc_temp
192 chuckv 9 real(kind = DP) :: system_ke, ke_temp
193 pconfort 8 real(kind = DP) :: system_temp
194     real(kind = DP) :: G_NkT
195     real(kind = DP) :: Q_mass
196     real(kind = DP) :: zetaScale
197     real(kind = DP),dimension(ndim) :: vi
198 chuckv 9 real(kind = DP),intent(out) :: this_time
199 chuckv 4
200 pconfort 8 integer :: i
201 chuckv 9 integer :: j
202 pconfort 8
203 chuckv 9 call calc_temp(system_temp, system_ke)
204 pconfort 8
205 chuckv 9 G_NkT = natoms*ndim * 8.31451d-7 * target_temp
206     ke_temp = system_ke*KCALMOL_TO_AMUA2FS2
207    
208     ! write(*,*) 'System_temp: ', system_temp
209     ! write(*,*) 'ke_temp: ',ke_temp
210    
211 pconfort 8 ! Q_mass is a function of the omega parameter
212 chuckv 9 ! Q_mass = G_NkT / (omeg * omeg)
213     Q_mass = 50000._DP
214 pconfort 8
215     ! advance the zeta term to zeta(t + dt)
216 chuckv 9 nzeta = nzeta + this_time*((ke_temp*2 - G_NkT)/Q_mass)
217 pconfort 8
218 chuckv 9 ! write(*,*) 'zeta: ',zeta
219     ! write(*,*) 'dt: ',dt
220     ! write(*,*) 'ke_temp: ',ke_temp
221     ! write(*,*) 'G_NkT: ',G_NkT
222     ! write(*,*) 'Q_mass: ',Q_mass
223    
224     zetaScale = nzeta * this_time
225    
226     ! write(*,*) 'zetaScale: ',zetaScale
227    
228 pconfort 8 ! perform thermostating on velocities and angular momenta
229     do i = 1, nlocal
230 chuckv 9 do j = 1, ndim
231     vi(j) = v(j,i)*zetaScale
232     v(j,i) = v(j,i) - vi(j)
233     enddo
234 pconfort 8 enddo
235    
236     end subroutine apply_NHC_par
237    
238    
239    
240     !!$ ! other code borrowed from Chris Fennell's code of
241     !!$ ! G.J. Martyna et al. Mol. Phys., 1996, Vol. 87, No. 5, 1117-1157
242     !!$
243     !!$ subroutine apply_NHC_par()
244     !!$ use velocity, ONLY : calc_temp
245     !!$ real(kind = DP) :: scale
246     !!$ real(kind = DP) :: system_ke
247     !!$ real(kind = DP) :: system_temp
248     !!$ real(kind = DP) :: G_NkT
249     !!$ real(kind = DP) :: omega2
250     !!$ real(kind = DP) :: value1, value2, value3, value4
251     !!$ real(kind = DP) :: wdti2(n_ysval), wdti4(n_ysval), wdti8(n_ysval)
252     !!$ real(kind = DP) :: G_val(N_nos), vval(N_nos), xival(N_nos)
253     !!$ real(kind = DP) :: Q_mass
254     !!$
255     !!$ integer :: i, j
256     !!$
257     !!$ scale = 1._DP
258     !!$
259     !!$ call calc_temp(system_temp,system_ke)
260     !!$
261     !!$ G_NkT = natoms*ndim*K_BOLTZ*my_temp
262     !!$
263     !!$ ! we need to get the w numbers for these values
264     !!$ ! but i think that chris has calculated the values
265     !!$ ! because they are values of constants
266     !!$ value1 = 0.67560359598d0 * dt
267     !!$ value2 = -0.85120719196d0 * dt
268     !!$ value3 = 0.207245385897d0 * dt
269     !!$ value4 = -0.328981543589d0 * dt
270     !!$ if (n_ysval.eq.3) then
271     !!$ wdti2(1) = value1
272     !!$ wdti2(2) = value2
273     !!$ wdti2(3) = value1
274     !!$ wdti4(1) = 0.5_DP * wdti2(1)
275     !!$ wdti4(2) = 0.5_DP * wdti2(2)
276     !!$ wdti4(3) = wdti4(1)
277     !!$ wdti8(1) = 0.5_DP * wdti4(1)
278     !!$ wdti8(2) = 0.5_DP * wdti4(2)
279     !!$ wdti8(3) = wdti8(1)
280     !!$ else
281     !!$ write(*,*) 'Error: n_syval must be 3'
282     !!$ stop
283     !!$ endif
284     !!$
285     !!$ omega2 = omega * omega
286     !!$
287     !!$ ! set the Q_mass values
288     !!$ Q_mass(1) = G_NkT/omega2
289     !!$ do i = 2, N_nos-1
290     !!$ Q_mass(i) = system_temp/omega2
291     !!$ enddo
292     !!$
293     !!$ qmass(N_nos) = 2 * omega
294     !!$
295     !!$ ! zero the intial xivals and vvals
296     !!$ do i = 1, N_nos
297     !!$ xival(i) = 0._DP
298     !!$ vval(i) = 0._DP
299     !!$ enddo
300     !!$
301     !!$ ! Start the Nose_Hoover chain stepping
302     !!$ ! update the forces
303     !!$ G_val(1) = (system_ke - G_NkT)/Q_mass(1)
304     !!$
305     !!$ ! start the multiple time stepping
306     !!$ do i = 1, n_cval
307     !!$ do j = 1, n_ysval
308     !!$
309     !!$ ! update the thermostat velocities
310     !!$ vval(N_nos) = vval(N_nos) + G_val(N_nos)*wdti4(j)/i
311     !!$ do mcount = 1, N_nos-1
312     !!$ aa = exp((-wdti8(j)/i) * vval((N_nos+1)-mcount))
313     !!$ vval(N_nos-mcount) = vval(N_nos-mcount)*aa*aa &
314     !!$ + wdti4(j)*G_val(N_nos)*wdti4(j)/(i*i)
315     !!$ enddo
316     !!$
317     !!$ ! update particle velocities
318     !!$ aa = exp((-wdti2(j)/i)*vval(1))
319     !!$ scale = scale*aa
320     !!$
321     !!$ ! update the forces
322     !!$ G_val(1) = (scale*scale*ke -G_NkT)/Q_mass(1)
323     !!$
324     !!$ ! update the thermostat positions
325     !!$ do mcount = 1, N_nos-1
326     !!$ xival(mcount) = xival(mcount) + vval(mcount)*(wdti2(j)/i)
327     !!$ enddo
328     !!$
329     !!$ ! update the thermostat velocities
330     !!$ do mcount = 1, N_nos-1
331     !!$ aa = exp((-wdti8(j)/i)*vval(mcount+1))
332     !!$ vval(mcount) = vval(mcount)*aa*aa &
333     !!$ + (wdti4(j)/i)*G_val(mcount)*aa
334     !!$ G_val(mcount+1) = (Q_mass(mcount)*vval(mcount)*vval(mcount) &
335     !!$ - system_temp)/Q_mass(mcount+1)
336     !!$ enddo
337     !!$
338     !!$ vval(N_nos) = vval(N_nos) + G_val(N_nos)*(wdti4(j)/i)
339     !!$ enddo
340     !!$ enddo
341     !!$
342     !!$ ! scale both linear velocities and angular momenta
343     !!$ do i = 1, nlocal
344     !!$ v(1:ndim,i) = v(1:ndim,i)*scale
345     !!$ !something here for what we use for angular momenta
346     !!$ enddo
347     !!$
348     !!$ end subroutine apply_NHC_par
349    
350    
351    
352 chuckv 4 end module dynamics_nose_hoover