RMPCDMD
setup_simple_rattle.f90
Go to the documentation of this file.
1 ! This file is part of RMPCDMD
2 ! Copyright (c) 2015-2016 Pierre de Buyl and contributors
3 ! License: BSD 3-clause (see file LICENSE)
4 
6  use common
7  use cell_system
9  use hilbert
10  use neighbor_list
11  use hdf5
12  use h5md_module
13  use interaction
14  use threefry_module
15  use mpcd
16  use md
17  use iso_c_binding
18  use omp_lib
19  implicit none
20 
21  type(cell_system_t) :: solvent_cells
22  type(particle_system_t) :: solvent
23  type(particle_system_t) :: colloids
24  type(neighbor_list_t) :: neigh
25  type(lj_params_t) :: solvent_colloid_lj
26  type(lj_params_t) :: colloid_lj
27 
28  integer, parameter :: rho = 10
29  integer, parameter :: L(3) = [12, 12, 12]
30  integer, parameter :: N = rho*l(1)*l(2)*l(3)
31 
32  integer :: error
33 
34  integer, parameter :: n_link=6
35  integer :: links(2,n_link)
36  double precision:: links_dist(n_link)
37 
38  double precision :: epsilon, sigma, sigma_cut
39  double precision :: so_max, co_max
40 
41  double precision :: e1, e2
42  double precision :: tau, dt
43  integer :: N_MD_steps
44  integer :: n_extra_sorting
45  integer :: n_threads
46 
47  type(threefry_rng_t), allocatable :: state(:)
48 
49  double precision :: tmp_x(3)
50  double precision :: skin
51 
52  integer :: i
53  integer :: j, k
54 
55  n_threads = omp_get_max_threads()
56  allocate(state(n_threads))
57  call threefry_rng_init(state, -4466704919147519266_c_int64_t)
58 
59  call h5open_f(error)
60 
61  epsilon = 1
62  sigma = 1.
63  sigma_cut = sigma*2**(1.d0/6.d0)
64 
65  call solvent_colloid_lj% init( reshape( [ epsilon ], [1, 1] ), &
66  reshape( [ sigma ], [1, 1] ), reshape( [ sigma_cut ], [1, 1] ) )
67 
68  epsilon = 1
69  sigma = 1
70  sigma_cut = sigma*2**(1.d0/6.d0)
71 
72  call colloid_lj% init( reshape( [ epsilon ], [1, 1] ), &
73  reshape( [ 2*sigma ], [1, 1] ), reshape( [ 2*sigma_cut ], [1, 1] ) )
74 
75  call solvent% init(n)
76 
77  call colloids%init(4)
78  colloids% species = 1
79  colloids% vel = 0
80 
81  colloids%mass = rho*sigma**3*4*3.14159/3
82 
83  colloids%pos(:,1) = [1.d0, 0.d0, -1/sqrt(2.d0)]
84  colloids%pos(:,2) = [1.d0, 0.d0, 1/sqrt(2.d0)]
85  colloids%pos(:,3) = [0.d0, 1.d0, 1/sqrt(2.d0)]
86  colloids%pos(:,4) = [0.d0, -1.d0, 1/sqrt(2.d0)]
87  colloids%pos = colloids%pos + 3
88 
89  links(:,1) = [1,2]
90  links(:,2) = [1,3]
91  links(:,3) = [1,4]
92  links(:,4) = [2,3]
93  links(:,5) = [2,4]
94  links(:,6) = [3,4]
95  do i = 1, n_link
96  links_dist(i) = sqrt(sum( &
97  rel_pos(colloids%pos(:,links(1,i)), colloids%pos(:,links(2,i)), solvent_cells%edges)**2 &
98  ))
99  end do
100 
101  call random_number(solvent% vel(:, :))
102  solvent% vel = (solvent% vel - 0.5d0)*sqrt(6.d0*2)
103  solvent% vel = solvent% vel - spread(sum(solvent% vel, dim=2)/solvent% Nmax, 2, solvent% Nmax)
104  solvent% force = 0
105  solvent% species = 1
106 
107  call solvent_cells%init(l, 1.d0)
108 
109  call solvent% random_placement(solvent_cells% edges, colloids, solvent_colloid_lj, state(1))
110 
111  call solvent% sort(solvent_cells)
112 
113  call neigh% init(colloids% Nmax, 1000)
114 
115  skin = 1.
116  call neigh% make_stencil(solvent_cells, sigma_cut+skin)
117 
118  tau = 1.
119  n_md_steps = 200
120  dt = tau / n_md_steps
121 
122  n_extra_sorting = 0
123 
124  call neigh% update_list(colloids, solvent, sigma_cut + skin, solvent_cells)
125 
126  e1 = compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
127  e2 = compute_force_n2(colloids, solvent_cells% edges, colloid_lj)
128  solvent% force_old = solvent% force
129  colloids% force_old = colloids% force
130 
131  write(*,*) ''
132  write(*,*) ' e co so | e co co | kin co | kin so | total | temp |'
133  write(*,*) ''
134 
135  solvent% pos_old = solvent% pos
136  colloids% pos_old = colloids% pos
137  do i = 1, 100
138  so_max = 0
139  co_max = 0
140  md_loop: do j = 1, n_md_steps
141  !$omp parallel do private(k, tmp_x)
142  do k = 1, solvent% Nmax
143  solvent% pos(:,k) = solvent% pos(:,k) + dt * solvent% vel(:,k) + dt**2 * solvent% force(:,k) / 2
144  end do
145 
146  ! Extra copy for rattle
147  colloids% pos_rattle = colloids% pos
148  do k=1, colloids% Nmax
149  colloids% pos(:,k) = colloids% pos(:,k) + dt * colloids% vel(:,k) + &
150  dt**2 * colloids% force(:,k) / (2 * colloids% mass(colloids%species(k)))
151  end do
152  call rattle_body_pos(colloids, links, links_dist, dt, solvent_cells% edges, 1d-12)
153 
154 
155  do k = 1, colloids% Nmax
156  colloids% pos(:,k) = colloids% pos(:,k) + dt * colloids% vel(:,k) + dt**2 * colloids% force(:,k) / (2 * colloids%mass(1))
157  end do
158  so_max = solvent% maximum_displacement()
159  co_max = colloids% maximum_displacement()
160 
161  if ( (co_max >= skin*0.2) .or. (so_max >= skin*0.8) ) then
162  call apply_pbc(solvent, solvent_cells% edges)
163  call apply_pbc(colloids, solvent_cells% edges)
164  call solvent% sort(solvent_cells)
165  call neigh% update_list(colloids, solvent, sigma_cut + skin, solvent_cells)
166  solvent% pos_old = solvent% pos
167  colloids% pos_old = colloids% pos
168  n_extra_sorting = n_extra_sorting + 1
169  end if
170 
171  call switch(solvent% force, solvent% force_old)
172  call switch(colloids% force, colloids% force_old)
173  solvent% force = 0
174  colloids% force = 0
175  e1 = compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
176  e2 = compute_force_n2(colloids, solvent_cells% edges, colloid_lj)
177 
178  !$omp parallel do private(k)
179  do k = 1, solvent% Nmax
180  solvent% vel(:,k) = solvent% vel(:,k) + dt * ( solvent% force(:,k) + solvent% force_old(:,k) ) / 2
181  end do
182  colloids% vel = colloids% vel + dt * ( colloids% force + colloids% force_old ) / (2 * colloids%mass(1))
183  call rattle_body_vel(colloids, links, links_dist, dt, solvent_cells% edges, 1d-9)
184 
185 
186  write(15,*) colloids% pos + colloids% image * spread(solvent_cells% edges, dim=2, ncopies=colloids% Nmax)
187 
188  end do md_loop
189 
190  call apply_pbc(solvent, solvent_cells%edges)
191  call apply_pbc(colloids, solvent_cells%edges)
192  call solvent% sort(solvent_cells)
193  call neigh% update_list(colloids, solvent, sigma_cut + skin, solvent_cells)
194  solvent% pos_old = solvent% pos
195  colloids% pos_old = colloids% pos
196 
197  call simple_mpcd_step(solvent, solvent_cells, state)
198 
199  write(*,'(6f16.3)') e1, e2, colloids%mass(1)*sum(colloids%vel**2)/2, sum(solvent% vel**2)/2, &
200  e1+e2+colloids%mass(1)*sum(colloids%vel**2)/2+sum(solvent% vel**2)/2, &
201  compute_temperature(solvent, solvent_cells)
202 
203  end do
204 
205  write(*,*) 'n extra sorting', n_extra_sorting
206 
207  call h5close_f(error)
208 
209 end program setup_simple_colloids
Derived type and routines for neighbor listing.
subroutine, public rattle_body_pos(p, links, distances, dt, edges, precision)
Definition: md.f90:322
double precision function, public compute_temperature(particles, cells, tz)
Compute the temperature of a mpcd solvent.
Definition: mpcd.f90:343
Data for particles.
subroutine, public simple_mpcd_step(particles, cells, state, alpha, thermostat, T, hydro)
Perform a collision.
Definition: mpcd.f90:72
double precision function, public compute_force(ps1, ps2, n_list, L, lj_params)
subroutine, public rattle_body_vel(p, links, distances, dt, edges, precision)
Definition: md.f90:411
subroutine, public apply_pbc(particles, edges)
Definition: md.f90:203
double precision function, public compute_force_n2(ps, L, lj_params)
Compute compact Hilbert indices.
Definition: hilbert.f90:9
Utility routines.
Definition: common.f90:12
integer, parameter dim
Definition: hilbert.f90:15
program setup_simple_colloids
Routines to perform MPCD dynamics.
Definition: mpcd.f90:18
Routines to perform Molecular Dynamics integration.
Definition: md.f90:13
pure double precision function, dimension(3), public rel_pos(x, y, L)
Return x-y distance with minimum image convention.
Definition: common.f90:163
Spatial cells.
Definition: cell_system.f90:11
Lennard-Jones potential definition.
Definition: interaction.f90:10