28 integer,
parameter :: rho = 10
29 integer,
parameter :: L(3) = [12, 12, 12]
30 integer,
parameter :: N = rho*l(1)*l(2)*l(3)
34 integer,
parameter :: n_link=6
35 integer :: links(2,n_link)
36 double precision:: links_dist(n_link)
38 double precision :: epsilon, sigma, sigma_cut
39 double precision :: so_max, co_max
41 double precision :: e1, e2
42 double precision :: tau, dt
44 integer :: n_extra_sorting
47 type(threefry_rng_t),
allocatable :: state(:)
49 double precision :: tmp_x(3)
50 double precision :: skin
55 n_threads = omp_get_max_threads()
56 allocate(state(n_threads))
57 call threefry_rng_init(state, -4466704919147519266_c_int64_t)
63 sigma_cut = sigma*2**(1.d0/6.d0)
65 call solvent_colloid_lj% init( reshape( [ epsilon ], [1, 1] ), &
66 reshape( [ sigma ], [1, 1] ), reshape( [ sigma_cut ], [1, 1] ) )
70 sigma_cut = sigma*2**(1.d0/6.d0)
72 call colloid_lj% init( reshape( [ epsilon ], [1, 1] ), &
73 reshape( [ 2*sigma ], [1, 1] ), reshape( [ 2*sigma_cut ], [1, 1] ) )
81 colloids%mass = rho*sigma**3*4*3.14159/3
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
96 links_dist(i) = sqrt(sum( &
97 rel_pos(colloids%pos(:,links(1,i)), colloids%pos(:,links(2,i)), solvent_cells%edges)**2 &
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)
107 call solvent_cells%init(l, 1.d0)
109 call solvent% random_placement(solvent_cells% edges, colloids, solvent_colloid_lj, state(1))
111 call solvent% sort(solvent_cells)
113 call neigh% init(colloids% Nmax, 1000)
116 call neigh% make_stencil(solvent_cells, sigma_cut+skin)
120 dt = tau / n_md_steps
124 call neigh% update_list(colloids, solvent, sigma_cut + skin, solvent_cells)
126 e1 =
compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
128 solvent% force_old = solvent% force
129 colloids% force_old = colloids% force
132 write(*,*)
' e co so | e co co | kin co | kin so | total | temp |' 135 solvent% pos_old = solvent% pos
136 colloids% pos_old = colloids% pos
140 md_loop:
do j = 1, n_md_steps
142 do k = 1, solvent% Nmax
143 solvent% pos(:,k) = solvent% pos(:,k) + dt * solvent% vel(:,k) + dt**2 * solvent% force(:,k) / 2
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)))
152 call rattle_body_pos(colloids, links, links_dist, dt, solvent_cells% edges, 1d-12)
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))
158 so_max = solvent% maximum_displacement()
159 co_max = colloids% maximum_displacement()
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
171 call switch(solvent% force, solvent% force_old)
172 call switch(colloids% force, colloids% force_old)
175 e1 =
compute_force(colloids, solvent, neigh, solvent_cells% edges, solvent_colloid_lj)
179 do k = 1, solvent% Nmax
180 solvent% vel(:,k) = solvent% vel(:,k) + dt * ( solvent% force(:,k) + solvent% force_old(:,k) ) / 2
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)
186 write(15,*) colloids% pos + colloids% image * spread(solvent_cells% edges,
dim=2, ncopies=colloids% Nmax)
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
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, &
205 write(*,*)
'n extra sorting', n_extra_sorting
207 call h5close_f(error)
Derived type and routines for neighbor listing.
subroutine, public rattle_body_pos(p, links, distances, dt, edges, precision)
double precision function, public compute_temperature(particles, cells, tz)
Compute the temperature of a mpcd solvent.
subroutine, public simple_mpcd_step(particles, cells, state, alpha, thermostat, T, hydro)
Perform a collision.
double precision function, public compute_force(ps1, ps2, n_list, L, lj_params)
subroutine, public rattle_body_vel(p, links, distances, dt, edges, precision)
subroutine, public apply_pbc(particles, edges)
double precision function, public compute_force_n2(ps, L, lj_params)
Compute compact Hilbert indices.
program setup_simple_colloids
Routines to perform MPCD dynamics.
Routines to perform Molecular Dynamics integration.
pure double precision function, dimension(3), public rel_pos(x, y, L)
Return x-y distance with minimum image convention.
Lennard-Jones potential definition.